import { formatDuration } from '@/web/utils/common' import { cx } from '@emotion/css' import player from '@/web/states/player' import { useSnapshot } from 'valtio' import Wave from './Wave' import Icon from '@/web/components/Icon' import useIsMobile from '@/web/hooks/useIsMobile' import useUserLikedTracksIDs, { useMutationLikeATrack, } from '@/web/api/hooks/useUserLikedTracksIDs' import toast from 'react-hot-toast' import { memo, useEffect, useState } from 'react' import contextMenus, { openContextMenu } from '@/web/states/contextMenus' const Actions = ({ track }: { track: Track }) => { const { data: likedTracksIDs } = useUserLikedTracksIDs() const likeATrack = useMutationLikeATrack() const [isContextMenuOpen, setIsContextMenuOpen] = useState(false) const menu = useSnapshot(contextMenus) useEffect(() => { if (menu.type !== 'track' || !menu.dataSourceID) { setIsContextMenuOpen(false) } }, [menu.dataSourceID, menu.type]) return (
e.stopPropagation()}> {/* Context menu */}
{/* Add to playlist */} {/* Like */}
) } const TrackList = ({ tracks, onPlay, className, isLoading, placeholderRows = 12, }: { tracks?: Track[] onPlay: (id: number) => void className?: string isLoading?: boolean placeholderRows?: number }) => { const { track: playingTrack, state } = useSnapshot(player) const isMobile = useIsMobile() const handleClick = (e: React.MouseEvent, trackID: number) => { if (isLoading) return if (e.type === 'contextmenu') { e.preventDefault() openContextMenu({ event: e, type: 'track', dataSourceID: trackID, options: { useCursorPosition: true, }, }) return } if (isMobile) { onPlay?.(trackID) } else { if (e.detail === 2) onPlay?.(trackID) } } return (
{(isLoading ? [] : tracks)?.map(track => (
handleClick(e, track.id)} onContextMenu={e => handleClick(e, track.id)} className='group relative flex h-14 items-center py-2 text-16 font-medium text-neutral-200 transition duration-300' > {/* Track no */}
{String(track.no).padStart(2, '0')}
{/* Track name */}
{track.name} {playingTrack?.id === track.id && ( )}
{/* Desktop menu */} {/* Mobile menu */}
{/* Track duration */}
{formatDuration(track.dt, 'en', 'hh:mm:ss')}
))} {(isLoading ? Array.from(new Array(placeholderRows).keys()) : []).map( index => (
{/* Track no */}
00
{/* Track name */}
PLACEHOLDER1234567
{/* Track duration */}
00:00
) )}
) } const memorizedTrackList = memo(TrackList) memorizedTrackList.displayName = 'TrackList' export default memorizedTrackList