From 3c0b6c620484446655e12826efe724609de10b57 Mon Sep 17 00:00:00 2001 From: Broque Thomas <26755000+Nezreka@users.noreply.github.com> Date: Sat, 23 May 2026 23:55:59 -0700 Subject: [PATCH] Cover missed Qobuz branches in Sync shared switches (#677) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Three follow-ups to the Qobuz playlist sync commit: * webui/static/sync-services.js openYouTubeDiscoveryModal โ€” the syncing-phase "start polling on modal open" switch was missing the isQobuz branch (the discovery-modal-close handler hit it but this earlier hook didn't). Resuming a sync after a page refresh would have fallen through to startYouTubeSyncPolling. * webui/static/sync-services.js closeYouTubeDiscoveryModal โ€” the per-service phase reset block had Tidal, Deezer, Spotify Public, Beatport branches but no Qobuz. After a Qobuz sync_complete or download_complete, closing the modal wouldn't reset the card phase back to 'discovered' or push the phase update to /api/qobuz/update_phase. * web_server.py _emit_discovery_progress_loop โ€” platform_states didn't include 'qobuz', so WebSocket discovery progress broadcasts were silently skipping Qobuz playlists. HTTP-poll fallback covers it but this puts Qobuz on equal footing with the other services. --- web_server.py | 1 + webui/static/sync-services.js | 36 ++++++++++++++++++++++++++++++++++- 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/web_server.py b/web_server.py index b6f3ea6a..a53bd02b 100644 --- a/web_server.py +++ b/web_server.py @@ -35272,6 +35272,7 @@ def _emit_discovery_progress_loop(): """Push discovery progress to subscribed rooms every 1 second.""" platform_states = { 'tidal': lambda: tidal_discovery_states, + 'qobuz': lambda: qobuz_discovery_states, 'deezer': lambda: deezer_discovery_states, 'youtube': lambda: youtube_playlist_states, 'beatport': lambda: beatport_chart_states, diff --git a/webui/static/sync-services.js b/webui/static/sync-services.js index b70ce0e7..41ab7761 100644 --- a/webui/static/sync-services.js +++ b/webui/static/sync-services.js @@ -8418,6 +8418,8 @@ function openYouTubeDiscoveryModal(urlHash) { console.log('๐Ÿ”„ Modal opened in syncing phase - starting immediate polling...'); if (state.is_tidal_playlist) { startTidalSyncPolling(urlHash); + } else if (state.is_qobuz_playlist) { + startQobuzSyncPolling(urlHash); } else if (state.is_deezer_playlist) { startDeezerSyncPolling(urlHash); } else if (state.is_spotify_public_playlist) { @@ -9011,13 +9013,14 @@ function closeYouTubeDiscoveryModal(urlHash) { const state = youtubePlaylistStates[urlHash]; if (state) { const isTidal = state.is_tidal_playlist; + const isQobuz = state.is_qobuz_playlist; const isDeezer = state.is_deezer_playlist; const isSpotifyPublic = state.is_spotify_public_playlist; const isBeatport = state.is_beatport_playlist; // Reset to 'discovered' phase if modal is closed after completion (like Tidal does) if (state.phase === 'sync_complete' || state.phase === 'download_complete') { - console.log(`๐Ÿงน [Modal Close] Resetting ${isSpotifyPublic ? 'Spotify Public' : (isDeezer ? 'Deezer' : (isBeatport ? 'Beatport' : (isTidal ? 'Tidal' : 'YouTube')))} state after completion`); + console.log(`๐Ÿงน [Modal Close] Resetting ${isSpotifyPublic ? 'Spotify Public' : (isDeezer ? 'Deezer' : (isQobuz ? 'Qobuz' : (isBeatport ? 'Beatport' : (isTidal ? 'Tidal' : 'YouTube'))))} state after completion`); if (isSpotifyPublic) { // Spotify Public: Extract url_hash and reset state @@ -9113,6 +9116,37 @@ function closeYouTubeDiscoveryModal(urlHash) { console.warn('โš ๏ธ Error updating backend Tidal phase:', error); } } + } else if (isQobuz) { + // Qobuz: same shape as Tidal โ€” preserve discovery data, + // reset phase to 'discovered', push update to backend. + const qobuzPlaylistId = state.qobuz_playlist_id || null; + if (qobuzPlaylistId && qobuzPlaylistStates[qobuzPlaylistId]) { + const preservedData = { + playlist: qobuzPlaylistStates[qobuzPlaylistId].playlist, + discovery_results: qobuzPlaylistStates[qobuzPlaylistId].discovery_results, + spotify_matches: qobuzPlaylistStates[qobuzPlaylistId].spotify_matches, + discovery_progress: qobuzPlaylistStates[qobuzPlaylistId].discovery_progress, + convertedSpotifyPlaylistId: qobuzPlaylistStates[qobuzPlaylistId].convertedSpotifyPlaylistId + }; + + delete qobuzPlaylistStates[qobuzPlaylistId].download_process_id; + delete qobuzPlaylistStates[qobuzPlaylistId].phase; + + Object.assign(qobuzPlaylistStates[qobuzPlaylistId], preservedData); + qobuzPlaylistStates[qobuzPlaylistId].phase = 'discovered'; + + updateQobuzCardPhase(qobuzPlaylistId, 'discovered'); + + try { + fetch(`/api/qobuz/update_phase/${qobuzPlaylistId}`, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ phase: 'discovered' }) + }); + } catch (error) { + console.warn('โš ๏ธ Error updating backend Qobuz phase:', error); + } + } } else if (isBeatport) { // Beatport: Reset chart state const chartHash = state.beatport_chart_hash || urlHash;