🐛 PostListItems were not updating successfully when liked or edited

Signed-off-by: Pau Costa <mico@micodev.es>
main
Pau Costa Ferrer 2024-02-12 12:04:21 +01:00
parent 2d9042235c
commit a5e6a9505b
5 changed files with 112 additions and 25 deletions

View File

@ -55,23 +55,41 @@ export const fetchGlobalPosts = (): AppThunk => async (dispatch: any) => {
};
export const likePost =
(postId: number): AppThunk =>
(postId: number, postType?: "global" | "followed"): AppThunk =>
async (dispatch: any) => {
const postApi = createApi(store);
dispatch(setStatus(Status.loading));
await postApi.likePost(postId);
dispatch(setStatus(Status.idle));
if (postType === "global") {
dispatch(fetchGlobalPosts());
} else if (postType === "followed") {
dispatch(fetchFollowedPosts());
} else {
dispatch(fetchFollowedPosts());
dispatch(fetchGlobalPosts());
}
};
export const unLikePost =
(postId: number): AppThunk =>
(postId: number, postType?: "global" | "followed"): AppThunk =>
async (dispatch: any) => {
const postApi = createApi(store);
dispatch(setStatus(Status.loading));
await postApi.unlikePost(postId);
dispatch(setStatus(Status.idle));
if (postType === "global") {
dispatch(fetchGlobalPosts());
} else if (postType === "followed") {
dispatch(fetchFollowedPosts());
} else {
dispatch(fetchFollowedPosts());
dispatch(fetchGlobalPosts());
}
};
export const fetchAPost =
@ -107,6 +125,28 @@ export const createPost =
dispatch(setStatus(Status.idle));
};
export const updatePost =
(postId: number, title: string, content: string): AppThunk =>
async (dispatch: any) => {
const postApi = createApi(store);
dispatch(setStatus(Status.loading));
await postApi.updatePost(postId, { title, content });
dispatch(fetchAPost(postId));
dispatch(fetchGlobalPosts());
dispatch(setStatus(Status.idle));
};
export const deletePost =
(postId: number): AppThunk =>
async (dispatch: any) => {
const postApi = createApi(store);
dispatch(setStatus(Status.loading));
await postApi.deletePost(postId);
dispatch(setStatus(Status.idle));
};
export const { setFollowedPosts, setGlobalPosts, setStatus, setAPost } =
postSlice.actions;

View File

@ -21,7 +21,8 @@ import { selectUserInfo } from "../app/loginSlice";
interface PostListItemProps {
post: Post;
postType: "all" | "user";
postType: "feed" | "user";
feedType?: "global" | "followed";
}
export default function PostListItem(props: PostListItemProps) {
@ -40,19 +41,19 @@ export default function PostListItem(props: PostListItemProps) {
props.post.likedBy?.some((user) => user.id === userInfo.id) || false
);
setNumberOfLikes(props.post.likedBy?.length || 0);
}, [props.post.likedBy, userInfo.id]);
}, [props.post, userInfo.id]);
const handleLike = () => {
if (!liked) {
setNumberOfLikes(numberOfLikes + 1);
dispatch(likePost(props.post.id as number));
dispatch(likePost(props.post.id as number, props.feedType));
}
// If the user has already liked the post, unlike it
else {
setNumberOfLikes(numberOfLikes - 1);
dispatch(unLikePost(props.post.id as number));
dispatch(unLikePost(props.post.id as number, props.feedType));
}
setLiked((prevState) => !prevState);
setLiked(!liked);
};
const handlePostClick = () => {

View File

@ -1,6 +1,11 @@
import { useSelector } from "react-redux";
import { useParams } from "react-router-dom";
import { commentAPost, fetchAPost, selectAPost } from "../app/postSlice";
import { useNavigate, useParams } from "react-router-dom";
import {
commentAPost,
deletePost,
fetchAPost,
selectAPost,
} from "../app/postSlice";
import { useAppDispatch } from "../app/store";
import { useEffect } from "react";
import React from "react";
@ -14,13 +19,16 @@ import {
Typography,
} from "@mui/material";
import { AppAvatar } from "../components/appAvatar";
import { selectUserInfo } from "../app/loginSlice";
export default function PostView() {
const postId = useParams<{ id: string }>().id;
const storePost = useSelector(selectAPost);
const selfUser = useSelector(selectUserInfo);
const [postToDisplay, setPostToDisplay] = React.useState<Post | null>(null);
const [newComentText, setNewCommentText] = React.useState("");
const dispatch = useAppDispatch();
const navigate = useNavigate();
useEffect(() => {
dispatch(fetchAPost(parseInt(postId!, 10)));
@ -41,6 +49,11 @@ export default function PostView() {
setNewCommentText("");
};
const handleDeletePost = () => {
dispatch(deletePost(postToDisplay!.id!));
navigate("/global");
};
return (
<Box
sx={{
@ -77,6 +90,14 @@ export default function PostView() {
</Paper>
</Box>
<Box sx={{ width: "100%" }}>
{postToDisplay?.createdBy?.id === selfUser?.id && (
<Box>
<Button onClick={() => navigate("edit")}>Edit</Button>
<Button color="warning" onClick={handleDeletePost}>
Delete
</Button>
</Box>
)}
<TextField
label="Add a comment..."
fullWidth

View File

@ -14,7 +14,8 @@ import PostListItem from "../components/postListItem";
import { Status } from "../util/types";
interface PostListProps {
type: "all" | "user";
type: "feed" | "user";
feedType?: "global" | "followed";
}
export default function PostList(props: PostListProps) {
@ -25,12 +26,20 @@ export default function PostList(props: PostListProps) {
const [posts, setPosts] = useState<Post[]>([]);
useEffect(() => {
dispatch(fetchGlobalPosts());
dispatch(fetchFollowedPosts());
}, []);
if (props.feedType === "global") {
dispatch(fetchGlobalPosts());
} else {
dispatch(fetchFollowedPosts());
}
}, [props.feedType]);
useEffect(() => {
const postsToDisplay = props.type === "all" ? globalPosts : followedPosts;
let postsToDisplay: Post[];
if (props.feedType === "global") {
postsToDisplay = globalPosts;
} else {
postsToDisplay = followedPosts;
}
let sortedPosts: Post[] = [];
if (postsToDisplay.length > 0) {
@ -43,7 +52,7 @@ export default function PostList(props: PostListProps) {
});
}
setPosts(sortedPosts);
}, [followedPosts, globalPosts, props.type]);
}, [followedPosts, globalPosts, props.feedType]);
return (
<Box
@ -58,17 +67,27 @@ export default function PostList(props: PostListProps) {
<CircularProgress />
) : (
<>
{props.type === "all" && (
{props.feedType === "global" && (
<List>
{posts.map((post: Post) => (
<PostListItem post={post} postType="all" key={post.id} />
<PostListItem
post={post}
postType="feed"
feedType="global"
key={post.id}
/>
))}
</List>
)}
{props.type === "user" && (
{props.feedType === "followed" && (
<List>
{followedPosts.map((post: Post) => (
<PostListItem post={post} postType="user" key={post.id} />
<PostListItem
post={post}
postType="feed"
feedType="followed"
key={post.id}
/>
))}
{followedPosts.length === 0 && (
<Box

View File

@ -28,11 +28,17 @@ export class Post {
public deleteSensitiveFields(){
this.createdBy.deleteSensitiveFields()
if(this.likedBy.length > 0){
this.likedBy.forEach(user => user.deleteSensitiveFields())
if (this.likedBy) {
if (this.likedBy.length > 0) {
this.likedBy.forEach((user) => user.deleteSensitiveFields());
}
}
if(this.comments.length > 0){
this.comments.forEach(comment => comment.createdBy.deleteSensitiveFields())
if (this.comments) {
if (this.comments.length > 0) {
this.comments.forEach((comment) =>
comment.createdBy.deleteSensitiveFields()
);
}
}
}