mirror of
				https://github.com/advplyr/audiobookshelf.git
				synced 2025-10-27 00:32:24 -04:00 
			
		
		
		
	
		
			
				
	
	
		
			193 lines
		
	
	
		
			6.8 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
			
		
		
	
	
			193 lines
		
	
	
		
			6.8 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
| <template>
 | |
|   <div class="w-full h-full relative">
 | |
|     <div id="scheduleWrapper" class="w-full overflow-y-auto px-2 py-4 md:px-6 md:py-6">
 | |
|       <template v-if="!feedUrl">
 | |
|         <widgets-alert type="warning" class="text-base mb-4">{{ $strings.ToastPodcastNoRssFeed }}</widgets-alert>
 | |
|       </template>
 | |
|       <template v-if="feedUrl || autoDownloadEpisodes">
 | |
|         <div class="flex items-center justify-between mb-4">
 | |
|           <p class="text-base md:text-xl font-semibold">{{ $strings.HeaderScheduleEpisodeDownloads }}</p>
 | |
|           <ui-checkbox v-model="enableAutoDownloadEpisodes" :label="$strings.LabelEnable" medium checkbox-bg="bg" label-class="pl-2 text-base md:text-lg" />
 | |
|         </div>
 | |
| 
 | |
|         <div v-if="enableAutoDownloadEpisodes" class="flex items-center py-2">
 | |
|           <ui-text-input ref="maxEpisodesInput" type="number" v-model="newMaxEpisodesToKeep" no-spinner :padding-x="1" text-center class="w-10 text-base" @change="updatedMaxEpisodesToKeep" />
 | |
|           <ui-tooltip :text="$strings.LabelMaxEpisodesToKeepHelp">
 | |
|             <p class="pl-4 text-base">
 | |
|               {{ $strings.LabelMaxEpisodesToKeep }}
 | |
|               <span class="material-symbols icon-text">info</span>
 | |
|             </p>
 | |
|           </ui-tooltip>
 | |
|         </div>
 | |
|         <div v-if="enableAutoDownloadEpisodes" class="flex items-center py-2">
 | |
|           <ui-text-input ref="maxEpisodesToDownloadInput" type="number" v-model="newMaxNewEpisodesToDownload" no-spinner :padding-x="1" text-center class="w-10 text-base" @change="updateMaxNewEpisodesToDownload" />
 | |
|           <ui-tooltip :text="$strings.LabelUseZeroForUnlimited">
 | |
|             <p class="pl-4 text-base">
 | |
|               {{ $strings.LabelMaxEpisodesToDownloadPerCheck }}
 | |
|               <span class="material-symbols icon-text">info</span>
 | |
|             </p>
 | |
|           </ui-tooltip>
 | |
|         </div>
 | |
| 
 | |
|         <widgets-cron-expression-builder ref="cronExpressionBuilder" v-if="enableAutoDownloadEpisodes" v-model="cronExpression" />
 | |
|       </template>
 | |
|     </div>
 | |
| 
 | |
|     <div v-if="feedUrl || autoDownloadEpisodes" class="absolute bottom-0 left-0 w-full py-2 md:py-4 bg-bg border-t border-white/5">
 | |
|       <div class="flex items-center px-2 md:px-4">
 | |
|         <div class="grow" />
 | |
|         <ui-btn @click="save" :disabled="!isUpdated" :color="isUpdated ? 'bg-success' : 'bg-primary'" class="mx-2">{{ isUpdated ? $strings.ButtonSave : $strings.MessageNoUpdatesWereNecessary }}</ui-btn>
 | |
|       </div>
 | |
|     </div>
 | |
|   </div>
 | |
| </template>
 | |
| 
 | |
| <script>
 | |
| export default {
 | |
|   props: {
 | |
|     processing: Boolean,
 | |
|     libraryItem: {
 | |
|       type: Object,
 | |
|       default: () => {}
 | |
|     }
 | |
|   },
 | |
|   data() {
 | |
|     return {
 | |
|       enableAutoDownloadEpisodes: false,
 | |
|       cronExpression: null,
 | |
|       newMaxEpisodesToKeep: 0,
 | |
|       newMaxNewEpisodesToDownload: 0
 | |
|     }
 | |
|   },
 | |
|   watch: {
 | |
|     libraryItem: {
 | |
|       immediate: true,
 | |
|       handler(newVal) {
 | |
|         if (newVal) this.init()
 | |
|       }
 | |
|     }
 | |
|   },
 | |
|   computed: {
 | |
|     isProcessing: {
 | |
|       get() {
 | |
|         return this.processing
 | |
|       },
 | |
|       set(val) {
 | |
|         this.$emit('update:processing', val)
 | |
|       }
 | |
|     },
 | |
|     userIsAdminOrUp() {
 | |
|       return this.$store.getters['user/getIsAdminOrUp']
 | |
|     },
 | |
|     media() {
 | |
|       return this.libraryItem ? this.libraryItem.media || {} : {}
 | |
|     },
 | |
|     mediaMetadata() {
 | |
|       return this.media.metadata || {}
 | |
|     },
 | |
|     libraryItemId() {
 | |
|       return this.libraryItem ? this.libraryItem.id : null
 | |
|     },
 | |
|     feedUrl() {
 | |
|       return this.mediaMetadata.feedUrl
 | |
|     },
 | |
|     autoDownloadEpisodes() {
 | |
|       return !!this.media.autoDownloadEpisodes
 | |
|     },
 | |
|     autoDownloadSchedule() {
 | |
|       return this.media.autoDownloadSchedule
 | |
|     },
 | |
|     maxEpisodesToKeep() {
 | |
|       return this.media.maxEpisodesToKeep
 | |
|     },
 | |
|     maxNewEpisodesToDownload() {
 | |
|       return this.media.maxNewEpisodesToDownload
 | |
|     },
 | |
|     isUpdated() {
 | |
|       return this.autoDownloadSchedule !== this.cronExpression || this.autoDownloadEpisodes !== this.enableAutoDownloadEpisodes || this.maxEpisodesToKeep !== Number(this.newMaxEpisodesToKeep) || this.maxNewEpisodesToDownload !== Number(this.newMaxNewEpisodesToDownload)
 | |
|     }
 | |
|   },
 | |
|   methods: {
 | |
|     updatedMaxEpisodesToKeep() {
 | |
|       if (isNaN(this.newMaxEpisodesToKeep) || this.newMaxEpisodesToKeep < 0) {
 | |
|         this.newMaxEpisodesToKeep = 0
 | |
|       } else {
 | |
|         this.newMaxEpisodesToKeep = Number(this.newMaxEpisodesToKeep)
 | |
|       }
 | |
|     },
 | |
|     updateMaxNewEpisodesToDownload() {
 | |
|       if (isNaN(this.newMaxNewEpisodesToDownload) || this.newMaxNewEpisodesToDownload < 0) {
 | |
|         this.newMaxNewEpisodesToDownload = 0
 | |
|       } else {
 | |
|         this.newMaxNewEpisodesToDownload = Number(this.newMaxNewEpisodesToDownload)
 | |
|       }
 | |
|     },
 | |
|     save() {
 | |
|       // If custom expression input is focused then unfocus it instead of submitting
 | |
|       if (this.$refs.cronExpressionBuilder && this.$refs.cronExpressionBuilder.checkBlurExpressionInput) {
 | |
|         if (this.$refs.cronExpressionBuilder.checkBlurExpressionInput()) {
 | |
|           return
 | |
|         }
 | |
|       }
 | |
| 
 | |
|       if (this.$refs.maxEpisodesInput?.isFocused) {
 | |
|         this.$refs.maxEpisodesInput.blur()
 | |
|       }
 | |
|       if (this.$refs.maxEpisodesToDownloadInput?.isFocused) {
 | |
|         this.$refs.maxEpisodesToDownloadInput.blur()
 | |
|       }
 | |
| 
 | |
|       const updatePayload = {
 | |
|         autoDownloadEpisodes: this.enableAutoDownloadEpisodes
 | |
|       }
 | |
|       if (this.enableAutoDownloadEpisodes) {
 | |
|         updatePayload.autoDownloadSchedule = this.cronExpression
 | |
|       }
 | |
|       this.newMaxEpisodesToKeep = Number(this.newMaxEpisodesToKeep)
 | |
|       if (this.newMaxEpisodesToKeep !== this.maxEpisodesToKeep) {
 | |
|         updatePayload.maxEpisodesToKeep = this.newMaxEpisodesToKeep
 | |
|       }
 | |
|       this.newMaxNewEpisodesToDownload = Number(this.newMaxNewEpisodesToDownload)
 | |
|       if (this.newMaxNewEpisodesToDownload !== this.maxNewEpisodesToDownload) {
 | |
|         updatePayload.maxNewEpisodesToDownload = this.newMaxNewEpisodesToDownload
 | |
|       }
 | |
| 
 | |
|       this.updateDetails(updatePayload)
 | |
|     },
 | |
|     async updateDetails(updatePayload) {
 | |
|       this.isProcessing = true
 | |
|       var updateResult = await this.$axios.$patch(`/api/items/${this.libraryItemId}/media`, updatePayload).catch((error) => {
 | |
|         console.error('Failed to update', error)
 | |
|         return false
 | |
|       })
 | |
|       this.isProcessing = false
 | |
|       if (updateResult) {
 | |
|         if (updateResult.updated) {
 | |
|           this.$toast.success(this.$strings.ToastItemDetailsUpdateSuccess)
 | |
|           return true
 | |
|         } else {
 | |
|           this.$toast.info(this.$strings.MessageNoUpdatesWereNecessary)
 | |
|         }
 | |
|       }
 | |
|       return false
 | |
|     },
 | |
|     init() {
 | |
|       this.enableAutoDownloadEpisodes = this.autoDownloadEpisodes
 | |
|       this.cronExpression = this.autoDownloadSchedule
 | |
|       this.newMaxEpisodesToKeep = this.maxEpisodesToKeep
 | |
|       this.newMaxNewEpisodesToDownload = this.maxNewEpisodesToDownload
 | |
|     }
 | |
|   },
 | |
|   mounted() {
 | |
|     this.init()
 | |
|   }
 | |
| }
 | |
| </script>
 | |
| 
 | |
| <style scoped>
 | |
| #scheduleWrapper {
 | |
|   height: calc(100% - 80px);
 | |
|   max-height: calc(100% - 80px);
 | |
| }
 | |
| </style>
 |