From 4ff5aef3f63e92c62ad17908a205f22b1b6b1e64 Mon Sep 17 00:00:00 2001 From: ChanLee_KR Date: Wed, 31 Jul 2024 00:05:18 +0900 Subject: [PATCH] =?UTF-8?q?refactor:=20=EC=8A=A4=ED=81=AC=EB=A1=A4=20?= =?UTF-8?q?=EC=B6=94=EC=A0=81=20=EA=B8=B0=EB=8A=A5=EC=97=90=20=EB=82=99?= =?UTF-8?q?=EA=B4=80=EC=A0=81=20=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8=20?= =?UTF-8?q?=EC=A0=81=EC=9A=A9=20(#ATR-594)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../user-article/model/type/article.ts | 6 +- .../model/useSendUserArticleBookmarkState.ts | 6 +- .../model/useTrackingUserArticleScroll.ts | 71 ++++++++++++++++--- .../model/userArticleQueryKeys.ts | 5 +- 4 files changed, 70 insertions(+), 18 deletions(-) diff --git a/apps/service/src/entities/user-article/model/type/article.ts b/apps/service/src/entities/user-article/model/type/article.ts index 5c6fb286..795b0e7e 100644 --- a/apps/service/src/entities/user-article/model/type/article.ts +++ b/apps/service/src/entities/user-article/model/type/article.ts @@ -15,8 +15,12 @@ export interface Article { newsletter: Pick } +export interface UserArticlesData extends Pagination { + content: Article[] +} + export type UserArticlesResponse = { - data: { content: Article[] } & Pagination + data: UserArticlesData message: string status: string } diff --git a/apps/service/src/entities/user-article/model/useSendUserArticleBookmarkState.ts b/apps/service/src/entities/user-article/model/useSendUserArticleBookmarkState.ts index 8e40d6fe..69d49d93 100644 --- a/apps/service/src/entities/user-article/model/useSendUserArticleBookmarkState.ts +++ b/apps/service/src/entities/user-article/model/useSendUserArticleBookmarkState.ts @@ -44,11 +44,7 @@ export default function useSendUserArticleBookmarkState({ pageType: 'bookmark', }), }) - if (isBookmark) { - toast.success('북마크가 삭제되었어요') - } else { - toast.success('북마크가 추가되었어요') - } + toast.success(`북마크가 ${isBookmark ? '삭제' : '추가'}되었어요`) }, onError: () => toast.error(`북마크 ${isBookmark ? '삭제' : '추가'}에 실패했어요`), diff --git a/apps/service/src/entities/user-article/model/useTrackingUserArticleScroll.ts b/apps/service/src/entities/user-article/model/useTrackingUserArticleScroll.ts index ee60efa8..a7522d39 100644 --- a/apps/service/src/entities/user-article/model/useTrackingUserArticleScroll.ts +++ b/apps/service/src/entities/user-article/model/useTrackingUserArticleScroll.ts @@ -2,7 +2,7 @@ import { useMutation, useQueryClient } from '@tanstack/react-query' import { useAuth } from '@/entities/auth' -import type { UserArticleParams } from './type' +import type { Article, UserArticleParams, UserArticlesData } from './type' import userArticleQueryKeys from './userArticleQueryKeys' import { trackingUserArticleScroll } from '../api' @@ -12,6 +12,12 @@ export default function useTrackingUserArticleScroll({ const { userEmail } = useAuth() const queryClient = useQueryClient() + const articleListKey = userArticleQueryKeys.userArticleList({ + userEmail, + pageType: 'default', + }) + const articleKey = userArticleQueryKeys.userArticle({ userEmail, articleId }) + return useMutation({ mutationKey: userArticleQueryKeys.trackingUserArticleScroll({ userEmail, @@ -19,13 +25,62 @@ export default function useTrackingUserArticleScroll({ }), mutationFn: (readPercentage: number) => trackingUserArticleScroll({ userEmail, articleId, readPercentage }), - onSuccess: () => { - queryClient.invalidateQueries({ - queryKey: userArticleQueryKeys.userArticleList({ - userEmail, - pageType: 'default', - }), - }) + onMutate: (readPercentage) => { + try { + const prevArticleList = queryClient.getQueriesData({ + queryKey: articleListKey, + }) + const prevArticle = queryClient.getQueryData(articleKey) + + queryClient.setQueriesData<{ pages: { data: UserArticlesData }[] }>( + { + queryKey: articleListKey, + }, + (oldData) => { + if (oldData !== undefined) { + return { + ...oldData, + pages: oldData.pages.map((page) => ({ + ...page, + data: { + ...page.data, + content: page.data.content.map((article) => { + if (article.id === articleId) { + return { ...article, readPercentage } + } + return article + }), + }, + })), + } + } + return undefined + }, + ) + queryClient.setQueryData
(articleKey, (oldData) => { + if (oldData) { + return { ...oldData, readPercentage } + } + return oldData + }) + return { readPercentage, prevArticleList, prevArticle, status: true } + } catch { + return { readPercentage, status: false } + } + }, + onSuccess: (_, __, context) => { + if (!context.status) { + queryClient.invalidateQueries({ queryKey: articleListKey }) + } + }, + onError: (_, __, context) => { + queryClient.setQueriesData( + { + queryKey: articleListKey, + }, + context?.prevArticleList, + ) + queryClient.setQueryData(articleKey, context?.prevArticle) }, }) } diff --git a/apps/service/src/entities/user-article/model/userArticleQueryKeys.ts b/apps/service/src/entities/user-article/model/userArticleQueryKeys.ts index 099924a5..c936cb22 100644 --- a/apps/service/src/entities/user-article/model/userArticleQueryKeys.ts +++ b/apps/service/src/entities/user-article/model/userArticleQueryKeys.ts @@ -9,16 +9,13 @@ const userArticleQueryKeys = { ], userArticleList: ({ userEmail, - category, pageType, - page, ...options - }: UserArticleListOption) => [ + }: Omit) => [ ...userArticleQueryKeys.all, 'articles', { userEmail }, { pageType }, - category, options, ], trackingUserArticleScroll: (params: UserArticleParams) => [