mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2026-02-07 10:49:39 +00:00
Lazy bookshelf, api routes for categories and filter data
This commit is contained in:
parent
4587916c8e
commit
5c92aef048
26 changed files with 1354 additions and 332 deletions
|
|
@ -13,7 +13,7 @@
|
|||
<div class="rounded-full py-1 bg-primary hover:bg-bg cursor-pointer px-2 border border-black-100 text-center flex items-center box-shadow-md" @mousedown.prevent @mouseup.prevent @click="showBookshelfTextureModal"><p class="text-sm py-0.5">Texture</p></div>
|
||||
</div>
|
||||
|
||||
<div v-if="!audiobooks.length" class="w-full flex flex-col items-center justify-center py-12">
|
||||
<div v-if="loaded && !shelves.length" class="w-full flex flex-col items-center justify-center py-12">
|
||||
<p class="text-center text-2xl font-book mb-4 py-4">Your Audiobookshelf is empty!</p>
|
||||
<div class="flex">
|
||||
<ui-btn to="/config" color="primary" class="w-52 mr-2" @click="scan">Configure Scanner</ui-btn>
|
||||
|
|
@ -30,89 +30,36 @@
|
|||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
search: Boolean,
|
||||
results: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
loaded: false,
|
||||
availableSizes: [60, 80, 100, 120, 140, 160, 180, 200, 220],
|
||||
selectedSizeIndex: 3,
|
||||
rowPaddingX: 40,
|
||||
keywordFilterTimeout: null,
|
||||
scannerParseSubtitle: false,
|
||||
wrapperClientWidth: 0,
|
||||
overflowingShelvesRight: {},
|
||||
overflowingShelvesLeft: {}
|
||||
shelves: []
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
showExperimentalFeatures() {
|
||||
return this.$store.state.showExperimentalFeatures
|
||||
},
|
||||
userAudiobooks() {
|
||||
return this.$store.state.user.user ? this.$store.state.user.user.audiobooks || {} : {}
|
||||
},
|
||||
audiobooks() {
|
||||
return this.$store.state.audiobooks.audiobooks
|
||||
currentLibraryId() {
|
||||
return this.$store.state.libraries.currentLibraryId
|
||||
},
|
||||
bookCoverWidth() {
|
||||
return this.availableSizes[this.selectedSizeIndex]
|
||||
},
|
||||
sizeMultiplier() {
|
||||
return this.bookCoverWidth / 120
|
||||
},
|
||||
paddingX() {
|
||||
return 16 * this.sizeMultiplier
|
||||
},
|
||||
bookWidth() {
|
||||
return this.bookCoverWidth + this.paddingX * 2
|
||||
},
|
||||
mostRecentPlayed() {
|
||||
var audiobooks = this.audiobooks.filter((ab) => this.userAudiobooks[ab.id] && this.userAudiobooks[ab.id].lastUpdate > 0 && this.userAudiobooks[ab.id].progress > 0 && !this.userAudiobooks[ab.id].isRead).map((ab) => ({ ...ab }))
|
||||
audiobooks.sort((a, b) => {
|
||||
return this.userAudiobooks[b.id].lastUpdate - this.userAudiobooks[a.id].lastUpdate
|
||||
})
|
||||
return audiobooks.slice(0, 10)
|
||||
},
|
||||
mostRecentAdded() {
|
||||
var audiobooks = this.audiobooks.map((ab) => ({ ...ab })).sort((a, b) => b.addedAt - a.addedAt)
|
||||
return audiobooks.slice(0, 10)
|
||||
},
|
||||
seriesGroups() {
|
||||
return this.$store.getters['audiobooks/getSeriesGroups']()
|
||||
},
|
||||
recentlyUpdatedSeries() {
|
||||
var mostRecentTime = 0
|
||||
var mostRecentSeries = null
|
||||
this.seriesGroups.forEach((series) => {
|
||||
if ((series.books.length && mostRecentSeries === null) || series.lastUpdate > mostRecentTime) {
|
||||
mostRecentTime = series.lastUpdate
|
||||
mostRecentSeries = series
|
||||
}
|
||||
})
|
||||
if (!mostRecentSeries) return null
|
||||
return mostRecentSeries.books
|
||||
},
|
||||
booksRecentlyRead() {
|
||||
var audiobooks = this.audiobooks.filter((ab) => this.userAudiobooks[ab.id] && this.userAudiobooks[ab.id].isRead).map((ab) => ({ ...ab }))
|
||||
audiobooks.sort((a, b) => {
|
||||
return this.userAudiobooks[b.id].finishedAt - this.userAudiobooks[a.id].finishedAt
|
||||
})
|
||||
return audiobooks.slice(0, 10)
|
||||
},
|
||||
shelves() {
|
||||
var shelves = []
|
||||
if (this.mostRecentPlayed.length) {
|
||||
shelves.push({ books: this.mostRecentPlayed, label: 'Continue Reading' })
|
||||
}
|
||||
|
||||
shelves.push({ books: this.mostRecentAdded, label: 'Recently Added' })
|
||||
|
||||
if (this.recentlyUpdatedSeries) {
|
||||
shelves.push({ books: this.recentlyUpdatedSeries, label: 'Newest Series' })
|
||||
}
|
||||
|
||||
if (this.booksRecentlyRead.length) {
|
||||
shelves.push({ books: this.booksRecentlyRead, label: 'Read Again' })
|
||||
}
|
||||
return shelves
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
|
@ -136,10 +83,73 @@ export default {
|
|||
var sizeIndex = this.availableSizes.findIndex((s) => s === bookshelfCoverSize)
|
||||
if (!isNaN(sizeIndex)) this.selectedSizeIndex = sizeIndex
|
||||
|
||||
await this.$store.dispatch('audiobooks/load')
|
||||
// await this.$store.dispatch('audiobooks/load')
|
||||
if (this.search) {
|
||||
this.setShelvesFromSearch()
|
||||
} else {
|
||||
var categories = await this.$axios
|
||||
.$get(`/api/libraries/${this.currentLibraryId}/categories`)
|
||||
.then((data) => {
|
||||
console.log('Category data', data)
|
||||
return data
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Failed to fetch cats', error)
|
||||
})
|
||||
this.shelves = categories
|
||||
}
|
||||
|
||||
this.loaded = true
|
||||
},
|
||||
async setShelvesFromSearch() {
|
||||
var shelves = []
|
||||
if (this.results.audiobooks) {
|
||||
shelves.push({
|
||||
id: 'audiobooks',
|
||||
label: 'Books',
|
||||
type: 'books',
|
||||
entities: this.results.audiobooks.map((ab) => ab.audiobook)
|
||||
})
|
||||
}
|
||||
if (this.results.authors) {
|
||||
shelves.push({
|
||||
id: 'authors',
|
||||
label: 'Authors',
|
||||
type: 'authors',
|
||||
entities: this.results.authors.map((a) => a.author)
|
||||
})
|
||||
}
|
||||
if (this.results.series) {
|
||||
shelves.push({
|
||||
id: 'series',
|
||||
label: 'Series',
|
||||
type: 'series',
|
||||
entities: this.results.series.map((seriesObj) => {
|
||||
return {
|
||||
name: seriesObj.series,
|
||||
books: seriesObj.audiobooks,
|
||||
type: 'series'
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
if (this.results.tags) {
|
||||
shelves.push({
|
||||
id: 'tags',
|
||||
label: 'Tags',
|
||||
type: 'tags',
|
||||
entities: this.results.tags.map((tagObj) => {
|
||||
return {
|
||||
name: tagObj.tag,
|
||||
books: tagObj.audiobooks,
|
||||
type: 'tags'
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
this.shelves = shelves
|
||||
},
|
||||
resize() {},
|
||||
audiobooksUpdated() {},
|
||||
settingsUpdated(settings) {
|
||||
if (settings.bookshelfCoverSize !== this.bookCoverWidth && settings.bookshelfCoverSize !== undefined) {
|
||||
var index = this.availableSizes.indexOf(settings.bookshelfCoverSize)
|
||||
|
|
@ -154,15 +164,11 @@ export default {
|
|||
}
|
||||
},
|
||||
mounted() {
|
||||
window.addEventListener('resize', this.resize)
|
||||
this.$store.commit('audiobooks/addListener', { id: 'bookshelf', meth: this.audiobooksUpdated })
|
||||
this.$store.commit('user/addSettingsListener', { id: 'bookshelf', meth: this.settingsUpdated })
|
||||
|
||||
this.init()
|
||||
},
|
||||
beforeDestroy() {
|
||||
window.removeEventListener('resize', this.resize)
|
||||
this.$store.commit('audiobooks/removeListener', 'bookshelf')
|
||||
this.$store.commit('user/removeSettingsListener', 'bookshelf')
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue