fix: use ebookProgress field for ebook reading progress#166
Closed
OnlyTerp wants to merge 9 commits intorohit-purandare:mainfrom
Closed
fix: use ebookProgress field for ebook reading progress#166OnlyTerp wants to merge 9 commits intorohit-purandare:mainfrom
OnlyTerp wants to merge 9 commits intorohit-purandare:mainfrom
Conversation
Audiobookshelf returns ebook progress in a separate ebookProgress field while the progress field is always 0 for ebooks. Prefer ebookProgress when available, falling back to progress for audiobooks.
Fixes issue where books finished naturally in Audiobookshelf were not updating to 100% completion in Hardcover. Root cause: extractFinishedFlag() only checked is_finished boolean but ignored finished_at timestamp. When users finish books naturally by listening to the end, Audiobookshelf sets finished_at but is_finished may remain false. Changes: - Check finished_at timestamp in addition to is_finished flag - Return null (not false) when no completion indicators found, allowing position-based and percentage-based detection to proceed - Reduce time-remaining threshold from 120s to 60s for audiobooks - Add aggressive 98% completion threshold for all formats - Fix parameter name mismatch in isBookComplete() method Tests: - Add comprehensive test suite with 28 tests covering all scenarios - All existing tests still pass (127 total) - Includes integration test reproducing exact bug scenario
…ress The ?? operator doesn't fall through when ebookProgress is 0 (not nullish), causing all audiobooks to report 0% progress. Using || correctly falls through to the progress field when ebookProgress is 0 (falsy).
Remove stale files that were accidentally left in the repo: DUPLICATE_MATCHING_FIX.md, SECURITY_NOTE.md, TESTING_WANT_TO_READ_STATUS_UPDATE.md, run-all-tests.sh, test-release-targeting.txt, test-signing.md, wait-and-test.sh
Two-stage title/author matches store the book ID at match.book.id when the book isn't in the user's library, but sync-manager only checked match.userBook?.book?.id (undefined when userBook is null). Also fix edition ID being cached as undefined since _cacheSuccessfulMatch used bestMatch.id instead of bestMatch.edition.id for two-stage results.
…and format Audiobookshelf uses mediaType 'book' for both audiobooks and ebooks. Previously this always resolved to 'audiobook', causing ebooks to match audiobook editions and report wrong progress (e.g. 62.5% → 0.0%). Now check media.ebookFile and media.audioFiles to distinguish ebooks from audiobooks. Also use the correct progress field per item type: ebookProgress for ebooks, progress for audiobooks.
The log used edition.reading_format?.format which is only present on raw Hardcover editions. Two-stage title/author matches flatten this to edition.format. Fall back to edition.format so the log isn't undefined.
Root cause: ShelfBridge used nullish coalescing (??) to fall back from progress to ebookProgress, but for ebooks the ABS API returns progress=0 (not null/undefined), so ?? never triggered the fallback. Changes: - audiobookshelf-client.js: Match ABS client logic - use ebookProgress when progress is falsy (0) and ebookProgress > 0. This avoids relying on fragile media type detection for choosing the progress field. - audiobookshelf-client.js: Store has_ebook_progress and ebook_location on item data for downstream format detection. - audiobookshelf-extractor.js: Use has_ebook_progress as the strongest signal for ebook format detection (overrides mediaType checks). - audiobookshelf-extractor.js: Handle dual-format items (both ebookFile and audioFiles) by checking which format has actual progress.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #162
Problem
ShelfBridge reads
progressinstead ofebookProgressfor ebooks, causing ebook reading progress to always show as 0%.Root Cause
The previous fix (PR #164) used nullish coalescing (
??) to fall back fromprogressData.progresstoprogressData.ebookProgress. However, for ebooks the ABS API returnsprogress: 0(notnullorundefined), so??never triggered the fallback —0 ?? ebookProgressreturns0.The media type detection (
isEbook) also had fragility issues — ifmedia.ebookFilewasn't detected correctly (e.g., dual-format items, unexpected API structure), the code would take the audiobook path and never checkebookProgress.Fix
1. Progress field selection (
src/audiobookshelf-client.js)Matches ABS's own client logic: if
progressis falsy (0) andebookProgress > 0, useebookProgress. This completely avoids relying on media type detection for choosing the right progress field.\\js
// Before (broken): 0 ?? ebookProgress === 0
const rawProgress = isEbook
? (progressData.ebookProgress ?? progressData.progress)
: (progressData.progress ?? progressData.ebookProgress);
// After (matches ABS client): 0 is falsy, so ebookProgress is used
const rawProgress = (!progressData.progress && progressData.ebookProgress > 0)
? progressData.ebookProgress
: (progressData.progress || 0);
\\
2. Ebook format detection (
src/matching/utils/audiobookshelf-extractor.js)has_ebook_progress(derived fromebookProgress > 0) as the strongest signal for ebook format detection, overriding fragilemediaType/media.ebookFilechecksebookFileandaudioFiles) by checking which format has actual user progressChanges
src/audiobookshelf-client.jshas_ebook_progressandebook_locationon item datasrc/matching/utils/audiobookshelf-extractor.jshas_ebook_progressas top-priority format signal; dual-format item handlingTesting