99 lines
3.2 KiB
JavaScript
99 lines
3.2 KiB
JavaScript
(() => {
|
|
const audioExts = ['.mp3', '.wav', '.ogg', '.m4a', '.flac'];
|
|
|
|
const safeDecode = (value) => {
|
|
try {
|
|
return decodeURIComponent(value);
|
|
} catch {
|
|
return value;
|
|
}
|
|
};
|
|
|
|
const normalizePath = (path) => {
|
|
if (!path) return '';
|
|
return path
|
|
.replace(/\\/g, '/')
|
|
.replace(/^\/+/, '');
|
|
};
|
|
|
|
const encodePath = (path) => {
|
|
const normalized = normalizePath(path);
|
|
if (!normalized) return '';
|
|
return normalized
|
|
.split('/')
|
|
.map(segment => encodeURIComponent(safeDecode(segment)))
|
|
.join('/');
|
|
};
|
|
|
|
const isAudio = (path) =>
|
|
audioExts.some(ext => path.toLowerCase().endsWith(ext));
|
|
|
|
const highlightFile = (filePath) => {
|
|
const normalized = normalizePath(filePath);
|
|
const target = document.querySelector(`.play-file[data-url="${normalized}"]`);
|
|
if (target) {
|
|
target.classList.add('search-highlight');
|
|
target.scrollIntoView({ behavior: 'smooth', block: 'center' });
|
|
}
|
|
};
|
|
|
|
const openFolder = (folderPath, filePath) => {
|
|
const normalizedFolder = normalizePath(folderPath);
|
|
const normalizedFile = normalizePath(filePath);
|
|
const payload = { folder: normalizedFolder || '', file: normalizedFile || '' };
|
|
sessionStorage.setItem('pendingFolderOpen', JSON.stringify(payload));
|
|
|
|
const url = normalizedFolder ? `/path/${encodePath(normalizedFolder)}` : '/';
|
|
if (window.PageRouter && typeof window.PageRouter.loadPage === 'function') {
|
|
window.PageRouter.loadPage(url, { push: true, scroll: true });
|
|
return;
|
|
}
|
|
window.location.href = url;
|
|
};
|
|
|
|
const initFileAccess = () => {
|
|
const table = document.getElementById('file-access-table');
|
|
if (!table || table.dataset.bound) return;
|
|
table.dataset.bound = '1';
|
|
|
|
table.querySelectorAll('.play-access-btn').forEach(btn => {
|
|
const path = normalizePath(btn.dataset.path || '');
|
|
if (!path) return;
|
|
|
|
if (!isAudio(path)) {
|
|
btn.innerHTML = '<i class="bi bi-download"></i>';
|
|
btn.setAttribute('title', 'Download');
|
|
btn.setAttribute('aria-label', 'Download');
|
|
btn.addEventListener('click', () => {
|
|
window.location.href = `/media/${encodePath(path)}`;
|
|
});
|
|
return;
|
|
}
|
|
|
|
btn.addEventListener('click', () => {
|
|
const activePlayer = (typeof player !== 'undefined' && player) ? player : window.player;
|
|
if (activePlayer && typeof activePlayer.loadTrack === 'function') {
|
|
activePlayer.loadTrack(path);
|
|
}
|
|
});
|
|
});
|
|
|
|
table.querySelectorAll('.folder-open-btn').forEach(btn => {
|
|
const folder = normalizePath(btn.dataset.folder || '');
|
|
const file = normalizePath(btn.dataset.file || '');
|
|
btn.addEventListener('click', () => {
|
|
// If we're already on the app page, load directly.
|
|
if (window.PageRegistry?.getCurrent?.() === 'app' && typeof loadDirectory === 'function') {
|
|
loadDirectory(folder).then(() => highlightFile(file));
|
|
} else {
|
|
openFolder(folder, file);
|
|
}
|
|
});
|
|
});
|
|
};
|
|
|
|
if (window.PageRegistry && typeof window.PageRegistry.register === 'function') {
|
|
window.PageRegistry.register('file_access', { init: initFileAccess });
|
|
}
|
|
})();
|