diff --git a/client/components/app/MediaPlayerContainer.vue b/client/components/app/MediaPlayerContainer.vue
index cbc76803..61508d7e 100644
--- a/client/components/app/MediaPlayerContainer.vue
+++ b/client/components/app/MediaPlayerContainer.vue
@@ -43,12 +43,14 @@
:sleep-timer-remaining="sleepTimerRemaining"
:sleep-timer-type="sleepTimerType"
:is-podcast="isPodcast"
+ :hasNextItemInQueue="hasNextItemInQueue"
@playPause="playPause"
@jumpForward="jumpForward"
@jumpBackward="jumpBackward"
@setVolume="setVolume"
@setPlaybackRate="setPlaybackRate"
@seek="seek"
+ @nextItemInQueue="playNextItemInQueue"
@close="closePlayer"
@showBookmarks="showBookmarks"
@showSleepTimer="showSleepTimerModal = true"
@@ -60,7 +62,7 @@
-
+
@@ -176,6 +178,16 @@ export default {
if (!this.isMusic) return null
return this.mediaMetadata.artists.join(', ')
},
+ hasNextItemInQueue() {
+ return this.currentPlayerQueueIndex < this.playerQueueItems.length - 1
+ },
+ currentPlayerQueueIndex() {
+ if (!this.libraryItemId) return -1
+ return this.playerQueueItems.findIndex((i) => {
+ if (this.streamEpisode?.id) return i.episodeId === this.streamEpisode.id
+ return i.libraryItemId === this.libraryItemId
+ })
+ },
playerQueueItems() {
return this.$store.state.playerQueueItems || []
}
@@ -460,6 +472,30 @@ export default {
this.playerHandler.switchPlayer()
}
},
+ playNextItemInQueue() {
+ if (this.hasNextItemInQueue) {
+ this.playQueueItem({ index: this.currentPlayerQueueIndex + 1 })
+ }
+ },
+ /**
+ * @param {{ index: number }} payload
+ */
+ playQueueItem(payload) {
+ if (payload?.index === undefined) {
+ console.error('playQueueItem: No index provided')
+ return
+ }
+ if (!this.playerQueueItems[payload.index]) {
+ console.error('playQueueItem: No item found at index', payload.index)
+ return
+ }
+ const item = this.playerQueueItems[payload.index]
+ this.playLibraryItem({
+ libraryItemId: item.libraryItemId,
+ episodeId: item.episodeId || null,
+ queueItems: this.playerQueueItems
+ })
+ },
async playLibraryItem(payload) {
const libraryItemId = payload.libraryItemId
const episodeId = payload.episodeId || null
@@ -512,6 +548,7 @@ export default {
this.$eventBus.$on('cast-session-active', this.castSessionActive)
this.$eventBus.$on('playback-seek', this.seek)
this.$eventBus.$on('playback-time-update', this.playbackTimeUpdate)
+ this.$eventBus.$on('play-queue-item', this.playQueueItem)
this.$eventBus.$on('play-item', this.playLibraryItem)
this.$eventBus.$on('pause-item', this.pauseItem)
},
@@ -519,6 +556,7 @@ export default {
this.$eventBus.$off('cast-session-active', this.castSessionActive)
this.$eventBus.$off('playback-seek', this.seek)
this.$eventBus.$off('playback-time-update', this.playbackTimeUpdate)
+ this.$eventBus.$off('play-queue-item', this.playQueueItem)
this.$eventBus.$off('play-item', this.playLibraryItem)
this.$eventBus.$off('pause-item', this.pauseItem)
}
diff --git a/client/components/modals/player/QueueItemsModal.vue b/client/components/modals/player/QueueItemsModal.vue
index d7893abd..1dad61d5 100644
--- a/client/components/modals/player/QueueItemsModal.vue
+++ b/client/components/modals/player/QueueItemsModal.vue
@@ -13,7 +13,7 @@
-
+
@@ -22,8 +22,7 @@
\ No newline at end of file
+
diff --git a/client/components/player/PlayerPlaybackControls.vue b/client/components/player/PlayerPlaybackControls.vue
index 1a92480b..39ce4f3c 100644
--- a/client/components/player/PlayerPlaybackControls.vue
+++ b/client/components/player/PlayerPlaybackControls.vue
@@ -20,8 +20,8 @@
forward_media
-
-
-
+
@@ -82,7 +82,8 @@ export default {
sleepTimerType: String,
isPodcast: Boolean,
hideBookmarks: Boolean,
- hideSleepTimer: Boolean
+ hideSleepTimer: Boolean,
+ hasNextItemInQueue: Boolean
},
data() {
return {
@@ -145,7 +146,7 @@ export default {
return Math.round((100 * time) / duration)
},
currentChapterName() {
- return this.currentChapter ? this.currentChapter.title : ''
+ return this.currentChapter?.title || ''
},
currentChapterDuration() {
if (!this.currentChapter) return 0
@@ -278,10 +279,13 @@ export default {
this.seek(this.currentChapter.start)
}
},
- nextChapter() {
- if (!this.currentChapter || !this.hasNextChapter) return
- var nextChapter = this.chapters[this.currentChapterIndex + 1]
- this.seek(nextChapter.start)
+ goToNext() {
+ if (this.hasNextChapter) {
+ const nextChapter = this.chapters[this.currentChapterIndex + 1]
+ this.seek(nextChapter.start)
+ } else if (this.hasNextItemInQueue) {
+ this.$emit('nextItemInQueue')
+ }
},
setStreamReady() {
if (this.$refs.trackbar) this.$refs.trackbar.setPercentageReady(1)
diff --git a/client/strings/en-us.json b/client/strings/en-us.json
index 84e31678..7420c1e7 100644
--- a/client/strings/en-us.json
+++ b/client/strings/en-us.json
@@ -46,6 +46,7 @@
"ButtonNevermind": "Nevermind",
"ButtonNext": "Next",
"ButtonNextChapter": "Next Chapter",
+ "ButtonNextItemInQueue": "Next Item in Queue",
"ButtonOk": "Ok",
"ButtonOpenFeed": "Open Feed",
"ButtonOpenManager": "Open Manager",