Skip to content

Commit f5e7937

Browse files
authored
Merge pull request #114 from dnd-side-project/fix/#113/cd-api-ui
[fix] μ±„νŒ… 총 갯수, μ’‹μ•„μš” API μ—°κ²° 및 UI μˆ˜μ •μ‚¬ν•­ 반영
2 parents 2ab2a4e + 5905768 commit f5e7937

File tree

36 files changed

+636
-299
lines changed

36 files changed

+636
-299
lines changed

β€Žsrc/assets/icons/icn_cta_arrow.svgβ€Ž

Lines changed: 0 additions & 3 deletions
This file was deleted.
Lines changed: 2 additions & 2 deletions
Loading

β€Žsrc/assets/icons/index.tsβ€Ž

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,5 +47,4 @@ export { default as BgCd } from './icn_bg_cd.svg?react'
4747
export { default as BgHeadphone } from './icn_bg_headphone.svg?react'
4848
export { default as BgMusic } from './icn_bg_music.svg?react'
4949
export { default as Volume } from './icn_volume.svg?react'
50-
export { default as CtaArrow } from './icn_cta_arrow.svg?react'
5150
export { default as LikeStroke } from './icn_like_stroke.svg?react'
-33.5 KB
Loading

β€Žsrc/features/chat/api/chat.tsβ€Ž

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
import type { ChatHistoryParams, ChatHistoryResponse } from '@/features/chat/types/chat'
1+
import type {
2+
ChatCountResponse,
3+
ChatHistoryParams,
4+
ChatHistoryResponse,
5+
} from '@/features/chat/types/chat'
26
import { api } from '@/shared/api/httpClient'
37

48
export const getChatHistory = (roomId: string, params: ChatHistoryParams = {}) => {
@@ -10,3 +14,7 @@ export const getChatHistory = (roomId: string, params: ChatHistoryParams = {}) =
1014
export const deleteChatMessage = async (roomId: string, messageId: string) => {
1115
return api.delete(`/chat/rooms/${roomId}/messages/${messageId}`)
1216
}
17+
18+
export const getChatCount = (roomId: string) => {
19+
return api.get<ChatCountResponse>(`/chat/rooms/${roomId}/count/chat`)
20+
}

β€Žsrc/features/chat/model/useChat.tsβ€Ž

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
import {
22
useInfiniteQuery,
33
useMutation,
4+
useQuery,
45
useQueryClient,
56
type InfiniteData,
67
} from '@tanstack/react-query'
78

8-
import { deleteChatMessage, getChatHistory } from '@/features/chat/api/chat'
9+
import { deleteChatMessage, getChatCount, getChatHistory } from '@/features/chat/api/chat'
910
import type { ChatHistoryResponse } from '@/features/chat/types/chat'
1011

1112
export const useInfiniteChatHistory = (roomId: string, limit = 50) => {
@@ -36,3 +37,11 @@ export const useDeleteChatMessage = (roomId: string, removeMessage: (id: string)
3637
},
3738
})
3839
}
40+
41+
export const useChatCount = (roomId: string) => {
42+
return useQuery({
43+
queryKey: ['chatCount', roomId],
44+
queryFn: () => getChatCount(roomId),
45+
staleTime: 0,
46+
})
47+
}

β€Žsrc/features/chat/types/chat.tsβ€Ž

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,7 @@ export interface ChatHistoryResponse {
1818
messages: ChatHistoryMessage[]
1919
nextCursor?: string
2020
}
21+
22+
export interface ChatCountResponse {
23+
totalCount: number
24+
}

β€Žsrc/features/like/api/like.tsβ€Ž

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import type { LikeStatusResponse } from '@/features/like/type/like'
12
import { api } from '@/shared/api/httpClient'
23

34
export const postLike = (playlistId: number) => {
@@ -9,5 +10,5 @@ export const deleteLike = (playlistId: number) => {
910
}
1011

1112
export const getLikeStatus = (playlistId: number) => {
12-
return api.get(`/main/likes/${playlistId}`)
13+
return api.get<LikeStatusResponse>(`/main/likes/${playlistId}`)
1314
}

β€Žsrc/features/like/model/useLike.tsβ€Ž

Lines changed: 65 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,80 @@
1-
import { useState } from 'react'
21
import { useNavigate } from 'react-router-dom'
32

43
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
54

65
import { useAuthStore } from '@/features/auth/store/authStore'
76
import { postLike, deleteLike, getLikeStatus } from '@/features/like/api/like'
7+
import type { LikeStatusResponse } from '@/features/like/type/like'
88

9-
const useLike = (playlistId: number, initialIsLiked: boolean) => {
9+
export const useLikeStatus = (playlistId: number, options?: { enabled?: boolean }) => {
10+
return useQuery({
11+
queryKey: ['likeStatus', playlistId],
12+
queryFn: () => getLikeStatus(playlistId),
13+
staleTime: 0,
14+
enabled: playlistId !== undefined && (options?.enabled ?? true),
15+
})
16+
}
17+
18+
const useLike = (playlistId: number) => {
1019
const queryClient = useQueryClient()
11-
const [isLiked, setIsLiked] = useState(initialIsLiked)
12-
const navigate = useNavigate()
1320
const { isLogin } = useAuthStore()
21+
const navigate = useNavigate()
22+
23+
const { data: statusData, isLoading } = useLikeStatus(playlistId, { enabled: isLogin })
24+
const isLiked = statusData?.isLiked ?? false
1425

1526
const likeMutation = useMutation({
16-
mutationFn: (playlistId: number) => postLike(playlistId),
17-
onSuccess: () => {
18-
setIsLiked(true)
19-
queryClient.invalidateQueries({ queryKey: ['playlistDetail', playlistId] })
27+
mutationFn: () => postLike(playlistId),
28+
29+
onMutate: async () => {
30+
await queryClient.cancelQueries({ queryKey: ['likeStatus', playlistId] })
31+
const previous = queryClient.getQueryData(['likeStatus', playlistId])
32+
33+
// 낙관적 μ—…λ°μ΄νŠΈ
34+
queryClient.setQueryData<LikeStatusResponse>(['likeStatus', playlistId], (old) => ({
35+
...(old ?? { isLiked: false }),
36+
isLiked: true,
37+
}))
38+
39+
return { previous }
40+
},
41+
onError: (_err, _vars, context) => {
42+
// contextλŠ” onMutate의 return κ°’(previous)
43+
if (context?.previous) {
44+
// μ‹€νŒ¨ μ‹œ UIλ₯Ό μ›λž˜λŒ€λ‘œ 돌림
45+
queryClient.setQueryData(['likeStatus', playlistId], context.previous)
46+
}
47+
},
48+
49+
// 성곡 μ‹€νŒ¨ 관계 없이 무쑰건 μ‹€ν–‰
50+
onSettled: () => {
51+
queryClient.invalidateQueries({ queryKey: ['likeStatus', playlistId] })
2052
},
2153
})
2254

2355
const unlikeMutation = useMutation({
24-
mutationFn: (playlistId: number) => deleteLike(playlistId),
25-
onSuccess: () => {
26-
setIsLiked(false)
27-
queryClient.invalidateQueries({ queryKey: ['playlistDetail', playlistId] })
56+
mutationFn: () => deleteLike(playlistId),
57+
58+
onMutate: async () => {
59+
await queryClient.cancelQueries({ queryKey: ['likeStatus', playlistId] })
60+
const previous = queryClient.getQueryData(['likeStatus', playlistId])
61+
62+
queryClient.setQueryData<LikeStatusResponse>(['likeStatus', playlistId], (old) => ({
63+
...(old ?? { isLiked: false }),
64+
isLiked: true,
65+
}))
66+
67+
return { previous }
68+
},
69+
70+
onError: (_err, _vars, context) => {
71+
if (context?.previous) {
72+
queryClient.setQueryData(['likeStatus', playlistId], context.previous)
73+
}
74+
},
75+
76+
onSettled: () => {
77+
queryClient.invalidateQueries({ queryKey: ['likeStatus', playlistId] })
2878
},
2979
})
3080

@@ -34,25 +84,11 @@ const useLike = (playlistId: number, initialIsLiked: boolean) => {
3484
return
3585
}
3686

37-
if (likeMutation.isPending || unlikeMutation.isPending) return
38-
39-
if (isLiked) {
40-
unlikeMutation.mutate(playlistId)
41-
} else {
42-
likeMutation.mutate(playlistId)
43-
}
87+
if (isLiked) unlikeMutation.mutate()
88+
else likeMutation.mutate()
4489
}
4590

46-
return { liked: isLiked, toggleLike, likeMutation, unlikeMutation }
91+
return { liked: isLiked, toggleLike, isLoading }
4792
}
4893

4994
export default useLike
50-
51-
export const useLikeStatus = (playlistId: number, options?: { enabled?: boolean }) => {
52-
return useQuery({
53-
queryKey: ['likeStatus', playlistId],
54-
queryFn: () => getLikeStatus(playlistId),
55-
staleTime: 0,
56-
enabled: playlistId !== undefined && (options?.enabled ?? true),
57-
})
58-
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export interface LikeStatusResponse {
2+
isLiked: boolean
3+
}

0 commit comments

Comments
Β (0)