From 3e4c94e2b4e151aaf985c1b2ded3d8d191d49fcf Mon Sep 17 00:00:00 2001 From: advplyr Date: Sat, 27 May 2023 08:20:09 -0500 Subject: [PATCH] Update:Continue Reading and Read Again home page shelves for ebook only items #1782 --- client/components/cards/LazyBookCard.vue | 6 +- client/strings/de.json | 4 +- client/strings/en-us.json | 2 + client/strings/es.json | 2 + client/strings/fr.json | 2 + client/strings/gu.json | 2 + client/strings/hi.json | 2 + client/strings/hr.json | 2 + client/strings/it.json | 2 + client/strings/nl.json | 2 + client/strings/pl.json | 2 + client/strings/ru.json | 2 + client/strings/zh-cn.json | 2 + server/objects/mediaTypes/Book.js | 3 + server/objects/user/MediaProgress.js | 2 +- server/utils/libraryHelpers.js | 190 ++++++++++++----------- 16 files changed, 132 insertions(+), 95 deletions(-) diff --git a/client/components/cards/LazyBookCard.vue b/client/components/cards/LazyBookCard.vue index a6d79c32..578c1e9b 100644 --- a/client/components/cards/LazyBookCard.vue +++ b/client/components/cards/LazyBookCard.vue @@ -256,14 +256,14 @@ export default { }, booksInSeries() { // Only added to item object when collapseSeries is enabled - return this.collapsedSeries ? this.collapsedSeries.numBooks : 0 + return this.collapsedSeries?.numBooks || 0 }, seriesSequenceList() { - return this.collapsedSeries ? this.collapsedSeries.seriesSequenceList : null + return this.collapsedSeries?.seriesSequenceList || null }, libraryItemIdsInSeries() { // Only added to item object when collapseSeries is enabled - return this.collapsedSeries ? this.collapsedSeries.libraryItemIds || [] : [] + return this.collapsedSeries?.libraryItemIds || [] }, hasCover() { return !!this.media.coverPath diff --git a/client/strings/de.json b/client/strings/de.json index dc9cea71..7d5f685e 100644 --- a/client/strings/de.json +++ b/client/strings/de.json @@ -197,6 +197,7 @@ "LabelComplete": "Vollständig", "LabelConfirmPassword": "Passwort bestätigen", "LabelContinueListening": "Weiterhören", + "LabelContinueReading": "Continue Reading", "LabelContinueSeries": "Serien fortsetzen", "LabelCover": "Titelbild", "LabelCoverImageURL": "URL des Titelbildes", @@ -331,6 +332,7 @@ "LabelPubDate": "Veröffentlichungsdatum", "LabelPublisher": "Herausgeber", "LabelPublishYear": "Jahr", + "LabelReadAgain": "Read Again", "LabelRecentlyAdded": "Kürzlich hinzugefügt", "LabelRecentSeries": "Aktuelle Serien", "LabelRecommended": "Empfohlen", @@ -654,4 +656,4 @@ "ToastSocketFailedToConnect": "Verbindung zum WebSocket fehlgeschlagen", "ToastUserDeleteFailed": "Benutzer konnte nicht gelöscht werden", "ToastUserDeleteSuccess": "Benutzer gelöscht" -} +} \ No newline at end of file diff --git a/client/strings/en-us.json b/client/strings/en-us.json index 72b1fb1e..e69c891d 100644 --- a/client/strings/en-us.json +++ b/client/strings/en-us.json @@ -197,6 +197,7 @@ "LabelComplete": "Complete", "LabelConfirmPassword": "Confirm Password", "LabelContinueListening": "Continue Listening", + "LabelContinueReading": "Continue Reading", "LabelContinueSeries": "Continue Series", "LabelCover": "Cover", "LabelCoverImageURL": "Cover Image URL", @@ -331,6 +332,7 @@ "LabelPubDate": "Pub Date", "LabelPublisher": "Publisher", "LabelPublishYear": "Publish Year", + "LabelReadAgain": "Read Again", "LabelRecentlyAdded": "Recently Added", "LabelRecentSeries": "Recent Series", "LabelRecommended": "Recommended", diff --git a/client/strings/es.json b/client/strings/es.json index 7006b95d..948f8308 100644 --- a/client/strings/es.json +++ b/client/strings/es.json @@ -197,6 +197,7 @@ "LabelComplete": "Completo", "LabelConfirmPassword": "Confirmar Contraseña", "LabelContinueListening": "Continuar Escuchando", + "LabelContinueReading": "Continue Reading", "LabelContinueSeries": "Continuar Series", "LabelCover": "Portada", "LabelCoverImageURL": "URL de Imagen de Portada", @@ -331,6 +332,7 @@ "LabelPubDate": "Fecha de Publicación", "LabelPublisher": "Editor", "LabelPublishYear": "Año de Publicación", + "LabelReadAgain": "Read Again", "LabelRecentlyAdded": "Agregado Reciente", "LabelRecentSeries": "Series Recientes", "LabelRecommended": "Recomendados", diff --git a/client/strings/fr.json b/client/strings/fr.json index 70ee629b..e6a1e448 100644 --- a/client/strings/fr.json +++ b/client/strings/fr.json @@ -197,6 +197,7 @@ "LabelComplete": "Complet", "LabelConfirmPassword": "Confirmer le mot de passe", "LabelContinueListening": "Continuer la lecture", + "LabelContinueReading": "Continue Reading", "LabelContinueSeries": "Continuer la série", "LabelCover": "Couverture", "LabelCoverImageURL": "URL vers l’image de couverture", @@ -331,6 +332,7 @@ "LabelPubDate": "Date de publication", "LabelPublisher": "Éditeur", "LabelPublishYear": "Année d’édition", + "LabelReadAgain": "Read Again", "LabelRecentlyAdded": "Derniers ajouts", "LabelRecentSeries": "Séries récentes", "LabelRecommended": "Recommandé", diff --git a/client/strings/gu.json b/client/strings/gu.json index 5cd23a02..98e5488e 100644 --- a/client/strings/gu.json +++ b/client/strings/gu.json @@ -197,6 +197,7 @@ "LabelComplete": "Complete", "LabelConfirmPassword": "Confirm Password", "LabelContinueListening": "Continue Listening", + "LabelContinueReading": "Continue Reading", "LabelContinueSeries": "Continue Series", "LabelCover": "Cover", "LabelCoverImageURL": "Cover Image URL", @@ -331,6 +332,7 @@ "LabelPubDate": "Pub Date", "LabelPublisher": "Publisher", "LabelPublishYear": "Publish Year", + "LabelReadAgain": "Read Again", "LabelRecentlyAdded": "Recently Added", "LabelRecentSeries": "Recent Series", "LabelRecommended": "Recommended", diff --git a/client/strings/hi.json b/client/strings/hi.json index 6e8e82a6..5cb063ee 100644 --- a/client/strings/hi.json +++ b/client/strings/hi.json @@ -197,6 +197,7 @@ "LabelComplete": "Complete", "LabelConfirmPassword": "Confirm Password", "LabelContinueListening": "Continue Listening", + "LabelContinueReading": "Continue Reading", "LabelContinueSeries": "Continue Series", "LabelCover": "Cover", "LabelCoverImageURL": "Cover Image URL", @@ -331,6 +332,7 @@ "LabelPubDate": "Pub Date", "LabelPublisher": "Publisher", "LabelPublishYear": "Publish Year", + "LabelReadAgain": "Read Again", "LabelRecentlyAdded": "Recently Added", "LabelRecentSeries": "Recent Series", "LabelRecommended": "Recommended", diff --git a/client/strings/hr.json b/client/strings/hr.json index 35ad18a1..39990e3a 100644 --- a/client/strings/hr.json +++ b/client/strings/hr.json @@ -197,6 +197,7 @@ "LabelComplete": "Complete", "LabelConfirmPassword": "Potvrdi lozinku", "LabelContinueListening": "Nastavi slušanje", + "LabelContinueReading": "Continue Reading", "LabelContinueSeries": "Nastavi seriju", "LabelCover": "Cover", "LabelCoverImageURL": "URL od covera", @@ -331,6 +332,7 @@ "LabelPubDate": "Datam izdavanja", "LabelPublisher": "Izdavač", "LabelPublishYear": "Godina izdavanja", + "LabelReadAgain": "Read Again", "LabelRecentlyAdded": "Nedavno dodano", "LabelRecentSeries": "Nedavne serije", "LabelRecommended": "Recommended", diff --git a/client/strings/it.json b/client/strings/it.json index d4d877cc..dcaa68bd 100644 --- a/client/strings/it.json +++ b/client/strings/it.json @@ -197,6 +197,7 @@ "LabelComplete": "Completo", "LabelConfirmPassword": "Conferma Password", "LabelContinueListening": "Continua ad Ascoltare", + "LabelContinueReading": "Continue Reading", "LabelContinueSeries": "Continua Serie", "LabelCover": "Cover", "LabelCoverImageURL": "Cover Image URL", @@ -331,6 +332,7 @@ "LabelPubDate": "Data Pubblicazione", "LabelPublisher": "Editore", "LabelPublishYear": "Anno Pubblicazione", + "LabelReadAgain": "Read Again", "LabelRecentlyAdded": "Aggiunti Recentemente", "LabelRecentSeries": "Serie Recenti", "LabelRecommended": "Raccomandati", diff --git a/client/strings/nl.json b/client/strings/nl.json index b0274943..c6646a74 100644 --- a/client/strings/nl.json +++ b/client/strings/nl.json @@ -197,6 +197,7 @@ "LabelComplete": "Compleet", "LabelConfirmPassword": "Bevestig wachtwoord", "LabelContinueListening": "Verder luisteren", + "LabelContinueReading": "Continue Reading", "LabelContinueSeries": "Ga verder met serie", "LabelCover": "Cover", "LabelCoverImageURL": "Coverafbeelding URL", @@ -331,6 +332,7 @@ "LabelPubDate": "Publicatiedatum", "LabelPublisher": "Uitgever", "LabelPublishYear": "Jaar van uitgave", + "LabelReadAgain": "Read Again", "LabelRecentlyAdded": "Recent toegevoegd", "LabelRecentSeries": "Recente series", "LabelRecommended": "Aangeraden", diff --git a/client/strings/pl.json b/client/strings/pl.json index 5a5ad81c..377bebef 100644 --- a/client/strings/pl.json +++ b/client/strings/pl.json @@ -197,6 +197,7 @@ "LabelComplete": "Ukończone", "LabelConfirmPassword": "Potwierdź hasło", "LabelContinueListening": "Kontynuuj odtwarzanie", + "LabelContinueReading": "Continue Reading", "LabelContinueSeries": "Kontynuuj serię", "LabelCover": "Okładka", "LabelCoverImageURL": "URL okładki", @@ -331,6 +332,7 @@ "LabelPubDate": "Data publikacji", "LabelPublisher": "Wydawca", "LabelPublishYear": "Rok publikacji", + "LabelReadAgain": "Read Again", "LabelRecentlyAdded": "Niedawno dodany", "LabelRecentSeries": "Ostatnie serie", "LabelRecommended": "Recommended", diff --git a/client/strings/ru.json b/client/strings/ru.json index f3650ba3..b62b8cd8 100644 --- a/client/strings/ru.json +++ b/client/strings/ru.json @@ -197,6 +197,7 @@ "LabelComplete": "Завершить", "LabelConfirmPassword": "Подтвердить пароль", "LabelContinueListening": "Продолжить слушать", + "LabelContinueReading": "Continue Reading", "LabelContinueSeries": "Продолжить серию", "LabelCover": "Обложка", "LabelCoverImageURL": "URL изображения обложки", @@ -331,6 +332,7 @@ "LabelPubDate": "Дата публикации", "LabelPublisher": "Издатель", "LabelPublishYear": "Год публикации", + "LabelReadAgain": "Read Again", "LabelRecentlyAdded": "Недавно добавленные", "LabelRecentSeries": "Последние серии", "LabelRecommended": "Рекомендованное", diff --git a/client/strings/zh-cn.json b/client/strings/zh-cn.json index d9e0a774..90367c23 100644 --- a/client/strings/zh-cn.json +++ b/client/strings/zh-cn.json @@ -197,6 +197,7 @@ "LabelComplete": "已完成", "LabelConfirmPassword": "确认密码", "LabelContinueListening": "继续收听", + "LabelContinueReading": "Continue Reading", "LabelContinueSeries": "继续收听系列", "LabelCover": "封面", "LabelCoverImageURL": "封面图像 URL", @@ -331,6 +332,7 @@ "LabelPubDate": "出版日期", "LabelPublisher": "出版商", "LabelPublishYear": "发布年份", + "LabelReadAgain": "Read Again", "LabelRecentlyAdded": "最近添加", "LabelRecentSeries": "最近添加系列", "LabelRecommended": "推荐内容", diff --git a/server/objects/mediaTypes/Book.js b/server/objects/mediaTypes/Book.js index c1e4dc99..8cd2c584 100644 --- a/server/objects/mediaTypes/Book.js +++ b/server/objects/mediaTypes/Book.js @@ -142,6 +142,9 @@ class Book { get numTracks() { return this.tracks.length } + get isEBookOnly() { + return this.ebookFile && !this.numTracks + } update(payload) { const json = this.toJSON() diff --git a/server/objects/user/MediaProgress.js b/server/objects/user/MediaProgress.js index 3d0de737..8c813a3b 100644 --- a/server/objects/user/MediaProgress.js +++ b/server/objects/user/MediaProgress.js @@ -57,7 +57,7 @@ class MediaProgress { } get inProgress() { - return !this.isFinished && (this.progress > 0 || this.ebookLocation != null) + return !this.isFinished && (this.progress > 0 || (this.ebookLocation != null && this.ebookProgress > 0)) } setData(libraryItemId, progress, episodeId = null) { diff --git a/server/utils/libraryHelpers.js b/server/utils/libraryHelpers.js index 7063dd2f..f7dd1c7f 100644 --- a/server/utils/libraryHelpers.js +++ b/server/utils/libraryHelpers.js @@ -346,71 +346,77 @@ module.exports = { label: 'Continue Listening', labelStringKey: 'LabelContinueListening', type: isPodcastLibrary ? 'episode' : mediaType, - entities: [], - category: 'recentlyListened' + entities: [] + }, + { + id: 'continue-reading', + label: 'Continue Reading', + labelStringKey: 'LabelContinueReading', + type: 'book', + entities: [] }, { id: 'continue-series', label: 'Continue Series', labelStringKey: 'LabelContinueSeries', type: mediaType, - entities: [], - category: 'continueSeries' + entities: [] }, { id: 'episodes-recently-added', label: 'Newest Episodes', labelStringKey: 'LabelNewestEpisodes', type: 'episode', - entities: [], - category: 'newestEpisodes' + entities: [] }, { id: 'recently-added', label: 'Recently Added', labelStringKey: 'LabelRecentlyAdded', type: mediaType, - entities: [], - category: 'newestItems' + entities: [] }, { id: 'recent-series', label: 'Recent Series', labelStringKey: 'LabelRecentSeries', type: 'series', - entities: [], - category: 'newestSeries' + entities: [] }, { id: 'recommended', label: 'Recommended', labelStringKey: 'LabelRecommended', type: mediaType, - entities: [], - category: 'recommended' + entities: [] }, { id: 'listen-again', label: 'Listen Again', labelStringKey: 'LabelListenAgain', type: isPodcastLibrary ? 'episode' : mediaType, - entities: [], - category: 'recentlyFinished' + entities: [] + }, + { + id: 'read-again', + label: 'Read Again', + labelStringKey: 'LabelReadAgain', + type: 'book', + entities: [] }, { id: 'newest-authors', label: 'Newest Authors', labelStringKey: 'LabelNewestAuthors', type: 'authors', - entities: [], - category: 'newestAuthors' + entities: [] } ] const categoryMap = {} shelves.forEach((shelf) => { - categoryMap[shelf.category] = { - category: shelf.category, + categoryMap[shelf.id] = { + id: shelf.id, biggest: 0, smallest: 0, items: [] @@ -427,21 +433,21 @@ module.exports = { const notStartedBooks = [] for (const libraryItem of libraryItems) { - if (libraryItem.addedAt > categoryMap.newestItems.smallest) { + if (libraryItem.addedAt > categoryMap['recently-added'].smallest) { - const indexToPut = categoryMap.newestItems.items.findIndex(i => libraryItem.addedAt > i.addedAt) + const indexToPut = categoryMap['recently-added'].items.findIndex(i => libraryItem.addedAt > i.addedAt) if (indexToPut >= 0) { - categoryMap.newestItems.items.splice(indexToPut, 0, libraryItem.toJSONMinified()) + categoryMap['recently-added'].items.splice(indexToPut, 0, libraryItem.toJSONMinified()) } else { - categoryMap.newestItems.items.push(libraryItem.toJSONMinified()) + categoryMap['recently-added'].items.push(libraryItem.toJSONMinified()) } - if (categoryMap.newestItems.items.length > maxEntitiesPerShelf) { + if (categoryMap['recently-added'].items.length > maxEntitiesPerShelf) { // Remove last item - categoryMap.newestItems.items.pop() - categoryMap.newestItems.smallest = categoryMap.newestItems.items[categoryMap.newestItems.items.length - 1].addedAt + categoryMap['recently-added'].items.pop() + categoryMap['recently-added'].smallest = categoryMap['recently-added'].items[categoryMap['recently-added'].items.length - 1].addedAt } - categoryMap.newestItems.biggest = categoryMap.newestItems.items[0].addedAt + categoryMap['recently-added'].biggest = categoryMap['recently-added'].items[0].addedAt } const allItemProgress = user.getAllMediaProgressForLibraryItem(libraryItem.id) @@ -450,74 +456,74 @@ module.exports = { const podcastEpisodes = libraryItem.media.episodes || [] for (const episode of podcastEpisodes) { // Newest episodes - if (episode.addedAt > categoryMap.newestEpisodes.smallest) { + if (episode.addedAt > categoryMap['episodes-recently-added'].smallest) { const libraryItemWithEpisode = { ...libraryItem.toJSONMinified(), recentEpisode: episode.toJSON() } - const indexToPut = categoryMap.newestEpisodes.items.findIndex(i => episode.addedAt > i.recentEpisode.addedAt) + const indexToPut = categoryMap['episodes-recently-added'].items.findIndex(i => episode.addedAt > i.recentEpisode.addedAt) if (indexToPut >= 0) { - categoryMap.newestEpisodes.items.splice(indexToPut, 0, libraryItemWithEpisode) + categoryMap['episodes-recently-added'].items.splice(indexToPut, 0, libraryItemWithEpisode) } else { - categoryMap.newestEpisodes.items.push(libraryItemWithEpisode) + categoryMap['episodes-recently-added'].items.push(libraryItemWithEpisode) } - if (categoryMap.newestEpisodes.items.length > maxEntitiesPerShelf) { + if (categoryMap['episodes-recently-added'].items.length > maxEntitiesPerShelf) { // Remove last item - categoryMap.newestEpisodes.items.pop() - categoryMap.newestEpisodes.smallest = categoryMap.newestEpisodes.items[categoryMap.newestEpisodes.items.length - 1].recentEpisode.addedAt + categoryMap['episodes-recently-added'].items.pop() + categoryMap['episodes-recently-added'].smallest = categoryMap['episodes-recently-added'].items[categoryMap['episodes-recently-added'].items.length - 1].recentEpisode.addedAt } - categoryMap.newestEpisodes.biggest = categoryMap.newestEpisodes.items[0].recentEpisode.addedAt + categoryMap['episodes-recently-added'].biggest = categoryMap['episodes-recently-added'].items[0].recentEpisode.addedAt } // Episode recently listened and finished const mediaProgress = allItemProgress.find(mp => mp.episodeId === episode.id) if (mediaProgress) { if (mediaProgress.isFinished) { - if (mediaProgress.finishedAt > categoryMap.recentlyFinished.smallest) { // Item belongs on shelf + if (mediaProgress.finishedAt > categoryMap['listen-again'].smallest) { // Item belongs on shelf const libraryItemWithEpisode = { ...libraryItem.toJSONMinified(), recentEpisode: episode.toJSON(), finishedAt: mediaProgress.finishedAt } - const indexToPut = categoryMap.recentlyFinished.items.findIndex(i => mediaProgress.finishedAt > i.finishedAt) + const indexToPut = categoryMap['listen-again'].items.findIndex(i => mediaProgress.finishedAt > i.finishedAt) if (indexToPut >= 0) { - categoryMap.recentlyFinished.items.splice(indexToPut, 0, libraryItemWithEpisode) + categoryMap['listen-again'].items.splice(indexToPut, 0, libraryItemWithEpisode) } else { - categoryMap.recentlyFinished.items.push(libraryItemWithEpisode) + categoryMap['listen-again'].items.push(libraryItemWithEpisode) } - if (categoryMap.recentlyFinished.items.length > maxEntitiesPerShelf) { + if (categoryMap['listen-again'].items.length > maxEntitiesPerShelf) { // Remove last item - categoryMap.recentlyFinished.items.pop() - categoryMap.recentlyFinished.smallest = categoryMap.recentlyFinished.items[categoryMap.recentlyFinished.items.length - 1].finishedAt + categoryMap['listen-again'].items.pop() + categoryMap['listen-again'].smallest = categoryMap['listen-again'].items[categoryMap['listen-again'].items.length - 1].finishedAt } - categoryMap.recentlyFinished.biggest = categoryMap.recentlyFinished.items[0].finishedAt + categoryMap['listen-again'].biggest = categoryMap['listen-again'].items[0].finishedAt } } else if (mediaProgress.inProgress && !mediaProgress.hideFromContinueListening) { // Handle most recently listened - if (mediaProgress.lastUpdate > categoryMap.recentlyListened.smallest) { // Item belongs on shelf + if (mediaProgress.lastUpdate > categoryMap['continue-listening'].smallest) { // Item belongs on shelf const libraryItemWithEpisode = { ...libraryItem.toJSONMinified(), recentEpisode: episode.toJSON(), progressLastUpdate: mediaProgress.lastUpdate } - const indexToPut = categoryMap.recentlyListened.items.findIndex(i => mediaProgress.lastUpdate > i.progressLastUpdate) + const indexToPut = categoryMap['continue-listening'].items.findIndex(i => mediaProgress.lastUpdate > i.progressLastUpdate) if (indexToPut >= 0) { - categoryMap.recentlyListened.items.splice(indexToPut, 0, libraryItemWithEpisode) + categoryMap['continue-listening'].items.splice(indexToPut, 0, libraryItemWithEpisode) } else { - categoryMap.recentlyListened.items.push(libraryItemWithEpisode) + categoryMap['continue-listening'].items.push(libraryItemWithEpisode) } - if (categoryMap.recentlyListened.items.length > maxEntitiesPerShelf) { + if (categoryMap['continue-listening'].items.length > maxEntitiesPerShelf) { // Remove last item - categoryMap.recentlyListened.items.pop() - categoryMap.recentlyListened.smallest = categoryMap.recentlyListened.items[categoryMap.recentlyListened.items.length - 1].progressLastUpdate + categoryMap['continue-listening'].items.pop() + categoryMap['continue-listening'].smallest = categoryMap['continue-listening'].items[categoryMap['continue-listening'].items.length - 1].progressLastUpdate } - categoryMap.recentlyListened.biggest = categoryMap.recentlyListened.items[0].progressLastUpdate + categoryMap['continue-listening'].biggest = categoryMap['continue-listening'].items[0].progressLastUpdate } } } @@ -568,21 +574,21 @@ module.exports = { } seriesMap[librarySeries.id] = series - if (series.addedAt > categoryMap.newestSeries.smallest) { - const indexToPut = categoryMap.newestSeries.items.findIndex(i => series.addedAt > i.addedAt) + if (series.addedAt > categoryMap['recent-series'].smallest) { + const indexToPut = categoryMap['recent-series'].items.findIndex(i => series.addedAt > i.addedAt) if (indexToPut >= 0) { - categoryMap.newestSeries.items.splice(indexToPut, 0, series) + categoryMap['recent-series'].items.splice(indexToPut, 0, series) } else { - categoryMap.newestSeries.items.push(series) + categoryMap['recent-series'].items.push(series) } // Max series is 5 - if (categoryMap.newestSeries.items.length > 5) { - categoryMap.newestSeries.items.pop() - categoryMap.newestSeries.smallest = categoryMap.newestSeries.items[categoryMap.newestSeries.items.length - 1].addedAt + if (categoryMap['recent-series'].items.length > 5) { + categoryMap['recent-series'].items.pop() + categoryMap['recent-series'].smallest = categoryMap['recent-series'].items[categoryMap['recent-series'].items.length - 1].addedAt } - categoryMap.newestSeries.biggest = categoryMap.newestSeries.items[0].addedAt + categoryMap['recent-series'].biggest = categoryMap['recent-series'].items[0].addedAt } } } else { @@ -624,22 +630,22 @@ module.exports = { numBooks: 1 } - if (author.addedAt > categoryMap.newestAuthors.smallest) { + if (author.addedAt > categoryMap['newest-authors'].smallest) { - const indexToPut = categoryMap.newestAuthors.items.findIndex(i => author.addedAt > i.addedAt) + const indexToPut = categoryMap['newest-authors'].items.findIndex(i => author.addedAt > i.addedAt) if (indexToPut >= 0) { - categoryMap.newestAuthors.items.splice(indexToPut, 0, author) + categoryMap['newest-authors'].items.splice(indexToPut, 0, author) } else { - categoryMap.newestAuthors.items.push(author) + categoryMap['newest-authors'].items.push(author) } // Max authors is 10 - if (categoryMap.newestAuthors.items.length > 10) { - categoryMap.newestAuthors.items.pop() - categoryMap.newestAuthors.smallest = categoryMap.newestAuthors.items[categoryMap.newestAuthors.items.length - 1].addedAt + if (categoryMap['newest-authors'].items.length > 10) { + categoryMap['newest-authors'].items.pop() + categoryMap['newest-authors'].smallest = categoryMap['newest-authors'].items[categoryMap['newest-authors'].items.length - 1].addedAt } - categoryMap.newestAuthors.biggest = categoryMap.newestAuthors.items[0].addedAt + categoryMap['newest-authors'].biggest = categoryMap['newest-authors'].items[0].addedAt } authorMap[libraryAuthor.id] = author @@ -652,46 +658,50 @@ module.exports = { // Book listening and finished if (mediaProgress) { + const categoryId = libraryItem.media.isEBookOnly ? 'read-again' : 'listen-again' + // Handle most recently finished if (mediaProgress.isFinished) { - if (mediaProgress.finishedAt > categoryMap.recentlyFinished.smallest) { // Item belongs on shelf + if (mediaProgress.finishedAt > categoryMap[categoryId].smallest) { // Item belongs on shelf const libraryItemObj = { ...libraryItem.toJSONMinified(), finishedAt: mediaProgress.finishedAt } - const indexToPut = categoryMap.recentlyFinished.items.findIndex(i => mediaProgress.finishedAt > i.finishedAt) + const indexToPut = categoryMap[categoryId].items.findIndex(i => mediaProgress.finishedAt > i.finishedAt) if (indexToPut >= 0) { - categoryMap.recentlyFinished.items.splice(indexToPut, 0, libraryItemObj) + categoryMap[categoryId].items.splice(indexToPut, 0, libraryItemObj) } else { - categoryMap.recentlyFinished.items.push(libraryItemObj) + categoryMap[categoryId].items.push(libraryItemObj) } - if (categoryMap.recentlyFinished.items.length > maxEntitiesPerShelf) { + if (categoryMap[categoryId].items.length > maxEntitiesPerShelf) { // Remove last item - categoryMap.recentlyFinished.items.pop() - categoryMap.recentlyFinished.smallest = categoryMap.recentlyFinished.items[categoryMap.recentlyFinished.items.length - 1].finishedAt + categoryMap[categoryId].items.pop() + categoryMap[categoryId].smallest = categoryMap[categoryId].items[categoryMap[categoryId].items.length - 1].finishedAt } - categoryMap.recentlyFinished.biggest = categoryMap.recentlyFinished.items[0].finishedAt + categoryMap[categoryId].biggest = categoryMap[categoryId].items[0].finishedAt } } else if (mediaProgress.inProgress && !mediaProgress.hideFromContinueListening) { // Handle most recently listened - if (mediaProgress.lastUpdate > categoryMap.recentlyListened.smallest) { // Item belongs on shelf + const categoryId = libraryItem.media.isEBookOnly ? 'continue-reading' : 'continue-listening' + + if (mediaProgress.lastUpdate > categoryMap[categoryId].smallest) { // Item belongs on shelf const libraryItemObj = { ...libraryItem.toJSONMinified(), progressLastUpdate: mediaProgress.lastUpdate } - const indexToPut = categoryMap.recentlyListened.items.findIndex(i => mediaProgress.lastUpdate > i.progressLastUpdate) + const indexToPut = categoryMap[categoryId].items.findIndex(i => mediaProgress.lastUpdate > i.progressLastUpdate) if (indexToPut >= 0) { - categoryMap.recentlyListened.items.splice(indexToPut, 0, libraryItemObj) + categoryMap[categoryId].items.splice(indexToPut, 0, libraryItemObj) } else { // Should only happen when array is < max - categoryMap.recentlyListened.items.push(libraryItemObj) + categoryMap[categoryId].items.push(libraryItemObj) } - if (categoryMap.recentlyListened.items.length > maxEntitiesPerShelf) { + if (categoryMap[categoryId].items.length > maxEntitiesPerShelf) { // Remove last item - categoryMap.recentlyListened.items.pop() - categoryMap.recentlyListened.smallest = categoryMap.recentlyListened.items[categoryMap.recentlyListened.items.length - 1].progressLastUpdate + categoryMap[categoryId].items.pop() + categoryMap[categoryId].smallest = categoryMap[categoryId].items[categoryMap[categoryId].items.length - 1].progressLastUpdate } - categoryMap.recentlyListened.biggest = categoryMap.recentlyListened.items[0].progressLastUpdate + categoryMap[categoryId].biggest = categoryMap[categoryId].items[0].progressLastUpdate } } } @@ -719,12 +729,12 @@ module.exports = { sequence: nextBookInSeries.seriesSequence } - const indexToPut = categoryMap.continueSeries.items.findIndex(i => i.prevBookInProgressLastUpdate < bookForContinueSeries.prevBookInProgressLastUpdate) - if (!categoryMap.continueSeries.items.find(book => book.id === bookForContinueSeries.id)) { + const indexToPut = categoryMap['continue-series'].items.findIndex(i => i.prevBookInProgressLastUpdate < bookForContinueSeries.prevBookInProgressLastUpdate) + if (!categoryMap['continue-series'].items.find(book => book.id === bookForContinueSeries.id)) { if (indexToPut >= 0) { - categoryMap.continueSeries.items.splice(indexToPut, 0, bookForContinueSeries) - } else if (categoryMap.continueSeries.items.length < 10) { // Max 10 books - categoryMap.continueSeries.items.push(bookForContinueSeries) + categoryMap['continue-series'].items.splice(indexToPut, 0, bookForContinueSeries) + } else if (categoryMap['continue-series'].items.length < 10) { // Max 10 books + categoryMap['continue-series'].items.push(bookForContinueSeries) } } } @@ -802,8 +812,8 @@ module.exports = { } // Sort series books by sequence - if (categoryMap.newestSeries.items.length) { - for (const seriesItem of categoryMap.newestSeries.items) { + if (categoryMap['recent-series'].items.length) { + for (const seriesItem of categoryMap['recent-series'].items) { seriesItem.books = naturalSort(seriesItem.books).asc(li => li.seriesSequence) } } @@ -811,7 +821,7 @@ module.exports = { const categoriesWithItems = Object.values(categoryMap).filter(cat => cat.items.length) return categoriesWithItems.map(cat => { - const shelf = shelves.find(s => s.category === cat.category) + const shelf = shelves.find(s => s.id === cat.id) shelf.entities = cat.items // Add rssFeed to entities if query string "include=rssfeed" was on request