mirror of
				https://github.com/advplyr/audiobookshelf.git
				synced 2025-10-27 11:18:14 +01:00 
			
		
		
		
	Update:Podcast library item covers show number of episodes incomplete #782
This commit is contained in:
		
							parent
							
								
									ddc54c8811
								
							
						
					
					
						commit
						ec998dc1ac
					
				| @ -168,7 +168,7 @@ export default { | ||||
|     }, | ||||
|     async fetchCategories() { | ||||
|       const categories = await this.$axios | ||||
|         .$get(`/api/libraries/${this.currentLibraryId}/personalized?include=rssfeed`) | ||||
|         .$get(`/api/libraries/${this.currentLibraryId}/personalized?include=rssfeed,numEpisodesIncomplete`) | ||||
|         .then((data) => { | ||||
|           return data | ||||
|         }) | ||||
|  | ||||
| @ -315,10 +315,10 @@ export default { | ||||
| 
 | ||||
|       const entityPath = this.entityName === 'series-books' ? 'items' : this.entityName | ||||
|       const sfQueryString = this.currentSFQueryString ? this.currentSFQueryString + '&' : '' | ||||
|       const fullQueryString = `?${sfQueryString}limit=${this.booksPerFetch}&page=${page}&minified=1&include=rssfeed` | ||||
|       const fullQueryString = `?${sfQueryString}limit=${this.booksPerFetch}&page=${page}&minified=1&include=rssfeed,numEpisodesIncomplete` | ||||
| 
 | ||||
|       const payload = await this.$axios.$get(`/api/libraries/${this.currentLibraryId}/${entityPath}${fullQueryString}`).catch((error) => { | ||||
|         console.error('failed to fetch books', error) | ||||
|         console.error('failed to fetch items', error) | ||||
|         return null | ||||
|       }) | ||||
| 
 | ||||
|  | ||||
| @ -116,9 +116,14 @@ | ||||
|     </div> | ||||
| 
 | ||||
|     <!-- Podcast Num Episodes --> | ||||
|     <div v-else-if="numEpisodes && !isHovering && !isSelectionMode" class="absolute rounded-full bg-black bg-opacity-90 box-shadow-md z-10 flex items-center justify-center" :style="{ top: 0.375 * sizeMultiplier + 'rem', right: 0.375 * sizeMultiplier + 'rem', width: 1.25 * sizeMultiplier + 'rem', height: 1.25 * sizeMultiplier + 'rem' }"> | ||||
|     <div v-else-if="!numEpisodesIncomplete && numEpisodes && !isHovering && !isSelectionMode" class="absolute rounded-full bg-black bg-opacity-90 box-shadow-md z-10 flex items-center justify-center" :style="{ top: 0.375 * sizeMultiplier + 'rem', right: 0.375 * sizeMultiplier + 'rem', width: 1.25 * sizeMultiplier + 'rem', height: 1.25 * sizeMultiplier + 'rem' }"> | ||||
|       <p :style="{ fontSize: sizeMultiplier * 0.8 + 'rem' }">{{ numEpisodes }}</p> | ||||
|     </div> | ||||
| 
 | ||||
|     <!-- Podcast Num Episodes --> | ||||
|     <div v-else-if="numEpisodesIncomplete && !isHovering && !isSelectionMode" class="absolute rounded-full bg-yellow-400 text-black font-semibold box-shadow-md z-10 flex items-center justify-center" :style="{ top: 0.375 * sizeMultiplier + 'rem', right: 0.375 * sizeMultiplier + 'rem', width: 1.25 * sizeMultiplier + 'rem', height: 1.25 * sizeMultiplier + 'rem' }"> | ||||
|       <p :style="{ fontSize: sizeMultiplier * 0.8 + 'rem' }">{{ numEpisodesIncomplete }}</p> | ||||
|     </div> | ||||
|   </div> | ||||
| </template> | ||||
| 
 | ||||
| @ -227,9 +232,11 @@ export default { | ||||
|       return this.media.numTracks || 0 // toJSONMinified | ||||
|     }, | ||||
|     numEpisodes() { | ||||
|       if (!this.isPodcast) return 0 | ||||
|       return this.media.numEpisodes || 0 | ||||
|     }, | ||||
|     numEpisodesIncomplete() { | ||||
|       return this._libraryItem.numEpisodesIncomplete || 0 | ||||
|     }, | ||||
|     processingBatch() { | ||||
|       return this.store.state.processingBatch | ||||
|     }, | ||||
|  | ||||
| @ -198,6 +198,7 @@ class LibraryController { | ||||
|       include: include.join(',') | ||||
|     } | ||||
|     const mediaIsBook = payload.mediaType === 'book' | ||||
|     const mediaIsPodcast = payload.mediaType === 'podcast' | ||||
| 
 | ||||
|     // Step 1 - Filter the retrieved library items
 | ||||
|     let filterSeries = null | ||||
| @ -236,7 +237,6 @@ class LibraryController { | ||||
|     const sortArray = [] | ||||
| 
 | ||||
|     // When on the series page, sort by sequence only
 | ||||
|     if (payload.sortBy === 'book.volumeNumber') payload.sortBy = null // TODO: Remove temp fix after mobile release 0.9.60
 | ||||
|     if (filterSeries && !payload.sortBy) { | ||||
|       sortArray.push({ asc: (li) => li.media.metadata.getSeries(filterSeries).sequence }) | ||||
|       // If no series sequence then fallback to sorting by title (or collapsed series name for sub-series)
 | ||||
| @ -360,6 +360,11 @@ class LibraryController { | ||||
|           json.rssFeed = feedData ? feedData.toJSONMinified() : null | ||||
|         } | ||||
| 
 | ||||
|         // add numEpisodesIncomplete if "include=numEpisodesIncomplete" was put in query string (only for podcasts)
 | ||||
|         if (mediaIsPodcast && include.includes('numepisodesincomplete')) { | ||||
|           json.numEpisodesIncomplete = req.user.getNumEpisodesIncompleteForPodcast(li) | ||||
|         } | ||||
| 
 | ||||
|         if (filterSeries) { | ||||
|           // If filtering by series, make sure to include the series metadata
 | ||||
|           json.media.metadata.series = li.media.metadata.getSeries(filterSeries) | ||||
|  | ||||
| @ -416,5 +416,23 @@ class User { | ||||
|     if (!progress) return false | ||||
|     return progress.removeFromContinueListening() | ||||
|   } | ||||
| 
 | ||||
|   /** | ||||
|    * Number of podcast episodes not finished for library item | ||||
|    * Note: libraryItem passed in from libraryHelpers is not a LibraryItem class instance | ||||
|    * @param {LibraryItem|object} libraryItem  | ||||
|    * @returns {number} | ||||
|    */ | ||||
|   getNumEpisodesIncompleteForPodcast(libraryItem) { | ||||
|     if (!libraryItem?.media.episodes) return 0 | ||||
|     let numEpisodesIncomplete = 0 | ||||
|     for (const episode of libraryItem.media.episodes) { | ||||
|       const mediaProgress = this.getMediaProgress(libraryItem.id, episode.id) | ||||
|       if (!mediaProgress?.isFinished) { | ||||
|         numEpisodesIncomplete++ | ||||
|       } | ||||
|     } | ||||
|     return numEpisodesIncomplete | ||||
|   } | ||||
| } | ||||
| module.exports = User | ||||
| @ -360,6 +360,7 @@ module.exports = { | ||||
|     const mediaType = library.mediaType | ||||
|     const isPodcastLibrary = mediaType === 'podcast' | ||||
|     const includeRssFeed = include.includes('rssfeed') | ||||
|     const includeNumEpisodesIncomplete = include.includes('numepisodesincomplete') // Podcasts only
 | ||||
|     const hideSingleBookSeries = library.settings.hideSingleBookSeries | ||||
| 
 | ||||
|     const shelves = [ | ||||
| @ -456,12 +457,18 @@ module.exports = { | ||||
| 
 | ||||
|     for (const libraryItem of libraryItems) { | ||||
|       if (libraryItem.addedAt > categoryMap['recently-added'].smallest) { | ||||
|         const libraryItemObj = libraryItem.toJSONMinified() | ||||
| 
 | ||||
|         // add numEpisodesIncomplete if "include=numEpisodesIncomplete" was put in query string (only for podcasts)
 | ||||
|         if (includeNumEpisodesIncomplete && libraryItem.isPodcast) { | ||||
|           libraryItemObj.numEpisodesIncomplete = user.getNumEpisodesIncompleteForPodcast(libraryItem) | ||||
|         } | ||||
| 
 | ||||
|         const indexToPut = categoryMap['recently-added'].items.findIndex(i => libraryItem.addedAt > i.addedAt) | ||||
|         if (indexToPut >= 0) { | ||||
|           categoryMap['recently-added'].items.splice(indexToPut, 0, libraryItem.toJSONMinified()) | ||||
|           categoryMap['recently-added'].items.splice(indexToPut, 0, libraryItemObj) | ||||
|         } else { | ||||
|           categoryMap['recently-added'].items.push(libraryItem.toJSONMinified()) | ||||
|           categoryMap['recently-added'].items.push(libraryItemObj) | ||||
|         } | ||||
| 
 | ||||
|         if (categoryMap['recently-added'].items.length > maxEntitiesPerShelf) { | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user