feat(webui): display library navigation within toolbar

use bottom navigation only for XS screens

closes #234
This commit is contained in:
Gauthier Roebroeck 2021-04-27 21:32:26 +08:00
parent 4c6b3f5e5e
commit a6252ff2e8
5 changed files with 129 additions and 57 deletions

View file

@ -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
},
},
})

View file

@ -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)
},
},

View file

@ -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>

View file

@ -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

View file

@ -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"