mirror of
				https://github.com/advplyr/audiobookshelf.git
				synced 2025-10-27 11:18:14 +01:00 
			
		
		
		
	Add:Recommended book home page shelf
This commit is contained in:
		
							parent
							
								
									030c20b12e
								
							
						
					
					
						commit
						49279430fc
					
				@ -820,7 +820,6 @@ export default {
 | 
				
			|||||||
        return null
 | 
					        return null
 | 
				
			||||||
      })
 | 
					      })
 | 
				
			||||||
      if (!libraryItem) return
 | 
					      if (!libraryItem) return
 | 
				
			||||||
      console.log('Got library itemn', libraryItem)
 | 
					 | 
				
			||||||
      this.store.commit('showEReader', libraryItem)
 | 
					      this.store.commit('showEReader', libraryItem)
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    selectBtnClick(evt) {
 | 
					    selectBtnClick(evt) {
 | 
				
			||||||
 | 
				
			|||||||
@ -308,6 +308,7 @@
 | 
				
			|||||||
  "LabelPublishYear": "Jahr",
 | 
					  "LabelPublishYear": "Jahr",
 | 
				
			||||||
  "LabelRecentlyAdded": "Kürzlich hinzugefügt",
 | 
					  "LabelRecentlyAdded": "Kürzlich hinzugefügt",
 | 
				
			||||||
  "LabelRecentSeries": "Aktuelle Serien",
 | 
					  "LabelRecentSeries": "Aktuelle Serien",
 | 
				
			||||||
 | 
					  "LabelRecommended": "Recommended",
 | 
				
			||||||
  "LabelRegion": "Region",
 | 
					  "LabelRegion": "Region",
 | 
				
			||||||
  "LabelReleaseDate": "Veröffentlichungsdatum",
 | 
					  "LabelReleaseDate": "Veröffentlichungsdatum",
 | 
				
			||||||
  "LabelRemoveCover": "Lösche Titelbild",
 | 
					  "LabelRemoveCover": "Lösche Titelbild",
 | 
				
			||||||
@ -640,4 +641,4 @@
 | 
				
			|||||||
  "WeekdayTuesday": "Dienstag",
 | 
					  "WeekdayTuesday": "Dienstag",
 | 
				
			||||||
  "WeekdayWed": "Wed",
 | 
					  "WeekdayWed": "Wed",
 | 
				
			||||||
  "WeekdayWednesday": "Mittwoch"
 | 
					  "WeekdayWednesday": "Mittwoch"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -308,6 +308,7 @@
 | 
				
			|||||||
  "LabelPublishYear": "Publish Year",
 | 
					  "LabelPublishYear": "Publish Year",
 | 
				
			||||||
  "LabelRecentlyAdded": "Recently Added",
 | 
					  "LabelRecentlyAdded": "Recently Added",
 | 
				
			||||||
  "LabelRecentSeries": "Recent Series",
 | 
					  "LabelRecentSeries": "Recent Series",
 | 
				
			||||||
 | 
					  "LabelRecommended": "Recommended",
 | 
				
			||||||
  "LabelRegion": "Region",
 | 
					  "LabelRegion": "Region",
 | 
				
			||||||
  "LabelReleaseDate": "Release Date",
 | 
					  "LabelReleaseDate": "Release Date",
 | 
				
			||||||
  "LabelRemoveCover": "Remove cover",
 | 
					  "LabelRemoveCover": "Remove cover",
 | 
				
			||||||
@ -640,4 +641,4 @@
 | 
				
			|||||||
  "WeekdayTuesday": "Tuesday",
 | 
					  "WeekdayTuesday": "Tuesday",
 | 
				
			||||||
  "WeekdayWed": "Wed",
 | 
					  "WeekdayWed": "Wed",
 | 
				
			||||||
  "WeekdayWednesday": "Wednesday"
 | 
					  "WeekdayWednesday": "Wednesday"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -308,6 +308,7 @@
 | 
				
			|||||||
  "LabelPublishYear": "Publish Year",
 | 
					  "LabelPublishYear": "Publish Year",
 | 
				
			||||||
  "LabelRecentlyAdded": "Recently Added",
 | 
					  "LabelRecentlyAdded": "Recently Added",
 | 
				
			||||||
  "LabelRecentSeries": "Recent Series",
 | 
					  "LabelRecentSeries": "Recent Series",
 | 
				
			||||||
 | 
					  "LabelRecommended": "Recommended",
 | 
				
			||||||
  "LabelRegion": "Region",
 | 
					  "LabelRegion": "Region",
 | 
				
			||||||
  "LabelReleaseDate": "Release Date",
 | 
					  "LabelReleaseDate": "Release Date",
 | 
				
			||||||
  "LabelRemoveCover": "Remove cover",
 | 
					  "LabelRemoveCover": "Remove cover",
 | 
				
			||||||
@ -640,4 +641,4 @@
 | 
				
			|||||||
  "WeekdayTuesday": "Tuesday",
 | 
					  "WeekdayTuesday": "Tuesday",
 | 
				
			||||||
  "WeekdayWed": "Wed",
 | 
					  "WeekdayWed": "Wed",
 | 
				
			||||||
  "WeekdayWednesday": "Wednesday"
 | 
					  "WeekdayWednesday": "Wednesday"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -308,6 +308,7 @@
 | 
				
			|||||||
  "LabelPublishYear": "Année d'Edition",
 | 
					  "LabelPublishYear": "Année d'Edition",
 | 
				
			||||||
  "LabelRecentlyAdded": "Derniers Ajouts",
 | 
					  "LabelRecentlyAdded": "Derniers Ajouts",
 | 
				
			||||||
  "LabelRecentSeries": "Séries Récentes",
 | 
					  "LabelRecentSeries": "Séries Récentes",
 | 
				
			||||||
 | 
					  "LabelRecommended": "Recommended",
 | 
				
			||||||
  "LabelRegion": "Région",
 | 
					  "LabelRegion": "Région",
 | 
				
			||||||
  "LabelReleaseDate": "Date de Parution",
 | 
					  "LabelReleaseDate": "Date de Parution",
 | 
				
			||||||
  "LabelRemoveCover": "Supprimer la Couverture",
 | 
					  "LabelRemoveCover": "Supprimer la Couverture",
 | 
				
			||||||
@ -640,4 +641,4 @@
 | 
				
			|||||||
  "WeekdayTuesday": "Mardi",
 | 
					  "WeekdayTuesday": "Mardi",
 | 
				
			||||||
  "WeekdayWed": "Mer",
 | 
					  "WeekdayWed": "Mer",
 | 
				
			||||||
  "WeekdayWednesday": "Mercredi"
 | 
					  "WeekdayWednesday": "Mercredi"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -308,6 +308,7 @@
 | 
				
			|||||||
  "LabelPublishYear": "Godina izdavanja",
 | 
					  "LabelPublishYear": "Godina izdavanja",
 | 
				
			||||||
  "LabelRecentlyAdded": "Nedavno dodano",
 | 
					  "LabelRecentlyAdded": "Nedavno dodano",
 | 
				
			||||||
  "LabelRecentSeries": "Nedavne serije",
 | 
					  "LabelRecentSeries": "Nedavne serije",
 | 
				
			||||||
 | 
					  "LabelRecommended": "Recommended",
 | 
				
			||||||
  "LabelRegion": "Regija",
 | 
					  "LabelRegion": "Regija",
 | 
				
			||||||
  "LabelReleaseDate": "Datum izlaska",
 | 
					  "LabelReleaseDate": "Datum izlaska",
 | 
				
			||||||
  "LabelRemoveCover": "Remove cover",
 | 
					  "LabelRemoveCover": "Remove cover",
 | 
				
			||||||
@ -640,4 +641,4 @@
 | 
				
			|||||||
  "WeekdayTuesday": "Utorak",
 | 
					  "WeekdayTuesday": "Utorak",
 | 
				
			||||||
  "WeekdayWed": "Wed",
 | 
					  "WeekdayWed": "Wed",
 | 
				
			||||||
  "WeekdayWednesday": "Srijeda"
 | 
					  "WeekdayWednesday": "Srijeda"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -308,6 +308,7 @@
 | 
				
			|||||||
  "LabelPublishYear": "Anno Pubblicazione",
 | 
					  "LabelPublishYear": "Anno Pubblicazione",
 | 
				
			||||||
  "LabelRecentlyAdded": "Aggiunti Recentemente",
 | 
					  "LabelRecentlyAdded": "Aggiunti Recentemente",
 | 
				
			||||||
  "LabelRecentSeries": "Serie Recenti",
 | 
					  "LabelRecentSeries": "Serie Recenti",
 | 
				
			||||||
 | 
					  "LabelRecommended": "Recommended",
 | 
				
			||||||
  "LabelRegion": "Regione",
 | 
					  "LabelRegion": "Regione",
 | 
				
			||||||
  "LabelReleaseDate": "Data Release",
 | 
					  "LabelReleaseDate": "Data Release",
 | 
				
			||||||
  "LabelRemoveCover": "Remove cover",
 | 
					  "LabelRemoveCover": "Remove cover",
 | 
				
			||||||
@ -640,4 +641,4 @@
 | 
				
			|||||||
  "WeekdayTuesday": "Martedì",
 | 
					  "WeekdayTuesday": "Martedì",
 | 
				
			||||||
  "WeekdayWed": "Mer",
 | 
					  "WeekdayWed": "Mer",
 | 
				
			||||||
  "WeekdayWednesday": "Mercoledì"
 | 
					  "WeekdayWednesday": "Mercoledì"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -308,6 +308,7 @@
 | 
				
			|||||||
  "LabelPublishYear": "Rok publikacji",
 | 
					  "LabelPublishYear": "Rok publikacji",
 | 
				
			||||||
  "LabelRecentlyAdded": "Niedawno dodany",
 | 
					  "LabelRecentlyAdded": "Niedawno dodany",
 | 
				
			||||||
  "LabelRecentSeries": "Ostatnie serie",
 | 
					  "LabelRecentSeries": "Ostatnie serie",
 | 
				
			||||||
 | 
					  "LabelRecommended": "Recommended",
 | 
				
			||||||
  "LabelRegion": "Region",
 | 
					  "LabelRegion": "Region",
 | 
				
			||||||
  "LabelReleaseDate": "Data wydania",
 | 
					  "LabelReleaseDate": "Data wydania",
 | 
				
			||||||
  "LabelRemoveCover": "Remove cover",
 | 
					  "LabelRemoveCover": "Remove cover",
 | 
				
			||||||
@ -640,4 +641,4 @@
 | 
				
			|||||||
  "WeekdayTuesday": "Wtorek",
 | 
					  "WeekdayTuesday": "Wtorek",
 | 
				
			||||||
  "WeekdayWed": "Wed",
 | 
					  "WeekdayWed": "Wed",
 | 
				
			||||||
  "WeekdayWednesday": "Środa"
 | 
					  "WeekdayWednesday": "Środa"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -308,6 +308,7 @@
 | 
				
			|||||||
  "LabelPublishYear": "发布年份",
 | 
					  "LabelPublishYear": "发布年份",
 | 
				
			||||||
  "LabelRecentlyAdded": "最近添加",
 | 
					  "LabelRecentlyAdded": "最近添加",
 | 
				
			||||||
  "LabelRecentSeries": "最近添加系列",
 | 
					  "LabelRecentSeries": "最近添加系列",
 | 
				
			||||||
 | 
					  "LabelRecommended": "Recommended",
 | 
				
			||||||
  "LabelRegion": "区域",
 | 
					  "LabelRegion": "区域",
 | 
				
			||||||
  "LabelReleaseDate": "发布日期",
 | 
					  "LabelReleaseDate": "发布日期",
 | 
				
			||||||
  "LabelRemoveCover": "移除封面",
 | 
					  "LabelRemoveCover": "移除封面",
 | 
				
			||||||
@ -640,4 +641,4 @@
 | 
				
			|||||||
  "WeekdayTuesday": "星期二",
 | 
					  "WeekdayTuesday": "星期二",
 | 
				
			||||||
  "WeekdayWed": "Wed",
 | 
					  "WeekdayWed": "Wed",
 | 
				
			||||||
  "WeekdayWednesday": "星期三"
 | 
					  "WeekdayWednesday": "星期三"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -339,6 +339,14 @@ module.exports = {
 | 
				
			|||||||
        entities: [],
 | 
					        entities: [],
 | 
				
			||||||
        category: 'continueSeries'
 | 
					        category: 'continueSeries'
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        id: 'episodes-recently-added',
 | 
				
			||||||
 | 
					        label: 'Newest Episodes',
 | 
				
			||||||
 | 
					        labelStringKey: 'LabelNewestEpisodes',
 | 
				
			||||||
 | 
					        type: 'episode',
 | 
				
			||||||
 | 
					        entities: [],
 | 
				
			||||||
 | 
					        category: 'newestEpisodes'
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
      {
 | 
					      {
 | 
				
			||||||
        id: 'recently-added',
 | 
					        id: 'recently-added',
 | 
				
			||||||
        label: 'Recently Added',
 | 
					        label: 'Recently Added',
 | 
				
			||||||
@ -347,14 +355,6 @@ module.exports = {
 | 
				
			|||||||
        entities: [],
 | 
					        entities: [],
 | 
				
			||||||
        category: 'newestItems'
 | 
					        category: 'newestItems'
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
      {
 | 
					 | 
				
			||||||
        id: 'listen-again',
 | 
					 | 
				
			||||||
        label: 'Listen Again',
 | 
					 | 
				
			||||||
        labelStringKey: 'LabelListenAgain',
 | 
					 | 
				
			||||||
        type: isPodcastLibrary ? 'episode' : mediaType,
 | 
					 | 
				
			||||||
        entities: [],
 | 
					 | 
				
			||||||
        category: 'recentlyFinished'
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      {
 | 
					      {
 | 
				
			||||||
        id: 'recent-series',
 | 
					        id: 'recent-series',
 | 
				
			||||||
        label: 'Recent Series',
 | 
					        label: 'Recent Series',
 | 
				
			||||||
@ -363,6 +363,22 @@ module.exports = {
 | 
				
			|||||||
        entities: [],
 | 
					        entities: [],
 | 
				
			||||||
        category: 'newestSeries'
 | 
					        category: 'newestSeries'
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        id: 'recommended',
 | 
				
			||||||
 | 
					        label: 'Recommended',
 | 
				
			||||||
 | 
					        labelStringKey: 'LabelRecommended',
 | 
				
			||||||
 | 
					        type: mediaType,
 | 
				
			||||||
 | 
					        entities: [],
 | 
				
			||||||
 | 
					        category: 'recommended'
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        id: 'listen-again',
 | 
				
			||||||
 | 
					        label: 'Listen Again',
 | 
				
			||||||
 | 
					        labelStringKey: 'LabelListenAgain',
 | 
				
			||||||
 | 
					        type: isPodcastLibrary ? 'episode' : mediaType,
 | 
				
			||||||
 | 
					        entities: [],
 | 
				
			||||||
 | 
					        category: 'recentlyFinished'
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
      {
 | 
					      {
 | 
				
			||||||
        id: 'newest-authors',
 | 
					        id: 'newest-authors',
 | 
				
			||||||
        label: 'Newest Authors',
 | 
					        label: 'Newest Authors',
 | 
				
			||||||
@ -370,22 +386,13 @@ module.exports = {
 | 
				
			|||||||
        type: 'authors',
 | 
					        type: 'authors',
 | 
				
			||||||
        entities: [],
 | 
					        entities: [],
 | 
				
			||||||
        category: 'newestAuthors'
 | 
					        category: 'newestAuthors'
 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      {
 | 
					 | 
				
			||||||
        id: 'episodes-recently-added',
 | 
					 | 
				
			||||||
        label: 'Newest Episodes',
 | 
					 | 
				
			||||||
        labelStringKey: 'LabelNewestEpisodes',
 | 
					 | 
				
			||||||
        type: 'episode',
 | 
					 | 
				
			||||||
        entities: [],
 | 
					 | 
				
			||||||
        category: 'newestEpisodes'
 | 
					 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    ]
 | 
					    ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const categories = ['recentlyListened', 'continueSeries', 'newestEpisodes', 'newestItems', 'newestSeries', 'recentlyFinished', 'newestAuthors']
 | 
					 | 
				
			||||||
    const categoryMap = {}
 | 
					    const categoryMap = {}
 | 
				
			||||||
    categories.forEach((cat) => {
 | 
					    shelves.forEach((shelf) => {
 | 
				
			||||||
      categoryMap[cat] = {
 | 
					      categoryMap[shelf.category] = {
 | 
				
			||||||
        category: cat,
 | 
					        category: shelf.category,
 | 
				
			||||||
        biggest: 0,
 | 
					        biggest: 0,
 | 
				
			||||||
        smallest: 0,
 | 
					        smallest: 0,
 | 
				
			||||||
        items: []
 | 
					        items: []
 | 
				
			||||||
@ -395,6 +402,12 @@ module.exports = {
 | 
				
			|||||||
    const seriesMap = {}
 | 
					    const seriesMap = {}
 | 
				
			||||||
    const authorMap = {}
 | 
					    const authorMap = {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // For use with recommended
 | 
				
			||||||
 | 
					    const topGenresListened = {}
 | 
				
			||||||
 | 
					    const topAuthorsListened = {}
 | 
				
			||||||
 | 
					    const topTagsListened = {}
 | 
				
			||||||
 | 
					    const notStartedBooks = []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for (const libraryItem of libraryItems) {
 | 
					    for (const libraryItem of libraryItems) {
 | 
				
			||||||
      if (libraryItem.addedAt > categoryMap.newestItems.smallest) {
 | 
					      if (libraryItem.addedAt > categoryMap.newestItems.smallest) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -494,10 +507,28 @@ module.exports = {
 | 
				
			|||||||
      } else if (libraryItem.isBook) {
 | 
					      } else if (libraryItem.isBook) {
 | 
				
			||||||
        // Book categories
 | 
					        // Book categories
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        const mediaProgress = allItemProgress.length ? allItemProgress[0] : null
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Used for recommended. Tally up most listened to authors/genres/tags
 | 
				
			||||||
 | 
					        if (mediaProgress && (mediaProgress.inProgress || mediaProgress.isFinished)) {
 | 
				
			||||||
 | 
					          libraryItem.media.metadata.authors.forEach((author) => {
 | 
				
			||||||
 | 
					            topAuthorsListened[author.id] = (topAuthorsListened[author.id] || 0) + 1
 | 
				
			||||||
 | 
					          })
 | 
				
			||||||
 | 
					          libraryItem.media.metadata.genres.forEach((genre) => {
 | 
				
			||||||
 | 
					            topGenresListened[genre] = (topGenresListened[genre] || 0) + 1
 | 
				
			||||||
 | 
					          })
 | 
				
			||||||
 | 
					          libraryItem.media.tags.forEach((tag) => {
 | 
				
			||||||
 | 
					            topTagsListened[tag] = (topTagsListened[tag] || 0) + 1
 | 
				
			||||||
 | 
					          })
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					          // Insert in random position to add randomization to equal weighted items
 | 
				
			||||||
 | 
					          notStartedBooks.splice(Math.floor(Math.random() * (notStartedBooks.length + 1)), 0, libraryItem)
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Newest series
 | 
					        // Newest series
 | 
				
			||||||
        if (libraryItem.media.metadata.series.length) {
 | 
					        if (libraryItem.media.metadata.series.length) {
 | 
				
			||||||
          for (const librarySeries of libraryItem.media.metadata.series) {
 | 
					          for (const librarySeries of libraryItem.media.metadata.series) {
 | 
				
			||||||
            const mediaProgress = allItemProgress.length ? allItemProgress[0] : null
 | 
					
 | 
				
			||||||
            const bookInProgress = mediaProgress && (mediaProgress.inProgress || mediaProgress.isFinished)
 | 
					            const bookInProgress = mediaProgress && (mediaProgress.inProgress || mediaProgress.isFinished)
 | 
				
			||||||
            const bookActive = mediaProgress && mediaProgress.inProgress && !mediaProgress.isFinished
 | 
					            const bookActive = mediaProgress && mediaProgress.inProgress && !mediaProgress.isFinished
 | 
				
			||||||
            const libraryItemJson = libraryItem.toJSONMinified()
 | 
					            const libraryItemJson = libraryItem.toJSONMinified()
 | 
				
			||||||
@ -602,7 +633,6 @@ module.exports = {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Book listening and finished
 | 
					        // Book listening and finished
 | 
				
			||||||
        var mediaProgress = allItemProgress.length ? allItemProgress[0] : null
 | 
					 | 
				
			||||||
        if (mediaProgress) {
 | 
					        if (mediaProgress) {
 | 
				
			||||||
          // Handle most recently finished
 | 
					          // Handle most recently finished
 | 
				
			||||||
          if (mediaProgress.isFinished) {
 | 
					          if (mediaProgress.isFinished) {
 | 
				
			||||||
@ -612,7 +642,7 @@ module.exports = {
 | 
				
			|||||||
                finishedAt: mediaProgress.finishedAt
 | 
					                finishedAt: mediaProgress.finishedAt
 | 
				
			||||||
              }
 | 
					              }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
              var indexToPut = categoryMap.recentlyFinished.items.findIndex(i => mediaProgress.finishedAt > i.finishedAt)
 | 
					              const indexToPut = categoryMap.recentlyFinished.items.findIndex(i => mediaProgress.finishedAt > i.finishedAt)
 | 
				
			||||||
              if (indexToPut >= 0) {
 | 
					              if (indexToPut >= 0) {
 | 
				
			||||||
                categoryMap.recentlyFinished.items.splice(indexToPut, 0, libraryItemObj)
 | 
					                categoryMap.recentlyFinished.items.splice(indexToPut, 0, libraryItemObj)
 | 
				
			||||||
              } else {
 | 
					              } else {
 | 
				
			||||||
@ -632,7 +662,7 @@ module.exports = {
 | 
				
			|||||||
                progressLastUpdate: mediaProgress.lastUpdate
 | 
					                progressLastUpdate: mediaProgress.lastUpdate
 | 
				
			||||||
              }
 | 
					              }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
              var indexToPut = categoryMap.recentlyListened.items.findIndex(i => mediaProgress.lastUpdate > i.progressLastUpdate)
 | 
					              const indexToPut = categoryMap.recentlyListened.items.findIndex(i => mediaProgress.lastUpdate > i.progressLastUpdate)
 | 
				
			||||||
              if (indexToPut >= 0) {
 | 
					              if (indexToPut >= 0) {
 | 
				
			||||||
                categoryMap.recentlyListened.items.splice(indexToPut, 0, libraryItemObj)
 | 
					                categoryMap.recentlyListened.items.splice(indexToPut, 0, libraryItemObj)
 | 
				
			||||||
              } else { // Should only happen when array is < max
 | 
					              } else { // Should only happen when array is < max
 | 
				
			||||||
@ -652,9 +682,9 @@ module.exports = {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    // For Continue Series - Find next book in series for series that are in progress
 | 
					    // For Continue Series - Find next book in series for series that are in progress
 | 
				
			||||||
    for (const seriesId in seriesMap) {
 | 
					    for (const seriesId in seriesMap) {
 | 
				
			||||||
      if (seriesMap[seriesId].inProgress && !seriesMap[seriesId].hideFromContinueListening) {
 | 
					      seriesMap[seriesId].books = naturalSort(seriesMap[seriesId].books).asc(li => li.seriesSequence)
 | 
				
			||||||
        seriesMap[seriesId].books = naturalSort(seriesMap[seriesId].books).asc(li => li.seriesSequence)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      if (seriesMap[seriesId].inProgress && !seriesMap[seriesId].hideFromContinueListening) {
 | 
				
			||||||
        // take the first book unread with the smallest series sequence
 | 
					        // take the first book unread with the smallest series sequence
 | 
				
			||||||
        // unless the user is already listening to a book from this series
 | 
					        // unless the user is already listening to a book from this series
 | 
				
			||||||
        const hasActiveBook = seriesMap[seriesId].hasActiveBook
 | 
					        const hasActiveBook = seriesMap[seriesId].hasActiveBook
 | 
				
			||||||
@ -683,6 +713,76 @@ module.exports = {
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // For recommended
 | 
				
			||||||
 | 
					    if (!isPodcastLibrary && notStartedBooks.length) {
 | 
				
			||||||
 | 
					      const genresCount = Object.values(topGenresListened).reduce((a, b) => a + b, 0)
 | 
				
			||||||
 | 
					      const authorsCount = Object.values(topAuthorsListened).reduce((a, b) => a + b, 0)
 | 
				
			||||||
 | 
					      const tagsCount = Object.values(topTagsListened).reduce((a, b) => a + b, 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      for (const libraryItem of notStartedBooks) {
 | 
				
			||||||
 | 
					        // dont include books in an unfinished series and books that are not first in an unstarted series
 | 
				
			||||||
 | 
					        let shouldContinue = !libraryItem.media.metadata.series.length
 | 
				
			||||||
 | 
					        libraryItem.media.metadata.series.forEach((se) => {
 | 
				
			||||||
 | 
					          if (seriesMap[se.id]) {
 | 
				
			||||||
 | 
					            if (seriesMap[se.id].inProgress) {
 | 
				
			||||||
 | 
					              shouldContinue = false
 | 
				
			||||||
 | 
					              return
 | 
				
			||||||
 | 
					            } else if (seriesMap[se.id].books[0].id === libraryItem.id) {
 | 
				
			||||||
 | 
					              shouldContinue = true
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					        if (!shouldContinue) {
 | 
				
			||||||
 | 
					          continue;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let totalWeight = 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (authorsCount > 0) {
 | 
				
			||||||
 | 
					          libraryItem.media.metadata.authors.forEach((author) => {
 | 
				
			||||||
 | 
					            if (topAuthorsListened[author.id]) {
 | 
				
			||||||
 | 
					              totalWeight += topAuthorsListened[author.id] / authorsCount
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          })
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (genresCount > 0) {
 | 
				
			||||||
 | 
					          libraryItem.media.metadata.genres.forEach((genre) => {
 | 
				
			||||||
 | 
					            if (topGenresListened[genre]) {
 | 
				
			||||||
 | 
					              totalWeight += topGenresListened[genre] / genresCount
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          })
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (tagsCount > 0) {
 | 
				
			||||||
 | 
					          libraryItem.media.tags.forEach((tag) => {
 | 
				
			||||||
 | 
					            if (topTagsListened[tag]) {
 | 
				
			||||||
 | 
					              totalWeight += topTagsListened[tag] / tagsCount
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          })
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!categoryMap.recommended.smallest || totalWeight > categoryMap.recommended.smallest) {
 | 
				
			||||||
 | 
					          const libraryItemObj = {
 | 
				
			||||||
 | 
					            ...libraryItem.toJSONMinified(),
 | 
				
			||||||
 | 
					            weight: totalWeight
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          const indexToPut = categoryMap.recommended.items.findIndex(i => totalWeight > i.weight)
 | 
				
			||||||
 | 
					          if (indexToPut >= 0) {
 | 
				
			||||||
 | 
					            categoryMap.recommended.items.splice(indexToPut, 0, libraryItemObj)
 | 
				
			||||||
 | 
					          } else {
 | 
				
			||||||
 | 
					            categoryMap.recommended.items.push(libraryItemObj)
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          if (categoryMap.recommended.items.length > maxEntitiesPerShelf) {
 | 
				
			||||||
 | 
					            categoryMap.recommended.items.pop()
 | 
				
			||||||
 | 
					            categoryMap.recommended.smallest = categoryMap.recommended.items[categoryMap.recommended.items.length - 1].weight
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Sort series books by sequence
 | 
					    // Sort series books by sequence
 | 
				
			||||||
    if (categoryMap.newestSeries.items.length) {
 | 
					    if (categoryMap.newestSeries.items.length) {
 | 
				
			||||||
      for (const seriesItem of categoryMap.newestSeries.items) {
 | 
					      for (const seriesItem of categoryMap.newestSeries.items) {
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user