140 lines
3.9 KiB
JavaScript
140 lines
3.9 KiB
JavaScript
// MusicRoom - Init module
|
|
// Application initialization sequence
|
|
|
|
(function() {
|
|
const M = window.MusicRoom;
|
|
|
|
// Check for /listen/<trackId> URL
|
|
function checkDirectTrackLink() {
|
|
const match = location.pathname.match(/^\/listen\/(.+)$/);
|
|
if (match) {
|
|
const trackId = decodeURIComponent(match[1]);
|
|
console.log("[Init] Direct track link detected:", trackId);
|
|
return trackId;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
// Play a specific track in local/desync mode
|
|
M.playDirectTrack = async function(trackId) {
|
|
// Find track in library
|
|
const track = M.library?.find(t => t.id === trackId);
|
|
if (!track) {
|
|
M.showToast("Track not found", "error");
|
|
// Clear the URL
|
|
history.replaceState(null, "", "/");
|
|
return;
|
|
}
|
|
|
|
// Desync from server
|
|
M.wantSync = false;
|
|
M.synced = false;
|
|
if (M.ws) {
|
|
M.ws.close();
|
|
M.ws = null;
|
|
}
|
|
|
|
// Set up and play track
|
|
M.currentTrackId = trackId;
|
|
M.serverTrackDuration = track.duration;
|
|
M.setTrackTitle(track.title || track.filename);
|
|
M.loadingSegments.clear();
|
|
|
|
const cachedUrl = await M.loadTrackBlob(trackId);
|
|
M.audio.src = cachedUrl || M.getTrackUrl(trackId);
|
|
M.audio.currentTime = 0;
|
|
M.localTimestamp = 0;
|
|
M.audio.play().catch(() => {
|
|
M.showToast("Click to start playback");
|
|
});
|
|
|
|
M.updateUI();
|
|
M.showToast(`Playing: ${track.title || track.filename}`);
|
|
|
|
// Clear the URL to normal
|
|
history.replaceState(null, "", "/");
|
|
};
|
|
|
|
// Fetch server status/config
|
|
async function loadServerStatus() {
|
|
try {
|
|
const res = await fetch("/api/status");
|
|
M.serverStatus = await res.json();
|
|
console.log("Server status:", M.serverStatus);
|
|
} catch (e) {
|
|
console.warn("Failed to load server status");
|
|
M.serverStatus = null;
|
|
}
|
|
}
|
|
|
|
// Initialize track storage
|
|
async function initStorage() {
|
|
await TrackStorage.init();
|
|
await M.updateCacheStatus();
|
|
console.log(`TrackStorage: ${M.cachedTracks.size} tracks cached`);
|
|
}
|
|
|
|
// Setup panel tab switching
|
|
function initPanelTabs() {
|
|
const tabs = document.querySelectorAll(".panel-tab");
|
|
tabs.forEach(tab => {
|
|
tab.onclick = () => {
|
|
const tabId = tab.dataset.tab;
|
|
const panel = tab.closest("#library-panel, #queue-panel");
|
|
if (!panel) return;
|
|
|
|
// Update active tab
|
|
panel.querySelectorAll(".panel-tab").forEach(t => t.classList.remove("active"));
|
|
tab.classList.add("active");
|
|
|
|
// Update active view
|
|
panel.querySelectorAll(".panel-view").forEach(v => v.classList.remove("active"));
|
|
const view = panel.querySelector(`#${tabId}-view`);
|
|
if (view) view.classList.add("active");
|
|
};
|
|
});
|
|
}
|
|
|
|
// Setup history panel handlers
|
|
document.addEventListener("DOMContentLoaded", () => {
|
|
const btnHistory = M.$("#btn-history");
|
|
const btnClose = M.$("#btn-close-history");
|
|
|
|
if (btnHistory) {
|
|
btnHistory.onclick = () => M.toggleToastHistory();
|
|
}
|
|
if (btnClose) {
|
|
btnClose.onclick = () => M.toggleToastHistory();
|
|
}
|
|
|
|
initPanelTabs();
|
|
});
|
|
|
|
// Update UI based on server status
|
|
function updateFeatureVisibility() {
|
|
const fetchBtn = M.$("#btn-fetch-url");
|
|
if (fetchBtn) {
|
|
const ytdlpEnabled = M.serverStatus?.ytdlp?.enabled && M.serverStatus?.ytdlp?.available;
|
|
fetchBtn.style.display = ytdlpEnabled ? "" : "none";
|
|
}
|
|
}
|
|
|
|
// Initialize the application
|
|
const directTrackId = checkDirectTrackLink();
|
|
|
|
Promise.all([initStorage(), loadServerStatus()]).then(async () => {
|
|
updateFeatureVisibility();
|
|
await M.loadLibrary();
|
|
await M.loadCurrentUser();
|
|
if (M.currentUser) {
|
|
M.loadChannels();
|
|
}
|
|
|
|
// Handle direct track link after everything is loaded
|
|
if (directTrackId) {
|
|
// Small delay to ensure UI is ready
|
|
setTimeout(() => M.playDirectTrack(directTrackId), 500);
|
|
}
|
|
});
|
|
})();
|