From 1e8e45431d9eecb73df15eef70f48df06df7c390 Mon Sep 17 00:00:00 2001 From: barry Date: Sat, 27 Aug 2022 23:40:02 -0400 Subject: [PATCH 1/3] Clear selectedEpisodes on download. Move item onClick to checkbox so you can't select existing downloads --- client/components/modals/podcast/EpisodeFeed.vue | 7 ++++--- package-lock.json | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/client/components/modals/podcast/EpisodeFeed.vue b/client/components/modals/podcast/EpisodeFeed.vue index 14a81f6e..25c06479 100644 --- a/client/components/modals/podcast/EpisodeFeed.vue +++ b/client/components/modals/podcast/EpisodeFeed.vue @@ -12,11 +12,11 @@ :key="index" class="relative" :class="episode.enclosure && itemEpisodeMap[episode.enclosure.url] ? 'bg-primary bg-opacity-40' : selectedEpisodes[String(index)] ? 'cursor-pointer bg-success bg-opacity-10' : index % 2 == 0 ? 'cursor-pointer bg-primary bg-opacity-25 hover:bg-opacity-40' : 'cursor-pointer bg-primary bg-opacity-5 hover:bg-opacity-25'" - @click="toggleSelectEpisode(index)" + >
download_done - +

#{{ episode.episode }}

@@ -123,6 +123,7 @@ export default { if (this.episodesSelected.length) { episodesToDownload = this.episodesSelected.map((episodeIndex) => this.episodes[Number(episodeIndex)]) } + this.selectedEpisodes = [] var payloadSize = JSON.stringify(episodesToDownload).length var sizeInMb = payloadSize / 1024 / 1024 @@ -170,4 +171,4 @@ export default { #episodes-scroll { max-height: calc(80vh - 200px); } - \ No newline at end of file + diff --git a/package-lock.json b/package-lock.json index 45168dc8..9dcf99df 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6,7 +6,7 @@ "packages": { "": { "name": "audiobookshelf", - "version": "2.1.2", + "version": "2.1.4", "license": "GPL-3.0", "dependencies": { "axios": "^0.26.1", @@ -1602,4 +1602,4 @@ "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==" } } -} \ No newline at end of file +} From 221061ea308c896579254a7bf3828d1d96ce595e Mon Sep 17 00:00:00 2001 From: barry Date: Sun, 28 Aug 2022 08:22:51 -0400 Subject: [PATCH 2/3] added method to clear selected episodes --- client/components/modals/podcast/EpisodeFeed.vue | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/client/components/modals/podcast/EpisodeFeed.vue b/client/components/modals/podcast/EpisodeFeed.vue index 25c06479..3e995b06 100644 --- a/client/components/modals/podcast/EpisodeFeed.vue +++ b/client/components/modals/podcast/EpisodeFeed.vue @@ -118,12 +118,15 @@ export default { toggleSelectEpisode(index) { this.$set(this.selectedEpisodes, String(index), !this.selectedEpisodes[String(index)]) }, + clearSelectedEpisodes() { + Object.keys(this.selectedEpisodes).forEach((key, idx) => this.$set(this.selectedEpisodes, String(idx), false)) + }, submit() { var episodesToDownload = [] if (this.episodesSelected.length) { episodesToDownload = this.episodesSelected.map((episodeIndex) => this.episodes[Number(episodeIndex)]) } - this.selectedEpisodes = [] + this.clearSelectedEpisodes() var payloadSize = JSON.stringify(episodesToDownload).length var sizeInMb = payloadSize / 1024 / 1024 From 1f37e32f910d8a9fcdcbaa27e8af5e6dc6291033 Mon Sep 17 00:00:00 2001 From: advplyr Date: Sun, 28 Aug 2022 08:48:41 -0500 Subject: [PATCH 3/3] Podcast episode feed modal refactor --- .../components/modals/podcast/EpisodeFeed.vue | 75 +++++++++---------- 1 file changed, 36 insertions(+), 39 deletions(-) diff --git a/client/components/modals/podcast/EpisodeFeed.vue b/client/components/modals/podcast/EpisodeFeed.vue index 3e995b06..642a6e0e 100644 --- a/client/components/modals/podcast/EpisodeFeed.vue +++ b/client/components/modals/podcast/EpisodeFeed.vue @@ -11,32 +11,25 @@ v-for="(episode, index) in episodes" :key="index" class="relative" - :class="episode.enclosure && itemEpisodeMap[episode.enclosure.url] ? 'bg-primary bg-opacity-40' : selectedEpisodes[String(index)] ? 'cursor-pointer bg-success bg-opacity-10' : index % 2 == 0 ? 'cursor-pointer bg-primary bg-opacity-25 hover:bg-opacity-40' : 'cursor-pointer bg-primary bg-opacity-5 hover:bg-opacity-25'" - + :class="itemEpisodeMap[episode.enclosure.url] ? 'bg-primary bg-opacity-40' : selectedEpisodes[String(index)] ? 'cursor-pointer bg-success bg-opacity-10' : index % 2 == 0 ? 'cursor-pointer bg-primary bg-opacity-25 hover:bg-opacity-40' : 'cursor-pointer bg-primary bg-opacity-5 hover:bg-opacity-25'" + @click="toggleSelectEpisode(index, episode)" >
- download_done - + download_done +

#{{ episode.episode }}

{{ episode.title }}

{{ episode.subtitle }}

Published {{ episode.publishedAt ? $dateDistanceFromNow(episode.publishedAt) : 'Unknown' }}

-
-
-
- -
-
-

Select all episodes

-
-
- {{ buttonText }} + + {{ buttonText }} +

All episodes are downloaded

@@ -58,7 +51,8 @@ export default { data() { return { processing: false, - selectedEpisodes: {} + selectedEpisodes: {}, + selectAll: false } }, watch: { @@ -78,22 +72,12 @@ export default { this.$emit('input', val) } }, - selectAll: { - get() { - return this.episodesSelected.length == this.episodes.filter((_, index) => !(this.episodes[index].enclosure && this.itemEpisodeMap[this.episodes[index].enclosure.url])).length - }, - set(val) { - for (const key in this.selectedEpisodes) { - this.selectedEpisodes[key] = val - } - } - }, title() { if (!this.libraryItem) return '' return this.libraryItem.media.metadata.title || 'Unknown' }, allDownloaded() { - return Object.values(this.episodes).filter((episode) => !(episode.enclosure && this.itemEpisodeMap[episode.enclosure.url])).length === 0 + return !this.episodes.some((episode) => !this.itemEpisodeMap[episode.enclosure.url]) }, episodesSelected() { return Object.keys(this.selectedEpisodes).filter((key) => !!this.selectedEpisodes[key]) @@ -115,18 +99,33 @@ export default { } }, methods: { - toggleSelectEpisode(index) { - this.$set(this.selectedEpisodes, String(index), !this.selectedEpisodes[String(index)]) + toggleSelectAll(val) { + for (let i = 0; i < this.episodes.length; i++) { + const episode = this.episodes[i] + if (this.itemEpisodeMap[episode.enclosure.url]) this.selectedEpisodes[String(i)] = false + else this.$set(this.selectedEpisodes, String(i), val) + } }, - clearSelectedEpisodes() { - Object.keys(this.selectedEpisodes).forEach((key, idx) => this.$set(this.selectedEpisodes, String(idx), false)) + checkSetIsSelectedAll() { + for (let i = 0; i < this.episodes.length; i++) { + const episode = this.episodes[i] + if (!this.itemEpisodeMap[episode.enclosure.url] && !this.selectedEpisodes[String(i)]) { + this.selectAll = false + return + } + } + this.selectAll = true + }, + toggleSelectEpisode(index, episode) { + if (this.itemEpisodeMap[episode.enclosure.url]) return + this.$set(this.selectedEpisodes, String(index), !this.selectedEpisodes[String(index)]) + this.checkSetIsSelectedAll() }, submit() { var episodesToDownload = [] if (this.episodesSelected.length) { episodesToDownload = this.episodesSelected.map((episodeIndex) => this.episodes[Number(episodeIndex)]) } - this.clearSelectedEpisodes() var payloadSize = JSON.stringify(episodesToDownload).length var sizeInMb = payloadSize / 1024 / 1024 @@ -149,17 +148,15 @@ export default { console.error('Failed to download episodes', error) this.processing = false this.$toast.error(errorMsg) + + this.selectedEpisodes = {} + this.selectAll = false }) }, init() { - this.episodes.sort((a, b) => (a.publishedAt < b.publishedAt) ? 1 : -1) - for (let i = 0; i < this.episodes.length; i++) { - var episode = this.episodes[i] - if (episode.enclosure && !this.itemEpisodeMap[episode.enclosure.url]) { - // Do not include episodes already downloaded - this.$set(this.selectedEpisodes, String(i), false) - } - } + this.episodes.sort((a, b) => (a.publishedAt < b.publishedAt ? 1 : -1)) + this.selectAll = false + this.selectedEpisodes = {} } }, mounted() {}