mirror of
https://github.com/gotson/komga.git
synced 2026-05-09 05:10:19 +02:00
feat(webui): display library navigation within toolbar
use bottom navigation only for XS screens closes #234
This commit is contained in:
parent
4c6b3f5e5e
commit
a6252ff2e8
5 changed files with 129 additions and 57 deletions
|
|
@ -1,35 +1,78 @@
|
||||||
<template>
|
<template>
|
||||||
<v-bottom-navigation
|
<div>
|
||||||
grow color="primary"
|
<v-bottom-navigation
|
||||||
:fixed="$vuetify.breakpoint.name === 'xs'"
|
v-if="show && bottomNavigation"
|
||||||
>
|
grow color="primary"
|
||||||
<v-btn :to="{name: 'browse-libraries', params: {libraryId: libraryId}}">
|
:fixed="$vuetify.breakpoint.name === 'xs'"
|
||||||
<span>{{ $t('library_navigation.browse') }}</span>
|
|
||||||
<v-icon>mdi-bookshelf</v-icon>
|
|
||||||
</v-btn>
|
|
||||||
|
|
||||||
<v-btn :to="{name: 'recommended-libraries', params: {libraryId: libraryId}}">
|
|
||||||
<span>{{ $t('library_navigation.recommended') }}</span>
|
|
||||||
<v-icon>mdi-view-dashboard</v-icon>
|
|
||||||
</v-btn>
|
|
||||||
|
|
||||||
<v-btn
|
|
||||||
v-if="collectionsCount > 0"
|
|
||||||
:to="{name: 'browse-collections', params: {libraryId: libraryId}}"
|
|
||||||
>
|
>
|
||||||
<span>{{ $t('library_navigation.collections') }}</span>
|
<v-btn v-if="showRecommended"
|
||||||
<v-icon>mdi-layers-triple</v-icon>
|
:to="{name: 'recommended-libraries', params: {libraryId: libraryId}}"
|
||||||
</v-btn>
|
>
|
||||||
|
<span>{{ $t('library_navigation.recommended') }}</span>
|
||||||
|
<v-icon>mdi-star</v-icon>
|
||||||
|
</v-btn>
|
||||||
|
|
||||||
<v-btn
|
<v-btn :to="{name: 'browse-libraries', params: {libraryId: libraryId}}">
|
||||||
v-if="readListsCount > 0"
|
<span>{{ $t('library_navigation.browse') }}</span>
|
||||||
:to="{name: 'browse-readlists', params: {libraryId: libraryId}}"
|
<v-icon>mdi-bookshelf</v-icon>
|
||||||
|
</v-btn>
|
||||||
|
|
||||||
|
<v-btn
|
||||||
|
v-if="collectionsCount > 0"
|
||||||
|
:to="{name: 'browse-collections', params: {libraryId: libraryId}}"
|
||||||
|
>
|
||||||
|
<span>{{ $t('library_navigation.collections') }}</span>
|
||||||
|
<v-icon>mdi-layers-triple</v-icon>
|
||||||
|
</v-btn>
|
||||||
|
|
||||||
|
<v-btn
|
||||||
|
v-if="readListsCount > 0"
|
||||||
|
:to="{name: 'browse-readlists', params: {libraryId: libraryId}}"
|
||||||
|
>
|
||||||
|
<span>{{ $t('library_navigation.readlists') }}</span>
|
||||||
|
<v-icon>mdi-book-multiple</v-icon>
|
||||||
|
</v-btn>
|
||||||
|
|
||||||
|
</v-bottom-navigation>
|
||||||
|
|
||||||
|
<template
|
||||||
|
v-if="show && !bottomNavigation"
|
||||||
>
|
>
|
||||||
<span>{{ $t('library_navigation.readlists') }}</span>
|
<v-btn v-if="showRecommended"
|
||||||
<v-icon>mdi-book-multiple</v-icon>
|
:to="{name: 'recommended-libraries', params: {libraryId: libraryId}}"
|
||||||
</v-btn>
|
text
|
||||||
|
class="mx-1"
|
||||||
|
>
|
||||||
|
{{ $t('library_navigation.recommended') }}
|
||||||
|
</v-btn>
|
||||||
|
|
||||||
</v-bottom-navigation>
|
<v-btn :to="{name: 'browse-libraries', params: {libraryId: libraryId}}"
|
||||||
|
text
|
||||||
|
class="mx-1"
|
||||||
|
>
|
||||||
|
{{ $t('library_navigation.browse') }}
|
||||||
|
</v-btn>
|
||||||
|
|
||||||
|
<v-btn
|
||||||
|
v-if="collectionsCount > 0"
|
||||||
|
:to="{name: 'browse-collections', params: {libraryId: libraryId}}"
|
||||||
|
text
|
||||||
|
class="mx-1"
|
||||||
|
>
|
||||||
|
{{ $t('library_navigation.collections') }}
|
||||||
|
</v-btn>
|
||||||
|
|
||||||
|
<v-btn
|
||||||
|
v-if="readListsCount > 0"
|
||||||
|
:to="{name: 'browse-readlists', params: {libraryId: libraryId}}"
|
||||||
|
text
|
||||||
|
class="mx-1"
|
||||||
|
>
|
||||||
|
{{ $t('library_navigation.readlists') }}
|
||||||
|
</v-btn>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
|
@ -50,31 +93,43 @@ export default Vue.extend({
|
||||||
type: String,
|
type: String,
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
|
bottomNavigation: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
libraryId: {
|
libraryId: {
|
||||||
handler (val) {
|
handler(val) {
|
||||||
this.loadCounts(val)
|
this.loadCounts(val)
|
||||||
},
|
},
|
||||||
immediate: true,
|
immediate: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
created () {
|
created() {
|
||||||
this.$eventHub.$on(COLLECTION_CHANGED, this.reloadCounts)
|
this.$eventHub.$on(COLLECTION_CHANGED, this.reloadCounts)
|
||||||
this.$eventHub.$on(READLIST_CHANGED, this.reloadCounts)
|
this.$eventHub.$on(READLIST_CHANGED, this.reloadCounts)
|
||||||
},
|
},
|
||||||
beforeDestroy () {
|
beforeDestroy() {
|
||||||
this.$eventHub.$off(COLLECTION_CHANGED, this.reloadCounts)
|
this.$eventHub.$off(COLLECTION_CHANGED, this.reloadCounts)
|
||||||
this.$eventHub.$off(READLIST_CHANGED, this.reloadCounts)
|
this.$eventHub.$off(READLIST_CHANGED, this.reloadCounts)
|
||||||
},
|
},
|
||||||
|
computed: {
|
||||||
|
showRecommended(): boolean {
|
||||||
|
return this.libraryId !== LIBRARIES_ALL
|
||||||
|
},
|
||||||
|
show(): boolean {
|
||||||
|
return this.collectionsCount > 0 || this.readListsCount > 0 || this.showRecommended
|
||||||
|
},
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
reloadCounts () {
|
reloadCounts() {
|
||||||
this.loadCounts(this.libraryId)
|
this.loadCounts(this.libraryId)
|
||||||
},
|
},
|
||||||
async loadCounts (libraryId: string) {
|
async loadCounts(libraryId: string) {
|
||||||
const lib = libraryId !== LIBRARIES_ALL ? [libraryId] : undefined
|
const lib = libraryId !== LIBRARIES_ALL ? [libraryId] : undefined
|
||||||
this.collectionsCount = (await this.$komgaCollections.getCollections(lib, { size: 1 })).totalElements
|
this.collectionsCount = (await this.$komgaCollections.getCollections(lib, {size: 1})).totalElements
|
||||||
this.readListsCount = (await this.$komgaReadLists.getReadLists(lib, { size: 1 })).totalElements
|
this.readListsCount = (await this.$komgaReadLists.getReadLists(lib, {size: 1})).totalElements
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -14,10 +14,14 @@
|
||||||
|
|
||||||
<v-spacer/>
|
<v-spacer/>
|
||||||
|
|
||||||
|
<library-navigation v-if="$vuetify.breakpoint.name !== 'xs'" :libraryId="libraryId"/>
|
||||||
|
|
||||||
|
<v-spacer/>
|
||||||
|
|
||||||
<page-size-select v-model="pageSize"/>
|
<page-size-select v-model="pageSize"/>
|
||||||
</toolbar-sticky>
|
</toolbar-sticky>
|
||||||
|
|
||||||
<library-navigation :libraryId="libraryId"/>
|
<library-navigation v-if="$vuetify.breakpoint.name === 'xs'" :libraryId="libraryId" bottom-navigation/>
|
||||||
|
|
||||||
<v-container fluid>
|
<v-container fluid>
|
||||||
<v-pagination
|
<v-pagination
|
||||||
|
|
@ -82,12 +86,12 @@ export default Vue.extend({
|
||||||
default: LIBRARIES_ALL,
|
default: LIBRARIES_ALL,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
created () {
|
created() {
|
||||||
this.$eventHub.$on(COLLECTION_CHANGED, this.reloadCollections)
|
this.$eventHub.$on(COLLECTION_CHANGED, this.reloadCollections)
|
||||||
this.$eventHub.$on(COLLECTION_DELETED, this.reloadCollections)
|
this.$eventHub.$on(COLLECTION_DELETED, this.reloadCollections)
|
||||||
this.$eventHub.$on(LIBRARY_CHANGED, this.reloadLibrary)
|
this.$eventHub.$on(LIBRARY_CHANGED, this.reloadLibrary)
|
||||||
},
|
},
|
||||||
beforeDestroy () {
|
beforeDestroy() {
|
||||||
this.$eventHub.$off(COLLECTION_CHANGED, this.reloadCollections)
|
this.$eventHub.$off(COLLECTION_CHANGED, this.reloadCollections)
|
||||||
this.$eventHub.$off(COLLECTION_DELETED, this.reloadCollections)
|
this.$eventHub.$off(COLLECTION_DELETED, this.reloadCollections)
|
||||||
this.$eventHub.$off(LIBRARY_CHANGED, this.reloadLibrary)
|
this.$eventHub.$off(LIBRARY_CHANGED, this.reloadLibrary)
|
||||||
|
|
@ -103,7 +107,7 @@ export default Vue.extend({
|
||||||
|
|
||||||
this.setWatches()
|
this.setWatches()
|
||||||
},
|
},
|
||||||
beforeRouteUpdate (to, from, next) {
|
beforeRouteUpdate(to, from, next) {
|
||||||
if (to.params.libraryId !== from.params.libraryId) {
|
if (to.params.libraryId !== from.params.libraryId) {
|
||||||
// reset
|
// reset
|
||||||
this.page = 1
|
this.page = 1
|
||||||
|
|
@ -117,10 +121,10 @@ export default Vue.extend({
|
||||||
next()
|
next()
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
isAdmin (): boolean {
|
isAdmin(): boolean {
|
||||||
return this.$store.getters.meAdmin
|
return this.$store.getters.meAdmin
|
||||||
},
|
},
|
||||||
paginationVisible (): number {
|
paginationVisible(): number {
|
||||||
switch (this.$vuetify.breakpoint.name) {
|
switch (this.$vuetify.breakpoint.name) {
|
||||||
case 'xs':
|
case 'xs':
|
||||||
return 5
|
return 5
|
||||||
|
|
@ -135,7 +139,7 @@ export default Vue.extend({
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
setWatches () {
|
setWatches() {
|
||||||
this.pageSizeUnwatch = this.$watch('pageSize', (val) => {
|
this.pageSizeUnwatch = this.$watch('pageSize', (val) => {
|
||||||
this.$store.commit('setBrowsingPageSize', val)
|
this.$store.commit('setBrowsingPageSize', val)
|
||||||
this.updateRouteAndReload()
|
this.updateRouteAndReload()
|
||||||
|
|
@ -146,11 +150,11 @@ export default Vue.extend({
|
||||||
this.loadPage(this.libraryId, val)
|
this.loadPage(this.libraryId, val)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
unsetWatches () {
|
unsetWatches() {
|
||||||
this.pageUnwatch()
|
this.pageUnwatch()
|
||||||
this.pageSizeUnwatch()
|
this.pageSizeUnwatch()
|
||||||
},
|
},
|
||||||
updateRouteAndReload () {
|
updateRouteAndReload() {
|
||||||
this.unsetWatches()
|
this.unsetWatches()
|
||||||
|
|
||||||
this.page = 1
|
this.page = 1
|
||||||
|
|
@ -160,10 +164,10 @@ export default Vue.extend({
|
||||||
|
|
||||||
this.setWatches()
|
this.setWatches()
|
||||||
},
|
},
|
||||||
updateRoute () {
|
updateRoute() {
|
||||||
this.$router.replace({
|
this.$router.replace({
|
||||||
name: this.$route.name,
|
name: this.$route.name,
|
||||||
params: { libraryId: this.$route.params.libraryId },
|
params: {libraryId: this.$route.params.libraryId},
|
||||||
query: {
|
query: {
|
||||||
page: `${this.page}`,
|
page: `${this.page}`,
|
||||||
pageSize: `${this.pageSize}`,
|
pageSize: `${this.pageSize}`,
|
||||||
|
|
@ -171,23 +175,23 @@ export default Vue.extend({
|
||||||
} as Location).catch((_: any) => {
|
} as Location).catch((_: any) => {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
reloadCollections () {
|
reloadCollections() {
|
||||||
this.loadLibrary(this.libraryId)
|
this.loadLibrary(this.libraryId)
|
||||||
},
|
},
|
||||||
reloadLibrary (event: EventLibraryChanged) {
|
reloadLibrary(event: EventLibraryChanged) {
|
||||||
if (event.id === this.libraryId) {
|
if (event.id === this.libraryId) {
|
||||||
this.loadLibrary(this.libraryId)
|
this.loadLibrary(this.libraryId)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async loadLibrary (libraryId: string) {
|
async loadLibrary(libraryId: string) {
|
||||||
this.library = this.getLibraryLazy(libraryId)
|
this.library = this.getLibraryLazy(libraryId)
|
||||||
await this.loadPage(libraryId, this.page)
|
await this.loadPage(libraryId, this.page)
|
||||||
|
|
||||||
if (this.totalElements === 0) {
|
if (this.totalElements === 0) {
|
||||||
await this.$router.push({ name: 'browse-libraries', params: { libraryId: libraryId.toString() } })
|
await this.$router.push({name: 'browse-libraries', params: {libraryId: libraryId.toString()}})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async loadPage (libraryId: string, page: number) {
|
async loadPage(libraryId: string, page: number) {
|
||||||
const pageRequest = {
|
const pageRequest = {
|
||||||
page: page - 1,
|
page: page - 1,
|
||||||
size: this.pageSize,
|
size: this.pageSize,
|
||||||
|
|
@ -200,14 +204,14 @@ export default Vue.extend({
|
||||||
this.totalElements = collectionsPage.totalElements
|
this.totalElements = collectionsPage.totalElements
|
||||||
this.collections = collectionsPage.content
|
this.collections = collectionsPage.content
|
||||||
},
|
},
|
||||||
getLibraryLazy (libraryId: string): LibraryDto | undefined {
|
getLibraryLazy(libraryId: string): LibraryDto | undefined {
|
||||||
if (libraryId !== LIBRARIES_ALL) {
|
if (libraryId !== LIBRARIES_ALL) {
|
||||||
return this.$store.getters.getLibraryById(libraryId)
|
return this.$store.getters.getLibraryById(libraryId)
|
||||||
} else {
|
} else {
|
||||||
return undefined
|
return undefined
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
editSingleCollection (collection: CollectionDto) {
|
editSingleCollection(collection: CollectionDto) {
|
||||||
this.$store.dispatch('dialogEditCollection', collection)
|
this.$store.dispatch('dialogEditCollection', collection)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,10 @@
|
||||||
|
|
||||||
<v-spacer/>
|
<v-spacer/>
|
||||||
|
|
||||||
|
<library-navigation v-if="$vuetify.breakpoint.name !== 'xs'" :libraryId="libraryId"/>
|
||||||
|
|
||||||
|
<v-spacer/>
|
||||||
|
|
||||||
<page-size-select v-model="pageSize"/>
|
<page-size-select v-model="pageSize"/>
|
||||||
|
|
||||||
<v-btn icon @click="drawer = !drawer">
|
<v-btn icon @click="drawer = !drawer">
|
||||||
|
|
@ -30,7 +34,7 @@
|
||||||
@edit="editMultipleSeries"
|
@edit="editMultipleSeries"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<library-navigation :libraryId="libraryId"/>
|
<library-navigation v-if="$vuetify.breakpoint.name === 'xs'" :libraryId="libraryId" bottom-navigation/>
|
||||||
|
|
||||||
<filter-drawer v-model="drawer">
|
<filter-drawer v-model="drawer">
|
||||||
<template v-slot:default>
|
<template v-slot:default>
|
||||||
|
|
|
||||||
|
|
@ -14,10 +14,14 @@
|
||||||
|
|
||||||
<v-spacer/>
|
<v-spacer/>
|
||||||
|
|
||||||
|
<library-navigation v-if="$vuetify.breakpoint.name !== 'xs'" :libraryId="libraryId"/>
|
||||||
|
|
||||||
|
<v-spacer/>
|
||||||
|
|
||||||
<page-size-select v-model="pageSize"/>
|
<page-size-select v-model="pageSize"/>
|
||||||
</toolbar-sticky>
|
</toolbar-sticky>
|
||||||
|
|
||||||
<library-navigation :libraryId="libraryId"/>
|
<library-navigation v-if="$vuetify.breakpoint.name === 'xs'" :libraryId="libraryId" bottom-navigation/>
|
||||||
|
|
||||||
<v-container fluid>
|
<v-container fluid>
|
||||||
<v-pagination
|
<v-pagination
|
||||||
|
|
|
||||||
|
|
@ -9,10 +9,15 @@
|
||||||
<span>{{ library ? library.name : $t('common.all_libraries') }}</span>
|
<span>{{ library ? library.name : $t('common.all_libraries') }}</span>
|
||||||
</v-toolbar-title>
|
</v-toolbar-title>
|
||||||
|
|
||||||
</toolbar-sticky>
|
<v-spacer/>
|
||||||
|
|
||||||
<library-navigation :libraryId="libraryId"/>
|
<library-navigation v-if="showLibraryBar && $vuetify.breakpoint.name !== 'xs'" :libraryId="libraryId"/>
|
||||||
</div>
|
|
||||||
|
<v-spacer/>
|
||||||
|
|
||||||
|
</toolbar-sticky>
|
||||||
|
|
||||||
|
<library-navigation v-if="showLibraryBar && $vuetify.breakpoint.name === 'xs'" :libraryId="libraryId" bottom-navigation/>
|
||||||
|
|
||||||
<series-multi-select-bar
|
<series-multi-select-bar
|
||||||
v-model="selectedSeries"
|
v-model="selectedSeries"
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue