FEAT: add track mix button to player bar and display release year
This commit is contained in:
parent
0791c59f15
commit
3e228a0d46
5 changed files with 54 additions and 7 deletions
|
|
@ -711,6 +711,11 @@
|
|||
<div class="player-actions-row">
|
||||
<button id="now-playing-like-btn" class="like-btn" data-action="toggle-like" title="Save to Favorites" style="display: none;">
|
||||
</button>
|
||||
<button id="now-playing-mix-btn" class="mix-btn" data-action="track-mix" title="Track Mix" style="display: none;">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="currentColor">
|
||||
<path d="M12 3v10.55c-.59-.34-1.27-.55-2-.55-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4V7h4V3h-6z"/>
|
||||
</svg>
|
||||
</button>
|
||||
<button id="toggle-lyrics-btn" title="Lyrics">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-mic"><path d="M12 2a3 3 0 0 0-3 3v7a3 3 0 0 0 6 0V5a3 3 0 0 0-3-3Z"/><path d="M19 10v2a7 7 0 0 1-14 0v-2"/><line x1="12" y1="19" x2="12" y2="22"/><line x1="8" y1="22" x2="16" y2="22"/></svg>
|
||||
</button>
|
||||
|
|
|
|||
10
js/events.js
10
js/events.js
|
|
@ -667,6 +667,16 @@ export function initializeTrackInteractions(player, api, mainContent, contextMen
|
|||
}
|
||||
});
|
||||
}
|
||||
|
||||
const nowPlayingMixBtn = document.getElementById('now-playing-mix-btn');
|
||||
if (nowPlayingMixBtn) {
|
||||
nowPlayingMixBtn.addEventListener('click', async (e) => {
|
||||
e.stopPropagation();
|
||||
if (player.currentTrack) {
|
||||
await handleTrackAction('track-mix', player.currentTrack, player, api, lyricsManager, 'track', ui, scrobbler);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function renderQueue(player) {
|
||||
|
|
|
|||
32
js/player.js
32
js/player.js
|
|
@ -44,6 +44,15 @@ export class Player {
|
|||
const track = this.currentTrack;
|
||||
const trackTitle = getTrackTitle(track);
|
||||
const trackArtistsHTML = getTrackArtistsHTML(track);
|
||||
|
||||
let yearDisplay = '';
|
||||
const releaseDate = track.album?.releaseDate || track.streamStartDate;
|
||||
if (releaseDate) {
|
||||
const date = new Date(releaseDate);
|
||||
if (!isNaN(date.getTime())) {
|
||||
yearDisplay = ` • ${date.getFullYear()}`;
|
||||
}
|
||||
}
|
||||
|
||||
const coverEl = document.querySelector('.now-playing-bar .cover');
|
||||
const titleEl = document.querySelector('.now-playing-bar .title');
|
||||
|
|
@ -51,7 +60,12 @@ export class Player {
|
|||
|
||||
if (coverEl) coverEl.src = this.api.getCoverUrl(track.album?.cover, '1280');
|
||||
if (titleEl) titleEl.textContent = trackTitle;
|
||||
if (artistEl) artistEl.innerHTML = trackArtistsHTML;
|
||||
if (artistEl) artistEl.innerHTML = trackArtistsHTML + yearDisplay;
|
||||
|
||||
const mixBtn = document.getElementById('now-playing-mix-btn');
|
||||
if (mixBtn) {
|
||||
mixBtn.style.display = (track.mixes && track.mixes.TRACK_MIX) ? 'flex' : 'none';
|
||||
}
|
||||
const totalDurationEl = document.getElementById('total-duration');
|
||||
if (totalDurationEl) totalDurationEl.textContent = formatTime(track.duration);
|
||||
document.title = `${trackTitle} • ${track.artist?.name || 'Unknown'}`;
|
||||
|
|
@ -169,11 +183,25 @@ export class Player {
|
|||
|
||||
const trackTitle = getTrackTitle(track);
|
||||
const trackArtistsHTML = getTrackArtistsHTML(track);
|
||||
|
||||
let yearDisplay = '';
|
||||
const releaseDate = track.album?.releaseDate || track.streamStartDate;
|
||||
if (releaseDate) {
|
||||
const date = new Date(releaseDate);
|
||||
if (!isNaN(date.getTime())) {
|
||||
yearDisplay = ` • ${date.getFullYear()}`;
|
||||
}
|
||||
}
|
||||
|
||||
document.querySelector('.now-playing-bar .cover').src =
|
||||
this.api.getCoverUrl(track.album?.cover, '1280');
|
||||
document.querySelector('.now-playing-bar .title').textContent = trackTitle;
|
||||
document.querySelector('.now-playing-bar .artist').innerHTML = trackArtistsHTML;
|
||||
document.querySelector('.now-playing-bar .artist').innerHTML = trackArtistsHTML + yearDisplay;
|
||||
|
||||
const mixBtn = document.getElementById('now-playing-mix-btn');
|
||||
if (mixBtn) {
|
||||
mixBtn.style.display = (track.mixes && track.mixes.TRACK_MIX) ? 'flex' : 'none';
|
||||
}
|
||||
document.title = `${trackTitle} • ${track.artist?.name || 'Unknown'}`;
|
||||
|
||||
this.updatePlayingTrackIndicator();
|
||||
|
|
|
|||
13
js/ui.js
13
js/ui.js
|
|
@ -1189,17 +1189,20 @@ async showFullscreenCover(track, nextTrack, lyricsManager, audioPlayer) {
|
|||
|
||||
let displayTitle;
|
||||
if (type === 'artist' && name) {
|
||||
displayTitle = `Mix for artist ${decodeURIComponent(name)}`;
|
||||
const decodedName = decodeURIComponent(name);
|
||||
titleEl.innerHTML = `<span style="color: var(--muted-foreground)">Mix for artist</span> ${decodedName}`;
|
||||
this.adjustTitleFontSize(titleEl, `Mix for artist ${decodedName}`);
|
||||
} else if (type === 'track' && name) {
|
||||
displayTitle = `Mix for track ${decodeURIComponent(name)}`;
|
||||
const decodedName = decodeURIComponent(name);
|
||||
titleEl.innerHTML = `<span style="color: var(--muted-foreground)">Mix for track</span> ${decodedName}`;
|
||||
this.adjustTitleFontSize(titleEl, `Mix for track ${decodedName}`);
|
||||
} else {
|
||||
const firstTrackArtist = tracks.length > 0 ? tracks[0].artist?.name : '';
|
||||
displayTitle = mix.title || (firstTrackArtist ? `${firstTrackArtist} Mix` : 'Mix');
|
||||
titleEl.textContent = displayTitle;
|
||||
this.adjustTitleFontSize(titleEl, displayTitle);
|
||||
}
|
||||
|
||||
titleEl.textContent = displayTitle;
|
||||
this.adjustTitleFontSize(titleEl, displayTitle);
|
||||
|
||||
const totalDuration = calculateTotalDuration(tracks);
|
||||
|
||||
metaEl.textContent = `${tracks.length} tracks • ${formatDuration(totalDuration)}`;
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ export const SVG_MENU = '<svg xmlns="http://www.w3.org/2000/svg" width="24" heig
|
|||
export const SVG_HEART = '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="heart-icon"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg>';
|
||||
export const SVG_CLOSE = '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg>';
|
||||
export const SVG_BIN = '<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="3 6 5 6 21 6"></polyline><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"></path><line x1="10" y1="11" x2="10" y2="17"></line><line x1="14" y1="11" x2="14" y2="17"></line></svg>';
|
||||
export const SVG_MIX = '<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="currentColor"><path d="M12 3v10.55c-.59-.34-1.27-.55-2-.55-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4V7h4V3h-6z"/></svg>';
|
||||
|
||||
export const formatTime = (seconds) => {
|
||||
if (isNaN(seconds)) return '0:00';
|
||||
|
|
|
|||
Loading…
Reference in a new issue