import React, { useCallback, useMemo } from 'react'; import { Play, Pause, SkipBack, SkipForward, Volume2, VolumeX, Music, List, Square, Repeat, Repeat1, Maximize2 } from 'lucide-react'; import { usePlayerStore } from '../store/playerStore'; import { buildCoverArtUrl, coverArtCacheKey } from '../api/subsonic'; import CachedImage from './CachedImage'; import { useTranslation } from 'react-i18next'; function formatTime(seconds: number): string { if (!seconds || isNaN(seconds)) return '0:00'; const m = Math.floor(seconds / 60); const s = Math.floor(seconds % 60); return `${m}:${s.toString().padStart(2, '0')}`; } export default function PlayerBar() { const { t } = useTranslation(); const { currentTrack, isPlaying, progress, currentTime, volume, togglePlay, next, previous, seek, setVolume, isQueueVisible, toggleQueue, stop, toggleRepeat, repeatMode, toggleFullscreen } = usePlayerStore(); const duration = currentTrack?.duration ?? 0; const coverSrc = useMemo(() => currentTrack?.coverArt ? buildCoverArtUrl(currentTrack.coverArt, 128) : '', [currentTrack?.coverArt]); const coverKey = currentTrack?.coverArt ? coverArtCacheKey(currentTrack.coverArt, 128) : ''; const handleSeek = useCallback((e: React.ChangeEvent) => { seek(parseFloat(e.target.value)); }, [seek]); const handleVolume = useCallback((e: React.ChangeEvent) => { setVolume(parseFloat(e.target.value)); }, [setVolume]); const progressStyle = { background: `linear-gradient(to right, var(--ctp-mauve) ${progress * 100}%, var(--ctp-surface2) ${progress * 100}%)`, }; const volumeStyle = { background: `linear-gradient(to right, var(--ctp-mauve) ${volume * 100}%, var(--ctp-surface2) ${volume * 100}%)`, }; return ( ); }