mirror of
https://github.com/gotson/komga.git
synced 2026-02-15 03:43:05 +01:00
feat(webui): display collections in search results and search box
closes #212
This commit is contained in:
parent
50b516d0c5
commit
82aec45660
2 changed files with 65 additions and 11 deletions
|
|
@ -19,7 +19,8 @@
|
||||||
:min-width="$vuetify.breakpoint.mdAndUp ? $vuetify.breakpoint.width * .4 : $vuetify.breakpoint.width * .8"
|
:min-width="$vuetify.breakpoint.mdAndUp ? $vuetify.breakpoint.width * .4 : $vuetify.breakpoint.width * .8"
|
||||||
>
|
>
|
||||||
<v-list>
|
<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">
|
<template v-if="series.length !== 0">
|
||||||
<v-subheader>SERIES</v-subheader>
|
<v-subheader>SERIES</v-subheader>
|
||||||
|
|
@ -57,13 +58,31 @@
|
||||||
</v-list-item>
|
</v-list-item>
|
||||||
</template>
|
</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-list>
|
||||||
</v-menu>
|
</v-menu>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { bookThumbnailUrl, seriesThumbnailUrl } from '@/functions/urls'
|
import { bookThumbnailUrl, collectionThumbnailUrl, seriesThumbnailUrl } from '@/functions/urls'
|
||||||
import { debounce } from 'lodash'
|
import { debounce } from 'lodash'
|
||||||
import Vue from 'vue'
|
import Vue from 'vue'
|
||||||
|
|
||||||
|
|
@ -76,6 +95,7 @@ export default Vue.extend({
|
||||||
loading: false,
|
loading: false,
|
||||||
series: [] as SeriesDto[],
|
series: [] as SeriesDto[],
|
||||||
books: [] as BookDto[],
|
books: [] as BookDto[],
|
||||||
|
collections: [] as CollectionDto[],
|
||||||
pageSize: 10,
|
pageSize: 10,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -93,6 +113,7 @@ export default Vue.extend({
|
||||||
this.loading = true
|
this.loading = true
|
||||||
this.series = (await this.$komgaSeries.getSeries(undefined, { size: this.pageSize }, query)).content
|
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.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.showResults = true
|
||||||
this.loading = false
|
this.loading = false
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -104,6 +125,7 @@ export default Vue.extend({
|
||||||
this.showResults = false
|
this.showResults = false
|
||||||
this.series = []
|
this.series = []
|
||||||
this.books = []
|
this.books = []
|
||||||
|
this.collections = []
|
||||||
},
|
},
|
||||||
searchDetails () {
|
searchDetails () {
|
||||||
const s = this.search
|
const s = this.search
|
||||||
|
|
@ -117,6 +139,9 @@ export default Vue.extend({
|
||||||
bookThumbnailUrl (bookId: number): string {
|
bookThumbnailUrl (bookId: number): string {
|
||||||
return bookThumbnailUrl(bookId)
|
return bookThumbnailUrl(bookId)
|
||||||
},
|
},
|
||||||
|
collectionThumbnailUrl (collectionId: number): string {
|
||||||
|
return collectionThumbnailUrl(collectionId)
|
||||||
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -23,9 +23,9 @@
|
||||||
<div class="title">Series</div>
|
<div class="title">Series</div>
|
||||||
</template>
|
</template>
|
||||||
<template v-slot:content>
|
<template v-slot:content>
|
||||||
<div v-for="(s, i) in series"
|
<div v-for="(item, index) in series"
|
||||||
:key="i">
|
:key="index">
|
||||||
<item-card class="ma-2 card" :item="s"/>
|
<item-card class="ma-2 card" :item="item"/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</horizontal-scroller>
|
</horizontal-scroller>
|
||||||
|
|
@ -35,9 +35,21 @@
|
||||||
<div class="title">Books</div>
|
<div class="title">Books</div>
|
||||||
</template>
|
</template>
|
||||||
<template v-slot:content>
|
<template v-slot:content>
|
||||||
<div v-for="(s, i) in books"
|
<div v-for="(item, index) in books"
|
||||||
:key="i">
|
:key="index">
|
||||||
<item-card class="ma-2 card" :item="s"/>
|
<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>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</horizontal-scroller>
|
</horizontal-scroller>
|
||||||
|
|
@ -53,10 +65,9 @@ import EmptyState from '@/components/EmptyState.vue'
|
||||||
import HorizontalScroller from '@/components/HorizontalScroller.vue'
|
import HorizontalScroller from '@/components/HorizontalScroller.vue'
|
||||||
import ItemCard from '@/components/ItemCard.vue'
|
import ItemCard from '@/components/ItemCard.vue'
|
||||||
import ToolbarSticky from '@/components/ToolbarSticky.vue'
|
import ToolbarSticky from '@/components/ToolbarSticky.vue'
|
||||||
|
import { BOOK_CHANGED, COLLECTION_CHANGED, LIBRARY_DELETED, SERIES_CHANGED } from '@/types/events'
|
||||||
import Vue from 'vue'
|
import Vue from 'vue'
|
||||||
|
|
||||||
const cookiePageSize = 'pagesize'
|
|
||||||
|
|
||||||
export default Vue.extend({
|
export default Vue.extend({
|
||||||
name: 'Search',
|
name: 'Search',
|
||||||
components: {
|
components: {
|
||||||
|
|
@ -69,10 +80,23 @@ export default Vue.extend({
|
||||||
return {
|
return {
|
||||||
series: [] as SeriesDto[],
|
series: [] as SeriesDto[],
|
||||||
books: [] as BookDto[],
|
books: [] as BookDto[],
|
||||||
|
collections: [] as CollectionDto[],
|
||||||
pageSize: 50,
|
pageSize: 50,
|
||||||
loading: false,
|
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: {
|
watch: {
|
||||||
'$route.query.q': {
|
'$route.query.q': {
|
||||||
handler: function (val) {
|
handler: function (val) {
|
||||||
|
|
@ -84,21 +108,26 @@ export default Vue.extend({
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
emptyResults (): boolean {
|
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: {
|
methods: {
|
||||||
|
reloadResults () {
|
||||||
|
this.loadResults(this.$route.query.q.toString())
|
||||||
|
},
|
||||||
async loadResults (search: string) {
|
async loadResults (search: string) {
|
||||||
if (search) {
|
if (search) {
|
||||||
this.loading = true
|
this.loading = true
|
||||||
|
|
||||||
this.series = (await this.$komgaSeries.getSeries(undefined, { size: this.pageSize }, search)).content
|
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.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
|
this.loading = false
|
||||||
} else {
|
} else {
|
||||||
this.series = []
|
this.series = []
|
||||||
this.books = []
|
this.books = []
|
||||||
|
this.collections = []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue