Skip to content

Commit 99d7caf

Browse files
authored
Merge pull request #108 from dnd-side-project/feat/#107/discover-ux
[feat] ๋‘˜๋Ÿฌ๋ณด๊ธฐ UX ๊ฐœ์„ ์‚ฌํ•ญ ๋ฐ˜์˜
2 parents 0149d36 + 82899fd commit 99d7caf

File tree

4 files changed

+52
-11
lines changed

4 files changed

+52
-11
lines changed

โ€Žsrc/shared/ui/Link.tsxโ€Ž

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,12 @@ import type { Track } from '@/entities/playlist'
66
interface LinkProps {
77
variant?: 'large' | 'small'
88
data: Track
9+
onClick?: () => void
910
}
1011

11-
const Link = ({ variant = 'large', data }: LinkProps) => {
12+
const Link = ({ variant = 'large', data, onClick }: LinkProps) => {
1213
return (
13-
<LinkBox $variant={variant}>
14+
<LinkBox $variant={variant} onClick={onClick}>
1415
<Thumbnail $thumbnail={data.youtubeThumbnail ?? undefined} $variant={variant}>
1516
{!data.youtubeThumbnail && (
1617
<Gallery width={variant === 'large' ? 24 : 20} height={variant === 'large' ? 24 : 20} />

โ€Žsrc/widgets/playlist/PlaylistInfo.tsxโ€Ž

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { useNavigate } from 'react-router-dom'
22

33
import styled from 'styled-components'
44

5+
import { usePlaylist } from '@/app/providers/PlayerProvider'
56
import { Cancel } from '@/assets/icons'
67
import type { PlaylistDetailResponse } from '@/entities/playlist'
78
import { getGenreLabel } from '@/shared/lib'
@@ -17,6 +18,13 @@ interface PlaylistInfoProps {
1718

1819
const PlaylistInfo = ({ playlistData, isLoading, isError }: PlaylistInfoProps) => {
1920
const navigate = useNavigate()
21+
const { setPlaylist, currentPlaylist } = usePlaylist()
22+
23+
const handleClickTrack = (trackIndex: number) => {
24+
if (!currentPlaylist) return
25+
navigate(-1)
26+
setPlaylist(currentPlaylist, trackIndex, 0)
27+
}
2028

2129
if (isError || !playlistData) {
2230
return (
@@ -50,7 +58,12 @@ const PlaylistInfo = ({ playlistData, isLoading, isError }: PlaylistInfoProps) =
5058
<TrackInfo>
5159
{playlistData.songs &&
5260
playlistData.songs.map((track, index) => (
53-
<Link key={index} data={track} variant="large" />
61+
<Link
62+
key={track.id}
63+
data={track}
64+
variant="large"
65+
onClick={() => handleClickTrack(index)}
66+
/>
5467
))}
5568
</TrackInfo>
5669
</Content>

โ€Žsrc/widgets/playlist/PlaylistLayout.tsxโ€Ž

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ const PlaylistLayout = ({
8080
)}
8181
</Container>
8282
<Wrapper>
83-
<CdWrapper>
83+
<CdWrapper $isPlaying={isPlaying}>
8484
{isMobile && (
8585
<VolumeButton playerRef={playerRef} isMuted={isMuted} setIsMuted={setIsMuted} />
8686
)}
@@ -130,6 +130,18 @@ const Container = styled.div`
130130
justify-content: space-between;
131131
`
132132

133-
const CdWrapper = styled.div`
133+
const CdWrapper = styled.div<{ $isPlaying: boolean }>`
134134
position: relative;
135+
animation: spin 40s linear infinite;
136+
animation-play-state: ${(props) => (props.$isPlaying ? 'running' : 'paused')};
137+
transform-origin: center;
138+
139+
@keyframes spin {
140+
0% {
141+
transform: rotate(0deg);
142+
}
143+
100% {
144+
transform: rotate(360deg);
145+
}
146+
}
135147
`

โ€Žsrc/widgets/playlist/YoutubePlayer.tsxโ€Ž

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1+
import { useRef, useEffect } from 'react'
12
import YouTube from 'react-youtube'
2-
import type { YouTubeProps, YouTubeEvent, YouTubePlayer } from 'react-youtube' //
3+
import type { YouTubeProps, YouTubeEvent, YouTubePlayer } from 'react-youtube'
34

4-
import { useDevice } from '@/shared/lib/useDevice'
55

66
interface YoutubePlayerProps {
77
videoId: string
@@ -10,23 +10,38 @@ interface YoutubePlayerProps {
1010
}
1111

1212
function YoutubePlayer({ videoId, onReady, onStateChange }: YoutubePlayerProps) {
13-
const deviceType = useDevice()
14-
const isMobile = deviceType === 'mobile'
13+
const playerRef = useRef<YouTubePlayer | null>(null)
14+
const isFirstLoad = useRef(true)
1515

1616
const playerOpts: YouTubeProps['opts'] = {
1717
playerVars: {
1818
autoplay: 1,
19-
mute: isMobile ? 1 : 0,
19+
mute: 0,
2020
playsinline: 1, // ๋ชจ๋ฐ”์ผ ์ธ๋ผ์ธ ์žฌ์ƒ
2121
},
2222
}
2323

24+
useEffect(() => {
25+
if (!isFirstLoad.current && playerRef.current && videoId) {
26+
// ์ฒซ ๋กœ๋”ฉ ์ œ์™ธํ•˜๊ณ  loadVideoById ํ˜ธ์ถœ
27+
try {
28+
playerRef.current.loadVideoById(videoId)
29+
} catch (e) {
30+
console.error('loadVideoById ์‹คํŒจ', e)
31+
}
32+
}
33+
isFirstLoad.current = false
34+
}, [videoId])
35+
2436
return (
2537
<div style={{ width: 0, height: 0, overflow: 'hidden', position: 'absolute' }}>
2638
<YouTube
2739
videoId={videoId}
2840
opts={playerOpts}
29-
onReady={onReady}
41+
onReady={(e) => {
42+
playerRef.current = e.target
43+
onReady(e)
44+
}}
3045
onStateChange={onStateChange}
3146
/>
3247
</div>

0 commit comments

Comments
ย (0)