feat(webui): remember view within library

closes #367
This commit is contained in:
Gauthier Roebroeck 2021-04-27 21:41:23 +08:00
parent b345c30d12
commit b1931aa892
8 changed files with 72 additions and 29 deletions

View file

@ -26,6 +26,7 @@ export const persistedModule: Module<any, any> = {
library: {
filter: {},
sort: {},
route: {},
},
},
getters: {
@ -38,6 +39,9 @@ export const persistedModule: Module<any, any> = {
getLibrarySort: (state) => (id: string) => {
return state.library.sort[id]
},
getLibraryRoute: (state) => (id: string) => {
return state.library.route[id]
},
},
mutations: {
setLocale(state, val) {
@ -82,5 +86,8 @@ export const persistedModule: Module<any, any> = {
setLibrarySort(state, {id, sort}) {
state.library.sort[id] = sort
},
setLibraryRoute(state, {id, route}) {
state.library.route[id] = route
},
},
}

View file

@ -2,22 +2,37 @@ import urls from '@/functions/urls'
import Vue from 'vue'
import Router from 'vue-router'
import store from './store'
import {LIBRARIES_ALL, LIBRARY_ROUTE} from "@/types/library";
Vue.use(Router)
const lStore = store as any
const adminGuard = (to: any, from: any, next: any) => {
if (!lStore.getters.meAdmin) next({ name: 'home' })
if (!lStore.getters.meAdmin) next({name: 'home'})
else next()
}
const noLibraryGuard = (to: any, from: any, next: any) => {
if (lStore.state.komgaLibraries.libraries.length === 0) {
next({ name: 'welcome' })
next({name: 'welcome'})
} else next()
}
const getLibraryRoute = (libraryId: string) => {
switch ((lStore.getters.getLibraryRoute(libraryId) as LIBRARY_ROUTE)) {
case LIBRARY_ROUTE.COLLECTIONS:
return 'browse-collections'
case LIBRARY_ROUTE.READLISTS:
return 'browse-readlists'
case LIBRARY_ROUTE.BROWSE:
return 'browse-libraries'
case LIBRARY_ROUTE.RECOMMENDED:
default:
return 'recommended-libraries'
}
}
const router = new Router({
mode: 'history',
base: urls.base,
@ -25,7 +40,7 @@ const router = new Router({
{
path: '/',
name: 'home',
redirect: { name: 'dashboard' },
redirect: {name: 'dashboard'},
component: () => import(/* webpackChunkName: "home" */ './views/Home.vue'),
children: [
{
@ -42,7 +57,7 @@ const router = new Router({
{
path: '/settings',
name: 'settings',
redirect: { name: 'settings-analysis' },
redirect: {name: 'settings-analysis'},
component: () => import(/* webpackChunkName: "settings" */ './views/Settings.vue'),
children: [
{
@ -83,57 +98,65 @@ const router = new Router({
name: 'account',
component: () => import(/* webpackChunkName: "account" */ './views/AccountSettings.vue'),
},
{
path: '/libraries/:libraryId?',
name: 'libraries',
redirect: (route) => ({
name: getLibraryRoute(route.params.libraryId || LIBRARIES_ALL),
params: {libraryId: route.params.libraryId || LIBRARIES_ALL},
}),
},
{
path: '/libraries/:libraryId/recommended',
name: 'recommended-libraries',
beforeEnter: noLibraryGuard,
component: () => import(/* webpackChunkName: "dashboard" */ './views/Dashboard.vue'),
props: (route) => ({libraryId: route.params.libraryId}),
},
{
path: '/libraries/:libraryId/series',
name: 'browse-libraries',
beforeEnter: noLibraryGuard,
component: () => import(/* webpackChunkName: "browse-libraries" */ './views/BrowseLibraries.vue'),
props: (route) => ({ libraryId: route.params.libraryId }),
},
{
path: '/libraries/:libraryId/dashboard',
name: 'recommended-libraries',
beforeEnter: noLibraryGuard,
component: () => import(/* webpackChunkName: "dashboard" */ './views/Dashboard.vue'),
props: (route) => ({ libraryId: route.params.libraryId }),
props: (route) => ({libraryId: route.params.libraryId}),
},
{
path: '/libraries/:libraryId/collections',
name: 'browse-collections',
beforeEnter: noLibraryGuard,
component: () => import(/* webpackChunkName: "browse-collections" */ './views/BrowseCollections.vue'),
props: (route) => ({ libraryId: route.params.libraryId }),
props: (route) => ({libraryId: route.params.libraryId}),
},
{
path: '/libraries/:libraryId/readlists',
name: 'browse-readlists',
beforeEnter: noLibraryGuard,
component: () => import(/* webpackChunkName: "browse-readlists" */ './views/BrowseReadLists.vue'),
props: (route) => ({ libraryId: route.params.libraryId }),
props: (route) => ({libraryId: route.params.libraryId}),
},
{
path: '/collections/:collectionId',
name: 'browse-collection',
component: () => import(/* webpackChunkName: "browse-collection" */ './views/BrowseCollection.vue'),
props: (route) => ({ collectionId: route.params.collectionId }),
props: (route) => ({collectionId: route.params.collectionId}),
},
{
path: '/readlists/:readListId',
name: 'browse-readlist',
component: () => import(/* webpackChunkName: "browse-readlist" */ './views/BrowseReadList.vue'),
props: (route) => ({ readListId: route.params.readListId }),
props: (route) => ({readListId: route.params.readListId}),
},
{
path: '/series/:seriesId',
name: 'browse-series',
component: () => import(/* webpackChunkName: "browse-series" */ './views/BrowseSeries.vue'),
props: (route) => ({ seriesId: route.params.seriesId }),
props: (route) => ({seriesId: route.params.seriesId}),
},
{
path: '/book/:bookId',
name: 'browse-book',
component: () => import(/* webpackChunkName: "browse-book" */ './views/BrowseBook.vue'),
props: (route) => ({ bookId: route.params.bookId }),
props: (route) => ({bookId: route.params.bookId}),
},
{
path: '/search',
@ -156,7 +179,7 @@ const router = new Router({
path: '/book/:bookId/read',
name: 'read-book',
component: () => import(/* webpackChunkName: "read-book" */ './views/BookReader.vue'),
props: (route) => ({ bookId: route.params.bookId }),
props: (route) => ({bookId: route.params.bookId}),
},
{
path: '*',
@ -164,12 +187,12 @@ const router = new Router({
component: () => import(/* webpackChunkName: "notfound" */ './views/PageNotFound.vue'),
},
],
scrollBehavior (to, from, savedPosition) {
scrollBehavior(to, from, savedPosition) {
if (savedPosition) {
return savedPosition
} else {
if (to.name !== from.name) {
return { x: 0, y: 0 }
return {x: 0, y: 0}
}
}
},
@ -180,7 +203,7 @@ router.beforeEach((to, from, next) => {
document.title = 'Komga'
}
if (to.name !== 'startup' && to.name !== 'login' && !lStore.getters.authenticated) {
next({ name: 'startup', query: { redirect: to.fullPath } })
next({name: 'startup', query: {redirect: to.fullPath}})
} else next()
})

View file

@ -1 +1,8 @@
export const LIBRARIES_ALL = 'all'
export enum LIBRARY_ROUTE {
BROWSE = 'BROWSE',
RECOMMENDED = 'RECOMMENDED',
COLLECTIONS = 'COLLECTIONS',
READLISTS = 'READLISTS'
}

View file

@ -57,7 +57,7 @@ import PageSizeSelect from '@/components/PageSizeSelect.vue'
import {COLLECTION_CHANGED, COLLECTION_DELETED, LIBRARY_CHANGED} from '@/types/events'
import Vue from 'vue'
import {Location} from 'vue-router'
import {LIBRARIES_ALL} from '@/types/library'
import {LIBRARIES_ALL, LIBRARY_ROUTE} from '@/types/library'
export default Vue.extend({
name: 'BrowseCollections',
@ -96,7 +96,8 @@ export default Vue.extend({
this.$eventHub.$off(COLLECTION_DELETED, this.reloadCollections)
this.$eventHub.$off(LIBRARY_CHANGED, this.reloadLibrary)
},
mounted () {
mounted() {
this.$store.commit('setLibraryRoute', {id: this.libraryId, route: LIBRARY_ROUTE.COLLECTIONS})
this.pageSize = this.$store.state.persistedState.browsingPageSize || this.pageSize
// restore from query param

View file

@ -110,7 +110,7 @@ import {SeriesStatus, SeriesStatusKeyValue} from '@/types/enum-series'
import {LIBRARY_CHANGED, LIBRARY_DELETED, SERIES_CHANGED} from '@/types/events'
import Vue from 'vue'
import {Location} from 'vue-router'
import {LIBRARIES_ALL} from '@/types/library'
import {LIBRARIES_ALL, LIBRARY_ROUTE} from '@/types/library'
import FilterDrawer from '@/components/FilterDrawer.vue'
import SortList from '@/components/SortList.vue'
import FilterPanels from '@/components/FilterPanels.vue'
@ -190,6 +190,7 @@ export default Vue.extend({
this.$eventHub.$off(LIBRARY_CHANGED, this.reloadLibrary)
},
async mounted() {
this.$store.commit('setLibraryRoute', {id: this.libraryId, route: LIBRARY_ROUTE.BROWSE})
this.pageSize = this.$store.state.persistedState.browsingPageSize || this.pageSize
// restore from query param

View file

@ -57,7 +57,7 @@ import PageSizeSelect from '@/components/PageSizeSelect.vue'
import {LIBRARY_CHANGED, READLIST_CHANGED, READLIST_DELETED} from '@/types/events'
import Vue from 'vue'
import {Location} from 'vue-router'
import {LIBRARIES_ALL} from '@/types/library'
import {LIBRARIES_ALL, LIBRARY_ROUTE} from '@/types/library'
export default Vue.extend({
name: 'BrowseReadLists',
@ -97,6 +97,7 @@ export default Vue.extend({
this.$eventHub.$off(LIBRARY_CHANGED, this.reloadLibrary)
},
mounted () {
this.$store.commit('setLibraryRoute', {id: this.libraryId, route: LIBRARY_ROUTE.READLISTS})
this.pageSize = this.$store.state.persistedState.browsingPageSize || this.pageSize
// restore from query param

View file

@ -137,7 +137,7 @@ import {BookDto} from '@/types/komga-books'
import {BOOK_CHANGED, LIBRARY_DELETED, SERIES_CHANGED} from '@/types/events'
import Vue from 'vue'
import {SeriesDto} from "@/types/komga-series";
import {LIBRARIES_ALL} from "@/types/library";
import {LIBRARIES_ALL, LIBRARY_ROUTE} from "@/types/library";
export default Vue.extend({
name: 'Dashboard',
@ -174,6 +174,7 @@ export default Vue.extend({
this.$eventHub.$off(BOOK_CHANGED, this.reload)
},
mounted() {
if(this.showLibraryBar) this.$store.commit('setLibraryRoute', {id: this.libraryId, route: LIBRARY_ROUTE.RECOMMENDED})
this.reload()
},
props: {

View file

@ -34,7 +34,7 @@
</v-list-item-content>
</v-list-item>
<v-list-item :to="{name:'browse-libraries', params: {libraryId: 'all'}}">
<v-list-item :to="{name:'libraries', params: {libraryId: LIBRARIES_ALL}}">
<v-list-item-icon>
<v-icon>mdi-book-multiple</v-icon>
</v-list-item-icon>
@ -51,7 +51,7 @@
<v-list-item v-for="(l, index) in libraries"
:key="index"
dense
:to="{name:'browse-libraries', params: {libraryId: l.id}}"
:to="{name:'libraries', params: {libraryId: l.id}}"
>
<v-list-item-icon>
</v-list-item-icon>
@ -149,12 +149,14 @@ import LibraryActionsMenu from '@/components/menus/LibraryActionsMenu.vue'
import SearchBox from '@/components/SearchBox.vue'
import {Theme} from '@/types/themes'
import Vue from 'vue'
import {LIBRARIES_ALL} from "@/types/library";
export default Vue.extend({
name: 'home',
components: {LibraryActionsMenu, SearchBox, Dialogs},
data: function () {
return {
LIBRARIES_ALL,
drawerVisible: this.$vuetify.breakpoint.lgAndUp,
info: {} as ActuatorInfo,
locales: this.$i18n.availableLocales.map((x: any) => ({text: this.$i18n.t('common.locale_name', x), value: x})),