From 4dd3ec1a0c64bfe1562dcc5f562f263eaf80102b Mon Sep 17 00:00:00 2001 From: Alan Brooks Date: Sun, 5 Apr 2026 23:03:59 -0400 Subject: [PATCH] fix: add lyrics toggle for mobile --- index.html | 3 ++ js/ui.js | 20 ++++++++---- styles.css | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 110 insertions(+), 7 deletions(-) diff --git a/index.html b/index.html index 4125d3c..4415024 100644 --- a/index.html +++ b/index.html @@ -206,6 +206,9 @@ " > + diff --git a/js/ui.js b/js/ui.js index b7cb8e8..1df95f6 100644 --- a/js/ui.js +++ b/js/ui.js @@ -1392,13 +1392,16 @@ export class UIRenderer { updateFullscreenLyricsVisibility(overlay = document.getElementById('fullscreen-cover-overlay')) { 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 shouldShowLyrics = this.fullscreenLyricsVisible && !lyricsUnavailable; overlay.classList.toggle('lyrics-hidden', !shouldShowLyrics); - if (lyricsToggleBtn) { + lyricsToggleButtons.forEach((lyricsToggleBtn) => { lyricsToggleBtn.classList.toggle('active', shouldShowLyrics); lyricsToggleBtn.title = shouldShowLyrics ? 'Hide Lyrics' : 'Show Lyrics'; lyricsToggleBtn.setAttribute('aria-pressed', shouldShowLyrics ? 'true' : 'false'); @@ -1407,7 +1410,7 @@ export class UIRenderer { } else { lyricsToggleBtn.style.removeProperty('display'); } - } + }); } async dismissFullscreenCover({ animate = true } = {}) { @@ -1870,8 +1873,11 @@ export class UIRenderer { this.fullscreenLyricsToggleCleanup = null; } - const toggleBtn = document.getElementById('toggle-fullscreen-lyrics-btn'); - if (!toggleBtn) return; + const toggleButtons = [ + document.getElementById('toggle-fullscreen-lyrics-btn'), + document.getElementById('toggle-fullscreen-lyrics-mobile-btn'), + ].filter(Boolean); + if (toggleButtons.length === 0) return; const handleToggle = (event) => { event.preventDefault(); @@ -1881,11 +1887,11 @@ export class UIRenderer { this.updateFullscreenLyricsVisibility(overlay); }; - toggleBtn.addEventListener('click', handleToggle); + toggleButtons.forEach((toggleBtn) => toggleBtn.addEventListener('click', handleToggle)); this.updateFullscreenLyricsVisibility(overlay); this.fullscreenLyricsToggleCleanup = () => { - toggleBtn.removeEventListener('click', handleToggle); + toggleButtons.forEach((toggleBtn) => toggleBtn.removeEventListener('click', handleToggle)); }; } setupFullscreenControls() { diff --git a/styles.css b/styles.css index 32f6a52..67ef486 100644 --- a/styles.css +++ b/styles.css @@ -4112,6 +4112,38 @@ input:checked + .slider::before { 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-fullscreen-cover-btn { position: absolute; @@ -10626,6 +10658,10 @@ body:has(#side-panel.active) #close-fullscreen-cover-btn { display: none !important; } + #toggle-fullscreen-lyrics-mobile-btn { + display: flex; + } + #fullscreen-cover-overlay .fullscreen-main-view { width: 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); } + #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 { width: min(280px, calc(100% - 3rem)); margin-top: 0;