import { createApp, markRaw, watch } from 'vue' import { createPinia } from 'pinia' import { setupRouter } from './router' import { createSubsonicApi } from './subsonicApi' import { useMainStore } from './store/main' import { useFavouriteStore } from './store/favourite' import { usePlaylistStore } from './store/playlist' import { setupAudio, usePlayerStore } from './store/player' import { components } from './components' import { RootView } from './view/Root.vine' import './style/main.scss' const APP_BASE = import.meta.env.BASE_URL ?? '/' const bootstrapApp = async () => { window.history.scrollRestoration = 'manual' // Initialize stores and app const subsonicApi = createSubsonicApi(), pinia = createPinia().use(({ store }) => { store.subsonicApi = markRaw(subsonicApi) }), mainStore = useMainStore(pinia), app = createApp(RootView) // Register plugins app.use(pinia) app.use(subsonicApi) app.use(setupRouter(APP_BASE)) // Register global properties app.config.globalProperties.appName = import.meta.env.APP_NAME ?? 'Domsonic' app.config.globalProperties.appBase = APP_BASE // Register components components.forEach( (component: any) => app.component(component.name, component) ) // set theme color if (mainStore.themeColor !== null) mainStore.applyThemeColor() const serverUrl = mainStore.serverUrl, serverCredentials = mainStore.serverCredentials if (serverUrl && serverCredentials) { subsonicApi.setServerUrl(serverUrl) subsonicApi.setAuth(serverCredentials) subsonicApi.setStreamFormat(mainStore.streamFormat, mainStore.streamBitrate) subsonicApi.initialize() } // Watch logged-in state watch( mainStore.isAuthenticated, async () => { try { if (!subsonicApi.isInitialized()) return const playerStore = usePlayerStore(pinia) // setup player once authenticated void setupAudio(playerStore, mainStore) await Promise.all([ useFavouriteStore(pinia).load(), usePlaylistStore(pinia).load(), playerStore.loadQueue(), ]) } catch (err) { console.error('Error loading user data', err) } }, { immediate: true } ) try { app.mount('#app') } catch (err) { console.error('App mount failed', err) } // Service Worker if ('serviceWorker' in navigator) { void navigator.serviceWorker.register(`${APP_BASE}service-worker.js`, { scope: APP_BASE }) navigator.serviceWorker.addEventListener('message', (event) => { if (event.data?.type === 'UPDATE_READY') console.log('New version !') }) } } // Run the bootstrap void bootstrapApp()