From 6d07720b4f8ba389caab9b2fca117b2ff3bc6858 Mon Sep 17 00:00:00 2001 From: Frank Stellmacher <171614930+Psychotoxical@users.noreply.github.com> Date: Tue, 12 May 2026 16:28:10 +0200 Subject: [PATCH] =?UTF-8?q?refactor(player):=20E.20=20=E2=80=94=20extract?= =?UTF-8?q?=20HTML5=20radio=20player=20(#584)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The HTMLAudioElement that handles internet-radio streams + its six event listeners + the bounded stalled-reconnect loop move into `src/store/radioPlayer.ts`. The module owns the singleton audio element, the `radioStopping` suppression flag, the reconnect counter and timer, and `MAX_RADIO_RECONNECTS`. Public API: - `playRadioStream(url, volume)` — sets src + clamped volume + play, resets reconnect counter - `pauseRadio()` / `resumeRadio()` — soft pause/resume (keep src) - `stopRadio()` — full stop (flag + pause + clear src + cancel reconnect timer) - `setRadioVolume(v)` — direct volume with clamp - `clearRadioReconnectTimer()` — exposed for cleanup paths playerStore's seven direct-access patterns become API calls. The three `radioStopping = true; pause; src = ''` triples collapse to single `stopRadio()` calls. 18 tests pin the imperative API + the listener loop: ended/error state-clear, stalled → 4 s reconnect, stalled coalescing, the MAX_RADIO_RECONNECTS hard stop, playing-resets-counter, and the suspend → cancel. playerStore 2983 → 2909 LOC. --- src/store/playerStore.ts | 104 +++-------------- src/store/radioPlayer.test.ts | 214 ++++++++++++++++++++++++++++++++++ src/store/radioPlayer.ts | 135 +++++++++++++++++++++ 3 files changed, 364 insertions(+), 89 deletions(-) create mode 100644 src/store/radioPlayer.test.ts create mode 100644 src/store/radioPlayer.ts diff --git a/src/store/playerStore.ts b/src/store/playerStore.ts index 1a2adfe6..d17099d2 100644 --- a/src/store/playerStore.ts +++ b/src/store/playerStore.ts @@ -98,6 +98,14 @@ import { tryAcquireTogglePlayLock } from './togglePlayLock'; import { reseedLoudnessForTrackId } from './loudnessReseed'; import { refreshWaveformForTrack } from './waveformRefresh'; import { refreshLoudnessForTrack } from './loudnessRefresh'; +import { + clearRadioReconnectTimer, + pauseRadio, + playRadioStream, + resumeRadio, + setRadioVolume, + stopRadio, +} from './radioPlayer'; // Re-export so TauriEventBridge + persistence test keep their existing // `from './playerStore'` imports. @@ -522,75 +530,6 @@ function scheduleSeekFallbackRetry(trackId: string, seconds: number) { }, SEEK_FALLBACK_RETRY_INTERVAL_MS); } -// ── HTML5 Radio Player ──────────────────────────────────────────────────────── -// Internet radio streams are played via a native