mirror of
https://github.com/SoPat712/allstarr.git
synced 2026-02-09 23:55:10 -05:00
feat: add tooltips, refresh & match button, and matching warning banner
This commit is contained in:
@@ -644,12 +644,18 @@
|
||||
|
||||
<!-- Active Playlists Tab -->
|
||||
<div class="tab-content" id="tab-playlists">
|
||||
<!-- Warning Banner (hidden by default) -->
|
||||
<div id="matching-warning-banner" style="display:none;background:#f59e0b;color:#000;padding:16px;border-radius:8px;margin-bottom:16px;font-weight:600;text-align:center;box-shadow:0 4px 6px rgba(0,0,0,0.1);">
|
||||
⚠️ TRACK MATCHING IN PROGRESS - Please wait for matching to complete before making changes to playlists or mappings!
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<h2>
|
||||
Active Spotify Playlists
|
||||
<div class="actions">
|
||||
<button onclick="matchAllPlaylists()">Match All Tracks</button>
|
||||
<button onclick="refreshPlaylists()">Refresh All</button>
|
||||
<button onclick="matchAllPlaylists()" title="Match tracks for all playlists against your local library and external providers. This may take several minutes.">Match All Tracks</button>
|
||||
<button onclick="refreshPlaylists()" title="Fetch the latest playlist data from Spotify without re-matching tracks.">Refresh All</button>
|
||||
<button onclick="refreshAndMatchAll()" title="Clear caches, fetch fresh data from Spotify, and match all tracks. This is a full rebuild and may take several minutes." style="background:var(--accent);border-color:var(--accent);">Refresh & Match All</button>
|
||||
</div>
|
||||
</h2>
|
||||
<p style="color: var(--text-secondary); margin-bottom: 12px;">
|
||||
@@ -1910,6 +1916,9 @@
|
||||
if (!confirm(`Clear cache and rebuild for "${name}"?\n\nThis will:\n• Clear Redis cache\n• Delete file caches\n• Rebuild with latest Spotify IDs\n\nThis may take a minute.`)) return;
|
||||
|
||||
try {
|
||||
// Show warning banner
|
||||
document.getElementById('matching-warning-banner').style.display = 'block';
|
||||
|
||||
showToast(`Clearing cache for ${name}...`, 'info');
|
||||
const res = await fetch(`/api/admin/playlists/${encodeURIComponent(name)}/clear-cache`, { method: 'POST' });
|
||||
const data = await res.json();
|
||||
@@ -1917,17 +1926,26 @@
|
||||
if (res.ok) {
|
||||
showToast(`✓ ${data.message} (Cleared ${data.clearedKeys} cache keys, ${data.clearedFiles} files)`, 'success', 5000);
|
||||
// Refresh the playlists table after a delay to show updated counts
|
||||
setTimeout(fetchPlaylists, 3000);
|
||||
setTimeout(() => {
|
||||
fetchPlaylists();
|
||||
// Hide warning banner after refresh
|
||||
document.getElementById('matching-warning-banner').style.display = 'none';
|
||||
}, 3000);
|
||||
} else {
|
||||
showToast(data.error || 'Failed to clear cache', 'error');
|
||||
document.getElementById('matching-warning-banner').style.display = 'none';
|
||||
}
|
||||
} catch (error) {
|
||||
showToast('Failed to clear cache', 'error');
|
||||
document.getElementById('matching-warning-banner').style.display = 'none';
|
||||
}
|
||||
}
|
||||
|
||||
async function matchPlaylistTracks(name) {
|
||||
try {
|
||||
// Show warning banner
|
||||
document.getElementById('matching-warning-banner').style.display = 'block';
|
||||
|
||||
showToast(`Matching tracks for ${name}...`, 'success');
|
||||
const res = await fetch(`/api/admin/playlists/${encodeURIComponent(name)}/match`, { method: 'POST' });
|
||||
const data = await res.json();
|
||||
@@ -1935,12 +1953,18 @@
|
||||
if (res.ok) {
|
||||
showToast(`✓ ${data.message}`, 'success');
|
||||
// Refresh the playlists table after a delay to show updated counts
|
||||
setTimeout(fetchPlaylists, 2000);
|
||||
setTimeout(() => {
|
||||
fetchPlaylists();
|
||||
// Hide warning banner after refresh
|
||||
document.getElementById('matching-warning-banner').style.display = 'none';
|
||||
}, 2000);
|
||||
} else {
|
||||
showToast(data.error || 'Failed to match tracks', 'error');
|
||||
document.getElementById('matching-warning-banner').style.display = 'none';
|
||||
}
|
||||
} catch (error) {
|
||||
showToast('Failed to match tracks', 'error');
|
||||
document.getElementById('matching-warning-banner').style.display = 'none';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1948,6 +1972,9 @@
|
||||
if (!confirm('Match tracks for ALL playlists? This may take a few minutes.')) return;
|
||||
|
||||
try {
|
||||
// Show warning banner
|
||||
document.getElementById('matching-warning-banner').style.display = 'block';
|
||||
|
||||
showToast('Matching tracks for all playlists...', 'success');
|
||||
const res = await fetch('/api/admin/playlists/match-all', { method: 'POST' });
|
||||
const data = await res.json();
|
||||
@@ -1955,12 +1982,61 @@
|
||||
if (res.ok) {
|
||||
showToast(`✓ ${data.message}`, 'success');
|
||||
// Refresh the playlists table after a delay to show updated counts
|
||||
setTimeout(fetchPlaylists, 2000);
|
||||
setTimeout(() => {
|
||||
fetchPlaylists();
|
||||
// Hide warning banner after refresh
|
||||
document.getElementById('matching-warning-banner').style.display = 'none';
|
||||
}, 2000);
|
||||
} else {
|
||||
showToast(data.error || 'Failed to match tracks', 'error');
|
||||
document.getElementById('matching-warning-banner').style.display = 'none';
|
||||
}
|
||||
} catch (error) {
|
||||
showToast('Failed to match tracks', 'error');
|
||||
document.getElementById('matching-warning-banner').style.display = 'none';
|
||||
}
|
||||
}
|
||||
|
||||
async function refreshAndMatchAll() {
|
||||
if (!confirm('Clear caches, refresh from Spotify, and match all tracks?\n\nThis will:\n• Clear all playlist caches\n• Fetch fresh data from Spotify\n• Match all tracks against local library and external providers\n\nThis may take several minutes.')) return;
|
||||
|
||||
try {
|
||||
// Show warning banner
|
||||
document.getElementById('matching-warning-banner').style.display = 'block';
|
||||
|
||||
showToast('Starting full refresh and match...', 'info', 3000);
|
||||
|
||||
// Step 1: Clear all caches
|
||||
showToast('Step 1/3: Clearing caches...', 'info', 2000);
|
||||
await fetch('/api/admin/cache/clear', { method: 'POST' });
|
||||
|
||||
// Step 2: Refresh playlists from Spotify
|
||||
showToast('Step 2/3: Fetching from Spotify...', 'info', 2000);
|
||||
await fetch('/api/admin/playlists/refresh', { method: 'POST' });
|
||||
|
||||
// Wait a bit for Spotify fetch to complete
|
||||
await new Promise(resolve => setTimeout(resolve, 3000));
|
||||
|
||||
// Step 3: Match all tracks
|
||||
showToast('Step 3/3: Matching all tracks...', 'info', 2000);
|
||||
const res = await fetch('/api/admin/playlists/match-all', { method: 'POST' });
|
||||
const data = await res.json();
|
||||
|
||||
if (res.ok) {
|
||||
showToast(`✓ Full refresh and match complete!`, 'success', 5000);
|
||||
// Refresh the playlists table after a delay
|
||||
setTimeout(() => {
|
||||
fetchPlaylists();
|
||||
// Hide warning banner after refresh
|
||||
document.getElementById('matching-warning-banner').style.display = 'none';
|
||||
}, 2000);
|
||||
} else {
|
||||
showToast(data.error || 'Failed to match tracks', 'error');
|
||||
document.getElementById('matching-warning-banner').style.display = 'none';
|
||||
}
|
||||
} catch (error) {
|
||||
showToast('Failed to complete refresh and match', 'error');
|
||||
document.getElementById('matching-warning-banner').style.display = 'none';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user