mirror of
https://github.com/Psychotoxical/psysonic.git
synced 2026-07-21 23:05:46 +00:00
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:
committed by
GitHub
parent
9cc74a7f88
commit
297c9f1125
@@ -1866,7 +1866,27 @@
|
||||
transform: translateX(0.5px);
|
||||
}
|
||||
|
||||
.playlist-suggestion-preview-btn.is-previewing .playlist-suggestion-preview-ring-progress {
|
||||
/* Loading state: the engine is still downloading/decoding/seeking. A short
|
||||
rotating arc (~25% of the circumference) signals "pending" without
|
||||
pretending to be progress. 150 ms delay suppresses the spinner for
|
||||
small/cached files where audio starts almost instantly. */
|
||||
.playlist-suggestion-preview-btn.is-previewing:not(.audio-started) .playlist-suggestion-preview-ring-progress {
|
||||
/* circumference = 2π × 10.5 ≈ 65.97 → 25% arc + 75% gap */
|
||||
stroke-dasharray: 16.5 49.5;
|
||||
stroke-dashoffset: 0;
|
||||
animation: playlist-preview-loading 1.1s linear infinite;
|
||||
animation-delay: 150ms;
|
||||
}
|
||||
|
||||
@keyframes playlist-preview-loading {
|
||||
from { stroke-dashoffset: 0; }
|
||||
to { stroke-dashoffset: -65.97; }
|
||||
}
|
||||
|
||||
/* Animation runs only after `audio-started` is added — i.e. once the engine
|
||||
emitted `audio:preview-start` for this track. Prevents the ring from
|
||||
sprinting ahead of audio during the engine's download/decode/seek warmup. */
|
||||
.playlist-suggestion-preview-btn.audio-started .playlist-suggestion-preview-ring-progress {
|
||||
animation: playlist-preview-progress var(--preview-duration, 30s) linear forwards;
|
||||
}
|
||||
|
||||
@@ -2487,6 +2507,27 @@ html[data-track-previews-randommix="off"] [data-preview-loc="randomMix"] .pl
|
||||
stroke-linecap: round;
|
||||
stroke-dasharray: 100;
|
||||
stroke-dashoffset: 100;
|
||||
}
|
||||
|
||||
/* Loading spinner — same logic as the tracklist ring above. The SVG uses
|
||||
pathLength="100", so the circumference is normalised: 25 unit arc + 75
|
||||
unit gap, with the offset rolling from 0 to -100. */
|
||||
.player-bar.is-previewing:not(.audio-started) .player-btn-preview-ring-progress {
|
||||
stroke-dasharray: 25 75;
|
||||
stroke-dashoffset: 0;
|
||||
animation: player-preview-loading 1.1s linear infinite;
|
||||
animation-delay: 150ms;
|
||||
}
|
||||
|
||||
@keyframes player-preview-loading {
|
||||
from { stroke-dashoffset: 0; }
|
||||
to { stroke-dashoffset: -100; }
|
||||
}
|
||||
|
||||
/* Animation gated on the player-bar `audio-started` flag (set after the
|
||||
engine emits `audio:preview-start`). Same rationale as the tracklist
|
||||
preview ring above. */
|
||||
.player-bar.audio-started .player-btn-preview-ring-progress {
|
||||
animation: player-preview-progress var(--preview-duration, 30s) linear forwards;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user