fix4dwayne
This commit is contained in:
parent
64ff09910b
commit
a9f3acb289
6 changed files with 95 additions and 6 deletions
13
index.html
13
index.html
|
|
@ -3108,6 +3108,19 @@
|
|||
<span class="slider"></span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="setting-item">
|
||||
<div class="info">
|
||||
<span class="label">Intercept Back to Close Modals</span>
|
||||
<span class="description"
|
||||
>When pressing back, close open modals/panels first without navigating.
|
||||
Press back again to actually go back.</span
|
||||
>
|
||||
</div>
|
||||
<label class="toggle-switch">
|
||||
<input type="checkbox" id="intercept-back-to-close-modals-toggle" />
|
||||
<span class="slider"></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
16
js/app.js
16
js/app.js
|
|
@ -2117,6 +2117,14 @@ document.addEventListener('DOMContentLoaded', async () => {
|
|||
return;
|
||||
}
|
||||
|
||||
// Intercept back navigation to close modals first if setting is enabled
|
||||
if (event && modalSettings.shouldInterceptBackToClose() && modalSettings.hasOpenModalsOrPanels()) {
|
||||
sidePanelManager.close();
|
||||
modalSettings.closeAllModals();
|
||||
history.pushState(history.state || { app: true }, '', window.location.pathname);
|
||||
return;
|
||||
}
|
||||
|
||||
// Close side panel (queue/lyrics) and modals on navigation if setting is enabled
|
||||
if (modalSettings.shouldCloseOnNavigation()) {
|
||||
sidePanelManager.close();
|
||||
|
|
@ -2293,6 +2301,12 @@ function showUpdateNotification(updateCallback) {
|
|||
});
|
||||
}
|
||||
|
||||
function escapeHtml(text) {
|
||||
const div = document.createElement('div');
|
||||
div.textContent = text;
|
||||
return div.innerHTML;
|
||||
}
|
||||
|
||||
function showMissingTracksNotification(missingTracks) {
|
||||
const modal = document.getElementById('missing-tracks-modal');
|
||||
const listUl = document.getElementById('missing-tracks-list-ul');
|
||||
|
|
@ -2301,7 +2315,7 @@ function showMissingTracksNotification(missingTracks) {
|
|||
.map((track) => {
|
||||
const text =
|
||||
typeof track === 'string' ? track : `${track.artist ? track.artist + ' - ' : ''}${track.title}`;
|
||||
return `<li>${text}</li>`;
|
||||
return `<li>${escapeHtml(text)}</li>`;
|
||||
})
|
||||
.join('');
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import {
|
|||
getTrackArtistsHTML,
|
||||
getTrackYearDisplay,
|
||||
createQualityBadgeHTML,
|
||||
escapeHtml,
|
||||
} from './utils.js';
|
||||
import {
|
||||
queueManager,
|
||||
|
|
@ -166,7 +167,7 @@ export class Player {
|
|||
if (coverEl) coverEl.src = this.api.getCoverUrl(track.album?.cover);
|
||||
if (titleEl) {
|
||||
const qualityBadge = createQualityBadgeHTML(track);
|
||||
titleEl.innerHTML = `${trackTitle} ${qualityBadge}`;
|
||||
titleEl.innerHTML = `${escapeHtml(trackTitle)} ${qualityBadge}`;
|
||||
}
|
||||
if (albumEl) {
|
||||
const albumTitle = track.album?.title || '';
|
||||
|
|
@ -356,7 +357,8 @@ export class Player {
|
|||
const yearDisplay = getTrackYearDisplay(track);
|
||||
|
||||
document.querySelector('.now-playing-bar .cover').src = this.api.getCoverUrl(track.album?.cover);
|
||||
document.querySelector('.now-playing-bar .title').innerHTML = `${trackTitle} ${createQualityBadgeHTML(track)}`;
|
||||
document.querySelector('.now-playing-bar .title').innerHTML =
|
||||
`${escapeHtml(trackTitle)} ${createQualityBadgeHTML(track)}`;
|
||||
const albumEl = document.querySelector('.now-playing-bar .album');
|
||||
if (albumEl) {
|
||||
const albumTitle = track.album?.title || '';
|
||||
|
|
|
|||
|
|
@ -1919,6 +1919,15 @@ export function initializeSettings(scrobbler, player, api, ui) {
|
|||
});
|
||||
}
|
||||
|
||||
// Intercept Back to Close Modals Toggle
|
||||
const interceptBackToCloseToggle = document.getElementById('intercept-back-to-close-modals-toggle');
|
||||
if (interceptBackToCloseToggle) {
|
||||
interceptBackToCloseToggle.checked = modalSettings.shouldInterceptBackToClose();
|
||||
interceptBackToCloseToggle.addEventListener('change', (e) => {
|
||||
modalSettings.setInterceptBackToClose(e.target.checked);
|
||||
});
|
||||
}
|
||||
|
||||
// Compact Artist Toggle
|
||||
const compactArtistToggle = document.getElementById('compact-artist-toggle');
|
||||
if (compactArtistToggle) {
|
||||
|
|
|
|||
|
|
@ -2210,10 +2210,10 @@ export const musicProviderSettings = {
|
|||
|
||||
export const modalSettings = {
|
||||
STORAGE_KEY: 'close-modals-on-navigation',
|
||||
INTERCEPT_BACK_KEY: 'intercept-back-to-close-modals',
|
||||
|
||||
shouldCloseOnNavigation() {
|
||||
try {
|
||||
// Default to false to preserve existing behavior
|
||||
const saved = localStorage.getItem(this.STORAGE_KEY);
|
||||
if (saved === null) {
|
||||
return false;
|
||||
|
|
@ -2228,6 +2228,54 @@ export const modalSettings = {
|
|||
localStorage.setItem(this.STORAGE_KEY, enabled ? 'true' : 'false');
|
||||
},
|
||||
|
||||
shouldInterceptBackToClose() {
|
||||
try {
|
||||
const saved = localStorage.getItem(this.INTERCEPT_BACK_KEY);
|
||||
if (saved === null) {
|
||||
return false;
|
||||
}
|
||||
return saved === 'true';
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
setInterceptBackToClose(enabled) {
|
||||
localStorage.setItem(this.INTERCEPT_BACK_KEY, enabled ? 'true' : 'false');
|
||||
},
|
||||
|
||||
hasOpenModalsOrPanels() {
|
||||
const sidePanel = document.getElementById('side-panel');
|
||||
if (sidePanel && sidePanel.classList.contains('active')) {
|
||||
return true;
|
||||
}
|
||||
if (document.querySelector('.modal.active')) {
|
||||
return true;
|
||||
}
|
||||
if (document.querySelector('.modal-overlay')) {
|
||||
return true;
|
||||
}
|
||||
const modalIds = [
|
||||
'playlist-modal',
|
||||
'folder-modal',
|
||||
'playlist-select-modal',
|
||||
'shortcuts-modal',
|
||||
'missing-tracks-modal',
|
||||
'sleep-timer-modal',
|
||||
'discography-download-modal',
|
||||
'custom-db-modal',
|
||||
'tracker-modal',
|
||||
'epilepsy-warning-modal',
|
||||
];
|
||||
for (const id of modalIds) {
|
||||
const modal = document.getElementById(id);
|
||||
if (modal && modal.classList.contains('active')) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
closeAllModals() {
|
||||
// Close all modal overlays
|
||||
document.querySelectorAll('.modal-overlay').forEach((modal) => {
|
||||
|
|
|
|||
|
|
@ -285,14 +285,17 @@ export const getTrackArtistsHTML = (track = {}, { fallback = 'Unknown Artist' }
|
|||
if (track?.artists?.length) {
|
||||
return track.artists
|
||||
.map((artist) => {
|
||||
const escapedName = escapeHtml(artist.name || 'Unknown Artist');
|
||||
const escapedId = escapeHtml(artist.id || '');
|
||||
// Check if this is a tracker/unreleased track
|
||||
const isTracker = track.isTracker || (track.id && String(track.id).startsWith('tracker-'));
|
||||
if (isTracker && track.trackerInfo?.sheetId) {
|
||||
const escapedSheetId = escapeHtml(track.trackerInfo.sheetId);
|
||||
// For tracker tracks, link to the tracker artist page
|
||||
return `<span class="artist-link tracker-artist-link" data-tracker-sheet-id="${track.trackerInfo.sheetId}">${artist.name}</span>`;
|
||||
return `<span class="artist-link tracker-artist-link" data-tracker-sheet-id="${escapedSheetId}">${escapedName}</span>`;
|
||||
}
|
||||
// For normal tracks, use the artist ID
|
||||
return `<span class="artist-link" data-artist-id="${artist.id}">${artist.name}</span>`;
|
||||
return `<span class="artist-link" data-artist-id="${escapedId}">${escapedName}</span>`;
|
||||
})
|
||||
.join(', ');
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue