Merge pull request #448 from rasmuslos/bulk-download

Added select all option to the episode selector
This commit is contained in:
advplyr 2022-04-09 05:36:06 -05:00 committed by GitHub
commit fc228013d3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 36 additions and 2 deletions

1
.gitignore vendored
View File

@ -4,6 +4,7 @@ node_modules/
/config/ /config/
/audiobooks/ /audiobooks/
/audiobooks2/ /audiobooks2/
/podcasts/
/media/ /media/
/metadata/ /metadata/
test/ test/

View File

@ -29,6 +29,14 @@
</div> </div>
</div> </div>
<div class="flex justify-end pt-4"> <div class="flex justify-end pt-4">
<div class="relative">
<div class="absolute top-0 left-0 h-full flex items-center p-2">
<ui-checkbox small checkbox-bg="primary" border-color="gray-600" v-on:input="selectedEpisodes = episodes.map(episode => episode.enclosure && itemEpisodeMap[episode.enclosure.url] ? false : !allSelected)" v-bind:value="allSelected" v-bind:disabled="allDownloaded" />
</div>
<div class="px-8 py-2">
<p :class="!allDownloaded ? 'font-semibold text-gray-200' : 'text-gray-400'">Select all episodes</p>
</div>
</div>
<ui-btn :disabled="!episodesSelected.length" @click="submit">{{ buttonText }}</ui-btn> <ui-btn :disabled="!episodesSelected.length" @click="submit">{{ buttonText }}</ui-btn>
</div> </div>
</div> </div>
@ -67,6 +75,20 @@ export default {
if (!this.libraryItem) return '' if (!this.libraryItem) return ''
return this.libraryItem.media.metadata.title || 'Unknown' return this.libraryItem.media.metadata.title || 'Unknown'
}, },
allSelected() {
try {
const values = Object.values(this.selectedEpisodes).filter((_, index) => !(this.episodes[index].enclosure && this.itemEpisodeMap[this.episodes[index].enclosure.url]))
if(!values.length) return false
return values.filter(episode => !episode).length === 0
} catch(error) {
console.error("Error while filtering selected episodes", error);
return false
}
},
allDownloaded() {
return Object.values(this.episodes).filter(episode => !(episode.enclosure && this.itemEpisodeMap[episode.enclosure.url])).length === 0
},
episodesSelected() { episodesSelected() {
return Object.keys(this.selectedEpisodes).filter((key) => !!this.selectedEpisodes[key]) return Object.keys(this.selectedEpisodes).filter((key) => !!this.selectedEpisodes[key])
}, },

View File

@ -39,6 +39,14 @@
<div class="w-full md:w-1/2 p-4"> <div class="w-full md:w-1/2 p-4">
<p class="text-lg font-semibold mb-2">Episodes</p> <p class="text-lg font-semibold mb-2">Episodes</p>
<div ref="episodeContainer" id="episodes-scroll" class="w-full overflow-x-hidden overflow-y-auto"> <div ref="episodeContainer" id="episodes-scroll" class="w-full overflow-x-hidden overflow-y-auto">
<div class="relative">
<div class="absolute top-0 left-0 h-full flex items-center p-2">
<ui-checkbox small checkbox-bg="primary" border-color="gray-600" v-on:input="selectedEpisodes = episodes.map(_ => !allSelected)" v-bind:value="allSelected" />
</div>
<div class="px-8 py-2">
<p class="font-semibold text-gray-200">Select all episodes</p>
</div>
</div>
<div v-for="(episode, index) in episodes" :key="index" class="relative cursor-pointer" :class="selectedEpisodes[String(index)] ? 'bg-success bg-opacity-10' : index % 2 == 0 ? 'bg-primary bg-opacity-25 hover:bg-opacity-40' : 'bg-primary bg-opacity-5 hover:bg-opacity-25'" @click="toggleSelectEpisode(index)"> <div v-for="(episode, index) in episodes" :key="index" class="relative cursor-pointer" :class="selectedEpisodes[String(index)] ? 'bg-success bg-opacity-10' : index % 2 == 0 ? 'bg-primary bg-opacity-25 hover:bg-opacity-40' : 'bg-primary bg-opacity-5 hover:bg-opacity-25'" @click="toggleSelectEpisode(index)">
<div class="absolute top-0 left-0 h-full flex items-center p-2"> <div class="absolute top-0 left-0 h-full flex items-center p-2">
<ui-checkbox v-model="selectedEpisodes[String(index)]" small checkbox-bg="primary" border-color="gray-600" /> <ui-checkbox v-model="selectedEpisodes[String(index)]" small checkbox-bg="primary" border-color="gray-600" />
@ -149,6 +157,9 @@ export default {
if (!this.podcastFeedData) return [] if (!this.podcastFeedData) return []
return this.podcastFeedData.episodes || [] return this.podcastFeedData.episodes || []
}, },
allSelected() {
return Object.values(this.selectedEpisodes).filter(episode => !episode).length === 0
},
episodesSelected() { episodesSelected() {
return Object.keys(this.selectedEpisodes).filter((key) => !!this.selectedEpisodes[key]) return Object.keys(this.selectedEpisodes).filter((key) => !!this.selectedEpisodes[key])
}, },

View File

@ -150,8 +150,8 @@ class Server {
app.use(this.auth.cors) app.use(this.auth.cors)
app.use(fileUpload()) app.use(fileUpload())
app.use(express.urlencoded({ extended: true })); app.use(express.urlencoded({ extended: true, limit: "3mb" }));
app.use(express.json()) app.use(express.json({ limit: "3mb" }))
// Static path to generated nuxt // Static path to generated nuxt
const distPath = Path.join(global.appRoot, '/client/dist') const distPath = Path.join(global.appRoot, '/client/dist')