From 0f01f21a0a47848926db465d8ad51d987ba9069b Mon Sep 17 00:00:00 2001 From: advplyr Date: Sat, 20 Aug 2022 14:21:58 -0500 Subject: [PATCH 01/38] Update:Remove auto download checkbox from edit podcast details tab, move max episodes to keep input to the schedule tab --- .../components/modals/item/tabs/Schedule.vue | 79 ++++++++++++++----- client/components/ui/Checkbox.vue | 4 + .../components/widgets/PodcastDetailsEdit.vue | 27 ------- client/tailwind.config.js | 5 +- 4 files changed, 67 insertions(+), 48 deletions(-) diff --git a/client/components/modals/item/tabs/Schedule.vue b/client/components/modals/item/tabs/Schedule.vue index e77425e4e..16de35b55 100644 --- a/client/components/modals/item/tabs/Schedule.vue +++ b/client/components/modals/item/tabs/Schedule.vue @@ -1,14 +1,30 @@ @@ -83,8 +67,6 @@ export default { explicit: false, language: null }, - autoDownloadEpisodes: false, - maxEpisodesToKeep: 0, newTags: [] } }, @@ -209,13 +191,6 @@ export default { updatePayload.tags = [...this.newTags] } - if (this.media.autoDownloadEpisodes !== this.autoDownloadEpisodes) { - updatePayload.autoDownloadEpisodes = !!this.autoDownloadEpisodes - } - if (this.autoDownloadEpisodes && !isNaN(this.maxEpisodesToKeep) && Number(this.maxEpisodesToKeep) != this.media.maxEpisodesToKeep) { - updatePayload.maxEpisodesToKeep = Number(this.maxEpisodesToKeep) - } - return { updatePayload, hasChanges: !!Object.keys(updatePayload).length @@ -235,8 +210,6 @@ export default { this.details.language = this.mediaMetadata.language || '' this.details.explicit = !!this.mediaMetadata.explicit - this.autoDownloadEpisodes = !!this.media.autoDownloadEpisodes - this.maxEpisodesToKeep = this.media.maxEpisodesToKeep || 0 this.newTags = [...(this.media.tags || [])] }, submitForm() { diff --git a/client/tailwind.config.js b/client/tailwind.config.js index cde080f3c..b5426856f 100644 --- a/client/tailwind.config.js +++ b/client/tailwind.config.js @@ -15,7 +15,10 @@ module.exports = { 'py-1.5', 'bg-info', 'px-1.5', - 'min-w-5' + 'min-w-5', + 'w-3.5', + 'h-3.5', + 'border-warning' ], }, theme: { From 4ec217e5d05bb685257f1a0fdf9a012c65d31280 Mon Sep 17 00:00:00 2001 From: advplyr Date: Sat, 20 Aug 2022 14:32:38 -0500 Subject: [PATCH 02/38] Fix:App bar for mobile screen, UI updates for schedule tabs --- client/components/app/Appbar.vue | 6 +++--- client/components/modals/item/tabs/Schedule.vue | 4 ++-- client/components/modals/libraries/EditModal.vue | 2 +- client/components/modals/libraries/ScheduleScan.vue | 4 ++-- client/components/ui/LibrariesDropdown.vue | 2 +- client/tailwind.config.js | 1 + 6 files changed, 10 insertions(+), 9 deletions(-) diff --git a/client/components/app/Appbar.vue b/client/components/app/Appbar.vue index 0d63eccce..4b0d923cc 100644 --- a/client/components/app/Appbar.vue +++ b/client/components/app/Appbar.vue @@ -3,7 +3,7 @@
- + @@ -12,10 +12,10 @@ - +
- logo_dev + logo_dev cast diff --git a/client/components/modals/item/tabs/Schedule.vue b/client/components/modals/item/tabs/Schedule.vue index 16de35b55..b1aa2cdcd 100644 --- a/client/components/modals/item/tabs/Schedule.vue +++ b/client/components/modals/item/tabs/Schedule.vue @@ -6,8 +6,8 @@ @@ -31,7 +31,11 @@ export default { default: 120 }, showOpenNewTab: Boolean, - bookCoverAspectRatio: Number + bookCoverAspectRatio: Number, + showResolution: { + type: Boolean, + default: true + } }, data() { return { diff --git a/client/components/modals/player/QueueItemRow.vue b/client/components/modals/player/QueueItemRow.vue new file mode 100644 index 000000000..aa710df7f --- /dev/null +++ b/client/components/modals/player/QueueItemRow.vue @@ -0,0 +1,98 @@ + + + + + \ No newline at end of file diff --git a/client/components/modals/player/QueueItemsModal.vue b/client/components/modals/player/QueueItemsModal.vue new file mode 100644 index 000000000..b4ee5aeff --- /dev/null +++ b/client/components/modals/player/QueueItemsModal.vue @@ -0,0 +1,56 @@ + + + \ No newline at end of file diff --git a/client/components/player/PlayerUi.vue b/client/components/player/PlayerUi.vue index c23c9f9f2..83189fa4b 100644 --- a/client/components/player/PlayerUi.vue +++ b/client/components/player/PlayerUi.vue @@ -27,6 +27,10 @@ timelapse
+ +
@@ -138,6 +142,9 @@ export default { hasNextChapter() { if (!this.chapters.length) return false return this.currentChapterIndex < this.chapters.length - 1 + }, + playerQueueItems() { + return this.$store.state.playerQueueItems || [] } }, methods: { diff --git a/client/components/tables/podcast/EpisodeTableRow.vue b/client/components/tables/podcast/EpisodeTableRow.vue index 315099544..74f6c847d 100644 --- a/client/components/tables/podcast/EpisodeTableRow.vue +++ b/client/components/tables/podcast/EpisodeTableRow.vue @@ -133,10 +133,7 @@ export default { if (this.streamIsPlaying) { this.$eventBus.$emit('pause-item') } else { - this.$eventBus.$emit('play-item', { - libraryItemId: this.libraryItemId, - episodeId: this.episode.id - }) + this.$emit('play', this.episode) } }, toggleFinished(confirmed = false) { diff --git a/client/components/tables/podcast/EpisodesTable.vue b/client/components/tables/podcast/EpisodesTable.vue index 8e402ae0e..26452313f 100644 --- a/client/components/tables/podcast/EpisodesTable.vue +++ b/client/components/tables/podcast/EpisodesTable.vue @@ -11,7 +11,7 @@

No Episodes

@@ -91,6 +91,28 @@ export default { this.selectedEpisodes = this.selectedEpisodes.filter((ep) => ep.id !== episode.id) } }, + playEpisode(episode) { + const queueItems = [] + const episodeIndex = this.episodes.findIndex((e) => e.id === episode.id) + for (let i = episodeIndex; i < this.episodes.length; i++) { + const episode = this.episodes[i] + const audioFile = episode.audioFile + queueItems.push({ + libraryItemId: this.libraryItem.id, + episodeId: episode.id, + title: episode.title, + subtitle: this.mediaMetadata.title, + duration: audioFile.duration || null, + coverPath: this.media.coverPath || null + }) + } + + this.$eventBus.$emit('play-item', { + libraryItemId: this.libraryItem.id, + episodeId: episode.id, + queueItems + }) + }, removeEpisode(episode) { this.episodesToRemove = [episode] this.showPodcastRemoveModal = true diff --git a/client/pages/item/_id/index.vue b/client/pages/item/_id/index.vue index 5b711ad88..fe4e6f015 100644 --- a/client/pages/item/_id/index.vue +++ b/client/pages/item/_id/index.vue @@ -12,7 +12,7 @@
-
+
play_circle_filled
@@ -128,7 +128,7 @@
- + play_arrow {{ isStreaming ? 'Playing' : 'Play' }} @@ -429,14 +429,14 @@ export default { message: `Start playback for "${this.title}" at ${this.$secondsToTimestamp(bookmark.time)}?`, callback: (confirmed) => { if (confirmed) { - this.startStream(bookmark.time) + this.playItem(bookmark.time) } }, type: 'yesNo' } this.$store.commit('globals/setConfirmPrompt', payload) } else { - this.startStream(bookmark.time) + this.playItem(bookmark.time) } this.showBookmarksModal = false }, @@ -515,21 +515,37 @@ export default { this.$toast.error(`Failed to mark as ${updatePayload.isFinished ? 'Finished' : 'Not Finished'}`) }) }, - startStream(startTime = null) { + playItem(startTime = null) { var episodeId = null + const queueItems = [] if (this.isPodcast) { - var episode = this.podcastEpisodes.find((ep) => { + var episodeIndex = this.podcastEpisodes.findIndex((ep) => { var podcastProgress = this.$store.getters['user/getUserMediaProgress'](this.libraryItemId, ep.id) return !podcastProgress || !podcastProgress.isFinished }) - if (!episode) episode = this.podcastEpisodes[0] - episodeId = episode.id + if (episodeIndex < 0) episodeIndex = 0 + + episodeId = this.podcastEpisodes[episodeIndex].id + + for (let i = episodeIndex; i < this.podcastEpisodes.length; i++) { + const episode = this.podcastEpisodes[i] + const audioFile = episode.audioFile + queueItems.push({ + libraryItemId: this.libraryItemId, + episodeId: episode.id, + title: episode.title, + subtitle: this.title, + duration: audioFile.duration || null, + coverPath: this.libraryItem.media.coverPath || null + }) + } } this.$eventBus.$emit('play-item', { libraryItemId: this.libraryItem.id, episodeId, - startTime + startTime, + queueItems }) }, editClick() { diff --git a/client/players/PlayerHandler.js b/client/players/PlayerHandler.js index f50c3aaf3..43ce84fac 100644 --- a/client/players/PlayerHandler.js +++ b/client/players/PlayerHandler.js @@ -133,6 +133,8 @@ export default class PlayerHandler { // TODO: Add listening time between last sync and now? this.sendProgressSync(currentTime) + + this.ctx.mediaFinished(this.libraryItemId, this.episodeId) } playerStateChange(state) { diff --git a/client/store/globals.js b/client/store/globals.js index 8a5edc36a..21a31d5a4 100644 --- a/client/store/globals.js +++ b/client/store/globals.js @@ -46,6 +46,14 @@ export const getters = { return `http://localhost:3333/api/items/${libraryItem.id}/cover?token=${userToken}&ts=${lastUpdate}` } return `/api/items/${libraryItem.id}/cover?token=${userToken}&ts=${lastUpdate}` + }, + getLibraryItemCoverSrcById: (state, getters, rootState, rootGetters) => (libraryItemId, placeholder = '/book_placeholder.jpg') => { + if (!libraryItemId) return placeholder + var userToken = rootGetters['user/getToken'] + if (process.env.NODE_ENV !== 'production') { // Testing + return `http://localhost:3333/api/items/${libraryItemId}/cover?token=${userToken}` + } + return `/api/items/${libraryItemId}/cover?token=${userToken}` } } diff --git a/client/store/index.js b/client/store/index.js index df3135766..1cff645d3 100644 --- a/client/store/index.js +++ b/client/store/index.js @@ -9,6 +9,7 @@ export const state = () => ({ streamLibraryItem: null, streamEpisodeId: null, streamIsPlaying: false, + playerQueueItems: [], playerIsFullscreen: false, editModalTab: 'details', showEditModal: false, @@ -144,14 +145,19 @@ export const mutations = { state.streamLibraryItem = null state.streamEpisodeId = null state.streamIsPlaying = false + state.playerQueueItems = [] } else { state.streamLibraryItem = payload.libraryItem state.streamEpisodeId = payload.episodeId || null + state.playerQueueItems = payload.queueItems || [] } }, setIsPlaying(state, isPlaying) { state.streamIsPlaying = isPlaying }, + setPlayerQueueItems(state, items) { + state.playerQueueItems = items || [] + }, showEditModal(state, libraryItem) { state.editModalTab = 'details' state.selectedLibraryItem = libraryItem diff --git a/client/tailwind.config.js b/client/tailwind.config.js index 6a1419d9d..390925562 100644 --- a/client/tailwind.config.js +++ b/client/tailwind.config.js @@ -11,6 +11,7 @@ module.exports = { safelist: [ 'bg-success', 'bg-red-600', + 'bg-yellow-400', 'text-green-500', 'py-1.5', 'bg-info', From 772c7b32172e07994ff2866a156e8aa51f623e01 Mon Sep 17 00:00:00 2001 From: advplyr Date: Sun, 28 Aug 2022 13:54:14 -0500 Subject: [PATCH 18/38] Set podcast episode queue when playing from home page --- client/components/cards/LazyBookCard.vue | 55 +++++++++++++++++--- client/components/widgets/LoadingSpinner.vue | 10 ++++ 2 files changed, 57 insertions(+), 8 deletions(-) diff --git a/client/components/cards/LazyBookCard.vue b/client/components/cards/LazyBookCard.vue index 8ae16daec..fc2285ab0 100644 --- a/client/components/cards/LazyBookCard.vue +++ b/client/components/cards/LazyBookCard.vue @@ -39,7 +39,7 @@
-