Skip to content

Commit

Permalink
[FIX] fix sns toggle likes and follow
Browse files Browse the repository at this point in the history
  • Loading branch information
CokeLee777 committed Jan 10, 2024
1 parent 11025a3 commit 8d66fdd
Show file tree
Hide file tree
Showing 8 changed files with 100 additions and 90 deletions.
21 changes: 4 additions & 17 deletions src/components/ootd/OOTDFollowComponent.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@ import { useFollowStore } from '@/stores/follow/FollowStore'
import { toggleFollow } from '@/apis/ootd/FollowService'
import { onBeforeRouteLeave } from 'vue-router'
import type { FollowingResponse } from '@/apis/ootd/FollowDto'
import { storeToRefs } from 'pinia'
const followStore = useFollowStore()
const follows = followStore.follows
const {follows} = storeToRefs(followStore)
const tabOptions = reactive([
{ label: '팔로워', value: 'follower' },
Expand All @@ -24,34 +25,20 @@ const onTabChange = async (tabOption: string) => {
const flushFollowStore = async () => {
const followingIds: number[] = []
follows.forEach((followingId: number) => {
follows.value.forEach((followingId: number) => {
followingIds.push(followingId)
})
if (followingIds.length !== 0) {
await toggleFollow(followingIds)
follows.clear()
await followStore.clearFollows()
}
}
// 페이지 이동 시 이벤트
onBeforeRouteLeave(async (to, from) => {
await flushFollowStore()
})
// 새로고침 or 브라우저 창 닫을 때 이벤트
window.addEventListener('beforeunload', async (event) => {
// event를 멈춰놓고 flush 성공시 리로드
event.returnValue = ''
flushFollowStore().then((res) => {
window.location.reload()
}).catch((error) => {
console.error(error)
event.preventDefault()
event.returnValue = ''
})
})
</script>

<template>
Expand Down
11 changes: 6 additions & 5 deletions src/components/ootd/OOTDFollowerTableComponent.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { getFollowers } from '@/apis/ootd/FollowService'
import { onBeforeMount, watch } from 'vue'
import PaginationComponent from '@/components/ootd/PaginationComponent.vue'
import { useFollowStore } from '@/stores/follow/FollowStore'
import { storeToRefs } from 'pinia'
const props = defineProps({
addedFollowings: {
Expand All @@ -23,7 +24,7 @@ const totalPages = ref<number>()
const totalElements = ref<number>()
const followStore = useFollowStore()
const follows = followStore.follows
const {follows} = storeToRefs(followStore)
const fetchDefaultData = async (): Promise<FollowerPageResponse<FollowerResponse>> => {
const followerPageResponse = await getFollowers(0, 5, 'createdAt,desc')
Expand Down Expand Up @@ -58,7 +59,7 @@ const followButtonClickListener = (followerId: number, isFollowing: boolean | un
// 이미 팔로잉하는 상태라면
if(isFollowing) {
// 언팔로우
if(!follows.has(followerId)) {
if(!followStore.hasFollowingId(followerId)) {
followers.value?.forEach((follower) => {
if(follower.id === followerId) {
props.addedFollowings!.push({
Expand All @@ -81,7 +82,7 @@ const followButtonClickListener = (followerId: number, isFollowing: boolean | un
// 아니라면
else {
// 언팔로우
if(follows.has(followerId)) {
if(followStore.hasFollowingId(followerId)) {
const indexToRemove = props.addedFollowings!.findIndex((following) => following.id === followerId)
if (indexToRemove !== -1) {
props.addedFollowings?.splice(indexToRemove, 1)
Expand All @@ -101,7 +102,7 @@ const followButtonClickListener = (followerId: number, isFollowing: boolean | un
})
}
}
follows.has(followerId) ? follows.delete(followerId) : follows.add(followerId)
followStore.toggleFollows(followerId)
}
const img = ref<Array<HTMLImageElement>>(new Array<HTMLImageElement>())
Expand Down Expand Up @@ -142,7 +143,7 @@ const handleImageLoad = async () => {
{{ follower.nickname }}
</RouterLink>
</div>
<div v-if='follows.has(follower.id) ? !follower.isFollowing : follower.isFollowing'
<div v-if='followStore.hasFollowingId(follower.id) ? !follower.isFollowing : follower.isFollowing'
class='follow-btn following'
@click='followButtonClickListener(follower.id, follower.isFollowing)'>
<svg
Expand Down
7 changes: 4 additions & 3 deletions src/components/ootd/OOTDFollowingTableComponent.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import PaginationComponent from '@/components/ootd/PaginationComponent.vue'
import type { FollowingPageResponse, FollowingResponse } from '@/apis/ootd/FollowDto'
import { getFollowings } from '@/apis/ootd/FollowService'
import { useFollowStore } from '@/stores/follow/FollowStore'
import { storeToRefs } from 'pinia'
const props = defineProps({
addedFollowings: {
Expand All @@ -21,7 +22,7 @@ const totalPages = ref<number>()
const totalElements = ref<number>()
const followStore = useFollowStore()
const follows = followStore.follows
const {follows} = storeToRefs(followStore)
const fetchDefaultData = async (): Promise<FollowingPageResponse<FollowingResponse>> => {
const followingPageResponse = await getFollowings(0, 5, 'createdAt,desc')
Expand Down Expand Up @@ -60,7 +61,7 @@ watch(requestPage, async (afterPage, beforePage) => {
})
const followButtonClickListener = (followingId: number, isFollowing: boolean | undefined) => {
follows.has(followingId) ? follows.delete(followingId) : follows.add(followingId)
followStore.toggleFollows(followingId)
}
const followingEmits = defineEmits(['followings'])
Expand Down Expand Up @@ -104,7 +105,7 @@ const handleImageLoad = async () => {
{{ following.nickname }}
</RouterLink>
</div>
<div v-if='follows.has(following.id) ? !following.isFollowing : following.isFollowing'
<div v-if='followStore.hasFollowingId(following.id) ? !following.isFollowing : following.isFollowing'
class='follow-btn following'
@click='followButtonClickListener(following.id, following.isFollowing)'>
<svg
Expand Down
36 changes: 12 additions & 24 deletions src/components/ootd/OOTDPostCardComponent.vue
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
<script setup lang='ts'>
import { onBeforeMount, onBeforeUnmount, onUnmounted, ref } from 'vue'
import { ref } from 'vue'
import type { PostResponse } from '@/apis/ootd/PostDto'
import { usePostLikeStore } from '@/stores/postlike/PostLikeStore'
import router from '@/router'
import { onBeforeRouteLeave } from 'vue-router'
import { storeToRefs } from 'pinia'
import { togglePostLike } from '@/apis/ootd/PostLikeService'
const VITE_STATIC_IMG_URL = ref<string>(import.meta.env.VITE_STATIC_IMG_URL)
const props = defineProps({
Expand All @@ -17,32 +16,34 @@ const props = defineProps({
})
const postLikeStore = usePostLikeStore()
const postLikes = postLikeStore.postLikes
const likeButtonClickListener = (postId: number, isLike: boolean | undefined) => {
const {postLikes} = storeToRefs(postLikeStore)
const likeButtonClickListener = async (postId: number, isLike: boolean | undefined) => {
if (isLike === undefined) {
alert('로그인이 필요합니다.')
} else {
const postIndex = props.posts.findIndex((post) => post.id === postId)
if (postIndex !== -1) {
if (postLikes.has(postId)) {
const hasPostLike = postLikeStore.hasPostLike(postId)
if (hasPostLike) {
props.posts[postIndex].isLike ? props.posts[postIndex].likeCount += 1 : props.posts[postIndex].likeCount -= 1
} else {
props.posts[postIndex].isLike ? props.posts[postIndex].likeCount -= 1 : props.posts[postIndex].likeCount += 1
}
postLikes.has(postId) ? postLikes.delete(postId) : postLikes.add(postId)
await postLikeStore.togglePostLikes(postId)
}
}
}
const flushLikeStore = async () => {
const postIds: number[] = []
postLikes.forEach((postLike) => {
postIds.push(postLike)
postLikes.value.forEach((storedPostLike) => {
postIds.push(storedPostLike)
})
if (postIds.length !== 0) {
await togglePostLike(postIds)
postLikes.clear()
await postLikeStore.clearPostLikes()
}
}
Expand All @@ -51,19 +52,6 @@ onBeforeRouteLeave(async (to, from) => {
await flushLikeStore()
})
// 새로고침 or 브라우저 창 닫을 때 이벤트
window.addEventListener('beforeunload', async (event) => {
// event를 멈춰놓고 flush 성공시 리로드
event.returnValue = ''
flushLikeStore().then((res) => {
window.location.reload()
}).catch((error) => {
console.error(error)
event.preventDefault()
event.returnValue = ''
})
})
const img = ref<Array<HTMLImageElement>>(new Array<HTMLImageElement>())
const imageSize = ref({
width: 0,
Expand Down Expand Up @@ -104,7 +92,7 @@ const handleImageLoad = async () => {
<svg class='ootd-post-card-like' xmlns='http://www.w3.org/2000/svg'
viewBox='0 0 44 42' fill='none'>
<path class='ootd-post-card-like-icon'
:class="{ 'selected': post.isLike === undefined ? false : (postLikes.has(post.id) ? !post.isLike : post.isLike) }"
:class="{ 'selected': post.isLike === undefined ? false : (postLikeStore.hasPostLike(post.id) ? !post.isLike : post.isLike) }"
d='M21.3268 39.4395L22 40.0523L22.6732 39.4395L25.5717 36.8008C25.5718 36.8007 25.5719 36.8007 25.572 36.8006C30.7022 32.1485 35.0416 28.2134 38.0868 24.4879C41.143 20.7488 43 17.0988 43 13C43 6.26652 37.7111 1 31 1C27.6025 1 24.3411 2.41653 22 4.70025C19.6589 2.41653 16.3975 1 13 1C6.28891 1 1 6.26652 1 13C1 17.0988 2.85704 20.7488 5.91324 24.4879C8.9584 28.2134 13.2978 32.1485 18.428 36.8006C18.4281 36.8007 18.4282 36.8007 18.4283 36.8008L21.3268 39.4395Z'
fill='#DADADA' fill-opacity='0.4' stroke='white' stroke-width='2' />
</svg>
Expand Down
9 changes: 5 additions & 4 deletions src/components/ootd/OOTDProfileCardComponent.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,14 @@ import { toggleFollow } from '@/apis/ootd/FollowService'
import { onBeforeRouteLeave } from 'vue-router'
import { useMemberStore } from '@/stores/member/MemberStore'
import type { GiftInfo } from '@/apis/order/orderDto'
import { storeToRefs } from 'pinia'
const emit = defineEmits(['fetchData'])
const memberStore = useMemberStore()
const memberId = memberStore.getMemberInfo().memberId
const nickname = memberStore.nickname ? memberStore.nickname : ''
const followStore = useFollowStore()
const follows = followStore.follows
const {follows} = storeToRefs(followStore)
const VITE_STATIC_IMG_URL = ref<string>(import.meta.env.VITE_STATIC_IMG_URL)
Expand Down Expand Up @@ -62,20 +63,20 @@ const followButtonClickListener = (followingId: number, isFollowing: boolean | u
? (member.value!.followerCount -= 1)
: (member.value!.followerCount += 1)
member.value!.isFollowing = !isFollowing
follows.has(followingId) ? follows.delete(followingId) : follows.add(followingId)
followStore.toggleFollows(followingId)
}
}
const flushFollowStore = async () => {
const followingIds: number[] = []
follows.forEach((followingId: number) => {
follows.value.forEach((followingId: number) => {
followingIds.push(followingId)
})
if (followingIds.length !== 0) {
await toggleFollow(followingIds)
follows.clear()
await followStore.clearFollows()
}
}
Expand Down
30 changes: 27 additions & 3 deletions src/stores/follow/FollowStore.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,32 @@
import { defineStore } from 'pinia'
import { ref } from 'vue'
import { type Ref, ref } from 'vue'

export const useFollowStore
= defineStore('follow', () => {
const follows = ref<Set<number>>(new Set<number>())
return { follows }
const follows: Ref<number[]> = ref<number[]>([])

const toggleFollows = async (followingId: number) => {
const findIndex = follows.value.indexOf(followingId)
if (findIndex === -1) {
follows.value.push(followingId)
} else {
follows.value.splice(findIndex, 1)
}
}

const hasFollowingId = (followingId: number) => {
return follows.value.includes(followingId)
}

const clearFollows = async () => {
follows.value = []
}

return { follows, clearFollows, hasFollowingId, toggleFollows }
}, {
persist: {
key: 'follows',
storage: localStorage,
paths: ['follows']
}
})
34 changes: 30 additions & 4 deletions src/stores/postlike/PostLikeStore.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,34 @@
import { defineStore } from 'pinia'
import { ref } from 'vue'
import { type Ref, ref } from 'vue'

export const usePostLikeStore
= defineStore('postLike', () => {
const postLikes = ref<Set<number>>(new Set<number>())
return { postLikes }
})

const postLikes: Ref<number[]> = ref<number[]>([])

const togglePostLikes = async (postId: number) => {
const findIndex = postLikes.value.indexOf(postId)
if (findIndex === -1) {
postLikes.value.push(postId)
} else {
postLikes.value.splice(findIndex, 1)
}
}

const hasPostLike = (postId: number) => {
return postLikes.value.includes(postId)
}

const clearPostLikes = async () => {
postLikes.value = []
}

return { postLikes, clearPostLikes, hasPostLike, togglePostLikes }
}, {
persist: {
key: 'postLikes',
storage: localStorage,
paths: ['postLikes']
}
}
)
Loading

0 comments on commit 8d66fdd

Please sign in to comment.