feat: implemented artwork fetching/downloading

This commit is contained in:
2026-03-11 08:35:09 +01:00
parent 343dfbaae1
commit bed1f4265a
2 changed files with 92 additions and 3 deletions

View File

@@ -179,6 +179,7 @@
<div style="margin-top: 16px; display: flex; gap: 8px;">
<button class="btn btn-sm btn-secondary" onclick="showPage('download')">Votify (Spotify)</button>
<button class="btn btn-sm btn-secondary" onclick="showPage('monochrome')">Monochrome (Tidal)</button>
<button class="btn btn-sm btn-secondary" onclick="showPage('artwork')">Artwork</button>
</div>
</div>
</div>
@@ -280,6 +281,19 @@
</div>
</div>
<!-- ARTWORK PAGE -->
<div id="page-artwork" class="page">
<div class="card">
<h2>Artwork</h2>
<div class="form-group">
<label for="artwork-url">Spotify URL (track, album, or playlist)</label>
<textarea id="artwork-url" placeholder="https://open.spotify.com/album/..." style="min-height:60px"></textarea>
</div>
<button class="btn" id="btn-artwork" onclick="fetchArtwork()">Get Artwork</button>
<div id="artwork-result" style="margin-top:20px"></div>
</div>
</div>
<!-- JOBS PAGE -->
<div id="page-jobs" class="page">
<div class="card">
@@ -448,8 +462,8 @@
document.querySelectorAll('.tab').forEach(t => t.classList.remove('active'));
document.getElementById('page-' + name).classList.add('active');
// For hidden pages (download/monochrome), highlight the "Download" tab
const tabName = (name === 'download' || name === 'monochrome') ? 'unified' : name;
// For sub-pages (download/monochrome/artwork), highlight the "Download" tab
const tabName = (name === 'download' || name === 'monochrome' || name === 'artwork') ? 'unified' : name;
const matchingTab = document.querySelector(`.tab[onclick="showPage('${tabName}')"]`);
if (matchingTab) matchingTab.classList.add('active');
document.querySelectorAll('.bottom-tab').forEach(t => t.classList.toggle('active', t.dataset.page === tabName));
@@ -1092,6 +1106,34 @@
}
}
async function fetchArtwork() {
const btn = document.getElementById('btn-artwork');
const url = document.getElementById('artwork-url').value.trim().split('\n')[0].trim();
const resultDiv = document.getElementById('artwork-result');
if (!url) { showToast('Enter a Spotify URL', 'error'); return; }
btn.disabled = true;
resultDiv.innerHTML = '<span style="color:var(--text2)">Fetching artwork...</span>';
try {
const res = await fetch('/api/artwork?url=' + encodeURIComponent(url));
const data = await res.json();
if (res.ok && data.image_url) {
const img = document.createElement('img');
img.src = data.image_url;
img.alt = 'Cover artwork';
img.style.cssText = 'max-width:100%;border-radius:var(--radius);display:block;';
resultDiv.innerHTML = '';
resultDiv.appendChild(img);
} else {
resultDiv.innerHTML = '<span style="color:var(--danger)">' + escapeHtml(data.error || 'No artwork found') + '</span>';
}
} catch (e) {
resultDiv.innerHTML = '<span style="color:var(--danger)">Failed to fetch artwork</span>';
}
btn.disabled = false;
}
function formatSize(bytes) {
if (!bytes) return '';
const units = ['B', 'KB', 'MB', 'GB'];
@@ -1137,9 +1179,11 @@
// Drop onto active page's textarea
const monoActive = document.getElementById('page-monochrome').classList.contains('active');
const votifyActive = document.getElementById('page-download').classList.contains('active');
const artworkActive = document.getElementById('page-artwork').classList.contains('active');
let taId = 'unified-urls';
if (monoActive) taId = 'mono-url';
else if (votifyActive) taId = 'urls';
else if (artworkActive) taId = 'artwork-url';
const ta = document.getElementById(taId);
ta.value = (ta.value.trim() ? ta.value.trim() + '\n' : '') + lines.join('\n');
ta.classList.remove('drop-flash');
@@ -1147,7 +1191,7 @@
ta.classList.add('drop-flash');
setTimeout(() => ta.classList.remove('drop-flash'), 650);
});
for (const id of ['urls', 'mono-url', 'unified-urls']) {
for (const id of ['urls', 'mono-url', 'unified-urls', 'artwork-url']) {
const ta = document.getElementById(id);
ta.addEventListener('dragover', () => ta.classList.add('drag-over'));
ta.addEventListener('dragleave', () => ta.classList.remove('drag-over'));