IMP: show link for each artist of current track
This commit is contained in:
parent
974d70184d
commit
d286c80540
5 changed files with 42 additions and 14 deletions
|
|
@ -315,7 +315,7 @@
|
||||||
<div class="setting-item">
|
<div class="setting-item">
|
||||||
<div class="info">
|
<div class="info">
|
||||||
<span class="label">Album Cover Background</span>
|
<span class="label">Album Cover Background</span>
|
||||||
<span class="description">Use the album cover as a blurred background on album pages</span>
|
<span class="description">Use the album cover as a blurred background on album pages and as primary color</span>
|
||||||
</div>
|
</div>
|
||||||
<label class="toggle-switch">
|
<label class="toggle-switch">
|
||||||
<input type="checkbox" id="album-background-toggle">
|
<input type="checkbox" id="album-background-toggle">
|
||||||
|
|
@ -426,7 +426,7 @@
|
||||||
<div class="setting-item">
|
<div class="setting-item">
|
||||||
<div class="info">
|
<div class="info">
|
||||||
<span class="label">Backup & Restore</span>
|
<span class="label">Backup & Restore</span>
|
||||||
<span class="description">Export or import your library and playlists as JSON</span>
|
<span class="description">Export or import your library and history as JSON</span>
|
||||||
</div>
|
</div>
|
||||||
<div style="display: flex; gap: 0.5rem;">
|
<div style="display: flex; gap: 0.5rem;">
|
||||||
<button id="export-library-btn" class="btn-secondary">Export</button>
|
<button id="export-library-btn" class="btn-secondary">Export</button>
|
||||||
|
|
|
||||||
13
js/events.js
13
js/events.js
|
|
@ -525,7 +525,18 @@ export function initializeTrackInteractions(player, api, mainContent, contextMen
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
document.querySelector('.now-playing-bar .artist').addEventListener('click', () => {
|
document.querySelector('.now-playing-bar .artist').addEventListener('click', (e) => {
|
||||||
|
const link = e.target.closest('.artist-link');
|
||||||
|
if (link) {
|
||||||
|
e.stopPropagation();
|
||||||
|
const artistId = link.dataset.artistId;
|
||||||
|
if (artistId) {
|
||||||
|
window.location.hash = `#artist/${artistId}`;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fallback for non-link clicks (e.g. separators) or single artist legacy
|
||||||
const track = player.currentTrack;
|
const track = player.currentTrack;
|
||||||
if (track?.artist?.id) {
|
if (track?.artist?.id) {
|
||||||
window.location.hash = `#artist/${track.artist.id}`;
|
window.location.hash = `#artist/${track.artist.id}`;
|
||||||
|
|
|
||||||
10
js/player.js
10
js/player.js
|
|
@ -1,5 +1,5 @@
|
||||||
//js/player.js
|
//js/player.js
|
||||||
import { REPEAT_MODE, formatTime, getTrackArtists, getTrackTitle} from './utils.js';
|
import { REPEAT_MODE, formatTime, getTrackArtists, getTrackTitle, getTrackArtistsHTML } from './utils.js';
|
||||||
import { queueManager } from './storage.js';
|
import { queueManager } from './storage.js';
|
||||||
|
|
||||||
export class Player {
|
export class Player {
|
||||||
|
|
@ -43,7 +43,7 @@ export class Player {
|
||||||
// Restore UI
|
// Restore UI
|
||||||
const track = this.currentTrack;
|
const track = this.currentTrack;
|
||||||
const trackTitle = getTrackTitle(track);
|
const trackTitle = getTrackTitle(track);
|
||||||
const trackArtists = getTrackArtists(track);
|
const trackArtistsHTML = getTrackArtistsHTML(track);
|
||||||
|
|
||||||
const coverEl = document.querySelector('.now-playing-bar .cover');
|
const coverEl = document.querySelector('.now-playing-bar .cover');
|
||||||
const titleEl = document.querySelector('.now-playing-bar .title');
|
const titleEl = document.querySelector('.now-playing-bar .title');
|
||||||
|
|
@ -51,7 +51,7 @@ export class Player {
|
||||||
|
|
||||||
if (coverEl) coverEl.src = this.api.getCoverUrl(track.album?.cover, '1280');
|
if (coverEl) coverEl.src = this.api.getCoverUrl(track.album?.cover, '1280');
|
||||||
if (titleEl) titleEl.textContent = trackTitle;
|
if (titleEl) titleEl.textContent = trackTitle;
|
||||||
if (artistEl) artistEl.textContent = trackArtists;
|
if (artistEl) artistEl.innerHTML = trackArtistsHTML;
|
||||||
const totalDurationEl = document.getElementById('total-duration');
|
const totalDurationEl = document.getElementById('total-duration');
|
||||||
if (totalDurationEl) totalDurationEl.textContent = formatTime(track.duration);
|
if (totalDurationEl) totalDurationEl.textContent = formatTime(track.duration);
|
||||||
document.title = `${trackTitle} • ${track.artist?.name || 'Unknown'}`;
|
document.title = `${trackTitle} • ${track.artist?.name || 'Unknown'}`;
|
||||||
|
|
@ -168,12 +168,12 @@ export class Player {
|
||||||
this.currentTrack = track;
|
this.currentTrack = track;
|
||||||
|
|
||||||
const trackTitle = getTrackTitle(track);
|
const trackTitle = getTrackTitle(track);
|
||||||
const trackArtists = getTrackArtists(track);
|
const trackArtistsHTML = getTrackArtistsHTML(track);
|
||||||
|
|
||||||
document.querySelector('.now-playing-bar .cover').src =
|
document.querySelector('.now-playing-bar .cover').src =
|
||||||
this.api.getCoverUrl(track.album?.cover, '1280');
|
this.api.getCoverUrl(track.album?.cover, '1280');
|
||||||
document.querySelector('.now-playing-bar .title').textContent = trackTitle;
|
document.querySelector('.now-playing-bar .title').textContent = trackTitle;
|
||||||
document.querySelector('.now-playing-bar .artist').textContent = trackArtists;
|
document.querySelector('.now-playing-bar .artist').innerHTML = trackArtistsHTML;
|
||||||
document.title = `${trackTitle} • ${track.artist?.name || 'Unknown'}`;
|
document.title = `${trackTitle} • ${track.artist?.name || 'Unknown'}`;
|
||||||
|
|
||||||
this.updatePlayingTrackIndicator();
|
this.updatePlayingTrackIndicator();
|
||||||
|
|
|
||||||
10
js/utils.js
10
js/utils.js
|
|
@ -176,6 +176,16 @@ export const getTrackArtists = (track = {}, { fallback = 'Unknown Artist' } = {}
|
||||||
return fallback;
|
return fallback;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const getTrackArtistsHTML = (track = {}, { fallback = 'Unknown Artist' } = {}) => {
|
||||||
|
if (track?.artists?.length) {
|
||||||
|
return track.artists.map(artist =>
|
||||||
|
`<span class="artist-link" data-artist-id="${artist.id}">${artist.name}</span>`
|
||||||
|
).join(', ');
|
||||||
|
}
|
||||||
|
|
||||||
|
return fallback;
|
||||||
|
};
|
||||||
|
|
||||||
export const formatTemplate = (template, data) => {
|
export const formatTemplate = (template, data) => {
|
||||||
let result = template;
|
let result = template;
|
||||||
result = result.replace(/\{trackNumber\}/g, data.trackNumber ? String(data.trackNumber).padStart(2, '0') : '00');
|
result = result.replace(/\{trackNumber\}/g, data.trackNumber ? String(data.trackNumber).padStart(2, '0') : '00');
|
||||||
|
|
|
||||||
19
styles.css
19
styles.css
|
|
@ -53,7 +53,7 @@
|
||||||
--highlight: #3b82f6;
|
--highlight: #3b82f6;
|
||||||
--highlight-rgb: 59, 130, 246;
|
--highlight-rgb: 59, 130, 246;
|
||||||
--active-highlight: #3b82f6;
|
--active-highlight: #3b82f6;
|
||||||
--explicit-badge: #ef4444;
|
--explicit-badge: #750a0a;
|
||||||
}
|
}
|
||||||
|
|
||||||
:root[data-theme="ocean"] {
|
:root[data-theme="ocean"] {
|
||||||
|
|
@ -133,8 +133,7 @@
|
||||||
--highlight: #2563eb;
|
--highlight: #2563eb;
|
||||||
--highlight-rgb: 37, 99, 235;
|
--highlight-rgb: 37, 99, 235;
|
||||||
--active-highlight: var(--highlight);
|
--active-highlight: var(--highlight);
|
||||||
--explicit-badge: #ef4444;
|
--explicit-badge: #f58a8a;
|
||||||
--explicit-badge-foreground: #ffffff;
|
|
||||||
--cover-filter: blur(30px) brightness(1.6) opacity(0.85);
|
--cover-filter: blur(30px) brightness(1.6) opacity(0.85);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -622,7 +621,7 @@ body.has-page-background .track-item:hover {
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
background-color: var(--explicit-badge);
|
background-color: var(--explicit-badge);
|
||||||
color: var(--explicit-badge-foreground, #000);
|
color: var(--background);
|
||||||
font-size: 0.65rem;
|
font-size: 0.65rem;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
padding: 0.15rem 0.35rem;
|
padding: 0.15rem 0.35rem;
|
||||||
|
|
@ -1464,14 +1463,14 @@ input:checked + .slider::before {
|
||||||
|
|
||||||
#fullscreen-track-artist {
|
#fullscreen-track-artist {
|
||||||
font-size: 1.25rem;
|
font-size: 1.25rem;
|
||||||
color: var(--primary);
|
color: var(--muted-foreground);
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
}
|
}
|
||||||
|
|
||||||
#fullscreen-next-track {
|
#fullscreen-next-track {
|
||||||
margin-top: 1.5rem;
|
margin-top: 1.5rem;
|
||||||
font-size: 0.9rem;
|
font-size: 0.9rem;
|
||||||
color: var(--primary);
|
color: var(--muted-foreground);
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 0.2rem;
|
gap: 0.2rem;
|
||||||
|
|
@ -3207,6 +3206,14 @@ input:checked + .slider::before {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.now-playing-bar .artist .artist-link {
|
||||||
|
cursor: pointer;
|
||||||
|
transition: color var(--transition);
|
||||||
|
}
|
||||||
|
.now-playing-bar .artist .artist-link:hover {
|
||||||
|
color: var(--highlight);
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
/* Updated Volume Controls Layout */
|
/* Updated Volume Controls Layout */
|
||||||
.volume-controls {
|
.volume-controls {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue