mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2025-12-29 23:29:38 +00:00
Add support to custom episode cover art
This commit is contained in:
parent
0c7b738b7c
commit
f703fb60da
16 changed files with 446 additions and 20 deletions
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<div v-if="streamLibraryItem" id="mediaPlayerContainer" class="w-full fixed bottom-0 left-0 right-0 h-48 lg:h-40 z-50 bg-primary px-2 lg:px-4 pb-1 lg:pb-4 pt-2">
|
||||
<div class="absolute left-2 top-2 lg:left-4 cursor-pointer">
|
||||
<covers-book-cover expand-on-click :library-item="streamLibraryItem" :width="bookCoverWidth" :book-cover-aspect-ratio="coverAspectRatio" />
|
||||
<covers-book-cover expand-on-click :library-item="streamLibraryItem" :width="bookCoverWidth" :book-cover-aspect-ratio="coverAspectRatio" :cover-src="currentCoverSrc" />
|
||||
</div>
|
||||
<div class="flex items-start mb-6 lg:mb-0" :class="isSquareCover ? 'pl-18 sm:pl-24' : 'pl-12 sm:pl-16'">
|
||||
<div class="min-w-0 w-full">
|
||||
|
|
@ -178,6 +178,12 @@ export default {
|
|||
},
|
||||
playerQueueItems() {
|
||||
return this.$store.state.playerQueueItems || []
|
||||
},
|
||||
currentCoverSrc() {
|
||||
if (this.streamEpisode?.coverPath) {
|
||||
return `${this.$store.state.routerBasePath}/api/podcasts/${this.libraryItemId}/episode/${this.streamEpisode.id}/cover?ts=${this.streamEpisode.updatedAt}`
|
||||
}
|
||||
return null
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
|
@ -397,7 +403,7 @@ export default {
|
|||
album: this.mediaMetadata.seriesName || '',
|
||||
artwork: [
|
||||
{
|
||||
src: this.$store.getters['globals/getLibraryItemCoverSrc'](this.streamLibraryItem, '/Logo.png', true)
|
||||
src: this.currentCoverSrc || this.$store.getters['globals/getLibraryItemCoverSrc'](this.streamLibraryItem, '/Logo.png', true)
|
||||
}
|
||||
],
|
||||
chapterInfo
|
||||
|
|
|
|||
|
|
@ -230,6 +230,9 @@ export default {
|
|||
return this.store.getters['globals/getPlaceholderCoverSrc']
|
||||
},
|
||||
bookCoverSrc() {
|
||||
if (this.recentEpisode?.coverPath) {
|
||||
return `${this.store.state.routerBasePath}/api/podcasts/${this.libraryItemId}/episode/${this.recentEpisode.id}/cover?ts=${this.recentEpisode.updatedAt}`
|
||||
}
|
||||
return this.store.getters['globals/getLibraryItemCoverSrc'](this._libraryItem, this.placeholderUrl)
|
||||
},
|
||||
libraryItemId() {
|
||||
|
|
@ -872,7 +875,7 @@ export default {
|
|||
subtitle: this.mediaMetadata.title,
|
||||
caption: this.recentEpisode.publishedAt ? this.$getString('LabelPublishedDate', [this.$formatDate(this.recentEpisode.publishedAt, this.dateFormat)]) : this.$strings.LabelUnknownPublishDate,
|
||||
duration: this.recentEpisode.audioFile.duration || null,
|
||||
coverPath: this.media.coverPath || null
|
||||
coverPath: this.recentEpisode.coverPath || this.media.coverPath || null
|
||||
}
|
||||
} else {
|
||||
queueItem = {
|
||||
|
|
@ -1032,7 +1035,7 @@ export default {
|
|||
subtitle: this.mediaMetadata.title,
|
||||
caption: episode.publishedAt ? this.$getString('LabelPublishedDate', [this.$formatDate(episode.publishedAt, this.dateFormat)]) : this.$strings.LabelUnknownPublishDate,
|
||||
duration: episode.audioFile.duration || null,
|
||||
coverPath: this.media.coverPath || null
|
||||
coverPath: episode.coverPath || this.media.coverPath || null
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,7 +45,11 @@ export default {
|
|||
default: 120
|
||||
},
|
||||
expandOnClick: Boolean,
|
||||
bookCoverAspectRatio: Number
|
||||
bookCoverAspectRatio: Number,
|
||||
coverSrc: {
|
||||
type: String,
|
||||
default: null
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
|
@ -100,6 +104,7 @@ export default {
|
|||
return store.getters['globals/getPlaceholderCoverSrc']
|
||||
},
|
||||
fullCoverUrl() {
|
||||
if (this.coverSrc) return this.coverSrc
|
||||
if (!this.libraryItem) return null
|
||||
const store = this.$store || this.$nuxt.$store
|
||||
return store.getters['globals/getLibraryItemCoverSrc'](this.libraryItem, this.placeholderUrl)
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
<div ref="wrapper" class="p-4 w-full text-sm rounded-lg bg-bg shadow-lg border border-black-300 relative overflow-y-auto" style="max-height: 80vh">
|
||||
<div class="flex mb-4">
|
||||
<div class="w-12 h-12">
|
||||
<covers-book-cover :library-item="libraryItem" :width="48" :book-cover-aspect-ratio="bookCoverAspectRatio" />
|
||||
<covers-book-cover :library-item="libraryItem" :width="48" :book-cover-aspect-ratio="bookCoverAspectRatio" :cover-src="episodeCoverSrc" />
|
||||
</div>
|
||||
<div class="grow px-2">
|
||||
<p class="text-base mb-1">{{ podcastTitle }}</p>
|
||||
|
|
@ -102,6 +102,12 @@ export default {
|
|||
},
|
||||
bookCoverAspectRatio() {
|
||||
return this.$store.getters['libraries/getBookCoverAspectRatio']
|
||||
},
|
||||
episodeCoverSrc() {
|
||||
if (this.episode?.coverPath) {
|
||||
return `${this.$store.state.routerBasePath}/api/podcasts/${this.libraryItem.id}/episode/${this.episode.id}/cover?ts=${this.episode.updatedAt}`
|
||||
}
|
||||
return null
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
|
|
|||
|
|
@ -8,11 +8,11 @@
|
|||
<p v-if="!recentEpisodes.length && !processing" class="text-center text-xl">{{ $strings.MessageNoEpisodes }}</p>
|
||||
<template v-for="(episode, index) in episodesMapped">
|
||||
<div :key="episode.id" class="flex py-5 cursor-pointer relative" @click.stop="clickEpisode(episode)">
|
||||
<covers-preview-cover :src="$store.getters['globals/getLibraryItemCoverSrcById'](episode.libraryItemId, episode.updatedAt)" :width="96" :book-cover-aspect-ratio="bookCoverAspectRatio" :show-resolution="false" class="hidden md:block" />
|
||||
<covers-preview-cover :src="getEpisodeCoverSrc(episode)" :width="96" :book-cover-aspect-ratio="bookCoverAspectRatio" :show-resolution="false" class="hidden md:block" />
|
||||
<div class="grow pl-4 max-w-2xl">
|
||||
<!-- mobile -->
|
||||
<div class="flex md:hidden mb-2">
|
||||
<covers-preview-cover :src="$store.getters['globals/getLibraryItemCoverSrcById'](episode.libraryItemId, episode.updatedAt)" :width="48" :book-cover-aspect-ratio="bookCoverAspectRatio" :show-resolution="false" class="md:hidden" />
|
||||
<covers-preview-cover :src="getEpisodeCoverSrc(episode)" :width="48" :book-cover-aspect-ratio="bookCoverAspectRatio" :show-resolution="false" class="md:hidden" />
|
||||
<div class="grow px-2">
|
||||
<div class="flex items-center">
|
||||
<div class="flex" @click.stop>
|
||||
|
|
@ -145,6 +145,13 @@ export default {
|
|||
}
|
||||
},
|
||||
methods: {
|
||||
getEpisodeCoverSrc(episode) {
|
||||
if (episode.coverPath) {
|
||||
return `${this.$store.state.routerBasePath}/api/podcasts/${episode.libraryItemId}/episode/${episode.id}/cover?ts=${episode.updatedAt}`
|
||||
}
|
||||
// Fallback to podcast cover
|
||||
return this.$store.getters['globals/getLibraryItemCoverSrcById'](episode.libraryItemId, episode.updatedAt)
|
||||
},
|
||||
async toggleEpisodeFinished(episode, confirmed = false) {
|
||||
if (this.episodesProcessingMap[episode.id]) {
|
||||
console.warn('Episode is already processing')
|
||||
|
|
@ -236,7 +243,7 @@ export default {
|
|||
subtitle: episode.podcast.metadata.title,
|
||||
caption: episode.publishedAt ? this.$getString('LabelPublishedDate', [this.$formatDate(episode.publishedAt, this.dateFormat)]) : this.$strings.LabelUnknownPublishDate,
|
||||
duration: episode.duration || null,
|
||||
coverPath: episode.podcast.coverPath || null
|
||||
coverPath: episode.coverPath || episode.podcast.coverPath || null
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -273,7 +280,7 @@ export default {
|
|||
subtitle: episode.podcast.metadata.title,
|
||||
caption: episode.publishedAt ? this.$getString('LabelPublishedDate', [this.$formatDate(episode.publishedAt, this.dateFormat)]) : this.$strings.LabelUnknownPublishDate,
|
||||
duration: episode.duration || null,
|
||||
coverPath: episode.podcast.coverPath || null
|
||||
coverPath: episode.coverPath || episode.podcast.coverPath || null
|
||||
}
|
||||
this.$store.commit('addItemToQueue', queueItem)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue