From 95e070a8971286499fcb102078ca86b0e636d338 Mon Sep 17 00:00:00 2001 From: advplyr Date: Thu, 11 Aug 2022 17:36:27 -0500 Subject: [PATCH] Add:Podcast item page play button to play next unfinished episode #139 --- components/app/AudioPlayerContainer.vue | 16 ++++-- components/tables/podcast/EpisodeRow.vue | 4 +- pages/item/_id.vue | 63 ++++++++++++++++++++---- 3 files changed, 69 insertions(+), 14 deletions(-) diff --git a/components/app/AudioPlayerContainer.vue b/components/app/AudioPlayerContainer.vue index 0516fd98..e7b7d282 100644 --- a/components/app/AudioPlayerContainer.vue +++ b/components/app/AudioPlayerContainer.vue @@ -32,7 +32,8 @@ export default { onMediaPlayerChangedListener: null, sleepInterval: null, currentEndOfChapterTime: 0, - serverLibraryItemId: null + serverLibraryItemId: null, + serverEpisodeId: null } }, watch: { @@ -173,15 +174,15 @@ export default { this.$toast.error(`Cannot cast locally downloaded media`) } else { // Change to server library item - this.playServerLibraryItemAndCast(this.serverLibraryItemId) + this.playServerLibraryItemAndCast(this.serverLibraryItemId, this.serverEpisodeId) } }, - playServerLibraryItemAndCast(libraryItemId) { + playServerLibraryItemAndCast(libraryItemId, episodeId) { var playbackRate = 1 if (this.$refs.audioPlayer) { playbackRate = this.$refs.audioPlayer.currentPlaybackRate || 1 } - AbsAudioPlayer.prepareLibraryItem({ libraryItemId, episodeId: null, playWhenReady: false, playbackRate }) + AbsAudioPlayer.prepareLibraryItem({ libraryItemId, episodeId, playWhenReady: false, playbackRate }) .then((data) => { if (data.error) { const errorMsg = data.error || 'Failed to play' @@ -203,6 +204,7 @@ export default { // When playing local library item and can also play this item from the server // then store the server library item id so it can be used if a cast is made var serverLibraryItemId = payload.serverLibraryItemId || null + var serverEpisodeId = payload.serverEpisodeId || null if (libraryItemId.startsWith('local') && this.$store.state.isCasting) { const { value } = await Dialog.confirm({ @@ -215,6 +217,7 @@ export default { } this.serverLibraryItemId = null + this.serverEpisodeId = null var playbackRate = 1 if (this.$refs.audioPlayer) { @@ -234,6 +237,11 @@ export default { } else { this.serverLibraryItemId = serverLibraryItemId } + if (episodeId && !episodeId.startsWith('local')) { + this.serverEpisodeId = episodeId + } else { + this.serverEpisodeId = serverEpisodeId + } } }) .catch((error) => { diff --git a/components/tables/podcast/EpisodeRow.vue b/components/tables/podcast/EpisodeRow.vue index 0110b1fd..d230670f 100644 --- a/components/tables/podcast/EpisodeRow.vue +++ b/components/tables/podcast/EpisodeRow.vue @@ -199,7 +199,9 @@ export default { this.$eventBus.$emit('play-item', { libraryItemId: this.localLibraryItemId, - episodeId: this.localEpisode.id + episodeId: this.localEpisode.id, + serverLibraryItemId: this.libraryItemId, + serverEpisodeId: this.episode.id }) } else { this.$eventBus.$emit('play-item', { diff --git a/pages/item/_id.vue b/pages/item/_id.vue index 87d0b00e..e2f66a62 100644 --- a/pages/item/_id.vue +++ b/pages/item/_id.vue @@ -85,7 +85,7 @@
play_arrow - {{ isPlaying ? (isStreaming ? 'Streaming' : 'Playing') : hasLocal ? 'Play' : 'Stream' }} + {{ isPlaying ? (isStreaming ? 'Streaming' : 'Playing') : isPodcast ? 'Next Episode' : hasLocal ? 'Play' : 'Stream' }} auto_stories @@ -305,13 +305,14 @@ export default { return this.libraryItem.isIncomplete }, showPlay() { - return !this.isMissing && !this.isIncomplete && this.numTracks + return !this.isMissing && !this.isIncomplete && (this.numTracks || this.episodes.length) }, showRead() { return this.ebookFile && this.ebookFormat !== 'pdf' }, showDownload() { if (this.isIos) return false + if (this.isPodcast) return false return this.user && this.userCanDownload && this.showPlay && !this.hasLocal }, ebookFile() { @@ -368,14 +369,58 @@ export default { this.$store.commit('openReader', this.libraryItem) }, playClick() { - // Todo: Allow playing local or streaming - if (this.hasLocal && this.serverLibraryItemId && this.isCasting) { - // If casting and connected to server for local library item then send server library item id - this.$eventBus.$emit('play-item', { libraryItemId: this.serverLibraryItemId }) - return + var episodeId = null + + if (this.isPodcast) { + this.episodes.sort((a, b) => { + return String(b.publishedAt).localeCompare(String(a.publishedAt), undefined, { numeric: true, sensitivity: 'base' }) + }) + + var episode = this.episodes.find((ep) => { + var podcastProgress = null + if (!this.isLocal) { + podcastProgress = this.$store.getters['user/getUserMediaProgress'](this.libraryItemId, ep.id) + } else { + podcastProgress = this.$store.getters['globals/getLocalMediaProgressById'](this.libraryItemId, ep.id) + } + return !podcastProgress || !podcastProgress.isFinished + }) + + if (!episode) episode = this.episodes[0] + + episodeId = episode.id + + var localEpisode = null + if (this.hasLocal && !this.isLocal) { + localEpisode = this.localLibraryItem.media.episodes.find((ep) => ep.serverEpisodeId == episodeId) + } else if (this.isLocal) { + localEpisode = episode + } + var serverEpisodeId = !this.isLocal ? episodeId : localEpisode ? localEpisode.serverEpisodeId : null + + if (serverEpisodeId && this.serverLibraryItemId && this.isCasting) { + // If casting and connected to server for local library item then send server library item id + this.$eventBus.$emit('play-item', { libraryItemId: this.serverLibraryItemId, episodeId: serverEpisodeId }) + return + } + if (localEpisode) { + this.$eventBus.$emit('play-item', { libraryItemId: this.localLibraryItem.id, episodeId: localEpisode.id, serverLibraryItemId: this.serverLibraryItemId, serverEpisodeId }) + return + } + } else { + // Audiobook + if (this.hasLocal && this.serverLibraryItemId && this.isCasting) { + // If casting and connected to server for local library item then send server library item id + this.$eventBus.$emit('play-item', { libraryItemId: this.serverLibraryItemId }) + return + } + if (this.hasLocal) { + this.$eventBus.$emit('play-item', { libraryItemId: this.localLibraryItem.id, serverLibraryItemId: this.serverLibraryItemId }) + return + } } - if (this.hasLocal) return this.$eventBus.$emit('play-item', { libraryItemId: this.localLibraryItem.id, serverLibraryItemId: this.serverLibraryItemId }) - this.$eventBus.$emit('play-item', { libraryItemId: this.libraryItemId }) + + this.$eventBus.$emit('play-item', { libraryItemId: this.libraryItemId, episodeId }) }, async clearProgressClick() { const { value } = await Dialog.confirm({