import { memo, useMemo, useSyncExternalStore } from 'react'; import { useTranslation } from 'react-i18next'; import { X } from 'lucide-react'; import { usePlayerStore } from '@/features/playback/store/playerStore'; import type { Track } from '@/lib/media/trackTypes'; import { resolveQueueTrack } from '@/features/playback/store/queueTrackView'; import { getQueueResolverVersion, subscribeQueueResolver, } from '@/features/playback/store/queueTrackResolver'; import { formatTrackTime } from '@/lib/format/formatDuration'; interface Props { onClose: () => void; } /** * Semi-transparent "Up next" overlay for the fullscreen player — lists the * upcoming queue (no blur, in keeping with the static player). Clicking a row * jumps to that queue item (same-queue jump as the queue panel). */ export const FsQueueModal = memo(function FsQueueModal({ onClose }: Props) { const { t } = useTranslation(); const queueItems = usePlayerStore(s => s.queueItems); const queueIndex = usePlayerStore(s => s.queueIndex); const playTrack = usePlayerStore(s => s.playTrack); // Re-resolve as the resolver cache fills. const version = useSyncExternalStore(subscribeQueueResolver, getQueueResolverVersion); const upcoming = useMemo(() => { const out: { track: Track; absIdx: number }[] = []; for (let i = queueIndex + 1; i < queueItems.length; i++) { const ref = queueItems[i]; if (ref) out.push({ track: resolveQueueTrack(ref), absIdx: i }); } return out; // eslint-disable-next-line react-hooks/exhaustive-deps }, [queueItems, queueIndex, version]); return (