mirror of
				https://github.com/advplyr/audiobookshelf.git
				synced 2025-10-27 11:18:14 +01:00 
			
		
		
		
	Show current episode download on init and download queue page updates
This commit is contained in:
		
							parent
							
								
									61c759e0c4
								
							
						
					
					
						commit
						022bf9d0ef
					
				| @ -10,7 +10,7 @@ | |||||||
|       <div class="w-full"> |       <div class="w-full"> | ||||||
|         <table class="text-sm tracksTable"> |         <table class="text-sm tracksTable"> | ||||||
|           <tr> |           <tr> | ||||||
|             <th class="text-left px-4">{{ $strings.LabelPodcast }}</th> |             <th class="text-left px-4 min-w-48">{{ $strings.LabelPodcast }}</th> | ||||||
|             <th class="text-left w-32 min-w-32">{{ $strings.LabelEpisode }}</th> |             <th class="text-left w-32 min-w-32">{{ $strings.LabelEpisode }}</th> | ||||||
|             <th class="text-left px-4">{{ $strings.LabelEpisodeTitle }}</th> |             <th class="text-left px-4">{{ $strings.LabelEpisodeTitle }}</th> | ||||||
|             <th class="text-left px-4 w-48">{{ $strings.LabelPubDate }}</th> |             <th class="text-left px-4 w-48">{{ $strings.LabelPubDate }}</th> | ||||||
| @ -58,11 +58,8 @@ export default { | |||||||
|   data() { |   data() { | ||||||
|     return {} |     return {} | ||||||
|   }, |   }, | ||||||
|   computed: { |   computed: {}, | ||||||
|   }, |   methods: {}, | ||||||
|   methods: { |   mounted() {} | ||||||
|   }, |  | ||||||
|   mounted() { |  | ||||||
|   } |  | ||||||
| } | } | ||||||
| </script> | </script> | ||||||
|  | |||||||
| @ -14,8 +14,8 @@ | |||||||
|             <template v-if="tasksRunningOrFailed.length"> |             <template v-if="tasksRunningOrFailed.length"> | ||||||
|               <p class="uppercase text-xs text-gray-400 my-1 px-1 font-semibold">{{ $strings.LabelTasks }}</p> |               <p class="uppercase text-xs text-gray-400 my-1 px-1 font-semibold">{{ $strings.LabelTasks }}</p> | ||||||
|               <template v-for="task in tasksRunningOrFailed"> |               <template v-for="task in tasksRunningOrFailed"> | ||||||
|                 <nuxt-link v-if="actionLink(task)" :to="actionLink(task)"> |                 <nuxt-link :key="task.id" v-if="actionLink(task)" :to="actionLink(task)"> | ||||||
|                   <li :key="task.id" class="text-gray-50 select-none relative hover:bg-black-400 py-1 cursor-pointer"> |                   <li class="text-gray-50 select-none relative hover:bg-black-400 py-1 cursor-pointer"> | ||||||
|                     <cards-item-task-running-card :task="task" /> |                     <cards-item-task-running-card :task="task" /> | ||||||
|                   </li> |                   </li> | ||||||
|                 </nuxt-link> |                 </nuxt-link> | ||||||
|  | |||||||
| @ -319,7 +319,7 @@ export default { | |||||||
|       return this.libraryItem.isInvalid |       return this.libraryItem.isInvalid | ||||||
|     }, |     }, | ||||||
|     isExplicit() { |     isExplicit() { | ||||||
|       return this.mediaMetadata.explicit || false; |       return this.mediaMetadata.explicit || false | ||||||
|     }, |     }, | ||||||
|     invalidAudioFiles() { |     invalidAudioFiles() { | ||||||
|       if (!this.isBook) return [] |       if (!this.isBook) return [] | ||||||
| @ -759,9 +759,8 @@ export default { | |||||||
|     } |     } | ||||||
|   }, |   }, | ||||||
|   mounted() { |   mounted() { | ||||||
|     if (this.libraryItem.episodesDownloading) { |     this.episodeDownloadsQueued = this.libraryItem.episodeDownloadsQueued || [] | ||||||
|       this.episodeDownloadsQueued = this.libraryItem.episodesDownloading || [] |     this.episodesDownloading = this.libraryItem.episodesDownloading || [] | ||||||
|     } |  | ||||||
| 
 | 
 | ||||||
|     // use this items library id as the current |     // use this items library id as the current | ||||||
|     if (this.libraryId) { |     if (this.libraryId) { | ||||||
|  | |||||||
| @ -3,10 +3,9 @@ | |||||||
|     <app-book-shelf-toolbar page="podcast-search" /> |     <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"> |     <div id="bookshelf" class="w-full overflow-y-auto px-2 py-6 sm:px-4 md:p-12 relative"> | ||||||
| 
 |       <div class="w-full max-w-5xl mx-auto py-4"> | ||||||
|       <div class="w-full max-w-3xl mx-auto py-4"> |  | ||||||
|         <p class="text-xl mb-2 font-semibold px-4 md:px-0">{{ $strings.HeaderCurrentDownloads }}</p> |         <p class="text-xl mb-2 font-semibold px-4 md:px-0">{{ $strings.HeaderCurrentDownloads }}</p> | ||||||
|         <p v-if="!episodesDownloading.length" class="text-center text-xl">{{ $strings.MessageNoDownloadsInProgress }}</p> |         <p v-if="!episodesDownloading.length" class="text-lg py-4">{{ $strings.MessageNoDownloadsInProgress }}</p> | ||||||
|         <template v-for="episode in episodesDownloading"> |         <template v-for="episode in episodesDownloading"> | ||||||
|           <div :key="episode.id" class="flex py-5 relative"> |           <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" /> |             <covers-preview-cover :src="$store.getters['globals/getLibraryItemCoverSrcById'](episode.libraryItemId)" :width="96" :book-cover-aspect-ratio="bookCoverAspectRatio" :show-resolution="false" class="hidden md:block" /> | ||||||
| @ -46,17 +45,15 @@ | |||||||
|             </div> |             </div> | ||||||
|           </div> |           </div> | ||||||
|         </template> |         </template> | ||||||
|       </div> |  | ||||||
| 
 | 
 | ||||||
|       <tables-podcast-download-queue-table :queue="episodeDownloadsQueued"></tables-podcast-download-queue-table> |         <tables-podcast-download-queue-table v-if="episodeDownloadsQueued.length" :queue="episodeDownloadsQueued"></tables-podcast-download-queue-table> | ||||||
|  |       </div> | ||||||
|     </div> |     </div> | ||||||
|   </div> |   </div> | ||||||
| </template> | </template> | ||||||
| <script> |  | ||||||
| import DownloadQueueTable from "~/components/tables/podcast/DownloadQueueTable.vue"; |  | ||||||
| 
 | 
 | ||||||
|  | <script> | ||||||
| export default { | export default { | ||||||
|   components: {DownloadQueueTable}, |  | ||||||
|   async asyncData({ params, redirect }) { |   async asyncData({ params, redirect }) { | ||||||
|     if (!params.library) { |     if (!params.library) { | ||||||
|       console.error('No library...', params.library) |       console.error('No library...', params.library) | ||||||
| @ -70,7 +67,7 @@ export default { | |||||||
|     return { |     return { | ||||||
|       episodesDownloading: [], |       episodesDownloading: [], | ||||||
|       episodeDownloadsQueued: [], |       episodeDownloadsQueued: [], | ||||||
|       processing: false, |       processing: false | ||||||
|     } |     } | ||||||
|   }, |   }, | ||||||
|   computed: { |   computed: { | ||||||
| @ -99,35 +96,45 @@ export default { | |||||||
|         this.episodesDownloading = this.episodesDownloading.filter((d) => d.id !== episodeDownload.id) |         this.episodesDownloading = this.episodesDownloading.filter((d) => d.id !== episodeDownload.id) | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     downloadQueueUpdated(downloadQueue) { |     episodeDownloadQueueUpdated(downloadQueueDetails) { | ||||||
|       this.episodeDownloadsQueued = downloadQueue.filter((q) => q.libraryId == this.libraryId) |       this.episodeDownloadsQueued = downloadQueueDetails.queue.filter((q) => q.libraryId == this.libraryId) | ||||||
|     }, |     }, | ||||||
|     async loadInitialDownloadQueue() { |     async loadInitialDownloadQueue() { | ||||||
|       this.processing = true |       this.processing = true | ||||||
|       const queuePayload = await this.$axios.$get(`/api/libraries/${this.libraryId}/downloads`).catch((error) => { |       const queuePayload = await this.$axios.$get(`/api/libraries/${this.libraryId}/episode-downloads`).catch((error) => { | ||||||
|         console.error('Failed to get download queue', error) |         console.error('Failed to get download queue', error) | ||||||
|         this.$toast.error('Failed to get download queue') |         this.$toast.error('Failed to get download queue') | ||||||
|         return null |         return null | ||||||
|       }) |       }) | ||||||
|       this.processing = false |       this.processing = false | ||||||
|       this.episodeDownloadsQueued = queuePayload || [] |       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) | ||||||
|     } |     } | ||||||
|   }, |   }, | ||||||
|   mounted() { |   mounted() { | ||||||
|     if (this.libraryId) { |     if (this.libraryId) { | ||||||
|       this.$store.commit('libraries/setCurrentLibrary', this.libraryId) |       this.$store.commit('libraries/setCurrentLibrary', this.libraryId) | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|     this.loadInitialDownloadQueue() |     this.loadInitialDownloadQueue() | ||||||
|     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('download_queue_updated', this.downloadQueueUpdated) |  | ||||||
|   }, |   }, | ||||||
|   beforeDestroy() { |   beforeDestroy() { | ||||||
|     this.$root.socket.off('episode_download_queued', this.episodeDownloadQueued) |     this.$root.socket.off('episode_download_queued', this.episodeDownloadQueued) | ||||||
|     this.$root.socket.off('episode_download_started', this.episodeDownloadStarted) |     this.$root.socket.off('episode_download_started', this.episodeDownloadStarted) | ||||||
|     this.$root.socket.off('episode_download_finished', this.episodeDownloadFinished) |     this.$root.socket.off('episode_download_finished', this.episodeDownloadFinished) | ||||||
|     this.$root.socket.off('download_queue_updated', this.downloadQueueUpdated) |     this.$root.socket.off('episode_download_queue_updated', this.episodeDownloadQueueUpdated) | ||||||
|   } |   } | ||||||
| } | } | ||||||
| </script> | </script> | ||||||
|  | |||||||
| @ -15,7 +15,9 @@ | |||||||
|                 <covers-preview-cover :src="$store.getters['globals/getLibraryItemCoverSrcById'](episode.libraryItemId)" :width="48" :book-cover-aspect-ratio="bookCoverAspectRatio" :show-resolution="false" class="md:hidden" /> |                 <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-grow px-2"> | ||||||
|                   <div class="flex items-center"> |                   <div class="flex items-center"> | ||||||
|  |                     <div class="flex" @click.stop> | ||||||
|                       <nuxt-link :to="`/item/${episode.libraryItemId}`" class="text-sm text-gray-200 hover:underline">{{ episode.podcast.metadata.title }}</nuxt-link> |                       <nuxt-link :to="`/item/${episode.libraryItemId}`" class="text-sm text-gray-200 hover:underline">{{ episode.podcast.metadata.title }}</nuxt-link> | ||||||
|  |                     </div> | ||||||
|                     <widgets-explicit-indicator :explicit="episode.podcast.metadata.explicit" /> |                     <widgets-explicit-indicator :explicit="episode.podcast.metadata.explicit" /> | ||||||
|                   </div> |                   </div> | ||||||
|                   <p class="text-xs text-gray-300 mb-1">{{ $dateDistanceFromNow(episode.publishedAt) }}</p> |                   <p class="text-xs text-gray-300 mb-1">{{ $dateDistanceFromNow(episode.publishedAt) }}</p> | ||||||
| @ -24,7 +26,9 @@ | |||||||
|               <!-- desktop --> |               <!-- desktop --> | ||||||
|               <div class="hidden md:block"> |               <div class="hidden md:block"> | ||||||
|                 <div class="flex items-center"> |                 <div class="flex items-center"> | ||||||
|  |                   <div class="flex" @click.stop> | ||||||
|                     <nuxt-link :to="`/item/${episode.libraryItemId}`" class="text-sm text-gray-200 hover:underline">{{ episode.podcast.metadata.title }}</nuxt-link> |                     <nuxt-link :to="`/item/${episode.libraryItemId}`" class="text-sm text-gray-200 hover:underline">{{ episode.podcast.metadata.title }}</nuxt-link> | ||||||
|  |                   </div> | ||||||
|                   <widgets-explicit-indicator :explicit="episode.podcast.metadata.explicit" /> |                   <widgets-explicit-indicator :explicit="episode.podcast.metadata.explicit" /> | ||||||
|                 </div> |                 </div> | ||||||
|                 <p class="text-xs text-gray-300 mb-1">{{ $dateDistanceFromNow(episode.publishedAt) }}</p> |                 <p class="text-xs text-gray-300 mb-1">{{ $dateDistanceFromNow(episode.publishedAt) }}</p> | ||||||
|  | |||||||
| @ -82,11 +82,9 @@ class LibraryController { | |||||||
|     return res.json(req.library) |     return res.json(req.library) | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   async getDownloadQueue(req, res) { |   async getEpisodeDownloadQueue(req, res) { | ||||||
|     const library = req.library |     const libraryDownloadQueueDetails = this.podcastManager.getDownloadQueueDetails(req.library.id) | ||||||
| 
 |     return res.json(libraryDownloadQueueDetails) | ||||||
|     let queue = this.podcastManager.getDownloadQueueDetails().filter(q => q.libraryId === library.id) |  | ||||||
|     return res.json(queue) |  | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   async update(req, res) { |   async update(req, res) { | ||||||
|  | |||||||
| @ -36,8 +36,11 @@ class LibraryItemController { | |||||||
|           }).filter(au => au) |           }).filter(au => au) | ||||||
|         } |         } | ||||||
|       } else if (includeEntities.includes('downloads')) { |       } else if (includeEntities.includes('downloads')) { | ||||||
|         var downloadsInQueue = this.podcastManager.getEpisodeDownloadsInQueue(req.libraryItem.id) |         const downloadsInQueue = this.podcastManager.getEpisodeDownloadsInQueue(req.libraryItem.id) | ||||||
|         item.episodesDownloading = downloadsInQueue.map(d => d.toJSONForClient()) |         item.episodeDownloadsQueued = downloadsInQueue.map(d => d.toJSONForClient()) | ||||||
|  |         if (this.podcastManager.currentDownload?.libraryItemId === req.libraryItem.id) { | ||||||
|  |           item.episodesDownloading = [this.podcastManager.currentDownload.toJSONForClient()] | ||||||
|  |         } | ||||||
|       } |       } | ||||||
| 
 | 
 | ||||||
|       return res.json(item) |       return res.json(item) | ||||||
|  | |||||||
| @ -14,8 +14,7 @@ const LibraryFile = require('../objects/files/LibraryFile') | |||||||
| const PodcastEpisodeDownload = require('../objects/PodcastEpisodeDownload') | const PodcastEpisodeDownload = require('../objects/PodcastEpisodeDownload') | ||||||
| const PodcastEpisode = require('../objects/entities/PodcastEpisode') | const PodcastEpisode = require('../objects/entities/PodcastEpisode') | ||||||
| const AudioFile = require('../objects/files/AudioFile') | const AudioFile = require('../objects/files/AudioFile') | ||||||
| const Task = require("../objects/Task"); | const Task = require("../objects/Task") | ||||||
| const Path = require("path"); |  | ||||||
| 
 | 
 | ||||||
| class PodcastManager { | class PodcastManager { | ||||||
|   constructor(db, watcher, notificationManager, taskManager) { |   constructor(db, watcher, notificationManager, taskManager) { | ||||||
| @ -60,12 +59,12 @@ class PodcastManager { | |||||||
|       newPe.libraryItemId = libraryItem.id |       newPe.libraryItemId = libraryItem.id | ||||||
|       var newPeDl = new PodcastEpisodeDownload() |       var newPeDl = new PodcastEpisodeDownload() | ||||||
|       newPeDl.setData(newPe, libraryItem, isAutoDownload, libraryItem.libraryId) |       newPeDl.setData(newPe, libraryItem, isAutoDownload, libraryItem.libraryId) | ||||||
|       this.startPodcastEpisodeDownload(newPeDl, libraryItem) |       this.startPodcastEpisodeDownload(newPeDl) | ||||||
|     }) |     }) | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   async startPodcastEpisodeDownload(podcastEpisodeDownload, libraryItem) { |   async startPodcastEpisodeDownload(podcastEpisodeDownload) { | ||||||
|     SocketAuthority.emitter('download_queue_updated', this.getDownloadQueueDetails()) |     SocketAuthority.emitter('episode_download_queue_updated', this.getDownloadQueueDetails()) | ||||||
|     if (this.currentDownload) { |     if (this.currentDownload) { | ||||||
|       this.downloadQueue.push(podcastEpisodeDownload) |       this.downloadQueue.push(podcastEpisodeDownload) | ||||||
|       SocketAuthority.emitter('episode_download_queued', podcastEpisodeDownload.toJSONForClient()) |       SocketAuthority.emitter('episode_download_queued', podcastEpisodeDownload.toJSONForClient()) | ||||||
| @ -75,8 +74,8 @@ class PodcastManager { | |||||||
|     const task = new Task() |     const task = new Task() | ||||||
|     const taskDescription = `Downloading episode "${podcastEpisodeDownload.podcastEpisode.title}".` |     const taskDescription = `Downloading episode "${podcastEpisodeDownload.podcastEpisode.title}".` | ||||||
|     const taskData = { |     const taskData = { | ||||||
|       libraryId: libraryItem.libraryId, |       libraryId: podcastEpisodeDownload.libraryId, | ||||||
|       libraryItemId: libraryItem.id, |       libraryItemId: podcastEpisodeDownload.libraryItemId, | ||||||
|     } |     } | ||||||
|     task.setData('download-podcast-episode', 'Downloading Episode', taskDescription, taskData) |     task.setData('download-podcast-episode', 'Downloading Episode', taskDescription, taskData) | ||||||
|     this.taskManager.addTask(task) |     this.taskManager.addTask(task) | ||||||
| @ -94,7 +93,7 @@ class PodcastManager { | |||||||
|       await filePerms.setDefault(this.currentDownload.libraryItem.path) |       await filePerms.setDefault(this.currentDownload.libraryItem.path) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     var success = await downloadFile(this.currentDownload.url, this.currentDownload.targetPath).then(() => true).catch((error) => { |     let success = await downloadFile(this.currentDownload.url, this.currentDownload.targetPath).then(() => true).catch((error) => { | ||||||
|       Logger.error(`[PodcastManager] Podcast Episode download failed`, error) |       Logger.error(`[PodcastManager] Podcast Episode download failed`, error) | ||||||
|       return false |       return false | ||||||
|     }) |     }) | ||||||
| @ -117,12 +116,12 @@ class PodcastManager { | |||||||
|     this.taskManager.taskFinished(task) |     this.taskManager.taskFinished(task) | ||||||
| 
 | 
 | ||||||
|     SocketAuthority.emitter('episode_download_finished', this.currentDownload.toJSONForClient()) |     SocketAuthority.emitter('episode_download_finished', this.currentDownload.toJSONForClient()) | ||||||
|     SocketAuthority.emitter('download_queue_updated', this.getDownloadQueueDetails()) |     SocketAuthority.emitter('episode_download_queue_updated', this.getDownloadQueueDetails()) | ||||||
| 
 | 
 | ||||||
|     this.watcher.removeIgnoreDir(this.currentDownload.libraryItem.path) |     this.watcher.removeIgnoreDir(this.currentDownload.libraryItem.path) | ||||||
|     this.currentDownload = null |     this.currentDownload = null | ||||||
|     if (this.downloadQueue.length) { |     if (this.downloadQueue.length) { | ||||||
|       this.startPodcastEpisodeDownload(this.downloadQueue.shift(), libraryItem) |       this.startPodcastEpisodeDownload(this.downloadQueue.shift()) | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
| @ -349,21 +348,14 @@ class PodcastManager { | |||||||
|     } |     } | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   getDownloadQueueDetails() { |   getDownloadQueueDetails(libraryId = null) { | ||||||
|     return this.downloadQueue.map(item => { |     let _currentDownload = this.currentDownload | ||||||
|  |     if (libraryId && _currentDownload?.libraryId !== libraryId) _currentDownload = null | ||||||
|  | 
 | ||||||
|     return { |     return { | ||||||
|         id: item.id, |       currentDownload: _currentDownload?.toJSONForClient(), | ||||||
|         libraryId: item.libraryId || null, |       queue: this.downloadQueue.filter(item => !libraryId || item.libraryId === libraryId).map(item => item.toJSONForClient()) | ||||||
|         libraryItemId: item.libraryItemId || null, |  | ||||||
|         podcastTitle: item.libraryItem.media.metadata.title || null, |  | ||||||
|         podcastExplicit: item.libraryItem.media.metadata.explicit || false, |  | ||||||
|         episodeDisplayTitle: item.podcastEpisode.title || null, |  | ||||||
|         season: item.podcastEpisode.season || null, |  | ||||||
|         episode: item.podcastEpisode.episode || null, |  | ||||||
|         episodeType: item.podcastEpisode.episodeType || 'full', |  | ||||||
|         publishedAt: item.podcastEpisode.publishedAt || null |  | ||||||
|     } |     } | ||||||
|     }) |  | ||||||
|   } |   } | ||||||
| } | } | ||||||
| module.exports = PodcastManager | module.exports = PodcastManager | ||||||
|  | |||||||
| @ -11,7 +11,6 @@ class PodcastEpisodeDownload { | |||||||
|     this.libraryId = null |     this.libraryId = null | ||||||
| 
 | 
 | ||||||
|     this.isAutoDownload = false |     this.isAutoDownload = false | ||||||
|     this.isDownloading = false |  | ||||||
|     this.isFinished = false |     this.isFinished = false | ||||||
|     this.failed = false |     this.failed = false | ||||||
| 
 | 
 | ||||||
| @ -23,20 +22,21 @@ class PodcastEpisodeDownload { | |||||||
|   toJSONForClient() { |   toJSONForClient() { | ||||||
|     return { |     return { | ||||||
|       id: this.id, |       id: this.id, | ||||||
|       episodeDisplayTitle: this.podcastEpisode ? this.podcastEpisode.title : null, |       episodeDisplayTitle: this.podcastEpisode?.title ?? null, | ||||||
|       url: this.url, |       url: this.url, | ||||||
|       libraryItemId: this.libraryItem ? this.libraryItem.id : null, |       libraryItemId: this.libraryItem?.id || null, | ||||||
|       libraryId: this.libraryId || null, |       libraryId: this.libraryId || null, | ||||||
|       isDownloading: this.isDownloading, |  | ||||||
|       isFinished: this.isFinished, |       isFinished: this.isFinished, | ||||||
|       failed: this.failed, |       failed: this.failed, | ||||||
|       startedAt: this.startedAt, |       startedAt: this.startedAt, | ||||||
|       createdAt: this.createdAt, |       createdAt: this.createdAt, | ||||||
|       finishedAt: this.finishedAt, |       finishedAt: this.finishedAt, | ||||||
|       season: this.podcastEpisode ? this.podcastEpisode.season : null, |       podcastTitle: this.libraryItem?.media.metadata.title ?? null, | ||||||
|       episode: this.podcastEpisode ? this.podcastEpisode.episode : null, |       podcastExplicit: !!this.libraryItem?.media.metadata.explicit, | ||||||
|       episodeType: this.podcastEpisode ? this.podcastEpisode.episodeType : 'full', |       season: this.podcastEpisode?.season ?? null, | ||||||
|       publishedAt: this.podcastEpisode ? this.podcastEpisode.publishedAt : null |       episode: this.podcastEpisode?.episode ?? null, | ||||||
|  |       episodeType: this.podcastEpisode?.episodeType ?? 'full', | ||||||
|  |       publishedAt: this.podcastEpisode?.publishedAt ?? null | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -76,7 +76,7 @@ class ApiRouter { | |||||||
| 
 | 
 | ||||||
|     this.router.get('/libraries/:id/items', LibraryController.middleware.bind(this), LibraryController.getLibraryItems.bind(this)) |     this.router.get('/libraries/:id/items', LibraryController.middleware.bind(this), LibraryController.getLibraryItems.bind(this)) | ||||||
|     this.router.delete('/libraries/:id/issues', LibraryController.middleware.bind(this), LibraryController.removeLibraryItemsWithIssues.bind(this)) |     this.router.delete('/libraries/:id/issues', LibraryController.middleware.bind(this), LibraryController.removeLibraryItemsWithIssues.bind(this)) | ||||||
|     this.router.get('/libraries/:id/downloads', LibraryController.middleware.bind(this), LibraryController.getDownloadQueue.bind(this)) |     this.router.get('/libraries/:id/episode-downloads', LibraryController.middleware.bind(this), LibraryController.getEpisodeDownloadQueue.bind(this)) | ||||||
|     this.router.get('/libraries/:id/series', LibraryController.middleware.bind(this), LibraryController.getAllSeriesForLibrary.bind(this)) |     this.router.get('/libraries/:id/series', LibraryController.middleware.bind(this), LibraryController.getAllSeriesForLibrary.bind(this)) | ||||||
|     this.router.get('/libraries/:id/collections', LibraryController.middleware.bind(this), LibraryController.getCollectionsForLibrary.bind(this)) |     this.router.get('/libraries/:id/collections', LibraryController.middleware.bind(this), LibraryController.getCollectionsForLibrary.bind(this)) | ||||||
|     this.router.get('/libraries/:id/playlists', LibraryController.middleware.bind(this), LibraryController.getUserPlaylistsForLibrary.bind(this)) |     this.router.get('/libraries/:id/playlists', LibraryController.middleware.bind(this), LibraryController.getUserPlaylistsForLibrary.bind(this)) | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user