From 2990b571b4881bc596c5eab5b779800daff071fc Mon Sep 17 00:00:00 2001
From: Broque Thomas <26755000+Nezreka@users.noreply.github.com>
Date: Mon, 30 Mar 2026 17:20:33 -0700
Subject: [PATCH] Add Clear Cache & Use Fallback button to Spotify settings
Always-visible button in Spotify API section that clears the OAuth
token cache, pauses enrichment, and switches to the configured
fallback metadata source. Also fixed the dashboard service card to
show the actual active source name (Spotify/iTunes/Deezer) instead
of always showing "Spotify" with an amber fallback indicator.
---
webui/index.html | 4 +++
webui/static/script.js | 55 +++++++++++++++++++++---------------------
2 files changed, 32 insertions(+), 27 deletions(-)
diff --git a/webui/index.html b/webui/index.html
index 4e614f3c..23703a9e 100644
--- a/webui/index.html
+++ b/webui/index.html
@@ -3692,6 +3692,10 @@
+
diff --git a/webui/static/script.js b/webui/static/script.js
index b51bd7c0..64568c61 100644
--- a/webui/static/script.js
+++ b/webui/static/script.js
@@ -7328,6 +7328,29 @@ async function disconnectSpotify() {
}
}
+async function clearSpotifyCacheAndFallback() {
+ const fallbackName = currentMusicSourceName !== 'Spotify' ? currentMusicSourceName : 'the configured fallback source';
+ if (!await showConfirmDialog({
+ title: 'Clear Spotify Cache',
+ message: `This will clear the Spotify token cache and switch metadata to ${fallbackName}. You can re-authenticate later.`
+ })) return;
+ try {
+ showLoadingOverlay('Clearing Spotify cache...');
+ const response = await fetch('/api/spotify/disconnect', { method: 'POST' });
+ const data = await response.json();
+ if (data.success) {
+ showToast(data.message || `Switched to ${fallbackName}`, 'success');
+ await fetchAndUpdateServiceStatus();
+ } else {
+ showToast(`Failed: ${data.error}`, 'error');
+ }
+ } catch (error) {
+ showToast('Failed to clear Spotify cache', 'error');
+ } finally {
+ hideLoadingOverlay();
+ }
+}
+
// ── Spotify Rate Limit Handling ───────────────────────────────────────────
let _spotifyRateLimitShown = false;
let _spotifyInCooldown = false;
@@ -36094,29 +36117,15 @@ function updateServiceStatus(service, statusData) {
}
}
- // Update music source title and status based on active source
+ // Update music source title based on active source
if (service === 'spotify' && statusData.source) {
const musicSourceTitleElement = document.getElementById('music-source-title');
if (musicSourceTitleElement) {
- // Card title always says "Spotify" — it represents the metadata source slot
- musicSourceTitleElement.textContent = 'Spotify';
- // Update global variable for use in discovery modals
const sourceName = statusData.source === 'spotify' ? 'Spotify' : statusData.source === 'deezer' ? 'Deezer' : 'iTunes';
+ musicSourceTitleElement.textContent = sourceName;
currentMusicSourceName = sourceName;
}
- // When using fallback, update status text to show which fallback is active
- if (statusData.source !== 'spotify' && !statusData.rate_limited && !statusData.post_ban_cooldown) {
- const fallbackName = statusData.source === 'deezer' ? 'Deezer' : 'iTunes';
- if (statusText) {
- statusText.textContent = `Using ${fallbackName}`;
- statusText.className = 'service-card-status-text fallback';
- }
- if (indicator) {
- indicator.className = 'service-card-indicator fallback';
- }
- }
-
// Show/hide Spotify disconnect button based on connection state
const disconnectBtn = document.getElementById('spotify-disconnect-btn');
if (disconnectBtn) {
@@ -36163,20 +36172,12 @@ function updateSidebarServiceStatus(service, statusData) {
}
}
- // Update music source name — always "Spotify" in sidebar
+ // Update music source name in sidebar based on active source
if (service === 'spotify' && statusData.source) {
const musicSourceNameElement = document.getElementById('music-source-name');
if (musicSourceNameElement) {
- musicSourceNameElement.textContent = 'Spotify';
- }
-
- // Show fallback state in sidebar dot
- if (statusData.source !== 'spotify' && !statusData.rate_limited && !statusData.post_ban_cooldown) {
- if (dot) {
- dot.className = 'status-dot fallback';
- const fallbackName = statusData.source === 'deezer' ? 'Deezer' : 'iTunes';
- dot.title = `Using ${fallbackName} fallback`;
- }
+ const sourceName = statusData.source === 'spotify' ? 'Spotify' : statusData.source === 'deezer' ? 'Deezer' : 'iTunes';
+ musicSourceNameElement.textContent = sourceName;
}
}