feat: add next track info to enlarged cover view with animation

This commit is contained in:
Julien Maille 2025-12-23 22:55:23 +01:00
parent 25c6f1e5fb
commit 8361d31408
5 changed files with 68 additions and 2 deletions

View file

@ -43,6 +43,10 @@
<div class="fullscreen-track-info">
<h2 id="fullscreen-track-title"></h2>
<h3 id="fullscreen-track-artist"></h3>
<div id="fullscreen-next-track" style="display: none;">
<span class="label">Up Next: </span>
<span class="value"></span>
</div>
</div>
<div class="fullscreen-controls">
<!-- Controls will be cloned or managed here if needed, or we just rely on main controls -->

View file

@ -252,7 +252,8 @@ document.addEventListener('DOMContentLoaded', async () => {
clearLyricsPanelSync(audioPlayer, lyricsPanel);
}
} else if (mode === 'cover') {
ui.showFullscreenCover(player.currentTrack);
const nextTrack = player.getNextTrack();
ui.showFullscreenCover(player.currentTrack, nextTrack);
} else {
// Default to 'album' mode - navigate to album
if (player.currentTrack.album?.id) {
@ -315,6 +316,13 @@ document.addEventListener('DOMContentLoaded', async () => {
}
}
}
// Update Fullscreen/Enlarged Cover if it's open
const fullscreenOverlay = document.getElementById('fullscreen-cover-overlay');
if (fullscreenOverlay && getComputedStyle(fullscreenOverlay).display !== 'none') {
const nextTrack = player.getNextTrack();
ui.showFullscreenCover(player.currentTrack, nextTrack);
}
});
document.addEventListener('click', async (e) => {

View file

@ -366,6 +366,19 @@ export class Player {
return this.shuffleActive ? this.shuffledQueue : this.queue;
}
getNextTrack() {
const currentQueue = this.getCurrentQueue();
if (this.currentQueueIndex === -1 || currentQueue.length === 0) return null;
const nextIndex = this.currentQueueIndex + 1;
if (nextIndex < currentQueue.length) {
return currentQueue[nextIndex];
} else if (this.repeatMode === REPEAT_MODE.ALL) {
return currentQueue[0];
}
return null;
}
updatePlayingTrackIndicator() {
const currentTrack = this.getCurrentQueue()[this.currentQueueIndex];
document.querySelectorAll('.track-item').forEach(item => {

View file

@ -259,13 +259,14 @@ export class UIRenderer {
root.style.removeProperty('--ring');
}
showFullscreenCover(track) {
showFullscreenCover(track, nextTrack) {
if (!track) return;
const overlay = document.getElementById('fullscreen-cover-overlay');
const image = document.getElementById('fullscreen-cover-image');
const title = document.getElementById('fullscreen-track-title');
const artist = document.getElementById('fullscreen-track-artist');
const nextTrackEl = document.getElementById('fullscreen-next-track');
const coverUrl = this.api.getCoverUrl(track.album?.cover, '1280');
@ -273,6 +274,19 @@ export class UIRenderer {
title.textContent = track.title;
artist.textContent = track.artist?.name || 'Unknown Artist';
if (nextTrack) {
nextTrackEl.style.display = 'flex';
nextTrackEl.querySelector('.value').textContent = `${nextTrack.title}${nextTrack.artist?.name || 'Unknown'}`;
// Replay animation
nextTrackEl.classList.remove('animate-in');
void nextTrackEl.offsetWidth; // Trigger reflow
nextTrackEl.classList.add('animate-in');
} else {
nextTrackEl.style.display = 'none';
nextTrackEl.classList.remove('animate-in');
}
// Set the background image via CSS variable for the pseudo-element to use
overlay.style.setProperty('--bg-image', `url('${coverUrl}')`);

View file

@ -1319,6 +1319,33 @@ input:checked + .slider::before {
text-shadow: 0 2px 10px rgba(0,0,0,0.5);
}
#fullscreen-next-track {
margin-top: 1.5rem;
font-size: 0.9rem;
color: rgba(255, 255, 255, 0.6);
text-shadow: 0 1px 4px rgba(0,0,0,0.5);
display: flex;
flex-direction: column;
gap: 0.2rem;
opacity: 0; /* Initially hidden for animation */
}
#fullscreen-next-track.animate-in {
animation: fadeIn 0.5s ease 0.2s forwards; /* Added forwards to keep opacity 1 */
}
#fullscreen-next-track .label {
text-transform: uppercase;
letter-spacing: 0.05em;
font-size: 0.75rem;
opacity: 0.8;
}
#fullscreen-next-track .value {
font-weight: 500;
color: rgba(255, 255, 255, 0.9);
}
@media (max-width: 768px) {
#fullscreen-cover-overlay {
padding-bottom: 160px; /* Account for taller mobile player bar */