feat: Gapless playback, seek recovery, buffered indicator, and UI polish (v1.0.9)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Psychotoxical
2026-03-13 23:54:32 +01:00
parent c9b4bc091e
commit 32571a2986
17 changed files with 271 additions and 107 deletions
+8 -1
View File
@@ -52,6 +52,7 @@ const FsBg = memo(function FsBg({ url }: { url: string }) {
// ─── Progress bar (isolated — re-renders every tick) ──────────────────────────
const FsProgress = memo(function FsProgress({ duration }: { duration: number }) {
const progress = usePlayerStore(s => s.progress);
const buffered = usePlayerStore(s => s.buffered);
const currentTime = usePlayerStore(s => s.currentTime);
const seek = usePlayerStore(s => s.seek);
@@ -60,6 +61,9 @@ const FsProgress = memo(function FsProgress({ duration }: { duration: number })
[seek]
);
const pct = progress * 100;
const buf = Math.max(pct, buffered * 100);
return (
<div className="fs-progress-wrap">
<span className="fs-time">{formatTime(currentTime)}</span>
@@ -68,7 +72,10 @@ const FsProgress = memo(function FsProgress({ duration }: { duration: number })
type="range" min={0} max={1} step={0.001}
value={progress}
onChange={handleSeek}
style={{ '--pct': `${progress * 100}%` } as React.CSSProperties}
style={{
'--pct': `${pct}%`,
'--buf': `${buf}%`,
} as React.CSSProperties}
aria-label="progress"
/>
</div>