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