Archived
feat: uv config other feats
- add uv configuration for the backend - update frontend to make auth work - add new auth endpoints - add bookmars feat - add reader feat
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
# 011 — Web reader (react-reader)
|
||||
|
||||
**Status:** Implemented
|
||||
**Created:** 2026-06-03
|
||||
|
||||
## Objective
|
||||
|
||||
Replace the custom HTML chapter reader with [react-reader](https://github.com/gerhardsletten/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 `FileResponse` with `Content-Type: application/epub+zip`
|
||||
- Returns `400` if format is not `epub`
|
||||
|
||||
### `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
|
||||
|
||||
1. Open an EPUB from library → paginated reading, swipe/tap page turns, built-in TOC
|
||||
2. Close and reopen → resumes at saved CFI
|
||||
3. Change theme/font in settings → applies inside epub iframe
|
||||
4. Click a PDF in library → notice shown, reader not opened
|
||||
5. `GET /api/books/ebooks/{id}/file/` without auth → 401
|
||||
Reference in New Issue
Block a user