2023-02-27 03:56:07 +01:00
|
|
|
<template>
|
|
|
|
<div class="page" :class="streamLibraryItem ? 'streaming' : ''">
|
|
|
|
<app-book-shelf-toolbar page="podcast-search" />
|
|
|
|
|
|
|
|
<div id="bookshelf" class="w-full overflow-y-auto px-2 py-6 sm:px-4 md:p-12 relative">
|
2023-03-05 17:35:34 +01:00
|
|
|
<div class="w-full max-w-5xl mx-auto py-4">
|
2023-02-27 03:56:07 +01:00
|
|
|
<p class="text-xl mb-2 font-semibold px-4 md:px-0">{{ $strings.HeaderCurrentDownloads }}</p>
|
2023-03-05 17:35:34 +01:00
|
|
|
<p v-if="!episodesDownloading.length" class="text-lg py-4">{{ $strings.MessageNoDownloadsInProgress }}</p>
|
2023-02-27 03:56:07 +01:00
|
|
|
<template v-for="episode in episodesDownloading">
|
|
|
|
<div :key="episode.id" class="flex py-5 relative">
|
|
|
|
<covers-preview-cover :src="$store.getters['globals/getLibraryItemCoverSrcById'](episode.libraryItemId)" :width="96" :book-cover-aspect-ratio="bookCoverAspectRatio" :show-resolution="false" class="hidden md:block" />
|
|
|
|
<div class="flex-grow pl-4 max-w-2xl">
|
|
|
|
<!-- mobile -->
|
|
|
|
<div class="flex md:hidden mb-2">
|
|
|
|
<covers-preview-cover :src="$store.getters['globals/getLibraryItemCoverSrcById'](episode.libraryItemId)" :width="48" :book-cover-aspect-ratio="bookCoverAspectRatio" :show-resolution="false" class="md:hidden" />
|
|
|
|
<div class="flex-grow px-2">
|
|
|
|
<div class="flex items-center">
|
|
|
|
<nuxt-link :to="`/item/${episode.libraryItemId}`" class="text-sm text-gray-200 hover:underline">{{ episode.podcastTitle }}</nuxt-link>
|
2024-05-12 20:35:03 +02:00
|
|
|
<widgets-explicit-indicator v-if="episode.podcastExplicit" />
|
2023-02-27 03:56:07 +01:00
|
|
|
</div>
|
|
|
|
<p class="text-xs text-gray-300 mb-1">{{ $dateDistanceFromNow(episode.publishedAt) }}</p>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<!-- desktop -->
|
|
|
|
<div class="hidden md:block">
|
|
|
|
<div class="flex items-center">
|
|
|
|
<nuxt-link :to="`/item/${episode.libraryItemId}`" class="text-sm text-gray-200 hover:underline">{{ episode.podcastTitle }}</nuxt-link>
|
2024-05-12 20:35:03 +02:00
|
|
|
<widgets-explicit-indicator v-if="episode.podcastExplicit" />
|
2023-02-27 03:56:07 +01:00
|
|
|
</div>
|
|
|
|
<p class="text-xs text-gray-300 mb-1">{{ $dateDistanceFromNow(episode.publishedAt) }}</p>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div class="flex items-center font-semibold text-gray-200">
|
|
|
|
<div v-if="episode.season || episode.episode">#</div>
|
|
|
|
<div v-if="episode.season">{{ episode.season }}x</div>
|
|
|
|
<div v-if="episode.episode">{{ episode.episode }}</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div class="flex items-center mb-2">
|
|
|
|
<span class="font-semibold text-sm md:text-base">{{ episode.episodeDisplayTitle }}</span>
|
|
|
|
<widgets-podcast-type-indicator :type="episode.episodeType" />
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<p class="text-sm text-gray-200 mb-4">{{ episode.subtitle }}</p>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</template>
|
|
|
|
|
2023-03-05 17:35:34 +01:00
|
|
|
<tables-podcast-download-queue-table v-if="episodeDownloadsQueued.length" :queue="episodeDownloadsQueued"></tables-podcast-download-queue-table>
|
|
|
|
</div>
|
2023-02-27 03:56:07 +01:00
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</template>
|
|
|
|
|
2023-03-05 17:35:34 +01:00
|
|
|
<script>
|
2023-02-27 03:56:07 +01:00
|
|
|
export default {
|
2024-07-30 23:35:26 +02:00
|
|
|
async asyncData({ params, redirect, store }) {
|
|
|
|
var libraryId = params.library
|
|
|
|
var libraryData = await store.dispatch('libraries/fetch', libraryId)
|
|
|
|
if (!libraryData) {
|
|
|
|
return redirect('/oops?message=Library not found')
|
2023-03-05 12:15:36 +01:00
|
|
|
}
|
2024-07-30 23:35:26 +02:00
|
|
|
|
|
|
|
// Redirect book libraries
|
|
|
|
const library = libraryData.library
|
|
|
|
if (library.mediaType === 'book') {
|
|
|
|
return redirect(`/library/${libraryId}`)
|
|
|
|
}
|
|
|
|
|
2023-03-05 12:15:36 +01:00
|
|
|
return {
|
|
|
|
libraryId: params.library
|
|
|
|
}
|
|
|
|
},
|
2023-02-27 03:56:07 +01:00
|
|
|
data() {
|
|
|
|
return {
|
|
|
|
episodesDownloading: [],
|
|
|
|
episodeDownloadsQueued: [],
|
2023-03-05 17:35:34 +01:00
|
|
|
processing: false
|
2023-02-27 03:56:07 +01:00
|
|
|
}
|
|
|
|
},
|
|
|
|
computed: {
|
|
|
|
bookCoverAspectRatio() {
|
|
|
|
return this.$store.getters['libraries/getBookCoverAspectRatio']
|
|
|
|
},
|
|
|
|
streamLibraryItem() {
|
|
|
|
return this.$store.state.streamLibraryItem
|
|
|
|
}
|
|
|
|
},
|
|
|
|
methods: {
|
|
|
|
episodeDownloadQueued(episodeDownload) {
|
2023-03-05 12:15:36 +01:00
|
|
|
if (episodeDownload.libraryId === this.libraryId) {
|
2023-02-27 03:56:07 +01:00
|
|
|
this.episodeDownloadsQueued.push(episodeDownload)
|
|
|
|
}
|
|
|
|
},
|
|
|
|
episodeDownloadStarted(episodeDownload) {
|
2023-03-05 12:15:36 +01:00
|
|
|
if (episodeDownload.libraryId === this.libraryId) {
|
2023-02-27 03:56:07 +01:00
|
|
|
this.episodeDownloadsQueued = this.episodeDownloadsQueued.filter((d) => d.id !== episodeDownload.id)
|
|
|
|
this.episodesDownloading.push(episodeDownload)
|
|
|
|
}
|
|
|
|
},
|
|
|
|
episodeDownloadFinished(episodeDownload) {
|
2023-03-05 12:15:36 +01:00
|
|
|
if (episodeDownload.libraryId === this.libraryId) {
|
2023-02-27 03:56:07 +01:00
|
|
|
this.episodeDownloadsQueued = this.episodeDownloadsQueued.filter((d) => d.id !== episodeDownload.id)
|
|
|
|
this.episodesDownloading = this.episodesDownloading.filter((d) => d.id !== episodeDownload.id)
|
|
|
|
}
|
|
|
|
},
|
2023-03-05 17:35:34 +01:00
|
|
|
episodeDownloadQueueUpdated(downloadQueueDetails) {
|
|
|
|
this.episodeDownloadsQueued = downloadQueueDetails.queue.filter((q) => q.libraryId == this.libraryId)
|
2023-02-27 03:56:07 +01:00
|
|
|
},
|
|
|
|
async loadInitialDownloadQueue() {
|
|
|
|
this.processing = true
|
2023-03-05 17:35:34 +01:00
|
|
|
const queuePayload = await this.$axios.$get(`/api/libraries/${this.libraryId}/episode-downloads`).catch((error) => {
|
2023-02-27 03:56:07 +01:00
|
|
|
console.error('Failed to get download queue', error)
|
2024-08-31 00:47:49 +02:00
|
|
|
this.$toast.error(this.$strings.ToastFailedToLoadData)
|
2023-02-27 03:56:07 +01:00
|
|
|
return null
|
|
|
|
})
|
|
|
|
this.processing = false
|
2023-03-05 17:35:34 +01:00
|
|
|
this.episodeDownloadsQueued = queuePayload?.queue || []
|
|
|
|
|
|
|
|
if (queuePayload?.currentDownload) {
|
|
|
|
this.episodesDownloading.push(queuePayload.currentDownload)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Initialize listeners after load to prevent event race conditions
|
|
|
|
this.initListeners()
|
|
|
|
},
|
|
|
|
initListeners() {
|
|
|
|
this.$root.socket.on('episode_download_queued', this.episodeDownloadQueued)
|
|
|
|
this.$root.socket.on('episode_download_started', this.episodeDownloadStarted)
|
|
|
|
this.$root.socket.on('episode_download_finished', this.episodeDownloadFinished)
|
|
|
|
this.$root.socket.on('episode_download_queue_updated', this.episodeDownloadQueueUpdated)
|
2023-02-27 03:56:07 +01:00
|
|
|
}
|
|
|
|
},
|
|
|
|
mounted() {
|
|
|
|
this.loadInitialDownloadQueue()
|
|
|
|
},
|
|
|
|
beforeDestroy() {
|
|
|
|
this.$root.socket.off('episode_download_queued', this.episodeDownloadQueued)
|
|
|
|
this.$root.socket.off('episode_download_started', this.episodeDownloadStarted)
|
|
|
|
this.$root.socket.off('episode_download_finished', this.episodeDownloadFinished)
|
2023-03-05 17:35:34 +01:00
|
|
|
this.$root.socket.off('episode_download_queue_updated', this.episodeDownloadQueueUpdated)
|
2023-02-27 03:56:07 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
</script>
|