Add source badges (Spotify/iTunes/Deezer) to watchlist artist cards

Shows which metadata sources each artist is matched to with small
colored badges on the card. Also adds deezer_artist_id to the
watchlist API response and fixes the data-artist-id fallback chain
to include Deezer-only artists.
This commit is contained in:
Broque Thomas 2026-03-16 13:37:53 -07:00
parent 46ac46134b
commit f10beeea0a
3 changed files with 44 additions and 3 deletions

View file

@ -30128,6 +30128,7 @@ def get_watchlist_artists():
"updated_at": artist.updated_at.isoformat() if artist.updated_at else None,
"image_url": artist.image_url, # Cached during watchlist scans
"itunes_artist_id": artist.itunes_artist_id, # For iTunes-only artists
"deezer_artist_id": getattr(artist, 'deezer_artist_id', None),
"include_albums": artist.include_albums,
"include_eps": artist.include_eps,
"include_singles": artist.include_singles,

View file

@ -34267,21 +34267,26 @@ async function showWatchlistModal() {
if (artist.include_remixes) pills.push('<span class="watchlist-pill watchlist-pill-filter">Remixes</span>');
if (artist.include_acoustic) pills.push('<span class="watchlist-pill watchlist-pill-filter">Acoustic</span>');
if (artist.include_compilations) pills.push('<span class="watchlist-pill watchlist-pill-filter">Compilations</span>');
const sourceBadges = [];
if (artist.spotify_artist_id) sourceBadges.push('<span class="watchlist-source-badge watchlist-source-spotify">Spotify</span>');
if (artist.itunes_artist_id) sourceBadges.push('<span class="watchlist-source-badge watchlist-source-itunes">iTunes</span>');
if (artist.deezer_artist_id) sourceBadges.push('<span class="watchlist-source-badge watchlist-source-deezer">Deezer</span>');
const artistPrimaryId = artist.spotify_artist_id || artist.itunes_artist_id || artist.deezer_artist_id;
return `
<div class="watchlist-artist-card"
data-artist-name="${artist.artist_name.toLowerCase().replace(/"/g, '&quot;')}"
data-artist-id="${artist.spotify_artist_id || artist.itunes_artist_id}">
data-artist-id="${artistPrimaryId}">
<label class="watchlist-card-checkbox" onclick="event.stopPropagation();">
<input type="checkbox" class="watchlist-select-cb"
data-artist-id="${artist.spotify_artist_id || artist.itunes_artist_id}"
data-artist-id="${artistPrimaryId}"
data-artist-name="${escapeHtml(artist.artist_name)}"
onchange="updateWatchlistBatchBar()">
<span class="watchlist-checkbox-custom"></span>
</label>
<button class="watchlist-card-gear"
data-artist-id="${artist.spotify_artist_id || artist.itunes_artist_id}"
data-artist-id="${artistPrimaryId}"
data-artist-name="${escapeHtml(artist.artist_name)}"
onclick="event.stopPropagation();"
title="Artist settings">
@ -34303,6 +34308,7 @@ async function showWatchlistModal() {
<span class="watchlist-card-name">${escapeHtml(artist.artist_name)}</span>
<span class="watchlist-card-meta">${formatRelativeScanTime(artist.last_scan_timestamp)}</span>
</div>
${sourceBadges.length > 0 ? `<div class="watchlist-card-sources">${sourceBadges.join('')}</div>` : ''}
${pills.length > 0 ? `<div class="watchlist-card-pills">${pills.join('')}</div>` : ''}
</div>
`}).join('')}

View file

@ -12063,6 +12063,40 @@ body {
}
/* Card release-type pills */
.watchlist-card-sources {
position: relative;
z-index: 2;
display: flex;
flex-wrap: wrap;
gap: 4px;
padding: 2px 16px 4px;
}
.watchlist-source-badge {
font-size: 8px;
font-weight: 700;
text-transform: uppercase;
padding: 2px 6px;
border-radius: 3px;
letter-spacing: 0.4px;
line-height: 1.3;
}
.watchlist-source-spotify {
background: rgba(30, 215, 96, 0.15);
color: #1ed760;
}
.watchlist-source-itunes {
background: rgba(252, 60, 68, 0.15);
color: #fc3c44;
}
.watchlist-source-deezer {
background: rgba(162, 101, 230, 0.15);
color: #a265e6;
}
.watchlist-card-pills {
position: relative;
z-index: 2;