Merge pull request #513 from ap5z/fullscreen-apple
fix: honor selected visualizer & fix scrollbar bug and lyrics shortcut bug
This commit is contained in:
commit
22524a4afa
4 changed files with 95 additions and 62 deletions
|
|
@ -293,12 +293,7 @@
|
|||
<button id="fs-repeat-btn" title="Repeat">
|
||||
<use svg="!lucide/repeat.svg" size="24" />
|
||||
</button>
|
||||
<button
|
||||
id="fs-quality-btn"
|
||||
class="fs-quality-btn"
|
||||
title="Quality"
|
||||
style="display: none"
|
||||
>
|
||||
<button id="fs-quality-btn" class="fs-quality-btn" title="Quality" style="display: none">
|
||||
<use svg="!lucide/pencil-line.svg" size="20" />
|
||||
<span class="fs-quality-label">Auto</span>
|
||||
</button>
|
||||
|
|
|
|||
46
js/app.js
46
js/app.js
|
|
@ -299,6 +299,13 @@ function initializeKeyboardShortcuts(player, _audioPlayer) {
|
|||
},
|
||||
lyrics: () => {
|
||||
trackKeyboardShortcut('L');
|
||||
const overlay = document.getElementById('fullscreen-cover-overlay');
|
||||
const isFullscreenOpen = overlay && getComputedStyle(overlay).display !== 'none';
|
||||
|
||||
if (isFullscreenOpen && UIRenderer.instance?.toggleFullscreenLyrics(overlay)) {
|
||||
return;
|
||||
}
|
||||
|
||||
document.getElementById('toggle-lyrics-btn')?.click();
|
||||
},
|
||||
search: () => {
|
||||
|
|
@ -361,6 +368,19 @@ function initializeKeyboardShortcuts(player, _audioPlayer) {
|
|||
});
|
||||
}
|
||||
|
||||
async function closeFullscreenOverlay() {
|
||||
if (UIRenderer.instance?.dismissFullscreenCover) {
|
||||
await UIRenderer.instance.dismissFullscreenCover({ animate: false });
|
||||
return;
|
||||
}
|
||||
|
||||
if (window.location.hash === '#fullscreen') {
|
||||
window.history.back();
|
||||
} else {
|
||||
UIRenderer.instance?.closeFullscreenCover();
|
||||
}
|
||||
}
|
||||
|
||||
function showOfflineNotification() {
|
||||
const notification = document.createElement('div');
|
||||
notification.className = 'offline-notification';
|
||||
|
|
@ -736,11 +756,7 @@ document.addEventListener('DOMContentLoaded', async () => {
|
|||
} else if (mode === 'cover') {
|
||||
const overlay = document.getElementById('fullscreen-cover-overlay');
|
||||
if (overlay && overlay.style.display === 'flex') {
|
||||
if (window.location.hash === '#fullscreen') {
|
||||
window.history.back();
|
||||
} else {
|
||||
UIRenderer.instance.closeFullscreenCover();
|
||||
}
|
||||
await closeFullscreenOverlay();
|
||||
} else {
|
||||
const nextTrack = Player.instance.getNextTrack();
|
||||
UIRenderer.instance.showFullscreenCover(
|
||||
|
|
@ -764,13 +780,9 @@ document.addEventListener('DOMContentLoaded', async () => {
|
|||
if (shareBtn) shareBtn.style.display = e.target.checked ? 'flex' : 'none';
|
||||
});
|
||||
|
||||
document.getElementById('close-fullscreen-cover-btn')?.addEventListener('click', () => {
|
||||
document.getElementById('close-fullscreen-cover-btn')?.addEventListener('click', async () => {
|
||||
trackCloseFullscreenCover();
|
||||
if (window.location.hash === '#fullscreen') {
|
||||
window.history.back();
|
||||
} else {
|
||||
UIRenderer.instance.closeFullscreenCover();
|
||||
}
|
||||
await closeFullscreenOverlay();
|
||||
});
|
||||
|
||||
document.getElementById('fullscreen-cover-overlay')?.addEventListener('click', (e) => {
|
||||
|
|
@ -785,11 +797,7 @@ document.addEventListener('DOMContentLoaded', async () => {
|
|||
|
||||
switch (action) {
|
||||
case 'exit':
|
||||
if (window.location.hash === '#fullscreen') {
|
||||
window.history.back();
|
||||
} else {
|
||||
UIRenderer.instance.closeFullscreenCover();
|
||||
}
|
||||
closeFullscreenOverlay();
|
||||
break;
|
||||
case 'hide-ui':
|
||||
if (overlay) {
|
||||
|
|
@ -831,11 +839,7 @@ document.addEventListener('DOMContentLoaded', async () => {
|
|||
case 'nothing':
|
||||
break;
|
||||
default:
|
||||
if (window.location.hash === '#fullscreen') {
|
||||
window.history.back();
|
||||
} else {
|
||||
UIRenderer.instance.closeFullscreenCover();
|
||||
}
|
||||
closeFullscreenOverlay();
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
|||
61
js/ui.js
61
js/ui.js
|
|
@ -1336,9 +1336,7 @@ export class UIRenderer {
|
|||
nextTrackEl.classList.remove('animate-in');
|
||||
}
|
||||
|
||||
const canRenderLyrics = Boolean(
|
||||
lyricsManager && activeElement && lyricsPane && lyricsContent && track.type !== 'video'
|
||||
);
|
||||
const canRenderLyrics = Boolean(lyricsManager && activeElement && lyricsPane && lyricsContent && track.type !== 'video');
|
||||
if (canRenderLyrics) {
|
||||
this.fullscreenLyricsVisible = true;
|
||||
if (lyricsToggleBtn) lyricsToggleBtn.style.removeProperty('display');
|
||||
|
|
@ -1351,8 +1349,7 @@ export class UIRenderer {
|
|||
overlay.classList.add('lyrics-unavailable');
|
||||
if (lyricsContent) {
|
||||
clearFullscreenLyricsSync(lyricsContent);
|
||||
lyricsContent.innerHTML =
|
||||
'<div class="fullscreen-lyrics-empty">Lyrics are not available for this track.</div>';
|
||||
lyricsContent.innerHTML = '<div class="fullscreen-lyrics-empty">Lyrics are not available for this track.</div>';
|
||||
}
|
||||
}
|
||||
this.updateFullscreenLyricsVisibility(overlay);
|
||||
|
|
@ -1364,8 +1361,15 @@ export class UIRenderer {
|
|||
}
|
||||
const mainContent = document.querySelector('.main-content');
|
||||
if (mainContent instanceof HTMLElement) {
|
||||
this.fullscreenMainContentOverflow = mainContent.style.overflowY;
|
||||
mainContent.style.overflowY = 'hidden';
|
||||
const computedStyles = window.getComputedStyle(mainContent);
|
||||
this.fullscreenMainContentOverflow = {
|
||||
overflow: mainContent.style.overflow,
|
||||
overflowX: mainContent.style.overflowX,
|
||||
overflowY: mainContent.style.overflowY,
|
||||
computedOverflowX: computedStyles.overflowX,
|
||||
computedOverflowY: computedStyles.overflowY,
|
||||
};
|
||||
mainContent.style.overflow = 'hidden';
|
||||
}
|
||||
|
||||
this.setupFullscreenControls();
|
||||
|
|
@ -1416,6 +1420,14 @@ export class UIRenderer {
|
|||
});
|
||||
}
|
||||
|
||||
toggleFullscreenLyrics(overlay = document.getElementById('fullscreen-cover-overlay')) {
|
||||
if (!overlay || overlay.classList.contains('lyrics-unavailable')) return false;
|
||||
|
||||
this.fullscreenLyricsVisible = !this.fullscreenLyricsVisible;
|
||||
this.updateFullscreenLyricsVisibility(overlay);
|
||||
return true;
|
||||
}
|
||||
|
||||
updateFullscreenQualityBadgePlacement(track, overlay = document.getElementById('fullscreen-cover-overlay')) {
|
||||
if (!track || !overlay) return;
|
||||
|
||||
|
|
@ -1492,12 +1504,32 @@ export class UIRenderer {
|
|||
if (playerBar) playerBar.style.removeProperty('display');
|
||||
const mainContent = document.querySelector('.main-content');
|
||||
if (mainContent instanceof HTMLElement) {
|
||||
if (
|
||||
typeof this.fullscreenMainContentOverflow === 'string' &&
|
||||
this.fullscreenMainContentOverflow.length > 0
|
||||
) {
|
||||
mainContent.style.overflowY = this.fullscreenMainContentOverflow;
|
||||
const previousOverflow = this.fullscreenMainContentOverflow;
|
||||
if (previousOverflow && typeof previousOverflow === 'object') {
|
||||
if (previousOverflow.overflow) {
|
||||
mainContent.style.overflow = previousOverflow.overflow;
|
||||
} else {
|
||||
mainContent.style.removeProperty('overflow');
|
||||
}
|
||||
|
||||
if (previousOverflow.overflowX) {
|
||||
mainContent.style.overflowX = previousOverflow.overflowX;
|
||||
} else if (previousOverflow.computedOverflowX && previousOverflow.computedOverflowX !== 'visible') {
|
||||
mainContent.style.overflowX = previousOverflow.computedOverflowX;
|
||||
} else {
|
||||
mainContent.style.removeProperty('overflow-x');
|
||||
}
|
||||
|
||||
if (previousOverflow.overflowY) {
|
||||
mainContent.style.overflowY = previousOverflow.overflowY;
|
||||
} else if (previousOverflow.computedOverflowY && previousOverflow.computedOverflowY !== 'visible') {
|
||||
mainContent.style.overflowY = previousOverflow.computedOverflowY;
|
||||
} else {
|
||||
mainContent.style.removeProperty('overflow-y');
|
||||
}
|
||||
} else {
|
||||
mainContent.style.removeProperty('overflow');
|
||||
mainContent.style.removeProperty('overflow-x');
|
||||
mainContent.style.removeProperty('overflow-y');
|
||||
}
|
||||
this.fullscreenMainContentOverflow = null;
|
||||
|
|
@ -1574,7 +1606,6 @@ export class UIRenderer {
|
|||
}
|
||||
|
||||
if (this.visualizer) {
|
||||
this.visualizer.applyPresetOverride('kawarp');
|
||||
await this.visualizer.start();
|
||||
overlay.classList.add('visualizer-active');
|
||||
}
|
||||
|
|
@ -1905,9 +1936,7 @@ export class UIRenderer {
|
|||
const handleToggle = (event) => {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
if (overlay.classList.contains('lyrics-unavailable')) return;
|
||||
this.fullscreenLyricsVisible = !this.fullscreenLyricsVisible;
|
||||
this.updateFullscreenLyricsVisibility(overlay);
|
||||
this.toggleFullscreenLyrics(overlay);
|
||||
};
|
||||
|
||||
toggleButtons.forEach((toggleBtn) => toggleBtn.addEventListener('click', handleToggle));
|
||||
|
|
|
|||
43
styles.css
43
styles.css
|
|
@ -3924,7 +3924,6 @@ input:checked + .slider::before {
|
|||
|
||||
/* Reserve space above taskbar / system UI so volume controls stay visible (fixes #322) */
|
||||
padding-bottom: max(env(safe-area-inset-bottom), 1.5rem);
|
||||
|
||||
--fullscreen-drag-progress: 0;
|
||||
--fs-accent-rgb: var(--highlight-rgb);
|
||||
}
|
||||
|
|
@ -3993,7 +3992,7 @@ input:checked + .slider::before {
|
|||
position: relative;
|
||||
padding: 1rem;
|
||||
overflow: hidden;
|
||||
transform: translateY(var(--fullscreen-drag-offset, 0));
|
||||
transform: translateY(var(--fullscreen-drag-offset, 0px));
|
||||
opacity: calc(1 - (var(--fullscreen-drag-progress, 0) * 0.16));
|
||||
transition:
|
||||
transform 0.26s cubic-bezier(0.22, 1, 0.36, 1),
|
||||
|
|
@ -4263,7 +4262,6 @@ input:checked + .slider::before {
|
|||
#fullscreen-cover-overlay.controls-idle {
|
||||
cursor: none;
|
||||
}
|
||||
|
||||
#fullscreen-cover-image {
|
||||
max-width: 55vw;
|
||||
max-height: 45vh;
|
||||
|
|
@ -10126,7 +10124,6 @@ body:has(#side-panel.active) #close-fullscreen-cover-btn {
|
|||
#fullscreen-cover-overlay .fullscreen-main-view {
|
||||
--fs-media-column-size: minmax(340px, 430px);
|
||||
--fs-lyrics-column-size: minmax(520px, 760px);
|
||||
|
||||
width: min(1480px, 100%);
|
||||
height: 100%;
|
||||
flex: 1;
|
||||
|
|
@ -10169,7 +10166,7 @@ body:has(#side-panel.active) #close-fullscreen-cover-btn {
|
|||
aspect-ratio: 1 / 1;
|
||||
border-radius: 18px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 28px 80px rgb(0, 0, 0, 0.26);
|
||||
box-shadow: 0 28px 80px rgba(0, 0, 0, 0.26);
|
||||
}
|
||||
|
||||
#fullscreen-cover-overlay #fullscreen-cover-image {
|
||||
|
|
@ -10336,7 +10333,7 @@ body:has(#side-panel.active) #close-fullscreen-cover-btn {
|
|||
|
||||
#fullscreen-cover-overlay #toggle-ui-btn {
|
||||
top: 1.25rem;
|
||||
left: calc(9.9rem + env(safe-area-inset-left));
|
||||
left: calc(1.5rem + env(safe-area-inset-left) + (40px * 3) + (0.4rem * 3));
|
||||
right: auto;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
|
|
@ -10530,16 +10527,16 @@ body:has(#side-panel.active) #close-fullscreen-cover-btn {
|
|||
--lyrics-scroll-padding-top: 18%;
|
||||
--lyplus-blur-amount: 0.16em;
|
||||
--lyplus-blur-amount-near: 0.085em;
|
||||
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
font-family: 'SF Pro Display', Inter, sans-serif;
|
||||
|
||||
font-family:
|
||||
'SF Pro Display',
|
||||
Inter,
|
||||
sans-serif;
|
||||
--lyplus-font-size-base: clamp(34px, 3vw, 52px);
|
||||
--lyplus-padding-line: 8px;
|
||||
--lyplus-text-color: rgb(246, 244, 239, 0.08);
|
||||
--lyplus-text-color: rgba(246, 244, 239, 0.08);
|
||||
--lyplus-active-color: #f6f4ef;
|
||||
|
||||
line-height: 1.32;
|
||||
letter-spacing: -0.04em;
|
||||
font-weight: 600;
|
||||
|
|
@ -10565,7 +10562,6 @@ body:has(#side-panel.active) #close-fullscreen-cover-btn {
|
|||
#fullscreen-cover-overlay.lyrics-hidden .fullscreen-main-view {
|
||||
--fs-media-column-size: minmax(420px, 760px);
|
||||
--fs-lyrics-column-size: minmax(0, 0fr);
|
||||
|
||||
width: min(760px, 100%);
|
||||
gap: 0;
|
||||
}
|
||||
|
|
@ -10612,8 +10608,11 @@ body:has(#side-panel.active) #close-fullscreen-cover-btn {
|
|||
width: min(760px, 100%);
|
||||
gap: 1.25rem;
|
||||
align-items: stretch;
|
||||
padding: calc(5rem + env(safe-area-inset-top)) clamp(1rem, 4vw, 1.75rem)
|
||||
calc(1.5rem + env(safe-area-inset-bottom));
|
||||
padding:
|
||||
calc(5rem + env(safe-area-inset-top))
|
||||
clamp(1rem, 4vw, 1.75rem)
|
||||
calc(1.5rem + env(safe-area-inset-bottom))
|
||||
clamp(1rem, 4vw, 1.75rem);
|
||||
}
|
||||
|
||||
#fullscreen-cover-overlay .fullscreen-media-column {
|
||||
|
|
@ -10682,7 +10681,11 @@ body:has(#side-panel.active) #close-fullscreen-cover-btn {
|
|||
'lyrics lyrics'
|
||||
'controls controls';
|
||||
gap: 1rem 0.9rem;
|
||||
padding: calc(4.45rem + env(safe-area-inset-top)) 0 calc(0.8rem + env(safe-area-inset-bottom));
|
||||
padding:
|
||||
calc(4.45rem + env(safe-area-inset-top))
|
||||
0
|
||||
calc(0.8rem + env(safe-area-inset-bottom))
|
||||
0;
|
||||
}
|
||||
|
||||
#fullscreen-cover-overlay .fullscreen-media-column {
|
||||
|
|
@ -10771,10 +10774,9 @@ body:has(#side-panel.active) #close-fullscreen-cover-btn {
|
|||
--lyrics-scroll-padding-top: 18%;
|
||||
--lyplus-font-size-base: clamp(1.75rem, 7vw, 2.35rem);
|
||||
--lyplus-padding-line: 6px;
|
||||
--lyplus-text-color: rgb(246, 244, 239, 0.16);
|
||||
--lyplus-text-color: rgba(246, 244, 239, 0.16);
|
||||
--lyplus-blur-amount: 0.16em;
|
||||
--lyplus-blur-amount-near: 0.08em;
|
||||
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
|
|
@ -10831,8 +10833,11 @@ body:has(#side-panel.active) #close-fullscreen-cover-btn {
|
|||
align-items: center;
|
||||
justify-items: center;
|
||||
gap: 0;
|
||||
padding: calc(4.45rem + env(safe-area-inset-top)) clamp(1rem, 4vw, 1.4rem)
|
||||
calc(0.8rem + env(safe-area-inset-bottom));
|
||||
padding:
|
||||
calc(4.45rem + env(safe-area-inset-top))
|
||||
clamp(1rem, 4vw, 1.4rem)
|
||||
calc(0.8rem + env(safe-area-inset-bottom))
|
||||
clamp(1rem, 4vw, 1.4rem);
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
|
|
|
|||
Loading…
Reference in a new issue