Skip to content

Commit 0149d36

Browse files
authored
Merge pull request #106 from dnd-side-project/refactor/#104/discover-mycd
[refactor] 둘러보기, 나의 cd 코드 리팩토링
2 parents 1e3b4c2 + 7b6700c commit 0149d36

File tree

15 files changed

+205
-381
lines changed

15 files changed

+205
-381
lines changed
Lines changed: 41 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { createContext, useState, useContext, type ReactNode } from 'react'
1+
import { createContext, useState, useContext, useRef, useCallback, type ReactNode } from 'react'
22

33
import type { PlaylistInfo } from '@/entities/playlist'
44

@@ -13,6 +13,8 @@ type PlaylistContextType = {
1313
nextTrack: () => void
1414
prevTrack: () => void
1515
updateCurrentTime: (time: number) => void
16+
playerRef: React.MutableRefObject<YT.Player | null>
17+
handlePlayerStateChange: (event: YT.OnStateChangeEvent) => void
1618
}
1719

1820
interface PlaylistProviderProps {
@@ -23,37 +25,58 @@ const PlaylistContext = createContext<PlaylistContextType | undefined>(undefined
2325

2426
const PlaylistProvider = ({ children }: PlaylistProviderProps) => {
2527
const [currentPlaylist, setCurrentPlaylist] = useState<PlaylistInfo | null>(null)
26-
const [currentTrackIndex, setCurrentTrackIndex] = useState<number>(0)
27-
const [isPlaying, setIsPlaying] = useState<boolean>(false)
28-
const [currentTime, setCurrentTime] = useState<number>(0)
28+
const [currentTrackIndex, setCurrentTrackIndex] = useState(0)
29+
const [currentTime, setCurrentTime] = useState(0)
30+
const [isPlaying, setIsPlaying] = useState(false)
31+
32+
const playerRef = useRef<YT.Player | null>(null)
2933

3034
const setPlaylist = (playlist: PlaylistInfo, trackIndex?: number, time?: number) => {
3135
setCurrentPlaylist(playlist)
3236
if (trackIndex !== undefined) setCurrentTrackIndex(trackIndex)
3337
if (time !== undefined) setCurrentTime(time)
3438
setIsPlaying(true)
39+
40+
if (playerRef.current) {
41+
if (time !== undefined) playerRef.current.seekTo(time, true)
42+
playerRef.current.playVideo()
43+
}
3544
}
3645

37-
const play = () => setIsPlaying(true)
38-
const pause = () => setIsPlaying(false)
46+
const play = useCallback(() => {
47+
if (playerRef.current) playerRef.current.playVideo()
48+
setIsPlaying(true)
49+
}, [])
50+
51+
const pause = useCallback(() => {
52+
if (playerRef.current) playerRef.current.pauseVideo()
53+
setIsPlaying(false)
54+
}, [])
3955

40-
const nextTrack = () => {
56+
const nextTrack = useCallback(() => {
4157
if (currentPlaylist && currentTrackIndex < currentPlaylist.songs.length - 1) {
42-
setCurrentTrackIndex((prevIndex) => prevIndex + 1)
58+
setCurrentTrackIndex((prev) => prev + 1)
4359
setCurrentTime(0)
60+
if (playerRef.current) playerRef.current.seekTo(0, true)
4461
}
45-
}
62+
}, [currentPlaylist, currentTrackIndex])
4663

47-
const prevTrack = () => {
64+
const prevTrack = useCallback(() => {
4865
if (currentTrackIndex > 0) {
49-
setCurrentTrackIndex((prevIndex) => prevIndex - 1)
66+
setCurrentTrackIndex((prev) => prev - 1)
5067
setCurrentTime(0)
68+
if (playerRef.current) playerRef.current.seekTo(0, true)
5169
}
52-
}
70+
}, [currentTrackIndex])
5371

54-
const updateCurrentTime = (time: number) => {
55-
setCurrentTime(time)
56-
}
72+
const updateCurrentTime = (time: number) => setCurrentTime(time)
73+
74+
const handlePlayerStateChange = useCallback(
75+
(event: YT.OnStateChangeEvent) => {
76+
if (event.data === window.YT.PlayerState.ENDED) nextTrack()
77+
},
78+
[nextTrack]
79+
)
5780

5881
const value = {
5982
currentPlaylist,
@@ -66,6 +89,8 @@ const PlaylistProvider = ({ children }: PlaylistProviderProps) => {
6689
nextTrack,
6790
prevTrack,
6891
updateCurrentTime,
92+
playerRef,
93+
handlePlayerStateChange,
6994
}
7095

7196
return <PlaylistContext.Provider value={value}>{children}</PlaylistContext.Provider>
@@ -75,8 +100,6 @@ export default PlaylistProvider
75100

76101
export const usePlaylist = () => {
77102
const context = useContext(PlaylistContext)
78-
if (context === undefined) {
79-
throw new Error('usePlaylist must be used within a PlaylistProvider')
80-
}
103+
if (!context) throw new Error('usePlaylist must be used within a PlaylistProvider')
81104
return context
82105
}

src/pages/discover/commentData.json

Lines changed: 0 additions & 50 deletions
This file was deleted.

src/pages/discover/index.tsx

Lines changed: 20 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
1+
import { useCallback, useEffect, useMemo, useState } from 'react'
22
import { useParams } from 'react-router-dom'
3-
import type { YouTubeEvent } from 'react-youtube'
43

54
import styled from 'styled-components'
65

@@ -20,18 +19,19 @@ import { PlaylistLayout, YoutubePlayer } from '@/widgets/playlist'
2019
const DiscoverPage = () => {
2120
const { id: playlistId } = useParams()
2221
const {
23-
setPlaylist,
24-
isPlaying,
2522
currentPlaylist,
2623
currentTrackIndex,
27-
nextTrack,
28-
prevTrack,
24+
currentTime,
25+
isPlaying,
26+
playerRef,
27+
setPlaylist,
2928
play,
3029
pause,
31-
currentTime,
32-
updateCurrentTime,
30+
nextTrack,
31+
prevTrack,
32+
handlePlayerStateChange,
3333
} = usePlaylist()
34-
const playerRef = useRef<YT.Player | null>(null)
34+
3535
const [showCoachmark, setShowCoachmark] = useState(false)
3636
const [isMuted, setIsMuted] = useState<boolean | null>(null)
3737

@@ -96,8 +96,6 @@ const DiscoverPage = () => {
9696
return [playlistAsInfo, ...shufflePlaylists]
9797
}, [playlistAsInfo, shufflePlaylists])
9898

99-
console.log(playlistsData)
100-
10199
const videoId = currentPlaylist
102100
? getVideoId(currentPlaylist.songs[currentTrackIndex]?.youtubeUrl)
103101
: null
@@ -109,11 +107,11 @@ const DiscoverPage = () => {
109107
if (!currentPlaylist && playlistsData.length > 0 && isReady) {
110108
const initialPlaylist =
111109
playlistsData.find((p) => p.playlistId === Number(playlistId)) || playlistsData[0]
112-
113110
setPlaylist(initialPlaylist, 0, 0)
114111
}
115-
}, [playlistsData, currentPlaylist, playlistId, setPlaylist])
112+
}, [playlistsData, currentPlaylist, playlistId, setPlaylist, isReady])
116113

114+
// 재생, 확인, 조회수 refetch
117115
useEffect(() => {
118116
if (!currentPlaylist || !isPlaying) return
119117
startPlaylist(currentPlaylist.playlistId)
@@ -135,21 +133,6 @@ const DiscoverPage = () => {
135133
}
136134
}, [currentPlaylist, isPlaying, startPlaylist, confirmPlaylist, refetchViewCounts])
137135

138-
// 현재 재생 시간 업데이트
139-
useEffect(() => {
140-
const intervalId = setInterval(() => {
141-
if (playerRef.current) updateCurrentTime(playerRef.current.getCurrentTime())
142-
}, 1000)
143-
return () => clearInterval(intervalId)
144-
}, [updateCurrentTime])
145-
146-
// 재생, 일시정지
147-
useEffect(() => {
148-
if (!playerRef.current) return
149-
if (isPlaying) playerRef.current.playVideo()
150-
else playerRef.current.pauseVideo()
151-
}, [isPlaying])
152-
153136
// 캐러셀 스와이프 시 현재 플레이리스트 업데이트
154137
const handleSelectPlaylist = useCallback(
155138
(index: number) => {
@@ -162,48 +145,26 @@ const DiscoverPage = () => {
162145
fetchNextPage()
163146
}
164147
},
165-
[setPlaylist, currentPlaylist, playlistsData, fetchNextPage, hasNextPage, isFetchingNextPage]
148+
[playlistsData, currentPlaylist, setPlaylist, hasNextPage, isFetchingNextPage, fetchNextPage]
166149
)
167150

168-
const handlePlayerStateChange = useCallback(
169-
(event: YouTubeEvent) => {
170-
if (event.data === window.YT.PlayerState.ENDED) nextTrack()
171-
},
172-
[nextTrack]
173-
)
174-
175-
const handlePlayPause = () => {
176-
if (isPlaying) pause()
177-
else play()
178-
}
179-
180-
const isCurrentlyPlaying = (() => {
181-
if (!window.YT || !playerRef.current) return false
182-
return isPlaying && playerRef.current.getPlayerState() === window.YT.PlayerState.PLAYING
183-
})()
184-
185151
return (
186152
<Page>
187153
{showCoachmark && <DiscoverCoachMark onClick={handleCloseCoachmark} />}
188154
<SwipeCarousel data={playlistsData} onSelectIndexChange={handleSelectPlaylist}>
189155
{playlistsData.map((data) => (
190156
<Slide key={data.playlistId}>
191157
<PlaylistLayout
192-
key={data.playlistId}
193158
data={data}
194159
currentPlaylist={currentPlaylist}
195160
currentTrackIndex={currentTrackIndex}
196161
currentTime={currentTime}
197-
isPlaying={isCurrentlyPlaying}
198-
onPlayPause={handlePlayPause}
162+
isPlaying={isPlaying}
163+
onPlayPause={() => (isPlaying ? pause() : play())}
199164
onNext={nextTrack}
200165
onPrev={prevTrack}
201166
onSelectTrack={(trackIndex, time) => {
202-
if (currentPlaylist) {
203-
setPlaylist(currentPlaylist, trackIndex)
204-
if (time !== undefined) playerRef.current?.seekTo(time, true)
205-
if (!isPlaying) play()
206-
}
167+
if (currentPlaylist) setPlaylist(currentPlaylist, trackIndex, time)
207168
}}
208169
playerRef={playerRef}
209170
isMuted={isMuted}
@@ -212,22 +173,16 @@ const DiscoverPage = () => {
212173
</Slide>
213174
))}
214175
</SwipeCarousel>
215-
{!showCoachmark && videoId && (
176+
177+
{videoId && (
216178
<YoutubePlayer
217179
videoId={videoId}
218180
onReady={(event) => {
219181
playerRef.current = event.target
220-
221-
// 현 상태 참조해서 동기화
182+
playerRef.current?.seekTo(currentTime, true)
183+
if (isPlaying) playerRef.current?.playVideo()
184+
else playerRef.current?.pauseVideo()
222185
setIsMuted(playerRef.current?.isMuted() ?? null)
223-
224-
if (isPlaying) {
225-
playerRef.current?.seekTo(currentTime, true)
226-
playerRef.current?.playVideo()
227-
} else {
228-
playerRef.current?.seekTo(currentTime, true)
229-
playerRef.current?.pauseVideo()
230-
}
231186
}}
232187
onStateChange={handlePlayerStateChange}
233188
/>
@@ -241,7 +196,6 @@ export default DiscoverPage
241196
const Slide = styled.div`
242197
flex: 0 0 100%;
243198
`
244-
245199
const Page = styled.div`
246200
position: relative;
247201
`

0 commit comments

Comments
 (0)