feat(reader): add R2Progression support for cross-device EPUB reading…#7
Open
feat(reader): add R2Progression support for cross-device EPUB reading…#7
Conversation
Deploying codex with
|
| Latest commit: |
b5279d3
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://f3abbad6.codex-asm.pages.dev |
| Branch Preview URL: | https://r2-progression.codex-asm.pages.dev |
… sync
Add R2Progression (Readium/OPDS 2.0 standard) storage and endpoints to
enable EPUB reading position sync between Codex web reader and third-party
apps like Komic.
- Add r2_progression TEXT column to read_progress table
- Add GET/PUT /books/{id}/progression endpoints to both Komga-compatible
and V1 APIs, storing the full R2Progression JSON alongside legacy fields
(current_page, progress_percentage, completed) for backwards compatibility
- Update the EPUB reader frontend to save and restore R2Progression with
CFI locations for precise cross-device position restoration
- Restore priority: localStorage CFI > R2Progression CFI >
R2Progression totalProgression > legacy progress_percentage
Includes integration tests for both Komga and V1 progression endpoints.
c67e76e to
5b16768
Compare
Fix EPUB parser failing to detect namespace-prefixed OPF tags (e.g., <opf:item>, <opf:spine>), which caused incorrect spine/page counts. Add helpers that match both bare and prefixed XML tag names, with tests. Fix cross-app sync with Readium-based readers (e.g., Komic) by resolving epub.js relative hrefs to full EPUB-internal paths when saving R2Progression locators (e.g., "contents.xhtml" -> "OEBPS/contents.xhtml"). Fix progress display on BookDetail and MediaCard to prefer R2Progression's totalProgression over the misleading currentPage/pageCount ratio for EPUBs. Remove dead startPercent URL parameter code from the EPUB reader, since position is now restored from R2Progression CFI automatically. Remove percentage change threshold from EPUB progress saving so every page turn triggers a save (still debounced at 1s), matching the behavior of comic/PDF readers.
…ss-device sync Previously, the EPUB reader always used the localStorage CFI on load, ignoring any newer progress from the API (e.g., updated via Komic or another device). This meant cross-device sync effectively never worked when the user had previously opened the same book on the current device. Now localStorage saves a timestamp alongside the CFI, and on load the reader compares it with the R2Progression `modified` timestamp from the API. Whichever is newer wins, so progress updated on another app or device is correctly restored.
…on sync Implement the Readium positions algorithm (1 position per 1024 bytes of each spine resource) to normalize totalProgression values from any client, matching Komga's approach. This fixes cross-app EPUB reading sync between Codex web (epub.js) and Readium-based readers like Komic, which calculate totalProgression differently. - Extend EPUB parser to extract spine item file sizes and media types - Add compute_epub_positions() and normalize_progression() functions - Add epub_positions column to books table with migration - Store positions as JSON during book analysis - Update both native API and Komga API PUT progression handlers to normalize client totalProgression against server positions before storing - Fall back to client values for books without positions (non-EPUB or not yet re-analyzed) - Add unit tests for positions computation and normalization logic
…normalized values The server was mutating the stored R2Progression JSON by replacing totalProgression and position in the locator with server-computed values. This broke cross-device sync because each client relies on its own locator (href + progression/CFI) for navigation, and the server-normalized values could differ from what the client originally sent. Now the R2Progression body is stored as-is from the client. The server's normalized values are still used internally for current_page and percentage tracking but no longer overwrite the client's locator data.
4eb01c8 to
1981b53
Compare
… editing Convert between KOReader's DocFragment format and Codex's R2Progression so EPUB reading progress is shared across all clients (web reader, KOReader, OPDS apps). Previously, KOReader sync only stored raw page numbers, breaking cross-client EPUB progress. Fix the KOReader partial hash algorithm to match LuaJIT's bit.lshift 32-bit wrapping semantics (i=-1 offset is 0, not 256). Recompute koreader_hash during both scan and analysis, and expose it in the book API/DTOs. Add ProgressRead/ProgressWrite permissions so API keys can be scoped for progress sync without granting broader access. Include these in all role presets (reader, maintainer, admin) and the OPDS preset. Add x-auth-user header authentication for KOReader's login flow, which sends the API key as a username rather than a Bearer token. Add API key permission editing UI with an edit modal on the profile settings page. Update OPDS preset to include progress permissions. Add KOReader setup documentation with troubleshooting guide.
1981b53 to
87c63b7
Compare
…s-device sync epub.js computes reading position based on character offsets while KOReader and Readium clients use byte offsets. For multi-byte content (CJK, accented text), the same percentage from each client points to different physical locations, causing cross-device sync drift. The server now acts as the conversion authority: - During EPUB analysis, count text characters per spine item alongside byte sizes (stripping HTML markup, scripts, and styles) - Store spine items with both char_count and file_size in a new epub_spine_items column - At the PUT progression API boundary, detect char-based clients by presence of CFI in the locator and convert their totalProgression from character-weighted to byte-weighted (Readium canonical) before normalization - Byte-based clients (KOReader, Komic) pass through unchanged Existing books need a rescan to populate epub_spine_items; without it, behavior falls back to the previous no-conversion path. Includes unit tests for character counting, char/byte conversion (ASCII, CJK, mixed content, roundtrip accuracy), and edge cases.
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.
… sync
Add R2Progression (Readium/OPDS 2.0 standard) storage and endpoints to enable EPUB reading position sync between Codex web reader and third-party apps like Komic.
R2Progression totalProgression > legacy progress_percentage
Includes integration tests for both Komga and V1 progression endpoints.