import { Slider } from 'modern-sk'; import { Icon } from '../common/Icon'; import { ArtTile } from '../common/ArtTile'; import { useAppDispatch, useAppSelector } from '../../hooks/useAppDispatch'; import { pause, resume, toggleMute, setVolume, toggleShuffle, setRepeat, toggleNowPlaying, toggleQueue, } from '../../store/slices/player'; import { useAudioPlayer } from '../../hooks/useAudioPlayer'; import { formatDuration } from '../../lib/format'; import { getCoverUrl } from '../../api/endpoints/streaming'; export function PersistentPlayer() { const dispatch = useAppDispatch(); const { seek, playNext, playPrev } = useAudioPlayer(); const player = useAppSelector((s) => s.player); const queue = useAppSelector((s) => s.queue); const currentEntry = queue.entries[queue.currentIndex]; if (!currentEntry && !player.currentTrackId) { return
Nothing playing
; } const artUrl = getCoverUrl(currentEntry?.albumArtUrl); const seedLabel = currentEntry?.albumTitle ?? currentEntry?.title ?? ''; // Streaming is the web default; local playback is a mobile-client concern. const onStream = true; return (
{/* now-playing identity */}
dispatch(toggleNowPlaying())} style={{ cursor: 'pointer' }} >
{currentEntry?.title ?? '—'}
{currentEntry?.artistName ?? ''}
{onStream ? 'Streaming · 320 kbps' : 'Local · FLAC'}
{/* transport + scrubber */}
{formatDuration(player.position * 1000)} seek(v)} aria-label="Seek" /> {formatDuration(player.duration * 1000)}
{/* volume + queue */}
dispatch(setVolume(v))} aria-label="Volume" />
); }