fix: add lyrics toggle for mobile

This commit is contained in:
Alan Brooks 2026-04-05 23:03:59 -04:00
parent a09f0cc356
commit 4dd3ec1a0c
3 changed files with 110 additions and 7 deletions

View file

@ -206,6 +206,9 @@
" "
></div> ></div>
<button id="fullscreen-dismiss-handle" type="button" aria-label="Dismiss fullscreen"></button> <button id="fullscreen-dismiss-handle" type="button" aria-label="Dismiss fullscreen"></button>
<button id="toggle-fullscreen-lyrics-mobile-btn" class="fullscreen-mobile-lyrics-toggle" title="Hide Lyrics">
<use svg="!lucide/mic-vocal.svg" size="18" />
</button>
<button id="toggle-ui-btn" class="fullscreen-ui-toggle" title="Toggle UI"> <button id="toggle-ui-btn" class="fullscreen-ui-toggle" title="Toggle UI">
<use svg="!lucide/eye-off.svg" size="24" /> <use svg="!lucide/eye-off.svg" size="24" />
</button> </button>

View file

@ -1392,13 +1392,16 @@ export class UIRenderer {
updateFullscreenLyricsVisibility(overlay = document.getElementById('fullscreen-cover-overlay')) { updateFullscreenLyricsVisibility(overlay = document.getElementById('fullscreen-cover-overlay')) {
if (!overlay) return; if (!overlay) return;
const lyricsToggleBtn = document.getElementById('toggle-fullscreen-lyrics-btn'); const lyricsToggleButtons = [
document.getElementById('toggle-fullscreen-lyrics-btn'),
document.getElementById('toggle-fullscreen-lyrics-mobile-btn'),
].filter(Boolean);
const lyricsUnavailable = overlay.classList.contains('lyrics-unavailable'); const lyricsUnavailable = overlay.classList.contains('lyrics-unavailable');
const shouldShowLyrics = this.fullscreenLyricsVisible && !lyricsUnavailable; const shouldShowLyrics = this.fullscreenLyricsVisible && !lyricsUnavailable;
overlay.classList.toggle('lyrics-hidden', !shouldShowLyrics); overlay.classList.toggle('lyrics-hidden', !shouldShowLyrics);
if (lyricsToggleBtn) { lyricsToggleButtons.forEach((lyricsToggleBtn) => {
lyricsToggleBtn.classList.toggle('active', shouldShowLyrics); lyricsToggleBtn.classList.toggle('active', shouldShowLyrics);
lyricsToggleBtn.title = shouldShowLyrics ? 'Hide Lyrics' : 'Show Lyrics'; lyricsToggleBtn.title = shouldShowLyrics ? 'Hide Lyrics' : 'Show Lyrics';
lyricsToggleBtn.setAttribute('aria-pressed', shouldShowLyrics ? 'true' : 'false'); lyricsToggleBtn.setAttribute('aria-pressed', shouldShowLyrics ? 'true' : 'false');
@ -1407,7 +1410,7 @@ export class UIRenderer {
} else { } else {
lyricsToggleBtn.style.removeProperty('display'); lyricsToggleBtn.style.removeProperty('display');
} }
} });
} }
async dismissFullscreenCover({ animate = true } = {}) { async dismissFullscreenCover({ animate = true } = {}) {
@ -1870,8 +1873,11 @@ export class UIRenderer {
this.fullscreenLyricsToggleCleanup = null; this.fullscreenLyricsToggleCleanup = null;
} }
const toggleBtn = document.getElementById('toggle-fullscreen-lyrics-btn'); const toggleButtons = [
if (!toggleBtn) return; document.getElementById('toggle-fullscreen-lyrics-btn'),
document.getElementById('toggle-fullscreen-lyrics-mobile-btn'),
].filter(Boolean);
if (toggleButtons.length === 0) return;
const handleToggle = (event) => { const handleToggle = (event) => {
event.preventDefault(); event.preventDefault();
@ -1881,11 +1887,11 @@ export class UIRenderer {
this.updateFullscreenLyricsVisibility(overlay); this.updateFullscreenLyricsVisibility(overlay);
}; };
toggleBtn.addEventListener('click', handleToggle); toggleButtons.forEach((toggleBtn) => toggleBtn.addEventListener('click', handleToggle));
this.updateFullscreenLyricsVisibility(overlay); this.updateFullscreenLyricsVisibility(overlay);
this.fullscreenLyricsToggleCleanup = () => { this.fullscreenLyricsToggleCleanup = () => {
toggleBtn.removeEventListener('click', handleToggle); toggleButtons.forEach((toggleBtn) => toggleBtn.removeEventListener('click', handleToggle));
}; };
} }
setupFullscreenControls() { setupFullscreenControls() {

View file

@ -4112,6 +4112,38 @@ input:checked + .slider::before {
background: var(--primary); background: var(--primary);
} }
#toggle-fullscreen-lyrics-mobile-btn {
display: none;
position: absolute;
top: calc(0.85rem + env(safe-area-inset-top));
right: calc(0.9rem + env(safe-area-inset-right));
width: 38px;
height: 38px;
border: none;
border-radius: 999px;
padding: 0;
align-items: center;
justify-content: center;
background: rgb(9 12 18 / 0.32);
color: rgb(255 255 255 / 0.76);
backdrop-filter: blur(10px);
z-index: 14;
transition:
background-color 0.2s ease,
color 0.2s ease,
opacity 0.2s ease,
transform 0.2s ease;
}
#toggle-fullscreen-lyrics-mobile-btn.active {
background: rgb(255 255 255 / 0.12);
color: rgb(255 255 255 / 0.96);
}
#toggle-fullscreen-lyrics-mobile-btn:hover {
transform: scale(1.04);
}
/* Close Button - Leftmost position */ /* Close Button - Leftmost position */
#close-fullscreen-cover-btn { #close-fullscreen-cover-btn {
position: absolute; position: absolute;
@ -10626,6 +10658,10 @@ body:has(#side-panel.active) #close-fullscreen-cover-btn {
display: none !important; display: none !important;
} }
#toggle-fullscreen-lyrics-mobile-btn {
display: flex;
}
#fullscreen-cover-overlay .fullscreen-main-view { #fullscreen-cover-overlay .fullscreen-main-view {
width: 100%; width: 100%;
height: 100%; height: 100%;
@ -10770,6 +10806,64 @@ body:has(#side-panel.active) #close-fullscreen-cover-btn {
box-shadow: 0 14px 28px rgb(0 0 0 / 0.3); box-shadow: 0 14px 28px rgb(0 0 0 / 0.3);
} }
#fullscreen-cover-overlay.lyrics-hidden .fullscreen-main-view {
grid-template-columns: minmax(0, 1fr);
grid-template-rows: minmax(0, 1fr) auto auto auto;
grid-template-areas:
'.'
'art'
'info'
'controls';
align-content: stretch;
justify-items: center;
gap: 0.95rem;
padding:
calc(4.45rem + env(safe-area-inset-top))
0
calc(0.8rem + env(safe-area-inset-bottom))
0;
height: 100%;
}
#fullscreen-cover-overlay.lyrics-hidden .fullscreen-lyrics-pane {
display: none;
}
#fullscreen-cover-overlay.lyrics-hidden .fullscreen-artwork-card {
max-width: min(88vw, 320px);
width: min(88vw, 320px);
margin-left: 0;
justify-self: center;
border-radius: 14px;
box-shadow: 0 24px 56px rgb(0 0 0 / 0.28);
}
#fullscreen-cover-overlay.lyrics-hidden #fullscreen-cover-image {
border-radius: 14px;
}
#fullscreen-cover-overlay.lyrics-hidden .fullscreen-track-info {
align-self: start;
justify-self: center;
width: min(88vw, 320px);
padding: 0;
gap: 0.3rem;
}
#fullscreen-cover-overlay.lyrics-hidden .fullscreen-track-text {
gap: 0.2rem;
}
#fullscreen-cover-overlay.lyrics-hidden #fullscreen-track-title {
font-size: clamp(1.15rem, 5vw, 1.5rem);
line-height: 1.05;
}
#fullscreen-cover-overlay.lyrics-hidden #fullscreen-track-artist {
font-size: 0.95rem;
color: rgb(255 255 255 / 0.66);
}
#fullscreen-cover-overlay .fullscreen-volume-container { #fullscreen-cover-overlay .fullscreen-volume-container {
width: min(280px, calc(100% - 3rem)); width: min(280px, calc(100% - 3rem));
margin-top: 0; margin-top: 0;