1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
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()