Archived
- add uv configuration for the backend - update frontend to make auth work - add new auth endpoints - add bookmars feat - add reader feat
2.6 KiB
2.6 KiB
011 — Web reader (react-reader)
Status: Implemented
Created: 2026-06-03
Objective
Replace the custom HTML chapter reader with react-reader (epub.js) for paginated EPUB reading in the web app. Keep the existing toolbar and settings panel chrome. Block PDFs from the in-browser reader.
Architecture
Library (EPUB only) → /read/:id → ReadingPage
→ GET /api/books/ebooks/{id}/ (metadata, format guard)
→ GET /api/books/ebooks/{id}/file/ (authenticated EPUB blob)
→ ReactReader (blob URL + CFI location)
→ PATCH /api/books/ebooks/{id}/progress/ (epub_location + percentage)
EPUB files are fetched with JWT via the API, converted to a blob URL client-side, and passed to react-reader. This avoids unauthenticated /media/ URLs and CORS issues in dev.
Backend changes
GET /api/books/ebooks/{id}/file/
- Authenticated, owner-only
- Returns
FileResponsewithContent-Type: application/epub+zip - Returns
400if format is notepub
ReadingProgress.epub_location
| Field | Type | Notes |
|---|---|---|
epub_location |
CharField(2048) | EPUB CFI string for resume position |
Exposed on GET/PATCH /api/books/ebooks/{id}/progress/ and in EBookDetail.progress.
current_position stores whole-book percentage (0–100) derived from epub.js locations.
Frontend changes
| File | Change |
|---|---|
pages/ReadingPage.tsx |
ReactReader replaces chapter HTML rendering |
hooks/useEpubReader.ts |
Blob load, CFI state, debounced progress save |
utils/epubRendition.ts |
Theme/font application via getRendition |
api/books.ts |
getEpubFile(id) |
pages/Library.tsx |
Block PDF open with notice |
App.tsx |
Single route /read/:id; /reader/:id redirects |
Removed (web-only)
useChapters.ts,TableOfContents.tsx,Reader.tsx,useReadingProgress.ts
Backend /toc/ and /content/ endpoints remain for mobile/API consumers.
EPUB-only policy
- Library: clicking a PDF shows a dismissible notice; no navigation to reader
- ReadingPage: deep-link guard if
format !== 'epub' - Upload still accepts PDF for storage; web reader is EPUB-only
Dependencies
- Frontend:
react-reader(^2.0.15)
Verification
- Open an EPUB from library → paginated reading, swipe/tap page turns, built-in TOC
- Close and reopen → resumes at saved CFI
- Change theme/font in settings → applies inside epub iframe
- Click a PDF in library → notice shown, reader not opened
GET /api/books/ebooks/{id}/file/without auth → 401