import { X, Play, Pause, SkipBack, SkipForward, Disc3 } from 'lucide-react'; import { useEffect, useRef } from 'react'; import { useQuery } from '@tanstack/react-query'; import { Link } from '@tanstack/react-router'; import { usePlaybackStore } from '../store/usePlaybackStore'; import { Artwork } from './Artwork'; import { ArtistLinks } from './ArtistLinks'; import { TrackRow, formatDuration } from './TrackRow'; import { albumService } from '../services/albumService'; import { useTransport } from '../hooks/useTransport'; export function NowPlayingPanel({ onClose }: { onClose: () => void }) { const panelRef = useRef(null); const closeRef = useRef(null); useEffect(() => { closeRef.current?.focus(); }, []); useEffect(() => { const previous = document.activeElement as HTMLElement | null; const trap = (event: KeyboardEvent) => { if (event.key !== 'Tab' || !panelRef.current) return; const focusable = [...panelRef.current.querySelectorAll( 'a[href], button:not([disabled]), input:not([disabled]), [tabindex]:not([tabindex="-1"])' )].filter((element) => !element.hasAttribute('hidden')); if (focusable.length === 0) return; const first = focusable[0]; const last = focusable[focusable.length - 1]; if (event.shiftKey && document.activeElement === first) { event.preventDefault(); last.focus(); } else if (!event.shiftKey && document.activeElement === last) { event.preventDefault(); first.focus(); } }; document.addEventListener('keydown', trap); return () => { document.removeEventListener('keydown', trap); previous?.focus(); }; }, []); const { currentTrack, queue, isPlaying, position, duration } = usePlaybackStore(); const transport = useTransport(); const currentIdx = currentTrack ? queue.findIndex((t) => t.id === currentTrack.id) : -1; const upNext = currentIdx >= 0 ? queue.slice(currentIdx + 1) : queue; const albumQ = useQuery({ queryKey: ['album', currentTrack?.album_id], queryFn: () => albumService.getAlbum(currentTrack!.album_id), enabled: !!currentTrack?.album_id, staleTime: 5 * 60 * 1000, }); const artwork = albumQ.data?.artwork_id ?? currentTrack?.artwork_id ?? null; return ( ); }