Add Discogs enrichment button to dashboard header
- Circular button with "dc" logo text, matching exact pattern of AudioDB/Deezer/Spotify/iTunes/Last.fm/Genius/Tidal/Qobuz buttons - Spinner animation when active, dimmed when paused, green when complete - Hover tooltip showing status, current item, and progress stats - Click to toggle pause/resume with config persistence - WebSocket status handler updates button state in real-time
This commit is contained in:
parent
b68aa09469
commit
72e720dd88
3 changed files with 172 additions and 2 deletions
|
|
@ -546,6 +546,28 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Discogs Enrichment Status Icon -->
|
||||
<div class="discogs-button-container">
|
||||
<button class="discogs-button" id="discogs-button" title="Discogs Library Enrichment"
|
||||
onclick="toggleDiscogsEnrichment()">
|
||||
<span class="discogs-logo-text">dc</span>
|
||||
<div class="discogs-spinner"></div>
|
||||
</button>
|
||||
<div class="discogs-tooltip" id="discogs-tooltip">
|
||||
<div class="discogs-tooltip-content">
|
||||
<div class="discogs-tooltip-header">Discogs Enrichment</div>
|
||||
<div class="discogs-tooltip-body" id="discogs-tooltip-body">
|
||||
<div class="tooltip-status">Status: <span
|
||||
id="discogs-tooltip-status">Idle</span>
|
||||
</div>
|
||||
<div class="tooltip-current" id="discogs-tooltip-current">No active matches
|
||||
</div>
|
||||
<div class="tooltip-progress" id="discogs-tooltip-progress">Progress: 0 / 0
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Hydrabase P2P Mirror Status Icon -->
|
||||
<div class="hydrabase-button-container" id="hydrabase-button-container" style="display: none;">
|
||||
<button class="hydrabase-button" id="hydrabase-button" title="Hydrabase P2P Mirror">
|
||||
|
|
|
|||
|
|
@ -57065,8 +57065,54 @@ function updateAudioDBStatusFromData(data) {
|
|||
}
|
||||
|
||||
function updateDiscogsStatusFromData(data) {
|
||||
// Discogs status is handled by the rate monitor cards — no standalone button
|
||||
// This handler exists for WebSocket event compatibility
|
||||
const button = document.getElementById('discogs-button');
|
||||
if (!button) return;
|
||||
|
||||
button.classList.remove('active', 'paused', 'complete');
|
||||
if (data.idle) {
|
||||
button.classList.add('complete');
|
||||
} else if (data.running && !data.paused) {
|
||||
button.classList.add('active');
|
||||
} else if (data.paused) {
|
||||
button.classList.add('paused');
|
||||
}
|
||||
|
||||
const tooltipStatus = document.getElementById('discogs-tooltip-status');
|
||||
const tooltipCurrent = document.getElementById('discogs-tooltip-current');
|
||||
const tooltipProgress = document.getElementById('discogs-tooltip-progress');
|
||||
|
||||
if (tooltipStatus) {
|
||||
if (data.idle) tooltipStatus.textContent = 'Complete';
|
||||
else if (data.running && !data.paused) tooltipStatus.textContent = 'Running';
|
||||
else if (data.paused) tooltipStatus.textContent = data.yield_reason === 'downloads' ? 'Yielding for downloads' : 'Paused';
|
||||
else tooltipStatus.textContent = 'Idle';
|
||||
}
|
||||
|
||||
if (tooltipCurrent) {
|
||||
if (data.idle) tooltipCurrent.textContent = 'All items processed';
|
||||
else if (data.current_item) tooltipCurrent.textContent = `Processing: "${data.current_item}"`;
|
||||
else tooltipCurrent.textContent = 'No active matches';
|
||||
}
|
||||
|
||||
if (tooltipProgress && data.stats) {
|
||||
const s = data.stats;
|
||||
tooltipProgress.textContent = `Matched: ${s.matched || 0} | Not found: ${s.not_found || 0} | Pending: ${s.pending || 0}`;
|
||||
}
|
||||
}
|
||||
|
||||
async function toggleDiscogsEnrichment() {
|
||||
try {
|
||||
const button = document.getElementById('discogs-button');
|
||||
if (!button) return;
|
||||
const isPaused = button.classList.contains('paused') || button.classList.contains('complete');
|
||||
const endpoint = isPaused ? '/api/discogs/resume' : '/api/discogs/pause';
|
||||
const response = await fetch(endpoint, { method: 'POST' });
|
||||
if (response.ok) {
|
||||
showToast(isPaused ? 'Discogs enrichment resumed' : 'Discogs enrichment paused', 'info');
|
||||
}
|
||||
} catch (e) {
|
||||
showToast('Failed to toggle Discogs enrichment', 'error');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -33891,6 +33891,108 @@ body.helper-mode-active #dashboard-activity-feed:hover {
|
|||
============================================================================ */
|
||||
|
||||
/* Container for button + tooltip positioning */
|
||||
/* Discogs Enrichment Button */
|
||||
.discogs-button-container {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
margin-right: 12px;
|
||||
}
|
||||
|
||||
.discogs-button {
|
||||
position: relative;
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
background: linear-gradient(135deg, rgba(51, 51, 51, 0.2) 0%, rgba(80, 80, 80, 0.25) 100%);
|
||||
backdrop-filter: blur(20px) saturate(1.4);
|
||||
border: 1.5px solid rgba(120, 120, 120, 0.25);
|
||||
border-radius: 50%;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
box-shadow: 0 4px 16px rgba(80, 80, 80, 0.15), 0 2px 8px rgba(0, 0, 0, 0.15), inset 0 1px 0 rgba(255, 255, 255, 0.08);
|
||||
}
|
||||
|
||||
.discogs-logo-text {
|
||||
font-size: 14px;
|
||||
font-weight: 900;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
letter-spacing: -0.5px;
|
||||
font-family: -apple-system, sans-serif;
|
||||
}
|
||||
|
||||
.discogs-button:hover {
|
||||
transform: scale(1.1);
|
||||
border-color: rgba(180, 180, 180, 0.4);
|
||||
box-shadow: 0 6px 24px rgba(120, 120, 120, 0.3), 0 3px 12px rgba(0, 0, 0, 0.2), inset 0 1px 0 rgba(255, 255, 255, 0.12);
|
||||
}
|
||||
|
||||
.discogs-button.active {
|
||||
border-color: rgba(120, 120, 120, 0.5);
|
||||
animation: discogs-pulse 2s ease-in-out infinite;
|
||||
}
|
||||
|
||||
@keyframes discogs-pulse {
|
||||
0%, 100% { box-shadow: 0 4px 16px rgba(120, 120, 120, 0.15), 0 0 0 rgba(120, 120, 120, 0); }
|
||||
50% { box-shadow: 0 4px 16px rgba(120, 120, 120, 0.3), 0 0 12px rgba(120, 120, 120, 0.15); }
|
||||
}
|
||||
|
||||
.discogs-button.paused {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.discogs-button.complete .discogs-logo-text {
|
||||
color: rgba(76, 175, 80, 0.8);
|
||||
}
|
||||
|
||||
.discogs-spinner {
|
||||
display: none;
|
||||
position: absolute;
|
||||
top: -3px; left: -3px; right: -3px; bottom: -3px;
|
||||
border: 2px solid transparent;
|
||||
border-top-color: rgba(120, 120, 120, 0.6);
|
||||
border-radius: 50%;
|
||||
animation: spin 1s linear infinite;
|
||||
}
|
||||
|
||||
.discogs-button.active .discogs-spinner { display: block; }
|
||||
|
||||
.discogs-tooltip {
|
||||
display: none;
|
||||
position: absolute;
|
||||
bottom: calc(100% + 12px);
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
z-index: 100;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.discogs-button-container:hover .discogs-tooltip { display: block; }
|
||||
|
||||
.discogs-tooltip-content {
|
||||
background: rgba(14, 14, 20, 0.97);
|
||||
border: 1px solid rgba(255, 255, 255, 0.08);
|
||||
border-radius: 12px;
|
||||
padding: 12px 16px;
|
||||
min-width: 200px;
|
||||
backdrop-filter: blur(20px);
|
||||
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
|
||||
.discogs-tooltip-header {
|
||||
font-size: 13px;
|
||||
font-weight: 700;
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.discogs-tooltip-body {
|
||||
font-size: 11px;
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.deezer-button-container {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
|
|
|
|||
Loading…
Reference in a new issue