From 3357ccfaf341c77b62b61e9d5b944430b8885d12 Mon Sep 17 00:00:00 2001 From: advplyr Date: Sat, 12 Nov 2022 15:41:41 -0600 Subject: [PATCH] Add:Buttons to add/remove podcast episodes from player queue --- client/components/app/StreamContainer.vue | 4 +- client/components/cards/LazyBookCard.vue | 45 +++++++++++++++- .../modals/player/QueueItemsModal.vue | 6 +-- client/components/player/PlayerUi.vue | 2 +- .../tables/podcast/EpisodeTableRow.vue | 22 ++++++++ .../tables/podcast/EpisodesTable.vue | 16 +++++- .../pages/library/_library/podcast/latest.vue | 54 +++++++++++++++---- client/store/index.js | 25 +++++++++ client/strings/en-us.json | 2 + server/controllers/LibraryController.js | 1 + 10 files changed, 158 insertions(+), 19 deletions(-) diff --git a/client/components/app/StreamContainer.vue b/client/components/app/StreamContainer.vue index c719bb27..1b766990 100644 --- a/client/components/app/StreamContainer.vue +++ b/client/components/app/StreamContainer.vue @@ -159,8 +159,8 @@ export default { return i.libraryItemId === libraryItemId }) if (currentQueueIndex < 0) { - console.error('Media finished not found in queue', this.playerQueueItems) - return + console.error('Media finished not found in queue - using first in queue', this.playerQueueItems) + currentQueueIndex = -1 } if (currentQueueIndex === this.playerQueueItems.length - 1) { console.log('Finished last item in queue') diff --git a/client/components/cards/LazyBookCard.vue b/client/components/cards/LazyBookCard.vue index cd1fec77..1d41ca95 100644 --- a/client/components/cards/LazyBookCard.vue +++ b/client/components/cards/LazyBookCard.vue @@ -324,8 +324,18 @@ export default { if (this.recentEpisode) return false // Dont show podcast error on episode card return this.numInvalidAudioFiles || this.numMissingParts || this.isMissing || this.isInvalid }, + libraryItemIdStreaming() { + return this.store.getters['getLibraryItemIdStreaming'] + }, isStreaming() { - return this.store.getters['getlibraryItemIdStreaming'] === this.libraryItemId + return this.libraryItemIdStreaming === this.libraryItemId + }, + isQueued() { + const episodeId = this.recentEpisode ? this.recentEpisode.id : null + return this.store.getters['getIsMediaQueued'](this.libraryItemId, episodeId) + }, + isStreamingFromDifferentLibrary() { + return this.store.getters['getIsStreamingFromDifferentLibrary'] }, showReadButton() { return !this.isSelectionMode && !this.showPlayButton && this.hasEbook && (this.showExperimentalFeatures || this.enableEReader) @@ -408,6 +418,19 @@ export default { text: this.$strings.ButtonRemoveFromContinueListening }) } + if (this.libraryItemIdStreaming && !this.isStreamingFromDifferentLibrary) { + if (!this.isQueued) { + items.push({ + func: 'addToQueue', + text: this.$strings.ButtonQueueAddItem + }) + } else if (!this.isStreaming) { + items.push({ + func: 'removeFromQueue', + text: this.$strings.ButtonQueueRemoveItem + }) + } + } return items } @@ -666,6 +689,25 @@ export default { this.processing = false }) }, + addToQueue() { + if (this.recentEpisode) { + const queueItem = { + libraryItemId: this.libraryItemId, + libraryId: this.libraryId, + episodeId: this.recentEpisode.id, + title: this.recentEpisode.title, + subtitle: this.mediaMetadata.title, + caption: this.recentEpisode.publishedAt ? `Published ${this.$formatDate(this.recentEpisode.publishedAt, 'MMM do, yyyy')}` : 'Unknown publish date', + duration: this.recentEpisode.audioFile.duration || null, + coverPath: this.media.coverPath || null + } + this.store.commit('addItemToQueue', queueItem) + } + }, + removeFromQueue() { + const episodeId = this.recentEpisode ? this.recentEpisode.id : null + this.store.commit('removeItemFromQueue', { libraryItemId: this.libraryItemId, episodeId }) + }, openCollections() { this.store.commit('setSelectedLibraryItem', this.libraryItem) this.store.commit('globals/setShowCollectionsModal', true) @@ -761,6 +803,7 @@ export default { if (!podcastProgress || !podcastProgress.isFinished) { queueItems.push({ libraryItemId: this.libraryItemId, + libraryId: this.libraryId, episodeId: episode.id, title: episode.title, subtitle: this.mediaMetadata.title, diff --git a/client/components/modals/player/QueueItemsModal.vue b/client/components/modals/player/QueueItemsModal.vue index 0b336e2f..f391e114 100644 --- a/client/components/modals/player/QueueItemsModal.vue +++ b/client/components/modals/player/QueueItemsModal.vue @@ -59,11 +59,7 @@ export default { this.show = false }, removeItem(item) { - const updatedQueue = this.playerQueueItems.filter((i) => { - if (!i.episodeId) return i.libraryItemId !== item.libraryItemId - return i.libraryItemId !== item.libraryItemId || i.episodeId !== item.episodeId - }) - this.$store.commit('setPlayerQueueItems', updatedQueue) + this.$store.commit('removeItemFromQueue', item) } } } diff --git a/client/components/player/PlayerUi.vue b/client/components/player/PlayerUi.vue index 9d1c92f2..2f5775ef 100644 --- a/client/components/player/PlayerUi.vue +++ b/client/components/player/PlayerUi.vue @@ -29,7 +29,7 @@ diff --git a/client/components/tables/podcast/EpisodeTableRow.vue b/client/components/tables/podcast/EpisodeTableRow.vue index ca9c2663..b6b60866 100644 --- a/client/components/tables/podcast/EpisodeTableRow.vue +++ b/client/components/tables/podcast/EpisodeTableRow.vue @@ -20,6 +20,10 @@

{{ timeRemaining }}

+ + @@ -83,9 +87,18 @@ export default { duration() { return this.$secondsToTimestamp(this.episode.duration) }, + libraryItemIdStreaming() { + return this.$store.getters['getLibraryItemIdStreaming'] + }, + isStreamingFromDifferentLibrary() { + return this.$store.getters['getIsStreamingFromDifferentLibrary'] + }, isStreaming() { return this.$store.getters['getIsMediaStreaming'](this.libraryItemId, this.episode.id) }, + isQueued() { + return this.$store.getters['getIsMediaQueued'](this.libraryItemId, this.episode.id) + }, streamIsPlaying() { return this.$store.state.streamIsPlaying && this.isStreaming }, @@ -169,6 +182,15 @@ export default { }, removeClick() { this.$emit('remove', this.episode) + }, + queueBtnClick() { + if (this.isQueued) { + // Remove from queue + this.$store.commit('removeItemFromQueue', { libraryItemId: this.libraryItemId, episodeId: this.episode.id }) + } else { + // Add to queue + this.$emit('addToQueue', this.episode) + } } } } diff --git a/client/components/tables/podcast/EpisodesTable.vue b/client/components/tables/podcast/EpisodesTable.vue index 4e9c63dd..e99fa815 100644 --- a/client/components/tables/podcast/EpisodesTable.vue +++ b/client/components/tables/podcast/EpisodesTable.vue @@ -17,7 +17,7 @@

{{ $strings.MessageNoEpisodes }}

@@ -131,6 +131,19 @@ export default { } }, methods: { + addEpisodeToQueue(episode) { + const queueItem = { + libraryItemId: this.libraryItem.id, + libraryId: this.libraryItem.libraryId, + episodeId: episode.id, + title: episode.title, + subtitle: this.mediaMetadata.title, + caption: episode.publishedAt ? `Published ${this.$formatDate(episode.publishedAt, 'MMM do, yyyy')}` : 'Unknown publish date', + duration: episode.audioFile.duration || null, + coverPath: this.media.coverPath || null + } + this.$store.commit('addItemToQueue', queueItem) + }, toggleBatchFinished() { this.processing = true var newIsFinished = !this.selectedIsFinished @@ -189,6 +202,7 @@ export default { if (!podcastProgress || !podcastProgress.isFinished) { queueItems.push({ libraryItemId: this.libraryItem.id, + libraryId: this.libraryItem.libraryId, episodeId: episode.id, title: episode.title, subtitle: this.mediaMetadata.title, diff --git a/client/pages/library/_library/podcast/latest.vue b/client/pages/library/_library/podcast/latest.vue index f1de2094..071bb283 100644 --- a/client/pages/library/_library/podcast/latest.vue +++ b/client/pages/library/_library/podcast/latest.vue @@ -1,5 +1,5 @@