diff --git a/client/components/cards/LazyBookCard.vue b/client/components/cards/LazyBookCard.vue index d54ab791..649b25a8 100644 --- a/client/components/cards/LazyBookCard.vue +++ b/client/components/cards/LazyBookCard.vue @@ -326,7 +326,7 @@ export default { return this.store.getters['user/getUserMediaProgress'](this.libraryItemId) }, userProgressPercent() { - return this.userProgress ? this.userProgress.progress || 0 : 0 + return this.userProgress ? Math.max(this.userProgress.progress || 0, this.userProgress.ebookProgress || 0) : 0 }, itemIsFinished() { return this.userProgress ? !!this.userProgress.isFinished : false diff --git a/client/components/readers/EpubReader.vue b/client/components/readers/EpubReader.vue index 72205dcd..e8fb0cff 100644 --- a/client/components/readers/EpubReader.vue +++ b/client/components/readers/EpubReader.vue @@ -53,6 +53,7 @@ export default { if (!this.libraryItemId) return return this.$store.getters['user/getUserMediaProgress'](this.libraryItemId) }, + localStorageLocationsKey() { return `ebookLocations-${this.libraryItemId}` }, }, methods: { prev() { return this.rendition?.prev() }, @@ -69,20 +70,29 @@ export default { /** * @param {object} payload * @param {string} payload.ebookLocation - CFI of the current location - * @param {string} payload.ebookLocations - list of CFI tags - * @param {number} payload.progress - Progress Percentage + * @param {string} payload.ebookProgress - eBook Progress Percentage */ updateProgress(payload) { this.$axios.$patch(`/api/me/progress/${this.libraryItemId}`, payload).catch((error) => { console.error('EpubReader.updateProgress failed:', error) }) }, + /** @param {string} locationString */ + saveLocations(locationString) { + localStorage.setItem(this.localStorageLocationsKey, locationString); + }, + hasSavedLocations() { + return localStorage.getItem(this.localStorageLocationsKey) !== null; + }, + loadLocations() { + return localStorage.getItem(this.localStorageLocationsKey); + }, /** @param {string} location - CFI of the new location */ relocated(location) { if (location.end.percentage) { this.updateProgress({ ebookLocation: location.start.cfi, - progress: location.end.percentage, + ebookProgress: location.end.percentage, }); } else { this.updateProgress({ @@ -119,13 +129,11 @@ export default { document.addEventListener('keydown', reader.keyUp, false); // load ebook cfi locations - if (this.userMediaProgress?.ebookLocations) { - reader.book.locations.load(this.userMediaProgress?.ebookLocations) + if (this.hasSavedLocations()) { + reader.book.locations.load(this.loadLocations()); } else { reader.book.locations.generate().then(() => { - this.updateProgress({ - ebookLocations: reader.book.locations.save(), - }); + this.saveLocations(reader.book.locations.save()); }); } }); diff --git a/client/pages/item/_id/index.vue b/client/pages/item/_id/index.vue index 86c1ea0e..988b89cc 100644 --- a/client/pages/item/_id/index.vue +++ b/client/pages/item/_id/index.vue @@ -472,7 +472,7 @@ export default { return duration - this.userMediaProgress.currentTime }, progressPercent() { - return this.userMediaProgress ? Math.max(Math.min(1, this.userMediaProgress.progress), 0) : 0 + return this.userMediaProgress ? Math.max(Math.min(1, Math.max(this.userMediaProgress.progress || 0, this.userMediaProgress.ebookProgress || 0)), 0) : 0 }, userProgressStartedAt() { return this.userMediaProgress ? this.userMediaProgress.startedAt : 0 diff --git a/server/controllers/MeController.js b/server/controllers/MeController.js index 1286cc12..9ca2c7a9 100644 --- a/server/controllers/MeController.js +++ b/server/controllers/MeController.js @@ -261,7 +261,7 @@ class MeController { var itemsInProgress = [] for (const mediaProgress of req.user.mediaProgress) { - if (!mediaProgress.isFinished && mediaProgress.progress > 0) { + if (!mediaProgress.isFinished && (mediaProgress.progress > 0 || libraryItem.ebookProgress > 0)) { const libraryItem = await this.db.getLibraryItem(mediaProgress.libraryItemId) if (libraryItem) { if (mediaProgress.episodeId && libraryItem.mediaType === 'podcast') { diff --git a/server/objects/user/MediaProgress.js b/server/objects/user/MediaProgress.js index e92ffca6..6e06c0fe 100644 --- a/server/objects/user/MediaProgress.js +++ b/server/objects/user/MediaProgress.js @@ -11,7 +11,7 @@ class MediaProgress { this.hideFromContinueListening = false this.ebookLocation = null // current cfi tag - this.ebookLocations = null // list of cfi tags + this.ebookProgress = null // 0 to 1 this.lastUpdate = null this.startedAt = null @@ -33,7 +33,7 @@ class MediaProgress { isFinished: this.isFinished, hideFromContinueListening: this.hideFromContinueListening, ebookLocation: this.ebookLocation, - ebookLocations: this.ebookLocations, + ebookProgress: this.ebookProgress, lastUpdate: this.lastUpdate, startedAt: this.startedAt, finishedAt: this.finishedAt @@ -50,7 +50,7 @@ class MediaProgress { this.isFinished = !!progress.isFinished this.hideFromContinueListening = !!progress.hideFromContinueListening this.ebookLocation = progress.ebookLocation || null - this.ebookLocations = progress.ebookLocations || null + this.ebookProgress = progress.ebookProgress this.lastUpdate = progress.lastUpdate this.startedAt = progress.startedAt this.finishedAt = progress.finishedAt || null @@ -70,7 +70,7 @@ class MediaProgress { this.isFinished = !!progress.isFinished || this.progress == 1 this.hideFromContinueListening = !!progress.hideFromContinueListening this.ebookLocation = progress.ebookLocation - this.ebookLocations = progress.ebookLocations + this.ebookProgress = Math.min(1, (progress.ebookProgress || 0)) this.lastUpdate = Date.now() this.finishedAt = null if (this.isFinished) {