advplyr.audiobookshelf-app/pages/search.vue

163 lines
6 KiB
Vue
Raw Permalink Normal View History

2021-11-19 10:14:36 -06:00
<template>
<div class="w-full h-full">
<div class="px-4 py-6">
<ui-text-input ref="input" v-model="search" @input="updateSearch" borderless :placeholder="$strings.ButtonSearch" bg="white bg-opacity-10" rounded="md" prepend-icon="search" text-size="base" clearable class="w-full text-lg" />
2021-11-19 10:14:36 -06:00
</div>
<div class="w-full overflow-x-hidden overflow-y-auto search-content px-4" @click.stop>
<div v-show="isFetching" class="w-full py-8 flex justify-center">
<p class="text-lg text-fg-muted">{{ $strings.MessageFetching }}</p>
2021-11-19 10:14:36 -06:00
</div>
2021-12-04 19:56:29 -06:00
<div v-if="!isFetching && lastSearch && !totalResults" class="w-full py-8 flex justify-center">
<p class="text-lg text-fg-muted">{{ $strings.MessageNoItemsFound }}</p>
2021-11-19 10:14:36 -06:00
</div>
<p v-if="bookResults.length" class="font-semibold text-sm mb-1">{{ $strings.LabelBooks }}</p>
<template v-for="item in bookResults">
2022-04-19 11:02:22 -04:00
<div :key="item.libraryItem.id" class="w-full h-16 py-1">
<nuxt-link :to="`/item/${item.libraryItem.id}`">
<cards-item-search-card :library-item="item.libraryItem" :match-key="item.matchKey" :match-text="item.matchText" :search="lastSearch" />
</nuxt-link>
</div>
</template>
<p v-if="podcastResults.length" class="uppercase text-xs text-fg-muted my-1 px-1 font-semibold">{{ $strings.LabelPodcasts }}</p>
<template v-for="item in podcastResults">
<div :key="item.libraryItem.id" class="text-fg select-none relative py-1">
2022-04-19 11:02:22 -04:00
<nuxt-link :to="`/item/${item.libraryItem.id}`">
<cards-item-search-card :library-item="item.libraryItem" :match-key="item.matchKey" :match-text="item.matchText" :search="lastSearch" />
2021-12-04 19:56:29 -06:00
</nuxt-link>
</div>
</template>
<p v-if="seriesResults.length" class="font-semibold text-sm mb-1 mt-2">{{ $strings.LabelSeries }}</p>
2021-12-04 19:56:29 -06:00
<template v-for="seriesResult in seriesResults">
<div :key="seriesResult.series.id" class="w-full h-16 py-1">
<nuxt-link :to="`/bookshelf/series/${seriesResult.series.id}`">
<cards-series-search-card :series="seriesResult.series" :book-items="seriesResult.books" />
2021-12-04 19:56:29 -06:00
</nuxt-link>
</div>
</template>
<p v-if="authorResults.length" class="font-semibold text-sm mb-1 mt-2">{{ $strings.LabelAuthors }}</p>
2021-12-04 19:56:29 -06:00
<template v-for="authorResult in authorResults">
<div :key="authorResult.id" class="w-full h-14 py-1">
<nuxt-link :to="`/bookshelf/library?filter=authors.${$encode(authorResult.id)}`">
2023-05-19 17:18:31 -05:00
<cards-author-search-card :author="authorResult" />
</nuxt-link>
</div>
</template>
<p v-if="narratorResults.length" class="font-semibold text-sm mb-1 mt-2">{{ $strings.LabelNarrators }}</p>
2023-05-19 17:18:31 -05:00
<template v-for="narrator in narratorResults">
<div :key="narrator.name" class="w-full h-14 py-1">
<nuxt-link :to="`/bookshelf/library?filter=narrators.${$encode(narrator.name)}`">
<cards-narrator-search-card :narrator="narrator.name" />
2021-12-04 19:56:29 -06:00
</nuxt-link>
2021-11-19 10:14:36 -06:00
</div>
</template>
2023-11-15 14:30:57 -06:00
<p v-if="tagResults.length" class="font-semibold text-sm mb-1 mt-2">{{ $strings.LabelTags }}</p>
2023-11-15 14:30:57 -06:00
<template v-for="tag in tagResults">
<div :key="tag.name" class="w-full h-14 py-1">
<nuxt-link :to="`/bookshelf/library?filter=tags.${$encode(tag.name)}`">
<cards-tag-search-card :tag="tag.name" />
</nuxt-link>
</div>
</template>
2021-11-19 10:14:36 -06:00
</div>
</div>
</template>
<script>
export default {
data() {
return {
search: null,
searchTimeout: null,
lastSearch: null,
isFetching: false,
2021-12-04 19:56:29 -06:00
bookResults: [],
podcastResults: [],
2021-12-04 19:56:29 -06:00
seriesResults: [],
2023-05-19 17:18:31 -05:00
authorResults: [],
2023-11-15 14:30:57 -06:00
narratorResults: [],
tagResults: []
2021-11-19 10:14:36 -06:00
}
},
2021-12-04 19:56:29 -06:00
computed: {
currentLibraryId() {
return this.$store.state.libraries.currentLibraryId
},
bookCoverAspectRatio() {
return this.$store.getters['libraries/getBookCoverAspectRatio']
2021-11-19 10:14:36 -06:00
},
2021-12-04 19:56:29 -06:00
totalResults() {
2023-11-15 14:30:57 -06:00
return this.bookResults.length + this.seriesResults.length + this.authorResults.length + this.podcastResults.length + this.narratorResults.length + this.tagResults.length
2021-12-04 19:56:29 -06:00
}
},
methods: {
2021-11-19 10:14:36 -06:00
async runSearch(value) {
2022-04-26 17:05:49 -05:00
if (this.isFetching && this.lastSearch === value) return
2021-11-19 10:14:36 -06:00
this.lastSearch = value
2022-04-26 17:05:49 -05:00
this.$store.commit('globals/setLastSearch', value)
2021-11-19 10:14:36 -06:00
if (!this.lastSearch) {
2021-12-04 19:56:29 -06:00
this.bookResults = []
this.podcastResults = []
2021-12-04 19:56:29 -06:00
this.seriesResults = []
this.authorResults = []
2023-05-19 17:18:31 -05:00
this.narratorResults = []
2023-11-15 14:30:57 -06:00
this.tagResults = []
2021-11-19 10:14:36 -06:00
return
}
this.isFetching = true
const results = await this.$nativeHttp.get(`/api/libraries/${this.currentLibraryId}/search?q=${value}&limit=5`).catch((error) => {
2021-11-19 10:14:36 -06:00
console.error('Search error', error)
return null
2021-11-19 10:14:36 -06:00
})
2022-04-26 17:05:49 -05:00
if (value !== this.lastSearch) {
console.log(`runSearch: New search was made for ${this.lastSearch} - results are from ${value}`)
return
}
2021-12-04 19:56:29 -06:00
console.log('RESULTS', results)
2021-11-19 10:14:36 -06:00
this.isFetching = false
2021-12-04 19:56:29 -06:00
2023-05-19 17:18:31 -05:00
this.bookResults = results?.book || []
this.podcastResults = results?.podcast || []
this.seriesResults = results?.series || []
this.authorResults = results?.authors || []
this.narratorResults = results?.narrators || []
2023-11-15 14:30:57 -06:00
this.tagResults = results?.tags || []
2021-11-19 10:14:36 -06:00
},
updateSearch(val) {
clearTimeout(this.searchTimeout)
this.searchTimeout = setTimeout(() => {
this.runSearch(val)
}, 500)
},
setFocus() {
setTimeout(() => {
if (this.$refs.input) {
this.$refs.input.focus()
}
}, 100)
}
},
mounted() {
2022-04-26 17:05:49 -05:00
if (this.$store.state.globals.lastSearch) {
this.search = this.$store.state.globals.lastSearch
this.runSearch(this.search)
} else {
this.$nextTick(this.setFocus())
}
2021-11-19 10:14:36 -06:00
}
}
</script>
<style>
.search-content {
height: calc(100% - 108px);
max-height: calc(100% - 108px);
}
</style>