diff --git a/server/models/Library.js b/server/models/Library.js index c6875ad7..49b54d68 100644 --- a/server/models/Library.js +++ b/server/models/Library.js @@ -11,6 +11,7 @@ const oldLibrary = require('../objects/Library') * @property {string} autoScanCronExpression * @property {boolean} audiobooksOnly * @property {boolean} hideSingleBookSeries Do not show series that only have 1 book + * @property {boolean} onlyShowLaterBooksInContinueSeries Skip showing books that are earlier than the max sequence read * @property {string[]} metadataPrecedence */ diff --git a/server/objects/settings/LibrarySettings.js b/server/objects/settings/LibrarySettings.js index b070ff79..a9885c79 100644 --- a/server/objects/settings/LibrarySettings.js +++ b/server/objects/settings/LibrarySettings.js @@ -8,7 +8,8 @@ class LibrarySettings { this.skipMatchingMediaWithIsbn = false this.autoScanCronExpression = null this.audiobooksOnly = false - this.hideSingleBookSeries = false // Do not show series that only have 1 book + this.hideSingleBookSeries = false // Do not show series that only have 1 book + this.onlyShowLaterBooksInContinueSeries = false // Skip showing books that are earlier than the max sequence read this.metadataPrecedence = ['folderStructure', 'audioMetatags', 'nfoFile', 'txtFiles', 'opfFile', 'absMetadata'] this.podcastSearchRegion = 'us' @@ -25,6 +26,7 @@ class LibrarySettings { this.autoScanCronExpression = settings.autoScanCronExpression || null this.audiobooksOnly = !!settings.audiobooksOnly this.hideSingleBookSeries = !!settings.hideSingleBookSeries + this.onlyShowLaterBooksInContinueSeries = !!settings.onlyShowLaterBooksInContinueSeries if (settings.metadataPrecedence) { this.metadataPrecedence = [...settings.metadataPrecedence] } else { @@ -43,6 +45,7 @@ class LibrarySettings { autoScanCronExpression: this.autoScanCronExpression, audiobooksOnly: this.audiobooksOnly, hideSingleBookSeries: this.hideSingleBookSeries, + onlyShowLaterBooksInContinueSeries: this.onlyShowLaterBooksInContinueSeries, metadataPrecedence: [...this.metadataPrecedence], podcastSearchRegion: this.podcastSearchRegion } diff --git a/server/utils/queries/libraryItemsBookFilters.js b/server/utils/queries/libraryItemsBookFilters.js index 16a25847..dc48c89c 100644 --- a/server/utils/queries/libraryItemsBookFilters.js +++ b/server/utils/queries/libraryItemsBookFilters.js @@ -676,11 +676,14 @@ module.exports = { ], attributes: { include: [ - [Sequelize.literal('(SELECT max(mp.updatedAt) FROM bookSeries bs, mediaProgresses mp WHERE mp.mediaItemId = bs.bookId AND mp.userId = :userId AND bs.seriesId = series.id)'), 'recent_progress'] + [Sequelize.literal('(SELECT max(mp.updatedAt) FROM bookSeries bs, mediaProgresses mp WHERE mp.mediaItemId = bs.bookId AND mp.userId = :userId AND bs.seriesId = series.id)'), 'recent_progress'], + [Sequelize.literal('(SELECT CAST(max(bs.sequence) as FLOAT) FROM bookSeries bs, mediaProgresses mp WHERE mp.mediaItemId = bs.bookId AND mp.userId = :userId AND bs.seriesId = series.id)'), 'maxSequence'], + [Sequelize.literal('(SELECT json_extract(libraries.settings, "$.onlyShowLaterBooksInContinueSeries") FROM libraries WHERE id = :libraryId)'), 'onlyShowLaterBooksInContinueSeries'] ] }, replacements: { userId: user.id, + libraryId: libraryId, ...userPermissionBookWhere.replacements }, include: { @@ -731,13 +734,26 @@ module.exports = { const libraryItems = series.map(s => { if (!s.bookSeries.length) return null // this is only possible if user has restricted books in series - const libraryItem = s.bookSeries[0].book.libraryItem.toJSON() - const book = s.bookSeries[0].book.toJSON() + + var bookIndex = 0 + // if the library setting is toggled, only show later entries in series, otherwise skip + if (s.dataValues.onlyShowLaterBooksInContinueSeries === 1) { + bookIndex = s.bookSeries.findIndex(function (b) { + return parseFloat(b.dataValues.sequence) > s.dataValues.maxSequence + }) + if (bookIndex === -1) { + // no later books than maxSequence + return null + } + } + + const libraryItem = s.bookSeries[bookIndex].book.libraryItem.toJSON() + const book = s.bookSeries[bookIndex].book.toJSON() delete book.libraryItem libraryItem.series = { id: s.id, name: s.name, - sequence: s.bookSeries[0].sequence + sequence: s.bookSeries[bookIndex].sequence } if (libraryItem.feeds?.length) { libraryItem.rssFeed = libraryItem.feeds[0]