refactor: extract app bootstrap to $lib/app/bootstrap.ts

Create bootstrap module with:
- loadSavedTheme() - theme initialization
- restoreLastfmSession() - Last.fm session restore
- setupMouseNavigation() - mouse back/forward handlers
- bootstrapApp() - combined init with cleanup

+page.svelte: 1,229 → 1,194 lines (-35 lines)
This commit is contained in:
vicrodh committed 2026-01-10 05:56:33 -06:00
1 parent 7580948e8c
commit 6dfcc8adaa
2 files changed
+109 -42

No files matched your search

+102
View File
@@ -0,0 +1,102 @@
/**
* App Bootstrap
*
* Handles application startup tasks that don't depend on component state.
* This includes theme initialization, Last.fm session restore, etc.
*/
import { invoke } from '@tauri-apps/api/core';
import { goBack, goForward } from '$lib/stores/navigationStore';
// ============ Theme Management ============
/**
* Load and apply saved theme from localStorage
*/
export function loadSavedTheme(): void {
const savedTheme = localStorage.getItem('qbz-theme');
if (savedTheme) {
document.documentElement.setAttribute('data-theme', savedTheme);
}
}
// ============ Last.fm Session ============
/**
* Restore Last.fm session from localStorage
*/
export async function restoreLastfmSession(): Promise<void> {
try {
const savedApiKey = localStorage.getItem('qbz-lastfm-api-key');
const savedApiSecret = localStorage.getItem('qbz-lastfm-api-secret');
const savedSessionKey = localStorage.getItem('qbz-lastfm-session-key');
// Restore credentials if user-provided
if (savedApiKey && savedApiSecret) {
await invoke('lastfm_set_credentials', {
apiKey: savedApiKey,
apiSecret: savedApiSecret
});
}
// Restore session if available
if (savedSessionKey) {
await invoke('lastfm_set_session', { sessionKey: savedSessionKey });
console.log('Last.fm session restored on startup');
}
} catch (err) {
console.error('Failed to restore Last.fm session:', err);
}
}
// ============ Mouse Navigation ============
/**
* Handle mouse back/forward buttons
*/
function handleMouseNavigation(event: MouseEvent): void {
if (event.button === 3) {
event.preventDefault();
goBack();
} else if (event.button === 4) {
event.preventDefault();
goForward();
}
}
/**
* Setup mouse navigation event listener
* @returns Cleanup function to remove listener
*/
export function setupMouseNavigation(): () => void {
window.addEventListener('mouseup', handleMouseNavigation);
return () => window.removeEventListener('mouseup', handleMouseNavigation);
}
// ============ Combined Bootstrap ============
export interface BootstrapResult {
cleanup: () => void;
}
/**
* Bootstrap the application
* Call this in onMount to initialize app-level features
* @returns Object with cleanup function for onDestroy
*/
export function bootstrapApp(): BootstrapResult {
// Load theme
loadSavedTheme();
// Setup mouse navigation
const cleanupMouse = setupMouseNavigation();
// Restore Last.fm session (async, fire-and-forget)
restoreLastfmSession();
return {
cleanup: () => {
cleanupMouse();
}
};
}
+7 -42
View File
@@ -161,6 +161,9 @@
shareSonglinkTrack
} from '$lib/services/trackActions';
// App bootstrap
import { bootstrapApp } from '$lib/app/bootstrap';
// Components
import Sidebar from '$lib/components/Sidebar.svelte';
import NowPlayingBar from '$lib/components/NowPlayingBar.svelte';
@@ -794,24 +797,11 @@
let downloadStateVersion = $state(0);
onMount(() => {
// Load saved theme
const savedTheme = localStorage.getItem('qbz-theme');
if (savedTheme) {
document.documentElement.setAttribute('data-theme', savedTheme);
}
const handleMouseNavigation = (event: MouseEvent) => {
if (event.button === 3) {
event.preventDefault();
navGoBack();
} else if (event.button === 4) {
event.preventDefault();
navGoForward();
}
};
// Bootstrap app (theme, mouse nav, Last.fm restore)
const { cleanup: cleanupBootstrap } = bootstrapApp();
// Keyboard navigation
document.addEventListener('keydown', handleKeydown);
window.addEventListener('mouseup', handleMouseNavigation);
// Initialize download states
initDownloadStates();
@@ -887,34 +877,9 @@
}
});
// Restore Last.fm session on app startup
(async () => {
try {
const savedApiKey = localStorage.getItem('qbz-lastfm-api-key');
const savedApiSecret = localStorage.getItem('qbz-lastfm-api-secret');
const savedSessionKey = localStorage.getItem('qbz-lastfm-session-key');
// Restore credentials if user-provided
if (savedApiKey && savedApiSecret) {
await invoke('lastfm_set_credentials', {
apiKey: savedApiKey,
apiSecret: savedApiSecret
});
}
// Restore session if available
if (savedSessionKey) {
await invoke('lastfm_set_session', { sessionKey: savedSessionKey });
console.log('Last.fm session restored on startup');
}
} catch (err) {
console.error('Failed to restore Last.fm session:', err);
}
})();
return () => {
cleanupBootstrap();
document.removeEventListener('keydown', handleKeydown);
window.removeEventListener('mouseup', handleMouseNavigation);
stopDownloadEventListeners();
unsubscribeDownloads();
unsubscribeToast();