mirror of
https://github.com/advplyr/audiobookshelf-app.git
synced 2025-07-16 00:44:51 +02:00
142 lines
4.8 KiB
Vue
142 lines
4.8 KiB
Vue
<template>
|
|
<div class="w-full h-full">
|
|
<div class="w-full h-full overflow-y-auto px-2 py-6 md:p-8">
|
|
<div class="w-full flex justify-center md:block sm:w-32 md:w-52" style="min-width: 240px">
|
|
<div class="relative" style="height: fit-content">
|
|
<covers-collection-cover :book-items="bookItems" :width="240" :height="120 * bookCoverAspectRatio" :book-cover-aspect-ratio="bookCoverAspectRatio" />
|
|
</div>
|
|
</div>
|
|
<div class="flex-grow py-6">
|
|
<div class="flex items-center px-2">
|
|
<h1 class="text-xl font-sans">
|
|
{{ collectionName }}
|
|
</h1>
|
|
<div class="flex-grow" />
|
|
<ui-btn v-if="showPlayButton" color="success" :padding-x="4" :loading="playerIsStartingForThisMedia" small class="flex items-center justify-center mx-1 w-24" @click="playClick">
|
|
<span class="material-symbols text-2xl fill">{{ playerIsPlaying ? 'pause' : 'play_arrow' }}</span>
|
|
<span class="px-1 text-sm">{{ playerIsPlaying ? $strings.ButtonPause : $strings.ButtonPlay }}</span>
|
|
</ui-btn>
|
|
</div>
|
|
|
|
<div class="my-8 max-w-2xl px-2">
|
|
<p class="text-base text-fg">{{ description }}</p>
|
|
</div>
|
|
|
|
<tables-collection-books-table :books="bookItems" :collection-id="collection.id" />
|
|
</div>
|
|
</div>
|
|
<div v-show="processingRemove" class="absolute top-0 left-0 w-full h-full z-10 bg-black bg-opacity-40 flex items-center justify-center">
|
|
<ui-loading-indicator />
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
export default {
|
|
async asyncData({ store, params, app, redirect, route }) {
|
|
if (!store.state.user.user) {
|
|
return redirect(`/connect?redirect=${route.path}`)
|
|
}
|
|
|
|
var collection = await app.$nativeHttp.get(`/api/collections/${params.id}`).catch((error) => {
|
|
console.error('Failed', error)
|
|
return false
|
|
})
|
|
|
|
if (!collection) {
|
|
return redirect('/bookshelf')
|
|
}
|
|
|
|
// Lookup matching local items and attach to collection items
|
|
if (collection.books.length) {
|
|
const localLibraryItems = (await app.$db.getLocalLibraryItems('book')) || []
|
|
if (localLibraryItems.length) {
|
|
collection.books.forEach((collectionItem) => {
|
|
const matchingLocalLibraryItem = localLibraryItems.find((lli) => lli.libraryItemId === collectionItem.id)
|
|
if (!matchingLocalLibraryItem) return
|
|
collectionItem.localLibraryItem = matchingLocalLibraryItem
|
|
})
|
|
}
|
|
}
|
|
|
|
return {
|
|
collection
|
|
}
|
|
},
|
|
data() {
|
|
return {
|
|
mediaIdStartingPlayback: null,
|
|
processingRemove: false
|
|
}
|
|
},
|
|
computed: {
|
|
bookCoverAspectRatio() {
|
|
return this.$store.getters['libraries/getBookCoverAspectRatio']
|
|
},
|
|
bookItems() {
|
|
return this.collection.books || []
|
|
},
|
|
collectionName() {
|
|
return this.collection.name || ''
|
|
},
|
|
description() {
|
|
return this.collection.description || ''
|
|
},
|
|
playableItems() {
|
|
return this.bookItems.filter((book) => {
|
|
return !book.isMissing && !book.isInvalid && book.media.tracks.length
|
|
})
|
|
},
|
|
playerIsPlaying() {
|
|
return this.$store.state.playerIsPlaying && this.isOpenInPlayer
|
|
},
|
|
isOpenInPlayer() {
|
|
return !!this.playableItems.find((i) => {
|
|
if (i.localLibraryItem && this.$store.getters['getIsMediaStreaming'](i.localLibraryItem.id)) return true
|
|
return this.$store.getters['getIsMediaStreaming'](i.id)
|
|
})
|
|
},
|
|
playerIsStartingPlayback() {
|
|
// Play has been pressed and waiting for native play response
|
|
return this.$store.state.playerIsStartingPlayback
|
|
},
|
|
playerIsStartingForThisMedia() {
|
|
if (!this.mediaIdStartingPlayback) return false
|
|
const mediaId = this.$store.state.playerStartingPlaybackMediaId
|
|
return mediaId === this.mediaIdStartingPlayback
|
|
},
|
|
showPlayButton() {
|
|
return this.playableItems.length
|
|
}
|
|
},
|
|
methods: {
|
|
async playClick() {
|
|
if (this.playerIsStartingPlayback) return
|
|
await this.$hapticsImpact()
|
|
|
|
if (this.playerIsPlaying) {
|
|
this.$eventBus.$emit('pause-item')
|
|
} else {
|
|
this.playNextItem()
|
|
}
|
|
},
|
|
playNextItem() {
|
|
const nextBookNotRead = this.playableItems.find((pb) => {
|
|
const prog = this.$store.getters['user/getUserMediaProgress'](pb.id)
|
|
return !prog?.isFinished
|
|
})
|
|
if (nextBookNotRead) {
|
|
this.mediaIdStartingPlayback = nextBookNotRead.id
|
|
this.$store.commit('setPlayerIsStartingPlayback', nextBookNotRead.id)
|
|
|
|
if (nextBookNotRead.localLibraryItem) {
|
|
this.$eventBus.$emit('play-item', { libraryItemId: nextBookNotRead.localLibraryItem.id, serverLibraryItemId: nextBookNotRead.id })
|
|
} else {
|
|
this.$eventBus.$emit('play-item', { libraryItemId: nextBookNotRead.id })
|
|
}
|
|
}
|
|
}
|
|
},
|
|
mounted() {}
|
|
}
|
|
</script>
|