Fix Spotify badge icon & compact card badge layout for overflow
This commit is contained in:
parent
87d567151e
commit
927fe6338e
3 changed files with 144 additions and 66 deletions
|
|
@ -5919,6 +5919,8 @@ class MusicDatabase:
|
||||||
a.itunes_artist_id,
|
a.itunes_artist_id,
|
||||||
a.deezer_id,
|
a.deezer_id,
|
||||||
a.audiodb_id,
|
a.audiodb_id,
|
||||||
|
a.lastfm_url,
|
||||||
|
a.genius_url,
|
||||||
COUNT(DISTINCT al.id) as album_count,
|
COUNT(DISTINCT al.id) as album_count,
|
||||||
COUNT(DISTINCT t.id) as track_count
|
COUNT(DISTINCT t.id) as track_count
|
||||||
FROM artists a
|
FROM artists a
|
||||||
|
|
@ -5929,7 +5931,7 @@ class MusicDatabase:
|
||||||
WHERE {where_clause}
|
WHERE {where_clause}
|
||||||
AND a.id = (SELECT MIN(a2.id) FROM artists a2
|
AND a.id = (SELECT MIN(a2.id) FROM artists a2
|
||||||
WHERE a2.name = a.name AND a2.server_source = a.server_source)
|
WHERE a2.name = a.name AND a2.server_source = a.server_source)
|
||||||
GROUP BY a.id, a.name, a.thumb_url, a.genres, a.musicbrainz_id, a.deezer_id, a.audiodb_id
|
GROUP BY a.id, a.name, a.thumb_url, a.genres, a.musicbrainz_id, a.spotify_artist_id, a.itunes_artist_id, a.deezer_id, a.audiodb_id, a.lastfm_url, a.genius_url
|
||||||
ORDER BY a.name COLLATE NOCASE
|
ORDER BY a.name COLLATE NOCASE
|
||||||
LIMIT ? OFFSET ?
|
LIMIT ? OFFSET ?
|
||||||
"""
|
"""
|
||||||
|
|
@ -5977,6 +5979,8 @@ class MusicDatabase:
|
||||||
'itunes_artist_id': row['itunes_artist_id'],
|
'itunes_artist_id': row['itunes_artist_id'],
|
||||||
'deezer_id': row['deezer_id'],
|
'deezer_id': row['deezer_id'],
|
||||||
'audiodb_id': row['audiodb_id'],
|
'audiodb_id': row['audiodb_id'],
|
||||||
|
'lastfm_url': row['lastfm_url'],
|
||||||
|
'genius_url': row['genius_url'],
|
||||||
'album_count': row['album_count'] or 0,
|
'album_count': row['album_count'] or 0,
|
||||||
'track_count': row['track_count'] or 0,
|
'track_count': row['track_count'] or 0,
|
||||||
'is_watched': bool(is_watched)
|
'is_watched': bool(is_watched)
|
||||||
|
|
@ -6032,7 +6036,9 @@ class MusicDatabase:
|
||||||
# Get artist information
|
# Get artist information
|
||||||
cursor.execute("""
|
cursor.execute("""
|
||||||
SELECT
|
SELECT
|
||||||
id, name, thumb_url, genres, server_source, musicbrainz_id, deezer_id, audiodb_id
|
id, name, thumb_url, genres, server_source,
|
||||||
|
musicbrainz_id, deezer_id, audiodb_id,
|
||||||
|
spotify_artist_id, itunes_artist_id, lastfm_url, genius_url
|
||||||
FROM artists
|
FROM artists
|
||||||
WHERE id = ?
|
WHERE id = ?
|
||||||
""", (artist_id,))
|
""", (artist_id,))
|
||||||
|
|
@ -6181,6 +6187,10 @@ class MusicDatabase:
|
||||||
'musicbrainz_id': artist_row['musicbrainz_id'],
|
'musicbrainz_id': artist_row['musicbrainz_id'],
|
||||||
'deezer_id': artist_row['deezer_id'],
|
'deezer_id': artist_row['deezer_id'],
|
||||||
'audiodb_id': artist_row['audiodb_id'],
|
'audiodb_id': artist_row['audiodb_id'],
|
||||||
|
'spotify_artist_id': artist_row['spotify_artist_id'],
|
||||||
|
'itunes_artist_id': artist_row['itunes_artist_id'],
|
||||||
|
'lastfm_url': artist_row['lastfm_url'],
|
||||||
|
'genius_url': artist_row['genius_url'],
|
||||||
'album_count': album_count,
|
'album_count': album_count,
|
||||||
'track_count': track_count
|
'track_count': track_count
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -398,9 +398,13 @@ function handleDashboardWishlistCount(data) {
|
||||||
// END WEBSOCKET CONNECTION MANAGER
|
// END WEBSOCKET CONNECTION MANAGER
|
||||||
// ===============================
|
// ===============================
|
||||||
|
|
||||||
// --- MusicBrainz Integration Constants ---
|
// --- Service Integration Logo Constants ---
|
||||||
const MUSICBRAINZ_LOGO_URL = 'https://upload.wikimedia.org/wikipedia/commons/thumb/9/9e/MusicBrainz_Logo_%282016%29.svg/500px-MusicBrainz_Logo_%282016%29.svg.png';
|
const MUSICBRAINZ_LOGO_URL = 'https://upload.wikimedia.org/wikipedia/commons/thumb/9/9e/MusicBrainz_Logo_%282016%29.svg/500px-MusicBrainz_Logo_%282016%29.svg.png';
|
||||||
const DEEZER_LOGO_URL = 'https://cdn.brandfetch.io/idEUKgCNtu/theme/dark/symbol.svg?c=1bxid64Mup7aczewSAYMX&t=1758260798610';
|
const DEEZER_LOGO_URL = 'https://cdn.brandfetch.io/idEUKgCNtu/theme/dark/symbol.svg?c=1bxid64Mup7aczewSAYMX&t=1758260798610';
|
||||||
|
const SPOTIFY_LOGO_URL = 'https://storage.googleapis.com/pr-newsroom-wp/1/2023/05/Spotify_Primary_Logo_RGB_Green.png';
|
||||||
|
const ITUNES_LOGO_URL = 'https://upload.wikimedia.org/wikipedia/commons/thumb/d/df/ITunes_logo.svg/960px-ITunes_logo.svg.png';
|
||||||
|
const LASTFM_LOGO_URL = 'https://www.last.fm/static/images/lastfm_avatar_twitter.52a5d69a85ac.png';
|
||||||
|
const GENIUS_LOGO_URL = 'https://images.genius.com/8ed669cadd956443e29c70361ec4f372.1000x1000x1.png';
|
||||||
function getAudioDBLogoURL() { const el = document.querySelector('img.audiodb-logo'); return el ? el.src : null; }
|
function getAudioDBLogoURL() { const el = document.querySelector('img.audiodb-logo'); return el ? el.src : null; }
|
||||||
|
|
||||||
// --- Wishlist Modal Persistence State Management ---
|
// --- Wishlist Modal Persistence State Management ---
|
||||||
|
|
@ -31780,8 +31784,11 @@ function createLibraryArtistCard(artist) {
|
||||||
card.style.position = 'relative';
|
card.style.position = 'relative';
|
||||||
card.style.transition = 'transform 0.2s, box-shadow 0.2s';
|
card.style.transition = 'transform 0.2s, box-shadow 0.2s';
|
||||||
|
|
||||||
// Add source badges (MusicBrainz, Deezer, AudioDB) stacked on top-right
|
// Add source badges stacked on top-right
|
||||||
const badgeSources = [];
|
const badgeSources = [];
|
||||||
|
if (artist.spotify_artist_id) {
|
||||||
|
badgeSources.push({ cls: 'spotify-card-icon', logo: SPOTIFY_LOGO_URL, fallback: 'SP', title: 'View on Spotify', url: `https://open.spotify.com/artist/${artist.spotify_artist_id}` });
|
||||||
|
}
|
||||||
if (artist.musicbrainz_id) {
|
if (artist.musicbrainz_id) {
|
||||||
badgeSources.push({ cls: 'mb-card-icon', logo: MUSICBRAINZ_LOGO_URL, fallback: 'MB', title: 'View on MusicBrainz', url: `https://musicbrainz.org/artist/${artist.musicbrainz_id}` });
|
badgeSources.push({ cls: 'mb-card-icon', logo: MUSICBRAINZ_LOGO_URL, fallback: 'MB', title: 'View on MusicBrainz', url: `https://musicbrainz.org/artist/${artist.musicbrainz_id}` });
|
||||||
}
|
}
|
||||||
|
|
@ -31792,28 +31799,39 @@ function createLibraryArtistCard(artist) {
|
||||||
const adbSlug = artist.name ? artist.name.replace(/\s+/g, '-').replace(/[^a-zA-Z0-9-]/g, '') : '';
|
const adbSlug = artist.name ? artist.name.replace(/\s+/g, '-').replace(/[^a-zA-Z0-9-]/g, '') : '';
|
||||||
badgeSources.push({ cls: 'audiodb-card-icon', logo: getAudioDBLogoURL(), fallback: 'ADB', title: 'View on TheAudioDB', url: `https://www.theaudiodb.com/artist/${artist.audiodb_id}-${adbSlug}` });
|
badgeSources.push({ cls: 'audiodb-card-icon', logo: getAudioDBLogoURL(), fallback: 'ADB', title: 'View on TheAudioDB', url: `https://www.theaudiodb.com/artist/${artist.audiodb_id}-${adbSlug}` });
|
||||||
}
|
}
|
||||||
let badgeOffset = 8;
|
if (artist.itunes_artist_id) {
|
||||||
badgeSources.forEach(source => {
|
badgeSources.push({ cls: 'itunes-card-icon', logo: ITUNES_LOGO_URL, fallback: 'IT', title: 'View on Apple Music', url: `https://music.apple.com/artist/${artist.itunes_artist_id}` });
|
||||||
const icon = document.createElement('div');
|
}
|
||||||
icon.className = `${source.cls} source-card-icon`;
|
if (artist.lastfm_url) {
|
||||||
icon.style.top = badgeOffset + 'px';
|
badgeSources.push({ cls: 'lastfm-card-icon', logo: LASTFM_LOGO_URL, fallback: 'LFM', title: 'View on Last.fm', url: artist.lastfm_url });
|
||||||
icon.title = source.title;
|
}
|
||||||
if (source.logo) {
|
if (artist.genius_url) {
|
||||||
const img = document.createElement('img');
|
badgeSources.push({ cls: 'genius-card-icon', logo: GENIUS_LOGO_URL, fallback: 'GEN', title: 'View on Genius', url: artist.genius_url });
|
||||||
img.src = source.logo;
|
}
|
||||||
img.style.cssText = 'width: 20px; height: auto; display: block;';
|
if (badgeSources.length > 0) {
|
||||||
img.onerror = () => { icon.textContent = source.fallback; };
|
const badgeContainer = document.createElement('div');
|
||||||
icon.appendChild(img);
|
badgeContainer.className = 'card-badge-container';
|
||||||
} else {
|
badgeSources.forEach(source => {
|
||||||
icon.textContent = source.fallback;
|
const icon = document.createElement('div');
|
||||||
}
|
icon.className = `${source.cls} source-card-icon`;
|
||||||
icon.onclick = (e) => {
|
icon.title = source.title;
|
||||||
e.stopPropagation();
|
if (source.logo) {
|
||||||
window.open(source.url, '_blank');
|
const img = document.createElement('img');
|
||||||
};
|
img.src = source.logo;
|
||||||
card.appendChild(icon);
|
img.style.cssText = 'width: 16px; height: auto; display: block;';
|
||||||
badgeOffset += 32;
|
img.onerror = () => { icon.textContent = source.fallback; };
|
||||||
});
|
icon.appendChild(img);
|
||||||
|
} else {
|
||||||
|
icon.textContent = source.fallback;
|
||||||
|
}
|
||||||
|
icon.onclick = (e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
window.open(source.url, '_blank');
|
||||||
|
};
|
||||||
|
badgeContainer.appendChild(icon);
|
||||||
|
});
|
||||||
|
card.appendChild(badgeContainer);
|
||||||
|
}
|
||||||
|
|
||||||
// Add watchlist button/indicator on the card
|
// Add watchlist button/indicator on the card
|
||||||
const hasExternalId = artist.itunes_artist_id || artist.spotify_artist_id;
|
const hasExternalId = artist.itunes_artist_id || artist.spotify_artist_id;
|
||||||
|
|
@ -32277,9 +32295,13 @@ function updateArtistDetailPageHeaderWithData(artist) {
|
||||||
|
|
||||||
const adbSlug = artist.name ? artist.name.replace(/\s+/g, '-').replace(/[^a-zA-Z0-9-]/g, '') : '';
|
const adbSlug = artist.name ? artist.name.replace(/\s+/g, '-').replace(/[^a-zA-Z0-9-]/g, '') : '';
|
||||||
const sources = [
|
const sources = [
|
||||||
|
{ id: artist.spotify_artist_id, url: `https://open.spotify.com/artist/${artist.spotify_artist_id}`, logo: SPOTIFY_LOGO_URL, label: 'Spotify' },
|
||||||
|
{ id: artist.itunes_artist_id, url: `https://music.apple.com/artist/${artist.itunes_artist_id}`, logo: ITUNES_LOGO_URL, label: 'Apple Music' },
|
||||||
{ id: artist.musicbrainz_id, url: `https://musicbrainz.org/artist/${artist.musicbrainz_id}`, logo: MUSICBRAINZ_LOGO_URL, label: 'MusicBrainz' },
|
{ id: artist.musicbrainz_id, url: `https://musicbrainz.org/artist/${artist.musicbrainz_id}`, logo: MUSICBRAINZ_LOGO_URL, label: 'MusicBrainz' },
|
||||||
{ id: artist.deezer_id, url: `https://www.deezer.com/artist/${artist.deezer_id}`, logo: DEEZER_LOGO_URL, label: 'Deezer' },
|
{ id: artist.deezer_id, url: `https://www.deezer.com/artist/${artist.deezer_id}`, logo: DEEZER_LOGO_URL, label: 'Deezer' },
|
||||||
{ id: artist.audiodb_id, url: `https://www.theaudiodb.com/artist/${artist.audiodb_id}-${adbSlug}`, logo: getAudioDBLogoURL(), label: 'TheAudioDB' },
|
{ id: artist.audiodb_id, url: `https://www.theaudiodb.com/artist/${artist.audiodb_id}-${adbSlug}`, logo: getAudioDBLogoURL(), label: 'TheAudioDB' },
|
||||||
|
{ id: artist.lastfm_url, url: artist.lastfm_url, logo: LASTFM_LOGO_URL, label: 'Last.fm' },
|
||||||
|
{ id: artist.genius_url, url: artist.genius_url, logo: GENIUS_LOGO_URL, label: 'Genius' },
|
||||||
];
|
];
|
||||||
|
|
||||||
sources.forEach(source => {
|
sources.forEach(source => {
|
||||||
|
|
@ -32289,27 +32311,15 @@ function updateArtistDetailPageHeaderWithData(artist) {
|
||||||
link.href = source.url;
|
link.href = source.url;
|
||||||
link.target = '_blank';
|
link.target = '_blank';
|
||||||
link.title = `View on ${source.label}`;
|
link.title = `View on ${source.label}`;
|
||||||
link.style.padding = '5px 14px';
|
|
||||||
link.style.border = '1px solid rgba(255,255,255,0.1)';
|
|
||||||
link.style.background = 'rgba(0,0,0,0.4)';
|
|
||||||
link.style.borderRadius = '20px';
|
|
||||||
link.style.marginLeft = '16px';
|
|
||||||
link.style.display = 'inline-flex';
|
|
||||||
link.style.alignItems = 'center';
|
|
||||||
link.style.textDecoration = 'none';
|
|
||||||
link.style.verticalAlign = 'middle';
|
|
||||||
|
|
||||||
const span = document.createElement('span');
|
|
||||||
span.style.cssText = `color:rgba(255,255,255,0.9); margin-left:${source.logo ? '10px' : '0'}; font-size: 13px; font-weight: 600; vertical-align: middle;`;
|
|
||||||
span.textContent = `View on ${source.label}`;
|
|
||||||
|
|
||||||
if (source.logo) {
|
if (source.logo) {
|
||||||
const img = document.createElement('img');
|
const img = document.createElement('img');
|
||||||
img.src = source.logo;
|
img.src = source.logo;
|
||||||
img.style.cssText = 'height: 24px; width: auto; vertical-align: middle; display: inline-block;';
|
img.onerror = () => { img.style.display = 'none'; };
|
||||||
img.onerror = () => { img.style.display = 'none'; span.style.marginLeft = '0'; };
|
|
||||||
link.appendChild(img);
|
link.appendChild(img);
|
||||||
}
|
}
|
||||||
|
const span = document.createElement('span');
|
||||||
|
span.textContent = source.label;
|
||||||
link.appendChild(span);
|
link.appendChild(span);
|
||||||
mainTitle.appendChild(link);
|
mainTitle.appendChild(link);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -28250,36 +28250,24 @@ body {
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mb-card-icon {
|
/* Legacy .mb-card-icon override removed — now handled by .source-card-icon inside .card-badge-container */
|
||||||
|
|
||||||
|
/* Badge container for artist cards */
|
||||||
|
.card-badge-container {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 8px;
|
top: 8px;
|
||||||
right: 8px;
|
right: 8px;
|
||||||
width: 28px;
|
|
||||||
height: 28px;
|
|
||||||
background: rgba(0, 0, 0, 0.75);
|
|
||||||
/* MusicBrainz Purple - Force visible color */
|
|
||||||
border: 1px solid rgba(255, 255, 255, 0.3);
|
|
||||||
border-radius: 4px;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
flex-direction: column;
|
||||||
justify-content: center;
|
gap: 4px;
|
||||||
opacity: 0.9 !important;
|
z-index: 100;
|
||||||
/* Force visible */
|
max-height: calc(100% - 80px);
|
||||||
transition: transform 0.2s;
|
overflow: hidden;
|
||||||
cursor: pointer;
|
|
||||||
z-index: 100 !important;
|
|
||||||
/* Force on top */
|
|
||||||
color: white;
|
|
||||||
font-size: 11px;
|
|
||||||
font-weight: 800;
|
|
||||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.5);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.source-card-icon {
|
.source-card-icon {
|
||||||
position: absolute;
|
width: 24px;
|
||||||
right: 8px;
|
height: 24px;
|
||||||
width: 28px;
|
|
||||||
height: 28px;
|
|
||||||
background: rgba(0, 0, 0, 0.75);
|
background: rgba(0, 0, 0, 0.75);
|
||||||
border: 1px solid rgba(255, 255, 255, 0.3);
|
border: 1px solid rgba(255, 255, 255, 0.3);
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
|
|
@ -28289,10 +28277,10 @@ body {
|
||||||
opacity: 0.9 !important;
|
opacity: 0.9 !important;
|
||||||
transition: transform 0.2s;
|
transition: transform 0.2s;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
z-index: 100 !important;
|
|
||||||
color: white;
|
color: white;
|
||||||
font-size: 11px;
|
font-size: 9px;
|
||||||
font-weight: 800;
|
font-weight: 800;
|
||||||
|
flex-shrink: 0;
|
||||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.5);
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -28315,6 +28303,76 @@ body {
|
||||||
background: #1a6bc4;
|
background: #1a6bc4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.spotify-card-icon:hover {
|
||||||
|
background: #1db954;
|
||||||
|
}
|
||||||
|
|
||||||
|
.itunes-card-icon:hover {
|
||||||
|
background: #fc3c44;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lastfm-card-icon:hover {
|
||||||
|
background: #d51007;
|
||||||
|
}
|
||||||
|
|
||||||
|
.genius-card-icon:hover {
|
||||||
|
background: #ffff64;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Artist detail page source link buttons */
|
||||||
|
.source-link-btn {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
padding: 6px 16px;
|
||||||
|
margin-left: 12px;
|
||||||
|
border-radius: 20px;
|
||||||
|
text-decoration: none;
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: rgba(255, 255, 255, 0.9);
|
||||||
|
background: rgba(255, 255, 255, 0.08);
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.12);
|
||||||
|
backdrop-filter: blur(8px);
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
vertical-align: middle;
|
||||||
|
font-family: 'SF Pro Text', -apple-system, BlinkMacSystemFont, sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.source-link-btn:hover {
|
||||||
|
background: rgba(255, 255, 255, 0.15);
|
||||||
|
border-color: rgba(255, 255, 255, 0.25);
|
||||||
|
transform: translateY(-1px);
|
||||||
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.source-link-btn img {
|
||||||
|
height: 20px;
|
||||||
|
width: auto;
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.source-link-btn span {
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.source-link-btn {
|
||||||
|
padding: 4px 10px;
|
||||||
|
margin-left: 6px;
|
||||||
|
font-size: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.source-link-btn img {
|
||||||
|
height: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.source-link-btn span {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.watchlist-card-icon {
|
.watchlist-card-icon {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 8px;
|
right: 8px;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue