Skip to content

Commit 673b2cd

Browse files
authored
Merge pull request #162 from wafflestudio/158-bug-story
✨ feat: ㅇ
2 parents bd4cbca + b39b54c commit 673b2cd

File tree

2 files changed

+50
-54
lines changed

2 files changed

+50
-54
lines changed

src/features/story-viewer/ui/StoryViewer.tsx

Lines changed: 33 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useState, useEffect, useMemo } from 'react'
1+
import { useState, useEffect } from 'react'
22
import {
33
X,
44
ChevronLeft,
@@ -8,7 +8,7 @@ import {
88
MoreHorizontal,
99
} from 'lucide-react'
1010
import { useNavigate, Link } from '@tanstack/react-router'
11-
import { useQueryClient, useQuery } from '@tanstack/react-query'
11+
import { useQueryClient } from '@tanstack/react-query'
1212
import type { StoryFeedItem, Story } from '@/entities/story/model/types'
1313
import { useStoryViewer } from '../model/useStoryViewer'
1414
import { STORY_VIEWER_UI } from './constants'
@@ -17,12 +17,12 @@ import ReportModal from '@/components/post/ReportModal'
1717
import AccountInfoModal from '@/components/post/AccountInfoModal'
1818
import { instance } from '@/shared/api/ky'
1919
import { useCurrentUser } from '@/shared/auth/useCurrentUser'
20-
import { getStoryDetail } from '@/entities/story/api/getStoryDetail'
2120
import instagramLogo from '@/assets/instagram-black-logo.png'
2221

2322
interface StoryViewerProps {
2423
feed: StoryFeedItem[]
2524
userId: string
25+
isDetailLoading?: boolean
2626
}
2727

2828
const formatRelativeTime = (createdAt: string) => {
@@ -37,7 +37,11 @@ const formatRelativeTime = (createdAt: string) => {
3737
return `${diffInHours}시간 전`
3838
}
3939

40-
export function StoryViewer({ feed, userId }: StoryViewerProps) {
40+
export function StoryViewer({
41+
feed,
42+
userId,
43+
isDetailLoading,
44+
}: StoryViewerProps) {
4145
const navigate = useNavigate()
4246
const queryClient = useQueryClient()
4347
const { data: me, isLoading: isMeLoading } = useCurrentUser()
@@ -48,19 +52,6 @@ export function StoryViewer({ feed, userId }: StoryViewerProps) {
4852
const [isAccountInfoOpen, setIsAccountInfoOpen] = useState(false)
4953
const [isDeleteConfirmOpen, setIsDeleteConfirmOpen] = useState(false)
5054

51-
const { data: detailData, isLoading: isDetailLoading } = useQuery({
52-
queryKey: ['stories', 'user', userId],
53-
queryFn: () => getStoryDetail(userId),
54-
enabled: !!userId,
55-
})
56-
57-
const enrichedFeed = useMemo(() => {
58-
if (!detailData) return feed
59-
return feed.map((item) =>
60-
String(item.userId) === String(userId) ? detailData : item
61-
)
62-
}, [feed, detailData, userId])
63-
6455
const {
6556
currentUser,
6657
currentStory,
@@ -71,7 +62,7 @@ export function StoryViewer({ feed, userId }: StoryViewerProps) {
7162
handleNext,
7263
handlePrev,
7364
togglePause,
74-
} = useStoryViewer(enrichedFeed, userId)
65+
} = useStoryViewer(feed, userId)
7566

7667
const isMine =
7768
!isMeLoading &&
@@ -85,13 +76,7 @@ export function StoryViewer({ feed, userId }: StoryViewerProps) {
8576
}
8677
}, [imageError, isPaused, togglePause])
8778

88-
if (isDetailLoading || !currentUser || !currentStory) {
89-
return (
90-
<div className="fixed inset-0 z-[100] flex items-center justify-center bg-black">
91-
<div className="h-8 w-8 animate-spin rounded-full border-4 border-gray-600 border-t-white" />
92-
</div>
93-
)
94-
}
79+
if (!currentUser) return null
9580

9681
const isFirstStoryOfFirstUser =
9782
currentUserIndex === 0 && currentStoryIndex === 0
@@ -128,7 +113,7 @@ export function StoryViewer({ feed, userId }: StoryViewerProps) {
128113
const handleDeleteStory = async () => {
129114
try {
130115
const response = await instance
131-
.delete(`api/v1/stories/${currentStory.id}`)
116+
.delete(`api/v1/stories/${currentStory?.id}`)
132117
.json<{ isSuccess: boolean; code: string; message: string }>()
133118
if (response.isSuccess) {
134119
queryClient.invalidateQueries({ queryKey: ['stories', 'feed'] })
@@ -173,6 +158,12 @@ export function StoryViewer({ feed, userId }: StoryViewerProps) {
173158
)}
174159

175160
<div className={STORY_VIEWER_UI.STYLES.VIEWER_CARD}>
161+
{isDetailLoading && !currentStory?.imageUrl && (
162+
<div className="absolute inset-0 z-10 flex items-center justify-center bg-black">
163+
<div className="h-8 w-8 animate-spin rounded-full border-4 border-gray-600 border-t-white" />
164+
</div>
165+
)}
166+
176167
<div className={STORY_VIEWER_UI.STYLES.OVERLAY_TOP}>
177168
<div className={STORY_VIEWER_UI.STYLES.PROGRESS_CONTAINER}>
178169
{currentUser.stories.map((story: Story, i: number) => (
@@ -208,9 +199,11 @@ export function StoryViewer({ feed, userId }: StoryViewerProps) {
208199
/>
209200
<div className={STORY_VIEWER_UI.STYLES.USER_INFO}>
210201
<span className="font-bold">{currentUser.nickname}</span>
211-
<span className="text-[13px] font-normal opacity-60">
212-
{formatRelativeTime(currentStory.createdAt)}
213-
</span>
202+
{currentStory && (
203+
<span className="text-[13px] font-normal opacity-60">
204+
{formatRelativeTime(currentStory.createdAt)}
205+
</span>
206+
)}
214207
</div>
215208
</Link>
216209

@@ -256,16 +249,18 @@ export function StoryViewer({ feed, userId }: StoryViewerProps) {
256249
</div>
257250
) : (
258251
<>
259-
<img
260-
key={currentStory.imageUrl}
261-
src={currentStory.imageUrl}
262-
className="h-full w-full object-cover select-none"
263-
alt="story"
264-
onError={() => setImageError(true)}
265-
referrerPolicy="no-referrer"
266-
/>
252+
{currentStory?.imageUrl && (
253+
<img
254+
key={currentStory.imageUrl}
255+
src={currentStory.imageUrl}
256+
className="h-full w-full object-cover select-none"
257+
alt="story"
258+
onError={() => setImageError(true)}
259+
referrerPolicy="no-referrer"
260+
/>
261+
)}
267262

268-
{isMine && currentStory.viewCount !== undefined && (
263+
{isMine && currentStory?.viewCount !== undefined && (
269264
<div className="absolute bottom-4 left-4 z-50 flex flex-col items-start gap-1">
270265
<span className="text-[13px] font-semibold text-white drop-shadow-md">
271266
{currentStory.viewCount}명이 읽음

src/routes/stories/$user_id.tsx

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,45 +3,46 @@ import { StoryViewer } from '@/features/story-viewer/ui/StoryViewer'
33
import { useStoryFeedQuery } from '@/entities/story/model/hooks/useStoryFeedQuery'
44
import { useQuery } from '@tanstack/react-query'
55
import { getStoryDetail } from '@/entities/story/api/getStoryDetail'
6+
import { useMemo } from 'react'
67

78
export const Route = createFileRoute('/stories/$user_id')({
89
component: RouteComponent,
910
})
1011

1112
function RouteComponent() {
1213
const { user_id } = Route.useParams()
13-
14-
const { data: feedData, isLoading: isFeedLoading } = useStoryFeedQuery()
14+
const { data: feedData } = useStoryFeedQuery()
1515

1616
const { data: detailData, isLoading: isDetailLoading } = useQuery({
1717
queryKey: ['stories', 'user', user_id],
1818
queryFn: () => getStoryDetail(user_id),
1919
enabled: !!user_id,
2020
})
2121

22-
if (isFeedLoading || isDetailLoading) {
23-
return (
24-
<div className="flex h-screen w-full items-center justify-center bg-black">
25-
<div className="h-8 w-8 animate-spin rounded-full border-4 border-gray-600 border-t-white" />
26-
</div>
22+
const mergedFeed = useMemo(() => {
23+
if (!feedData) return []
24+
if (!detailData) return feedData
25+
26+
return feedData.map((item) =>
27+
String(item.userId) === String(user_id) ? detailData : item
2728
)
28-
}
29+
}, [feedData, detailData, user_id])
2930

30-
if (!feedData || !detailData) {
31+
if (!feedData) {
3132
return (
32-
<div className="flex h-screen w-full items-center justify-center bg-black text-white">
33-
<p>표시할 스토리가 없습니다.</p>
33+
<div className="flex h-screen w-full items-center justify-center bg-black">
34+
<div className="h-8 w-8 animate-spin rounded-full border-4 border-gray-600 border-t-white" />
3435
</div>
3536
)
3637
}
3738

38-
const mergedFeed = feedData.map((item) =>
39-
String(item.userId) === String(user_id) ? detailData : item
40-
)
41-
4239
return (
4340
<div className="h-screen w-full bg-black">
44-
<StoryViewer feed={mergedFeed} userId={user_id} />
41+
<StoryViewer
42+
feed={mergedFeed}
43+
userId={user_id}
44+
isDetailLoading={isDetailLoading}
45+
/>
4546
</div>
4647
)
4748
}

0 commit comments

Comments
 (0)