kv-music/js/router.js
2026-04-02 00:01:57 +03:00

145 lines
5 KiB
JavaScript

//router.js
import { getTrackArtists } from './utils.js';
import { loadProfile } from './profile.js';
export function navigate(path) {
if (path === window.location.pathname) {
return;
}
window.history.pushState({}, '', path);
window.dispatchEvent(new PopStateEvent('popstate'));
}
export function createRouter(ui) {
const router = async () => {
if (window.location.hash && window.location.hash.length > 1) {
const hash = window.location.hash.substring(1);
if (hash.includes('/')) {
const newPath = hash.startsWith('/') ? hash : '/' + hash;
window.history.replaceState(null, '', newPath);
}
}
let path = window.location.pathname;
if (path.startsWith('/')) path = path.substring(1);
if (path.endsWith('/')) path = path.substring(0, path.length - 1);
if (path === '' || path === 'index.html') path = 'home';
const parts = path.split('/');
const page = parts[0];
const param = parts.slice(1).join('/');
// Helper to extract provider prefix and ID from params
// Supports formats like: /track/t/123 (Tidal), /track/123 (default)
const extractProviderAndId = (p) => {
if (p.startsWith('t/')) {
return { provider: 'tidal', id: p.slice(2) };
}
return { provider: null, id: p };
};
switch (page) {
case 'parties':
await ui.renderPartiesPage();
break;
case 'party':
await ui.renderPartyDetailPage(param);
break;
case 'search':
await ui.renderSearchPage(decodeURIComponent(param));
break;
case 'album': {
const { provider, id } = extractProviderAndId(param);
await ui.renderAlbumPage(id, provider);
break;
}
case 'artist': {
const { provider, id } = extractProviderAndId(param);
await ui.renderArtistPage(id, provider);
break;
}
case 'playlist': {
const { provider, id } = extractProviderAndId(param);
await ui.renderPlaylistPage(id, 'api', provider);
break;
}
case 'userplaylist':
await ui.renderPlaylistPage(param, 'user');
break;
case 'folder':
await ui.renderFolderPage(param);
break;
case 'mix': {
const { provider, id } = extractProviderAndId(param);
await ui.renderMixPage(id, provider);
break;
}
case 'track': {
const { provider, id } = extractProviderAndId(param);
if (id.startsWith('tracker-')) {
await ui.renderTrackerTrackPage(id);
} else {
await ui.renderTrackPage(id, provider);
}
break;
}
case 'library':
await ui.renderLibraryPage();
break;
case 'recent':
await ui.renderRecentPage();
break;
case 'unreleased':
if (param) {
const parts = param.split('/');
const sheetId = parts[0];
const projectName = parts[1] ? decodeURIComponent(parts[1]) : null;
if (projectName) {
await ui.renderTrackerProjectPage(sheetId, projectName);
} else {
await ui.renderTrackerArtistPage(sheetId);
}
} else {
await ui.renderUnreleasedPage();
}
break;
case 'podcasts':
if (param) {
await ui.renderPodcastPage(param);
} else {
await ui.renderPodcastsBrowsePage();
}
break;
case 'home':
await ui.renderHomePage();
break;
case 'donate':
ui.showPage('donate');
break;
case 'user':
if (param && param.startsWith('@') && !param.includes('/')) {
await loadProfile(decodeURIComponent(param.slice(1)));
}
break;
default:
ui.showPage(page);
break;
}
};
return router;
}
export function updateTabTitle(player) {
if (player.currentTrack) {
const track = player.currentTrack;
document.title = `${track.title}${getTrackArtists(track)}`;
} else {
const path = window.location.pathname;
if (path.startsWith('/album/') || path.startsWith('/playlist/') || path.startsWith('/track/')) {
return;
}
document.title = 'Monochrome Music';
}
}