import { memo } from 'react' import ArtistInline from '@/components/ArtistsInline' import Skeleton from '@/components/Skeleton' import SvgIcon from '@/components/SvgIcon' import useUser from '@/hooks/useUser' import useUserLikedSongsIDs from '@/hooks/useUserLikedSongsIDs' import { player } from '@/store' import { formatDuration } from '@/utils/common' import { State as PlayerState } from '@/utils/player' const enableRenderLog = true const PlayOrPauseButtonInTrack = memo( ({ isHighlight, trackID }: { isHighlight: boolean; trackID: number }) => { if (enableRenderLog) console.debug(`Rendering TracksAlbum.tsx PlayOrPauseButtonInTrack`) const playerSnapshot = useSnapshot(player) const isPlaying = useMemo( () => playerSnapshot.state === PlayerState.PLAYING, [playerSnapshot.state] ) const onClick = () => { isHighlight ? player.playOrPause() : player.playTrack(trackID) } return (
) } ) PlayOrPauseButtonInTrack.displayName = 'PlayOrPauseButtonInTrack' const Track = memo( ({ track, isLiked = false, isSkeleton = false, isHighlight = false, subtitle = undefined, onClick, }: { track: Track isLiked?: boolean isSkeleton?: boolean isHighlight?: boolean subtitle?: string onClick: (e: React.MouseEvent, trackID: number) => void }) => { if (enableRenderLog) console.debug(`Rendering TracksAlbum.tsx Track ${track.name}`) return (
onClick(e, track.id)} className={classNames( 'group grid w-full rounded-xl after:scale-[.98] after:rounded-xl', 'grid-cols-12 py-2.5 px-4', !isSkeleton && { 'btn-hover-animation after:bg-gray-100 dark:after:bg-white/10': !isHighlight, 'bg-brand-50 dark:bg-gray-800': isHighlight, } )} > {/* Track name and number */}
{/* Track number */} {isSkeleton ? ( ) : ( !isHighlight && (
{track.no}
) )} {/* Play or pause button for playing track */} {!isSkeleton && ( )} {/* Track name */}
{isSkeleton ? ( PLACEHOLDER123456789012345 ) : (
{track.name} {track.mark === 1318912 && ( )} {subtitle && ( ({subtitle}) )}
)}
{/* Artists */}
{isSkeleton ? ( PLACEHOLDER1234 ) : ( )}
{/* Actions & Track duration */}
{/* Like button */} {!isSkeleton && ( )} {/* Track duration */} {isSkeleton ? ( 0:00 ) : (
{formatDuration(track.dt, 'en', 'hh:mm:ss')}
)}
) } ) Track.displayName = 'Track' const TracksAlbum = ({ tracks, isSkeleton = false, onTrackDoubleClick, }: { tracks: Track[] isSkeleton?: boolean onTrackDoubleClick?: (trackID: number) => void }) => { // Fake data when isSkeleton is true const skeletonTracks: Track[] = new Array(1).fill({}) // Liked songs ids const { data: user } = useUser() const { data: userLikedSongs } = useUserLikedSongsIDs({ uid: user?.account?.id ?? 0, }) const handleClick = useCallback( (e: React.MouseEvent, trackID: number) => { if (e.detail === 2) onTrackDoubleClick?.(trackID) }, [onTrackDoubleClick] ) const playerSnapshot = useSnapshot(player) const playingTrack = useMemo( () => playerSnapshot.track, [playerSnapshot.track] ) return (
{/* Tracks table header */}
#
标题
艺人
时长
{/* Tracks */} {isSkeleton ? skeletonTracks.map((track, index) => ( null} isSkeleton={true} /> )) : tracks.map(track => ( ))}
) } export default TracksAlbum