mirror of
				https://github.com/advplyr/audiobookshelf.git
				synced 2025-10-27 11:18:14 +01:00 
			
		
		
		
	Add:Hide series from home page option #919
This commit is contained in:
		
							parent
							
								
									8c32fed911
								
							
						
					
					
						commit
						9ee6eaade9
					
				| @ -244,6 +244,24 @@ export default { | |||||||
|         this.libraryItemUpdated(li) |         this.libraryItemUpdated(li) | ||||||
|       }) |       }) | ||||||
|     }, |     }, | ||||||
|  |     seriesUpdated(series) { | ||||||
|  |       if (series.hideFromHome) { | ||||||
|  |         this.shelves.forEach((shelf) => { | ||||||
|  |           if (shelf.type == 'book' && shelf.id == 'continue-series') { | ||||||
|  |             // Filter out series books from continue series shelf | ||||||
|  |             shelf.entities = shelf.entities.filter((ent) => { | ||||||
|  |               if (ent.media.metadata.series && ent.media.metadata.series.id == series.id) return false | ||||||
|  |               return true | ||||||
|  |             }) | ||||||
|  |           } else if (shelf.type == 'series') { | ||||||
|  |             // Filter out series from series shelf | ||||||
|  |             shelf.entities = shelf.entities.filter((ent) => { | ||||||
|  |               return ent.id != series.id | ||||||
|  |             }) | ||||||
|  |           } | ||||||
|  |         }) | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|     authorUpdated(author) { |     authorUpdated(author) { | ||||||
|       this.shelves.forEach((shelf) => { |       this.shelves.forEach((shelf) => { | ||||||
|         if (shelf.type == 'authors') { |         if (shelf.type == 'authors') { | ||||||
| @ -270,6 +288,7 @@ export default { | |||||||
|       this.$store.commit('user/addSettingsListener', { id: 'bookshelf', meth: this.settingsUpdated }) |       this.$store.commit('user/addSettingsListener', { id: 'bookshelf', meth: this.settingsUpdated }) | ||||||
| 
 | 
 | ||||||
|       if (this.$root.socket) { |       if (this.$root.socket) { | ||||||
|  |         this.$root.socket.on('series_updated', this.seriesUpdated) | ||||||
|         this.$root.socket.on('author_updated', this.authorUpdated) |         this.$root.socket.on('author_updated', this.authorUpdated) | ||||||
|         this.$root.socket.on('author_removed', this.authorRemoved) |         this.$root.socket.on('author_removed', this.authorRemoved) | ||||||
|         this.$root.socket.on('item_updated', this.libraryItemUpdated) |         this.$root.socket.on('item_updated', this.libraryItemUpdated) | ||||||
| @ -285,6 +304,7 @@ export default { | |||||||
|       this.$store.commit('user/removeSettingsListener', 'bookshelf') |       this.$store.commit('user/removeSettingsListener', 'bookshelf') | ||||||
| 
 | 
 | ||||||
|       if (this.$root.socket) { |       if (this.$root.socket) { | ||||||
|  |         this.$root.socket.off('series_updated', this.seriesUpdated) | ||||||
|         this.$root.socket.off('author_updated', this.authorUpdated) |         this.$root.socket.off('author_updated', this.authorUpdated) | ||||||
|         this.$root.socket.off('author_removed', this.authorRemoved) |         this.$root.socket.off('author_removed', this.authorRemoved) | ||||||
|         this.$root.socket.off('item_updated', this.libraryItemUpdated) |         this.$root.socket.off('item_updated', this.libraryItemUpdated) | ||||||
|  | |||||||
| @ -21,13 +21,14 @@ | |||||||
|       <template v-if="page !== 'search' && page !== 'podcast-search' && page !== 'recent-episodes' && !isHome"> |       <template v-if="page !== 'search' && page !== 'podcast-search' && page !== 'recent-episodes' && !isHome"> | ||||||
|         <p v-if="!selectedSeries" class="font-book hidden md:block">{{ numShowing }} {{ entityName }}</p> |         <p v-if="!selectedSeries" class="font-book hidden md:block">{{ numShowing }} {{ entityName }}</p> | ||||||
|         <div v-else class="items-center hidden md:flex w-full"> |         <div v-else class="items-center hidden md:flex w-full"> | ||||||
|           <p class="pl-4 font-book text-lg"> |           <p class="pl-2 font-book text-lg"> | ||||||
|             {{ seriesName }} |             {{ seriesName }} | ||||||
|           </p> |           </p> | ||||||
|           <div class="w-6 h-6 rounded-full bg-black bg-opacity-30 flex items-center justify-center ml-3"> |           <div class="w-6 h-6 rounded-full bg-black bg-opacity-30 flex items-center justify-center ml-3"> | ||||||
|             <span class="font-mono">{{ numShowing }}</span> |             <span class="font-mono">{{ numShowing }}</span> | ||||||
|           </div> |           </div> | ||||||
|           <div class="flex-grow" /> |           <div class="flex-grow" /> | ||||||
|  |           <ui-btn v-if="seriesHideFromHome" :loading="processingSeriesHideFromHome" color="primary" small class="mr-2" @click="showSeriesOnHome">Show on Home</ui-btn> | ||||||
|           <ui-btn color="primary" small :loading="processingSeries" class="flex items-center" @click="markSeriesFinished"> |           <ui-btn color="primary" small :loading="processingSeries" class="flex items-center" @click="markSeriesFinished"> | ||||||
|             <div class="h-5 w-5"> |             <div class="h-5 w-5"> | ||||||
|               <svg v-if="isSeriesFinished" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="rgb(63, 181, 68)"> |               <svg v-if="isSeriesFinished" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="rgb(63, 181, 68)"> | ||||||
| @ -37,8 +38,8 @@ | |||||||
|                 <path d="M19 1H5c-1.1 0-1.99.9-1.99 2L3 15.93c0 .69.35 1.3.88 1.66L12 23l8.11-5.41c.53-.36.88-.97.88-1.66L21 3c0-1.1-.9-2-2-2zm-7 19.6l-7-4.66V3h14v12.93l-7 4.67zm-2.01-7.42l-2.58-2.59L6 12l4 4 8-8-1.42-1.42z" /> |                 <path d="M19 1H5c-1.1 0-1.99.9-1.99 2L3 15.93c0 .69.35 1.3.88 1.66L12 23l8.11-5.41c.53-.36.88-.97.88-1.66L21 3c0-1.1-.9-2-2-2zm-7 19.6l-7-4.66V3h14v12.93l-7 4.67zm-2.01-7.42l-2.58-2.59L6 12l4 4 8-8-1.42-1.42z" /> | ||||||
|               </svg> |               </svg> | ||||||
|             </div> |             </div> | ||||||
|             <span class="pl-2"> Mark Series {{ isSeriesFinished ? 'Not Finished' : 'Finished' }}</span></ui-btn |             <span class="pl-2"> Mark Series {{ isSeriesFinished ? 'Not Finished' : 'Finished' }}</span> | ||||||
|           > |           </ui-btn> | ||||||
|         </div> |         </div> | ||||||
|         <div class="flex-grow hidden sm:inline-block" /> |         <div class="flex-grow hidden sm:inline-block" /> | ||||||
| 
 | 
 | ||||||
| @ -83,7 +84,7 @@ export default { | |||||||
|     authors: { |     authors: { | ||||||
|       type: Array, |       type: Array, | ||||||
|       default: () => [] |       default: () => [] | ||||||
|     }, |     } | ||||||
|   }, |   }, | ||||||
|   data() { |   data() { | ||||||
|     return { |     return { | ||||||
| @ -94,7 +95,8 @@ export default { | |||||||
|       keywordTimeout: null, |       keywordTimeout: null, | ||||||
|       processingSeries: false, |       processingSeries: false, | ||||||
|       processingIssues: false, |       processingIssues: false, | ||||||
|       processingAuthors: false |       processingAuthors: false, | ||||||
|  |       processingSeriesHideFromHome: false | ||||||
|     } |     } | ||||||
|   }, |   }, | ||||||
|   computed: { |   computed: { | ||||||
| @ -150,6 +152,9 @@ export default { | |||||||
|     seriesName() { |     seriesName() { | ||||||
|       return this.selectedSeries ? this.selectedSeries.name : null |       return this.selectedSeries ? this.selectedSeries.name : null | ||||||
|     }, |     }, | ||||||
|  |     seriesHideFromHome() { | ||||||
|  |       return this.selectedSeries ? this.selectedSeries.hideFromHome : null | ||||||
|  |     }, | ||||||
|     seriesProgress() { |     seriesProgress() { | ||||||
|       return this.selectedSeries ? this.selectedSeries.progress : null |       return this.selectedSeries ? this.selectedSeries.progress : null | ||||||
|     }, |     }, | ||||||
| @ -171,6 +176,23 @@ export default { | |||||||
|     } |     } | ||||||
|   }, |   }, | ||||||
|   methods: { |   methods: { | ||||||
|  |     async showSeriesOnHome() { | ||||||
|  |       this.processingSeriesHideFromHome = true | ||||||
|  |       const seriesId = this.selectedSeries.id | ||||||
|  |       this.$axios | ||||||
|  |         .$patch(`/api/series/${seriesId}`, { hideFromHome: false }) | ||||||
|  |         .then((data) => { | ||||||
|  |           console.log('Updated series', data) | ||||||
|  |           this.$toast.success('Series updated successfully') | ||||||
|  |         }) | ||||||
|  |         .catch((error) => { | ||||||
|  |           console.error('Failed to update series', error) | ||||||
|  |           this.$toast.error('Failed to update series') | ||||||
|  |         }) | ||||||
|  |         .finally(() => { | ||||||
|  |           this.processingSeriesHideFromHome = false | ||||||
|  |         }) | ||||||
|  |     }, | ||||||
|     async matchAllAuthors() { |     async matchAllAuthors() { | ||||||
|       this.processingAuthors = true |       this.processingAuthors = true | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -411,6 +411,12 @@ export default { | |||||||
|           text: 'Re-Scan' |           text: 'Re-Scan' | ||||||
|         }) |         }) | ||||||
|       } |       } | ||||||
|  |       if (this.userIsAdminOrUp && this.series && this.bookMount) { | ||||||
|  |         items.push({ | ||||||
|  |           func: 'hideSeriesFromHome', | ||||||
|  |           text: 'Hide Series from Home' | ||||||
|  |         }) | ||||||
|  |       } | ||||||
|       return items |       return items | ||||||
|     }, |     }, | ||||||
|     _socket() { |     _socket() { | ||||||
| @ -572,11 +578,12 @@ export default { | |||||||
|           } else if (result === 'REMOVED') { |           } else if (result === 'REMOVED') { | ||||||
|             this.$toast.error(`Re-Scan complete item was removed`) |             this.$toast.error(`Re-Scan complete item was removed`) | ||||||
|           } |           } | ||||||
|           this.processing = false |  | ||||||
|         }) |         }) | ||||||
|         .catch((error) => { |         .catch((error) => { | ||||||
|           console.error('Failed to scan library item', error) |           console.error('Failed to scan library item', error) | ||||||
|           this.$toast.error('Failed to scan library item') |           this.$toast.error('Failed to scan library item') | ||||||
|  |         }) | ||||||
|  |         .finally(() => { | ||||||
|           this.processing = false |           this.processing = false | ||||||
|         }) |         }) | ||||||
|     }, |     }, | ||||||
| @ -588,6 +595,22 @@ export default { | |||||||
|       // More menu func |       // More menu func | ||||||
|       this.store.commit('showEditModalOnTab', { libraryItem: this.libraryItem, tab: 'match' }) |       this.store.commit('showEditModalOnTab', { libraryItem: this.libraryItem, tab: 'match' }) | ||||||
|     }, |     }, | ||||||
|  |     hideSeriesFromHome() { | ||||||
|  |       const axios = this.$axios || this.$nuxt.$axios | ||||||
|  |       this.processing = true | ||||||
|  |       axios | ||||||
|  |         .$patch(`/api/series/${this.series.id}`, { hideFromHome: true }) | ||||||
|  |         .then((data) => { | ||||||
|  |           console.log('Series updated', data) | ||||||
|  |         }) | ||||||
|  |         .catch((error) => { | ||||||
|  |           console.error('Failed to hide series from home', error) | ||||||
|  |           this.$toast.error('Failed to update series') | ||||||
|  |         }) | ||||||
|  |         .finally(() => { | ||||||
|  |           this.processing = false | ||||||
|  |         }) | ||||||
|  |     }, | ||||||
|     openCollections() { |     openCollections() { | ||||||
|       this.store.commit('setSelectedLibraryItem', this.libraryItem) |       this.store.commit('setSelectedLibraryItem', this.libraryItem) | ||||||
|       this.store.commit('globals/setShowUserCollectionsModal', true) |       this.store.commit('globals/setShowUserCollectionsModal', true) | ||||||
|  | |||||||
| @ -40,7 +40,20 @@ export default { | |||||||
|       return this.$store.state.streamLibraryItem |       return this.$store.state.streamLibraryItem | ||||||
|     } |     } | ||||||
|   }, |   }, | ||||||
|   mounted() {}, |   methods: { | ||||||
|   beforeDestroy() {} |     seriesUpdated(series) { | ||||||
|  |       this.series = series | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   mounted() { | ||||||
|  |     if (this.$root.socket) { | ||||||
|  |       this.$root.socket.on('series_updated', this.seriesUpdated) | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   beforeDestroy() { | ||||||
|  |     if (this.$root.socket) { | ||||||
|  |       this.$root.socket.off('series_updated', this.seriesUpdated) | ||||||
|  |     } | ||||||
|  |   } | ||||||
| } | } | ||||||
| </script> | </script> | ||||||
|  | |||||||
| @ -34,6 +34,15 @@ class SeriesController { | |||||||
|     res.json(series) |     res.json(series) | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  |   async update(req, res) { | ||||||
|  |     const hasUpdated = req.series.update(req.body) | ||||||
|  |     if (hasUpdated) { | ||||||
|  |       await this.db.updateEntity('series', req.series) | ||||||
|  |       this.emitter('series_updated', req.series) | ||||||
|  |     } | ||||||
|  |     res.json(req.series) | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|   middleware(req, res, next) { |   middleware(req, res, next) { | ||||||
|     var series = this.db.series.find(se => se.id === req.params.id) |     var series = this.db.series.find(se => se.id === req.params.id) | ||||||
|     if (!series) return res.sendStatus(404) |     if (!series) return res.sendStatus(404) | ||||||
|  | |||||||
| @ -5,6 +5,7 @@ class Series { | |||||||
|     this.id = null |     this.id = null | ||||||
|     this.name = null |     this.name = null | ||||||
|     this.description = null |     this.description = null | ||||||
|  |     this.hideFromHome = false | ||||||
|     this.addedAt = null |     this.addedAt = null | ||||||
|     this.updatedAt = null |     this.updatedAt = null | ||||||
| 
 | 
 | ||||||
| @ -17,6 +18,7 @@ class Series { | |||||||
|     this.id = series.id |     this.id = series.id | ||||||
|     this.name = series.name |     this.name = series.name | ||||||
|     this.description = series.description || null |     this.description = series.description || null | ||||||
|  |     this.hideFromHome = !!series.hideFromHome | ||||||
|     this.addedAt = series.addedAt |     this.addedAt = series.addedAt | ||||||
|     this.updatedAt = series.updatedAt |     this.updatedAt = series.updatedAt | ||||||
|   } |   } | ||||||
| @ -26,6 +28,7 @@ class Series { | |||||||
|       id: this.id, |       id: this.id, | ||||||
|       name: this.name, |       name: this.name, | ||||||
|       description: this.description, |       description: this.description, | ||||||
|  |       hideFromHome: this.hideFromHome, | ||||||
|       addedAt: this.addedAt, |       addedAt: this.addedAt, | ||||||
|       updatedAt: this.updatedAt |       updatedAt: this.updatedAt | ||||||
|     } |     } | ||||||
| @ -43,10 +46,24 @@ class Series { | |||||||
|     this.id = getId('ser') |     this.id = getId('ser') | ||||||
|     this.name = data.name |     this.name = data.name | ||||||
|     this.description = data.description || null |     this.description = data.description || null | ||||||
|  |     this.hideFromHome = !!data.hideFromHome | ||||||
|     this.addedAt = Date.now() |     this.addedAt = Date.now() | ||||||
|     this.updatedAt = Date.now() |     this.updatedAt = Date.now() | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  |   update(series) { | ||||||
|  |     if (!series) return false | ||||||
|  |     const keysToUpdate = ['name', 'description', 'hideFromHome'] | ||||||
|  |     var hasUpdated = false | ||||||
|  |     for (const key of keysToUpdate) { | ||||||
|  |       if (series[key] !== undefined && series[key] !== this[key]) { | ||||||
|  |         this[key] = series[key] | ||||||
|  |         hasUpdated = true | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     return hasUpdated | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|   checkNameEquals(name) { |   checkNameEquals(name) { | ||||||
|     if (!name || !this.name) return false |     if (!name || !this.name) return false | ||||||
|     return this.name.toLowerCase() == name.toLowerCase().trim() |     return this.name.toLowerCase() == name.toLowerCase().trim() | ||||||
|  | |||||||
| @ -178,6 +178,7 @@ class ApiRouter { | |||||||
|     //
 |     //
 | ||||||
|     this.router.get('/series/search', SeriesController.search.bind(this)) |     this.router.get('/series/search', SeriesController.search.bind(this)) | ||||||
|     this.router.get('/series/:id', SeriesController.middleware.bind(this), SeriesController.findOne.bind(this)) |     this.router.get('/series/:id', SeriesController.middleware.bind(this), SeriesController.findOne.bind(this)) | ||||||
|  |     this.router.patch('/series/:id', SeriesController.middleware.bind(this), SeriesController.update.bind(this)) | ||||||
| 
 | 
 | ||||||
|     //
 |     //
 | ||||||
|     // Playback Session Routes
 |     // Playback Session Routes
 | ||||||
|  | |||||||
| @ -417,7 +417,7 @@ module.exports = { | |||||||
| 
 | 
 | ||||||
|             if (!seriesMap[librarySeries.id]) { |             if (!seriesMap[librarySeries.id]) { | ||||||
|               const seriesObj = allSeries.find(se => se.id === librarySeries.id) |               const seriesObj = allSeries.find(se => se.id === librarySeries.id) | ||||||
|               if (seriesObj) { |               if (seriesObj && !seriesObj.hideFromHome) { | ||||||
|                 var series = { |                 var series = { | ||||||
|                   ...seriesObj.toJSON(), |                   ...seriesObj.toJSON(), | ||||||
|                   books: [libraryItemJson], |                   books: [libraryItemJson], | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user