feat(webui): display collections in search results and search box

closes #212
This commit is contained in:
Gauthier Roebroeck 2020-06-26 17:54:52 +08:00
parent 50b516d0c5
commit 82aec45660
2 changed files with 65 additions and 11 deletions

View file

@ -19,7 +19,8 @@
:min-width="$vuetify.breakpoint.mdAndUp ? $vuetify.breakpoint.width * .4 : $vuetify.breakpoint.width * .8"
>
<v-list>
<v-list-item v-if="series.length === 0 && books.length === 0">No results</v-list-item>
<v-list-item v-if="series.length === 0 && books.length === 0 && collections.length === 0">No results
</v-list-item>
<template v-if="series.length !== 0">
<v-subheader>SERIES</v-subheader>
@ -57,13 +58,31 @@
</v-list-item>
</template>
<template v-if="collections.length !== 0">
<v-subheader>COLLECTIONS</v-subheader>
<v-list-item v-for="item in collections"
:key="item.id"
link
:to="{name: 'browse-collection', params: {collectionId: item.id}}"
>
<v-img :src="collectionThumbnailUrl(item.id)"
height="50"
max-width="35"
class="ma-1 mr-3"
/>
<v-list-item-content>
<v-list-item-title v-text="item.name"/>
</v-list-item-content>
</v-list-item>
</template>
</v-list>
</v-menu>
</div>
</template>
<script lang="ts">
import { bookThumbnailUrl, seriesThumbnailUrl } from '@/functions/urls'
import { bookThumbnailUrl, collectionThumbnailUrl, seriesThumbnailUrl } from '@/functions/urls'
import { debounce } from 'lodash'
import Vue from 'vue'
@ -76,6 +95,7 @@ export default Vue.extend({
loading: false,
series: [] as SeriesDto[],
books: [] as BookDto[],
collections: [] as CollectionDto[],
pageSize: 10,
}
},
@ -93,6 +113,7 @@ export default Vue.extend({
this.loading = true
this.series = (await this.$komgaSeries.getSeries(undefined, { size: this.pageSize }, query)).content
this.books = (await this.$komgaBooks.getBooks(undefined, { size: this.pageSize }, query)).content
this.collections = (await this.$komgaCollections.getCollections(undefined, { size: this.pageSize }, false, query)).content
this.showResults = true
this.loading = false
} else {
@ -104,6 +125,7 @@ export default Vue.extend({
this.showResults = false
this.series = []
this.books = []
this.collections = []
},
searchDetails () {
const s = this.search
@ -117,6 +139,9 @@ export default Vue.extend({
bookThumbnailUrl (bookId: number): string {
return bookThumbnailUrl(bookId)
},
collectionThumbnailUrl (collectionId: number): string {
return collectionThumbnailUrl(collectionId)
},
},
})
</script>

View file

@ -23,9 +23,9 @@
<div class="title">Series</div>
</template>
<template v-slot:content>
<div v-for="(s, i) in series"
:key="i">
<item-card class="ma-2 card" :item="s"/>
<div v-for="(item, index) in series"
:key="index">
<item-card class="ma-2 card" :item="item"/>
</div>
</template>
</horizontal-scroller>
@ -35,9 +35,21 @@
<div class="title">Books</div>
</template>
<template v-slot:content>
<div v-for="(s, i) in books"
:key="i">
<item-card class="ma-2 card" :item="s"/>
<div v-for="(item, index) in books"
:key="index">
<item-card class="ma-2 card" :item="item"/>
</div>
</template>
</horizontal-scroller>
<horizontal-scroller v-if="collections.length !== 0" class="my-4">
<template v-slot:prepend>
<div class="title">Collections</div>
</template>
<template v-slot:content>
<div v-for="(item, index) in collections"
:key="index">
<item-card class="ma-2 card" :item="item"/>
</div>
</template>
</horizontal-scroller>
@ -53,10 +65,9 @@ import EmptyState from '@/components/EmptyState.vue'
import HorizontalScroller from '@/components/HorizontalScroller.vue'
import ItemCard from '@/components/ItemCard.vue'
import ToolbarSticky from '@/components/ToolbarSticky.vue'
import { BOOK_CHANGED, COLLECTION_CHANGED, LIBRARY_DELETED, SERIES_CHANGED } from '@/types/events'
import Vue from 'vue'
const cookiePageSize = 'pagesize'
export default Vue.extend({
name: 'Search',
components: {
@ -69,10 +80,23 @@ export default Vue.extend({
return {
series: [] as SeriesDto[],
books: [] as BookDto[],
collections: [] as CollectionDto[],
pageSize: 50,
loading: false,
}
},
created () {
this.$eventHub.$on(LIBRARY_DELETED, this.reloadResults)
this.$eventHub.$on(SERIES_CHANGED, this.reloadResults)
this.$eventHub.$on(BOOK_CHANGED, this.reloadResults)
this.$eventHub.$on(COLLECTION_CHANGED, this.reloadResults)
},
beforeDestroy () {
this.$eventHub.$off(LIBRARY_DELETED, this.reloadResults)
this.$eventHub.$off(SERIES_CHANGED, this.reloadResults)
this.$eventHub.$off(BOOK_CHANGED, this.reloadResults)
this.$eventHub.$off(COLLECTION_CHANGED, this.reloadResults)
},
watch: {
'$route.query.q': {
handler: function (val) {
@ -84,21 +108,26 @@ export default Vue.extend({
},
computed: {
emptyResults (): boolean {
return !this.loading && this.series.length === 0 && this.books.length === 0
return !this.loading && this.series.length === 0 && this.books.length === 0 && this.collections.length === 0
},
},
methods: {
reloadResults () {
this.loadResults(this.$route.query.q.toString())
},
async loadResults (search: string) {
if (search) {
this.loading = true
this.series = (await this.$komgaSeries.getSeries(undefined, { size: this.pageSize }, search)).content
this.books = (await this.$komgaBooks.getBooks(undefined, { size: this.pageSize }, search)).content
this.collections = (await this.$komgaCollections.getCollections(undefined, { size: this.pageSize }, undefined, search)).content
this.loading = false
} else {
this.series = []
this.books = []
this.collections = []
}
},
},