Archived
- add uv configuration for the backend - update frontend to make auth work - add new auth endpoints - add bookmars feat - add reader feat
8.5 KiB
8.5 KiB
US: Customizable Mobile Reading Experience
Issue: https://gitea-dev.codescripters.org/HermesFactory/cloud-reader/issues (TBD)
Overview
Add a full-screen reading view for ebooks with customizable typography, themes, table of contents navigation, and orientation support. Mobile-first, responsive design that adapts to any screen size.
Backend Specification
New Models
apps.books.models.Chapter
| Field | Type | Notes |
|---|---|---|
| id | AutoField (PK) | |
| book | FK -> Book | related_name="chapters" |
| title | CharField(512) | Chapter title |
| number | PositiveIntegerField | Chapter ordering / TOC index |
| content | TextField | Chapter text/markdown content |
| created_at | DateTimeField | auto_now_add |
| updated_at | DateTimeField | auto_now |
Constraints: UniqueConstraint(book, chapter_number) Ordering: [book, number] Index: FK to book with db_index
apps.books.models.ReadingProgress
| Field | Type | Notes |
|---|---|---|
| id | AutoField (PK) | |
| user | FK -> User | related_name="reading_progress" |
| book | FK -> Book | related_name="reading_progress" |
| current_chapter | PositiveIntegerField | Last chapter number |
| current_position | PositiveIntegerField | Position within chapter (paragraph) |
| percentage | FloatField | 0.0 - 100.0 overall progress |
| updated_at | DateTimeField | auto_now |
Constraints: UniqueConstraint(user, book) Indexes: (user, book) composite, (user) filter for list queries
apps.reader.models.ReadingSettings
New app apps/reader/ for reading preferences, isolated from book data model.
| Field | Type | Notes |
|---|---|---|
| id | AutoField (PK) | |
| user | OneToOneField -> User | related_name="reading_settings" |
| font_family | CharField(32) | "sans-serif", "serif", "monospace" |
| font_size | PositiveSmallIntegerField | 12-32, default 18 |
| line_height | FloatField | 1.2 - 2.0, default 1.6 |
| margin_width | PositiveSmallIntegerField | 8-48, default 16 (px) |
| background_color | CharField(7) | Hex color, default "#f5f0eb" |
| text_color | CharField(7) | Hex color, default "#1a1a1a" |
| brightness | PositiveSmallIntegerField | 0-100, default 100 |
| orientation_lock | CharField(16) | "auto", "portrait", "landscape" |
| theme | CharField(32) | "sepia", "dark", "light", "paper" |
| created_at | DateTimeField | auto_now_add |
| updated_at | DateTimeField | auto_now |
New API Endpoints
All under /api/ prefix, authenticated with JWT.
Reader Settings (/api/reader/settings/)
| Method | URL | Action |
|---|---|---|
| GET | /api/reader/settings/ | Get current user settings |
| PUT | /api/reader/settings/ | Create/update settings |
| PATCH | /api/reader/settings/ | Partial update settings |
- Single-object endpoint (one settings record per user, auto-created on first GET)
- Validation: font_size 12-32, line_height 1.2-2.0, margin_width 8-48
Reading Progress (/api/books/{id}/progress/)
| Method | URL | Action |
|---|---|---|
| GET | /api/books/{id}/progress/ | Get reading progress for book |
| PUT | /api/books/{id}/progress/ | Create/update reading progress |
- Nested under book detail
- Auto-creates progress record on first PUT
Chapters (/api/books/{id}/chapters/)
| Method | URL | Action |
|---|---|---|
| GET | /api/books/{id}/chapters/ | List chapters for book (TOC) |
| GET | /api/books/{id}/chapters/{number}/ | Get specific chapter content |
- Ordering by
number - Used by frontend TOC sidebar and content loading
Frontend Specification
New Pages
/reader/:bookId — ReadingPage
Full-screen reading view with:
- Chapter content display (left/right swiping or scroll)
- Bottom toolbar: TOC toggle, Settings toggle, Progress indicator
- Top bar: Back button, Book title, Chapter title
- Swipe/tap/page navigation between chapters
New Components
ReaderToolbar
- Fixed bottom toolbar
- TOC button (opens TOC drawer)
- Settings/theme button (opens settings panel)
- Progress bar showing overall reading progress
TableOfContents
- Slide-in drawer from left
- Lists all chapters with current chapter highlighted
- Tap on chapter to navigate
- Shows reading progress per chapter
ReadingSettingsPanel
- Slide-in drawer from right (or bottom sheet on mobile)
- Controls:
- Theme presets: Sepia, Dark, Light, Paper
- Font family: Sans-serif, Serif, Monospace
- Font size slider (12-32)
- Line height slider (1.2-2.0)
- Margin/padding control
- Orientation lock toggle (Auto / Portrait / Landscape)
- All changes persist immediately via API
- LocalStorage fallback when offline
New Hooks
useReadingSettings(bookId)
- Fetches user reading settings from API
- Returns current settings + update function
- Applies CSS custom properties to document root
- Falls back to defaults if API unavailable
useChapters(bookId)
- Fetches chapter list for TOC
- Returns chapters array, current chapter, navigate function
- Prefetches next/prev chapter content
useReadingProgress(bookId)
- Fetches/updates reading progress
- Auto-saves position on chapter change and periodic interval
New Types
interface Chapter {
id: number;
book: number;
title: string;
number: number;
content?: string; // Only present when fetching individual chapter
}
interface ChapterSummary {
id: number;
book: number;
title: string;
number: number;
}
interface ReadingSettings {
font_family: "sans-serif" | "serif" | "monospace";
font_size: number;
line_height: number;
margin_width: number;
background_color: string;
text_color: string;
brightness: number;
orientation_lock: "auto" | "portrait" | "landscape";
theme: "sepia" | "dark" | "light" | "paper";
}
interface ReadingProgress {
current_chapter: number;
current_position: number;
percentage: number;
updated_at: string;
}
CSS / Theming
Reading view uses CSS custom properties driven by reading settings:
:root {
--reader-bg: var(--bg-color, #f5f0eb);
--reader-text: var(--text-color, #1a1a1a);
--reader-font-family: var(--font-family, "Georgia", serif);
--reader-font-size: var(--font-size, 18px);
--reader-line-height: var(--line-height, 1.6);
--reader-margin: var(--margin-width, 16px);
}
Three theme presets:
- Sepia:
bg:#f5f0eb,text:#1a1a1a— warm, easy on eyes - Dark:
bg:#1a1a2e,text:#e0e0e0— for low-light reading - Light:
bg:#ffffff,text:#1a1a1a— crisp and clean - Paper:
bg:#e8e0d4,text:#2c2c2c— book-like feel
Orientation Support
- CSS
@media (orientation: portrait)and@media (orientation: landscape)breakpoints - Reading settings panel includes orientation lock toggle
- On mobile, landscape mode expands content horizontally with wider margins
- Portrait mode stacks controls vertically for thumb-reachable UI
Routing
Add to App.tsx:
/ → LibraryPage
/books/:bookId → BookDetailPage
/reader/:bookId → ReadingPage
Implementation Order
- Backend models + migrations (Chapter, ReadingProgress, ReadingSettings)
- Backend serializers + views + URLs
- Frontend types + API client
- Frontend hooks (useReadingSettings, useChapters, useReadingProgress)
- Frontend components (ReadingSettingsPanel, TableOfContents, ReaderToolbar)
- Frontend page (ReadingPage)
- Routing updates
- CSS / theming