import { nextTick } from 'vue' import { createRouter, createWebHistory } from 'vue-router' import { useMainStore } from './store/main' import { useSubsonicApi } from './subsonicApi' import { LoginView } from './view/Login.vine' import { DiscoverView } from './view/Discover.vine' import { PlayerQueueView } from './view/PlayerQueue.vine' import { ArtistView } from './view/Artist.vine' import { AlbumView } from './view/Album.vine' import { GenreView } from './view/Genre.vine' import { PlaylistsView } from './view/Playlists.vine' import { PlaylistView } from './view/Playlist.vine' import { FavouritesView } from './view/Favourites.vine' import { SearchResultView } from './view/SearchResult.vine' export function setupRouter(appBase) { const router = createRouter({ history: createWebHistory(appBase), linkExactActiveClass: 'active', scrollBehavior: (to, from, savedPosition) => ( (savedPosition) ? (new Promise( resolve => (nextTick().then(() => { if (['discover', 'albums', 'artists', 'genre'].includes(to.name as string)) { setTimeout(() => { resolve({ left: savedPosition.left, top: Math.max(savedPosition.top - 38, 0) }) }, 500) } else { setTimeout(() => { resolve({ left: savedPosition.left, top: Math.max(savedPosition.top - 38, 0) }) }, 100) } })) )) : ( (to.hash) ? { el: to.hash, behavior: 'smooth' } : { left: 0, top: 0 } ) ), routes: [ { name: 'login', path: '/login', component: LoginView, props: (route) => ({ returnTo: route.query.returnTo, }), }, { path: '/', name: 'discover', component: DiscoverView, meta: { keepAlive: true }, }, { name: 'queue', path: '/queue', component: PlayerQueueView, meta: { keepAlive: true }, }, { name: 'albums', path: '/albums', component: AlbumView, meta: { keepAlive: true }, props: (route) => ({ sort: route.query.sort, }), }, { name: 'album', path: '/albums/:id', component: AlbumView, meta: { keepAlive: true, backButton: true }, props: true, }, { name: 'artists', path: '/artists', component: ArtistView, meta: { keepAlive: true }, }, { name: 'artist', path: '/artists/:id', component: ArtistView, meta: { keepAlive: true, backButton: true }, props: true, }, { name: 'artist-tracks', path: '/artists/:id/tracks', component: ArtistView, meta: { keepAlive: true }, props: (route) => ({ trackView: true, ...route.params, }), }, { name: 'genres', path: '/genres', component: GenreView, meta: { keepAlive: true }, }, { name: 'genre', path: '/genres/:id/:section?', component: GenreView, meta: { keepAlive: true, backButton: true }, props: true, }, { name: 'favourites', path: '/favourites/:section?', component: FavouritesView, props: true, }, { name: 'playlists', path: '/playlists', component: PlaylistsView, meta: { keepAlive: true }, }, { name: 'playlist', path: '/playlist/:id', component: PlaylistView, meta: { keepAlive: true, backButton: true }, props: true, }, { name: 'search', path: '/search/:mode?', component: SearchResultView, meta: { backButton: true }, props: (route) => ({ query: route.query.q, ...route.params, }) }, ], }) router.beforeEach( (to) => { if (to.name === 'login') return try { const mainStore = useMainStore(), subsonicApi = useSubsonicApi() if (!subsonicApi.isInitialized) subsonicApi.initialize() if(!mainStore.serverInfo) throw Error() } catch { return { name: 'login', query: { q: to.query.q, returnTo: ( (to.fullPath.startsWith(appBase)) ? to.fullPath.slice(appBase.length - 1) : to.fullPath ), } } } } ) return router }