Skip to content

Commit

Permalink
Feat/backend integration bookmark (#83)
Browse files Browse the repository at this point in the history
* feat: 북마크 생성 백엔드 연결 및 변수명 직관적으로 변경

수정사항
- 북마크 생성 백엔드 연결
- api.js의 좋아요 생성 변수명 변경 (postHeart -> createLike)
- PostPage의 handleHeart <-> handleHeart 변수명 변경

* feat: 좋아요 및 북마크한 게시물의 색상 변화가 유지되도록 수정

수정사항
- 사용자가 좋아요 및 북마크한 게시물의 색상 변화, 즉 상태가 유지되도록 수정

* fix: 서버 데이터 구조 변경에 따른 북마크한 글 조회 오류 수정

수정사항
- 모든 북마크 조회 api 서버 데이터 구조가 바뀜에 따라, 북마크한 글 조회를 할 수 있게 조건부로 수정

* style: Prettier & ESLint 적용
  • Loading branch information
nnyouung authored Jul 21, 2024
1 parent ad3c279 commit 11e4dba
Show file tree
Hide file tree
Showing 6 changed files with 155 additions and 58 deletions.
38 changes: 22 additions & 16 deletions src/components/community/IconBookmark.jsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,26 @@
import * as React from "react";
import Svg, { Path } from "react-native-svg";

const IconBookmark = (props) => (
<Svg
xmlns="http://www.w3.org/2000/svg"
width={16}
height={17}
fill="none"
{...props}
>
<Path
fill="#CDCFD5"
fillRule="evenodd"
d="M10.451 7.146h-4.57a.5.5 0 0 1 0-1h4.57a.5.5 0 0 1 0 1Zm3.028 2.015-.002-1.374c0-5.063-.793-5.953-5.31-5.953-4.517 0-5.31.89-5.31 5.953L2.853 9.16c-.006 3.75-.009 5.154.564 5.726.185.186.431.28.73.28.637 0 1.345-.604 2.095-1.245.664-.567 1.417-1.21 1.924-1.21.507 0 1.26.643 1.923 1.21.75.64 1.458 1.245 2.095 1.245.3 0 .545-.094.73-.28.573-.572.57-1.976.565-5.726Z"
clipRule="evenodd"
/>
</Svg>
);
import { CustomTheme } from "@styles/CustomTheme";

const IconBookmark = ({ props, active }) => {
const color = active ? CustomTheme.pointYellow : CustomTheme.borderColor;
return (
<Svg
xmlns="http://www.w3.org/2000/svg"
width={16}
height={17}
fill="none"
{...props}
>
<Path
fill={color}
fillRule="evenodd"
d="M10.451 7.146h-4.57a.5.5 0 0 1 0-1h4.57a.5.5 0 0 1 0 1Zm3.028 2.015-.002-1.374c0-5.063-.793-5.953-5.31-5.953-4.517 0-5.31.89-5.31 5.953L2.853 9.16c-.006 3.75-.009 5.154.564 5.726.185.186.431.28.73.28.637 0 1.345-.604 2.095-1.245.664-.567 1.417-1.21 1.924-1.21.507 0 1.26.643 1.923 1.21.75.64 1.458 1.245 2.095 1.245.3 0 .545-.094.73-.28.573-.572.57-1.976.565-5.726Z"
clipRule="evenodd"
/>
</Svg>
);
};

export default IconBookmark;
6 changes: 3 additions & 3 deletions src/components/community/ItemComment.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, { useState, useEffect } from "react";
import { View, Text, StyleSheet, TouchableOpacity, Alert } from "react-native";

import { CustomTheme } from "@styles/CustomTheme";
import { postHeart } from "config/api";
import { createLike } from "config/api";

import IconHeart from "@components/community/IconHeart";
import IconBookmark from "@components/community/IconBookmark";
Expand Down Expand Up @@ -32,7 +32,7 @@ const ItemComment = ({ props, id }) => {

const heartCommentAlert = async (commentId) => {
try {
await postHeart("COMMENT", id, commentId);
await createLike("COMMENT", id, commentId);
console.log("댓글 좋아요 성공");
} catch (error) {
console.error(
Expand Down Expand Up @@ -125,7 +125,7 @@ const ItemComment = ({ props, id }) => {
</View>
<View style={styles.containerText}>
<Text style={styles.text}>
{date(post.created)}
{date(post.date)}
</Text>
</View>
</View>
Expand Down
12 changes: 7 additions & 5 deletions src/components/member/ItemLikeBookmark.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { CustomTheme } from "@styles/CustomTheme";

const { fontCaption, fontNavi } = CustomTheme;

const ItemLikeBookmark = ({ props }) => {
const ItemLikeBookmark = ({ props, type = "like" }) => {
const navigation = useNavigation();

return (
Expand All @@ -27,15 +27,17 @@ const ItemLikeBookmark = ({ props }) => {
post.image ? { width: 196 } : {},
]}
>
{post.title}
{type === "like" ? post.title : post.post.title}
</Text>
<Text
style={[
styles.textPostContext,
post.image ? { width: 196 } : {},
]}
>
{post.content}
{type === "like"
? post.content
: post.post.content}
</Text>
</View>

Expand All @@ -55,10 +57,10 @@ const ItemLikeBookmark = ({ props }) => {
const styles = StyleSheet.create({
ItemCommunity: {
width: "100%",
height: 78,
height: 62,
backgroundColor: CustomTheme.bgBasic,
borderRadius: 20,
borderWidth: 2,
borderWidth: 3,
borderColor: CustomTheme.primaryBg,
paddingHorizontal: 20,
justifyContent: "center",
Expand Down
12 changes: 10 additions & 2 deletions src/config/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -139,10 +139,18 @@ export const getCommentById = (id) => {
return api.get(`comments/${id}`);
};

export const postHeart = (type, id, commentId) => {
export const createLike = (type, postId, commentId) => {
return api.post("/likes", {
type: type,
postId: id,
postId: postId,
commentId: commentId,
});
};

export const createBookmark = (chatroomId, chatId, postId) => {
return api.post("/bookmarks", {
chatroomId: chatroomId,
chatId: chatId,
postId: postId,
});
};
139 changes: 108 additions & 31 deletions src/pages/community/PostPage.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useState } from "react";
import React, { useState, useEffect } from "react";
import {
TouchableOpacity,
Text,
Expand All @@ -12,16 +12,19 @@ import {
Alert,
} from "react-native";
import { useFocusEffect } from "@react-navigation/native";
import * as SecureStore from "expo-secure-store";

import PostStyles from "@pages/community/PostStyles";
import { CustomTheme } from "@styles/CustomTheme";
import { useOnboarding } from "src/states/OnboardingContext.js";
import { usePostModify } from "src/states/PostModifyContext";
import {
getPostById,
getCommentById,
postCommentSend,
postHeart,
createLike,
createBookmark,
getLikedPost,
getBookmarkPost,
} from "config/api";

import TopBar from "@components/common/TopBar";
Expand All @@ -39,6 +42,7 @@ const PostPage = ({ route }) => {
const [modalVisible, setModalVisible] = useState(false);

const { id } = route.params;
const { onboardingData } = useOnboarding();
const { updatePostModifyData } = usePostModify();

const [title, setTitle] = useState("");
Expand Down Expand Up @@ -70,31 +74,28 @@ const PostPage = ({ route }) => {
const postComment = async () => {
try {
const postByIdResponse = await getPostById(id);
const postData = postByIdResponse.data;
setTitle(postData.title);
setContext(postData.content);
setHeart(postData.likesCount);
setBookmark(postData.bookmarkCount);
setCreated(date(postData.created));
setIsPublic(postData.isPublic);

if (postData.isPublic === false) {
setWriterName(postData.writer.username);
} else if (postData.isPublic === true) {
setTitle(postByIdResponse.data.title);
setContext(postByIdResponse.data.content);
setHeart(postByIdResponse.data.likesCount);
setBookmark(postByIdResponse.data.bookmarkCount);
setCreated(date(postByIdResponse.data.created));
setIsPublic(postByIdResponse.data.isPublic);

if (postByIdResponse.data.isPublic === false) {
setWriterName(postByIdResponse.data.writer.username);
} else if (postByIdResponse.data.isPublic === true) {
setWriterName("익명");
}

const memberId =
await SecureStore.getItemAsync("member_id");
if (memberId === postData.writer.id) {
if (onboardingData.id === postByIdResponse.data.writer.id) {
setIsMe(true);
updatePostModifyData({
memberId: postData.writer.id,
memberId: postByIdResponse.data.writer.id,
id: id,
title: postData.title,
context: postData.content,
boardType: postData.boardType,
isPublic: postData.isPublic,
title: postByIdResponse.data.title,
context: postByIdResponse.data.content,
boardType: postByIdResponse.data.boardType,
isPublic: postByIdResponse.data.isPublic,
});
}

Expand All @@ -104,7 +105,11 @@ const PostPage = ({ route }) => {
console.log("게시글 및 댓글 조회 성공");
} catch (error) {
console.error(
"게시글 및 댓글 조회 오류:",
"게시글 조회 오류:",
error.response ? error.response.data : error.message,
);
console.error(
"댓글 조회 오류:",
error.response ? error.response.data : error.message,
);
}
Expand Down Expand Up @@ -173,9 +178,9 @@ const PostPage = ({ route }) => {

const [pressHeart, setPressHeart] = useState();

const heartAlert = async () => {
const handleHeart = async () => {
try {
await postHeart("POST", id);
await createLike("POST", id);
console.log("게시글 좋아요 성공");
} catch (error) {
console.error(
Expand All @@ -187,7 +192,7 @@ const PostPage = ({ route }) => {
}
};

const handleHeart = () => {
const heartAlert = () => {
Alert.alert(
"",
"이 게시물에 좋아요를 누르시겠습니까?",
Expand All @@ -201,14 +206,83 @@ const PostPage = ({ route }) => {
onPress: () => {
setHeart((prevHeart) => prevHeart + 1);
setPressHeart(true);
heartAlert();
handleHeart();
},
},
],
{ cancelable: false },
);
};

const likedPosts = async () => {
try {
const response = await getLikedPost();
const likedPostIdList = response.data.map((item) => item.id);
setPressHeart(likedPostIdList.includes(id));
} catch (error) {
console.error(
"좋아요 상태 조회 실패:",
error.response ? error.response.data : error.message,
);
}
};

const [pressBookmark, setPressBookmark] = useState();

const handleBookmark = async () => {
try {
await createBookmark(null, null, id);
console.log("게시글 북마크 성공");
} catch (error) {
console.error(
"게시글 북마크 실패:",
error.response ? error.response.data : error.message,
);
setBookmark((prevBookmark) => prevBookmark - 1);
setPressBookmark(false);
}
};

const bookmarkAlert = () => {
Alert.alert(
"",
"이 게시물을 북마크하시겠습니까?",
[
{
text: "취소",
style: "cancel",
},
{
text: "확인",
onPress: () => {
setBookmark((prevBookmark) => prevBookmark + 1);
setPressBookmark(true);
handleBookmark();
},
},
],
{ cancelable: false },
);
};

const bookmarkedPosts = async () => {
try {
const response = await getBookmarkPost();
const bookmarkedPostIdList = response.data.map((item) => item.id);
setPressBookmark(bookmarkedPostIdList.includes(id));
} catch (error) {
console.error(
"북마크 상태 조회 실패:",
error.response ? error.response.data : error.message,
);
}
};

useEffect(() => {
likedPosts();
bookmarkedPosts();
}, [id]);

return (
<SafeAreaView style={PostStyles.container}>
<View onLayout={handleTopBarLayout}>
Expand Down Expand Up @@ -248,15 +322,18 @@ const PostPage = ({ route }) => {
<View style={PostStyles.containerIconRow}>
<TouchableOpacity
style={PostStyles.iconRow}
onPress={handleHeart}
onPress={heartAlert}
>
<IconHeart active={pressHeart} />
<Text style={PostStyles.textIcon}>{heart}</Text>
</TouchableOpacity>
<View style={PostStyles.iconRow}>
<IconBookmark />
<TouchableOpacity
style={PostStyles.iconRow}
onPress={bookmarkAlert}
>
<IconBookmark active={pressBookmark} />
<Text style={PostStyles.textIcon}>{bookmark}</Text>
</View>
</TouchableOpacity>
<TouchableOpacity style={PostStyles.textTranslation}>
<Text style={PostStyles.textTranslation}>
번역하기
Expand Down
6 changes: 5 additions & 1 deletion src/pages/member/BookmarkPostPage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const BookmarkPostPage = () => {
try {
const bookmarkPostResponse = await getBookmarkPost();
setBookmarkPostList(bookmarkPostResponse.data);
console.log(bookmarkPostResponse.data);
} catch (error) {
console.error(
"북마크한 게시글 조회 오류:",
Expand All @@ -28,7 +29,10 @@ const BookmarkPostPage = () => {
<View style={BookmarkPostStyles.container}>
<ScrollView>
<View style={BookmarkPostStyles.itemLikeBookmark}>
<ItemLikeBookmark props={bookmarkPostList} />
<ItemLikeBookmark
props={bookmarkPostList}
type="bookmark"
/>
</View>
</ScrollView>
</View>
Expand Down

0 comments on commit 11e4dba

Please sign in to comment.