fix(preview): sync audio start, ring animation, and download timeout (#423)

* fix(preview): sync audio start, ring animation, and download timeout

Three coupled fixes for the track-preview engine:

1. Audio sync. `Sink::try_seek` was running on a worker thread after
   `sink.append(source)`, so the sink began playing position 0 while
   the seek was still iterating to the mid-track target. With the
   30 s `take_duration` cap counting wall-clock from append, audio
   could only become audible ~25% into the preview window. The seek
   now runs on the bare source before append, then `take_duration`
   wraps it — playback starts at the seek position with the cap
   measured from there.

2. Ring animation gating. The CSS progress-ring animation was
   bound to `is-previewing` (set on click), so the ring sprinted
   ahead of any download/decode/seek warmup and didn't reset
   cleanly when switching from one preview to another. Added an
   `audioStarted` flag in `previewStore` that flips on
   `audio:preview-start` from the engine; CSS animation is now
   gated on `audio-started` instead. `is-previewing` still drives
   tooltip/icon for instant click feedback. Same SVG is reused for
   a 25%-arc rotating loading spinner while waiting for audio,
   with a 150 ms delay so cached/short previews don't flash.

3. Download timeout. The shared `audio_http_client` caps at 30 s,
   which aborts mid-download on multi-hundred-MB uncompressed
   files (e.g. 18-min Hi-Res WAV ~600 MB). The preview engine now
   builds a dedicated client with a 5 min timeout for the bytes
   fetch. Watchdog still bounds the playback window at 30 s once
   the audio actually starts.

Touches `audio/preview.rs`, `previewStore.ts`, `components.css`
plus the eight tracklist/player-bar components that render the
preview button.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(changelog): add preview audio sync fix for PR #423

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Frank Stellmacher
2026-05-02 14:44:49 +02:00
committed by GitHub
parent 9cc74a7f88
commit 297c9f1125
10 changed files with 104 additions and 34 deletions
+2
View File
@@ -113,6 +113,8 @@ The drag ghost shows a **trash** affordance only while the cursor is outside the
- **Polish** *(PR [#397](https://github.com/Psychotoxical/psysonic/pull/397), by [@cucadmuh](https://github.com/cucadmuh))*: multiple branch-local interaction fixes around sidebar drag/drop behavior, Live dropdown layering, queue-resize handle behavior during scroll/overlay-scrollbar interaction, and now-playing narrow-layout stability.
- **Track preview audio in sync with progress ring; huge files no longer abort** *(Issue [#421](https://github.com/Psychotoxical/psysonic/issues/421), PR [#423](https://github.com/Psychotoxical/psysonic/pull/423), by [@Psychotoxical](https://github.com/Psychotoxical))*: Previews used to start audio about 25 % into the preview window on mid-track starts because `Sink::try_seek` ran in parallel with `sink.append` while the 30 s `take_duration` cap was already counting wall-clock from append. The seek now runs on the bare source before append, and the progress-ring animation only starts once the engine actually emits `audio:preview-start` — a small loading spinner is shown during the download/decode/seek warmup. The preview HTTP-client timeout was raised from 30 s to 5 min, so multi-hundred-megabyte Hi-Res files no longer abort the download mid-fetch.
## [1.44.0] - 2026-04-29