🐛 PostListItems were not updating successfully when liked or edited
Signed-off-by: Pau Costa <mico@micodev.es>main
parent
2d9042235c
commit
a5e6a9505b
|
|
@ -55,23 +55,41 @@ export const fetchGlobalPosts = (): AppThunk => async (dispatch: any) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
export const likePost =
|
export const likePost =
|
||||||
(postId: number): AppThunk =>
|
(postId: number, postType?: "global" | "followed"): AppThunk =>
|
||||||
async (dispatch: any) => {
|
async (dispatch: any) => {
|
||||||
const postApi = createApi(store);
|
const postApi = createApi(store);
|
||||||
|
|
||||||
dispatch(setStatus(Status.loading));
|
dispatch(setStatus(Status.loading));
|
||||||
await postApi.likePost(postId);
|
await postApi.likePost(postId);
|
||||||
dispatch(setStatus(Status.idle));
|
dispatch(setStatus(Status.idle));
|
||||||
|
|
||||||
|
if (postType === "global") {
|
||||||
|
dispatch(fetchGlobalPosts());
|
||||||
|
} else if (postType === "followed") {
|
||||||
|
dispatch(fetchFollowedPosts());
|
||||||
|
} else {
|
||||||
|
dispatch(fetchFollowedPosts());
|
||||||
|
dispatch(fetchGlobalPosts());
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const unLikePost =
|
export const unLikePost =
|
||||||
(postId: number): AppThunk =>
|
(postId: number, postType?: "global" | "followed"): AppThunk =>
|
||||||
async (dispatch: any) => {
|
async (dispatch: any) => {
|
||||||
const postApi = createApi(store);
|
const postApi = createApi(store);
|
||||||
|
|
||||||
dispatch(setStatus(Status.loading));
|
dispatch(setStatus(Status.loading));
|
||||||
await postApi.unlikePost(postId);
|
await postApi.unlikePost(postId);
|
||||||
dispatch(setStatus(Status.idle));
|
dispatch(setStatus(Status.idle));
|
||||||
|
|
||||||
|
if (postType === "global") {
|
||||||
|
dispatch(fetchGlobalPosts());
|
||||||
|
} else if (postType === "followed") {
|
||||||
|
dispatch(fetchFollowedPosts());
|
||||||
|
} else {
|
||||||
|
dispatch(fetchFollowedPosts());
|
||||||
|
dispatch(fetchGlobalPosts());
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const fetchAPost =
|
export const fetchAPost =
|
||||||
|
|
@ -107,6 +125,28 @@ export const createPost =
|
||||||
dispatch(setStatus(Status.idle));
|
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 } =
|
export const { setFollowedPosts, setGlobalPosts, setStatus, setAPost } =
|
||||||
postSlice.actions;
|
postSlice.actions;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,8 @@ import { selectUserInfo } from "../app/loginSlice";
|
||||||
|
|
||||||
interface PostListItemProps {
|
interface PostListItemProps {
|
||||||
post: Post;
|
post: Post;
|
||||||
postType: "all" | "user";
|
postType: "feed" | "user";
|
||||||
|
feedType?: "global" | "followed";
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function PostListItem(props: PostListItemProps) {
|
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
|
props.post.likedBy?.some((user) => user.id === userInfo.id) || false
|
||||||
);
|
);
|
||||||
setNumberOfLikes(props.post.likedBy?.length || 0);
|
setNumberOfLikes(props.post.likedBy?.length || 0);
|
||||||
}, [props.post.likedBy, userInfo.id]);
|
}, [props.post, userInfo.id]);
|
||||||
|
|
||||||
const handleLike = () => {
|
const handleLike = () => {
|
||||||
if (!liked) {
|
if (!liked) {
|
||||||
setNumberOfLikes(numberOfLikes + 1);
|
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
|
// If the user has already liked the post, unlike it
|
||||||
else {
|
else {
|
||||||
setNumberOfLikes(numberOfLikes - 1);
|
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 = () => {
|
const handlePostClick = () => {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,11 @@
|
||||||
import { useSelector } from "react-redux";
|
import { useSelector } from "react-redux";
|
||||||
import { useParams } from "react-router-dom";
|
import { useNavigate, useParams } from "react-router-dom";
|
||||||
import { commentAPost, fetchAPost, selectAPost } from "../app/postSlice";
|
import {
|
||||||
|
commentAPost,
|
||||||
|
deletePost,
|
||||||
|
fetchAPost,
|
||||||
|
selectAPost,
|
||||||
|
} from "../app/postSlice";
|
||||||
import { useAppDispatch } from "../app/store";
|
import { useAppDispatch } from "../app/store";
|
||||||
import { useEffect } from "react";
|
import { useEffect } from "react";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
@ -14,13 +19,16 @@ import {
|
||||||
Typography,
|
Typography,
|
||||||
} from "@mui/material";
|
} from "@mui/material";
|
||||||
import { AppAvatar } from "../components/appAvatar";
|
import { AppAvatar } from "../components/appAvatar";
|
||||||
|
import { selectUserInfo } from "../app/loginSlice";
|
||||||
|
|
||||||
export default function PostView() {
|
export default function PostView() {
|
||||||
const postId = useParams<{ id: string }>().id;
|
const postId = useParams<{ id: string }>().id;
|
||||||
const storePost = useSelector(selectAPost);
|
const storePost = useSelector(selectAPost);
|
||||||
|
const selfUser = useSelector(selectUserInfo);
|
||||||
const [postToDisplay, setPostToDisplay] = React.useState<Post | null>(null);
|
const [postToDisplay, setPostToDisplay] = React.useState<Post | null>(null);
|
||||||
const [newComentText, setNewCommentText] = React.useState("");
|
const [newComentText, setNewCommentText] = React.useState("");
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
|
const navigate = useNavigate();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
dispatch(fetchAPost(parseInt(postId!, 10)));
|
dispatch(fetchAPost(parseInt(postId!, 10)));
|
||||||
|
|
@ -41,6 +49,11 @@ export default function PostView() {
|
||||||
setNewCommentText("");
|
setNewCommentText("");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleDeletePost = () => {
|
||||||
|
dispatch(deletePost(postToDisplay!.id!));
|
||||||
|
navigate("/global");
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
|
|
@ -77,6 +90,14 @@ export default function PostView() {
|
||||||
</Paper>
|
</Paper>
|
||||||
</Box>
|
</Box>
|
||||||
<Box sx={{ width: "100%" }}>
|
<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
|
<TextField
|
||||||
label="Add a comment..."
|
label="Add a comment..."
|
||||||
fullWidth
|
fullWidth
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,8 @@ import PostListItem from "../components/postListItem";
|
||||||
import { Status } from "../util/types";
|
import { Status } from "../util/types";
|
||||||
|
|
||||||
interface PostListProps {
|
interface PostListProps {
|
||||||
type: "all" | "user";
|
type: "feed" | "user";
|
||||||
|
feedType?: "global" | "followed";
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function PostList(props: PostListProps) {
|
export default function PostList(props: PostListProps) {
|
||||||
|
|
@ -25,12 +26,20 @@ export default function PostList(props: PostListProps) {
|
||||||
const [posts, setPosts] = useState<Post[]>([]);
|
const [posts, setPosts] = useState<Post[]>([]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
if (props.feedType === "global") {
|
||||||
dispatch(fetchGlobalPosts());
|
dispatch(fetchGlobalPosts());
|
||||||
|
} else {
|
||||||
dispatch(fetchFollowedPosts());
|
dispatch(fetchFollowedPosts());
|
||||||
}, []);
|
}
|
||||||
|
}, [props.feedType]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const postsToDisplay = props.type === "all" ? globalPosts : followedPosts;
|
let postsToDisplay: Post[];
|
||||||
|
if (props.feedType === "global") {
|
||||||
|
postsToDisplay = globalPosts;
|
||||||
|
} else {
|
||||||
|
postsToDisplay = followedPosts;
|
||||||
|
}
|
||||||
let sortedPosts: Post[] = [];
|
let sortedPosts: Post[] = [];
|
||||||
|
|
||||||
if (postsToDisplay.length > 0) {
|
if (postsToDisplay.length > 0) {
|
||||||
|
|
@ -43,7 +52,7 @@ export default function PostList(props: PostListProps) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
setPosts(sortedPosts);
|
setPosts(sortedPosts);
|
||||||
}, [followedPosts, globalPosts, props.type]);
|
}, [followedPosts, globalPosts, props.feedType]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box
|
<Box
|
||||||
|
|
@ -58,17 +67,27 @@ export default function PostList(props: PostListProps) {
|
||||||
<CircularProgress />
|
<CircularProgress />
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
{props.type === "all" && (
|
{props.feedType === "global" && (
|
||||||
<List>
|
<List>
|
||||||
{posts.map((post: Post) => (
|
{posts.map((post: Post) => (
|
||||||
<PostListItem post={post} postType="all" key={post.id} />
|
<PostListItem
|
||||||
|
post={post}
|
||||||
|
postType="feed"
|
||||||
|
feedType="global"
|
||||||
|
key={post.id}
|
||||||
|
/>
|
||||||
))}
|
))}
|
||||||
</List>
|
</List>
|
||||||
)}
|
)}
|
||||||
{props.type === "user" && (
|
{props.feedType === "followed" && (
|
||||||
<List>
|
<List>
|
||||||
{followedPosts.map((post: Post) => (
|
{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 && (
|
{followedPosts.length === 0 && (
|
||||||
<Box
|
<Box
|
||||||
|
|
|
||||||
|
|
@ -28,11 +28,17 @@ export class Post {
|
||||||
|
|
||||||
public deleteSensitiveFields(){
|
public deleteSensitiveFields(){
|
||||||
this.createdBy.deleteSensitiveFields()
|
this.createdBy.deleteSensitiveFields()
|
||||||
if(this.likedBy.length > 0){
|
if (this.likedBy) {
|
||||||
this.likedBy.forEach(user => user.deleteSensitiveFields())
|
if (this.likedBy.length > 0) {
|
||||||
|
this.likedBy.forEach((user) => user.deleteSensitiveFields());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (this.comments) {
|
||||||
|
if (this.comments.length > 0) {
|
||||||
|
this.comments.forEach((comment) =>
|
||||||
|
comment.createdBy.deleteSensitiveFields()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
if(this.comments.length > 0){
|
|
||||||
this.comments.forEach(comment => comment.createdBy.deleteSensitiveFields())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue