Archived
feat: customizable mobile reading experience
- Backend: Chapter, ReadingProgress, ReadingSettings models - Backend: Chapter API (TOC + content), progress tracking, settings CRUD - Frontend: ReadingPage with chapter navigation - Frontend: TableOfContents drawer - Frontend: ReadingSettingsPanel (theme, font, size, orientation) - Frontend: Custom hooks for settings, chapters, progress tracking - CSS: Mobile-first reading view with sepia/dark/light/paper themes - Route: /reader/:bookId reading view from book detail page - Docs: 001-customizable-mobile-reading-experience.md
This commit is contained in:
+20
-5
@@ -1,16 +1,19 @@
|
||||
/**
|
||||
* App — root component with simple page navigation (library ↔ book detail).
|
||||
* App — root component with page navigation (library ↔ book detail ↔ reading view).
|
||||
*/
|
||||
|
||||
import { useState, lazy, Suspense } from "react";
|
||||
import "./App.css";
|
||||
import "./reader.css";
|
||||
|
||||
const LibraryPage = lazy(() => import("./pages/LibraryPage"));
|
||||
const BookDetailPage = lazy(() => import("./pages/BookDetailPage"));
|
||||
const ReadingPage = lazy(() => import("./pages/ReadingPage"));
|
||||
|
||||
type View =
|
||||
| { kind: "library" }
|
||||
| { kind: "detail"; bookId: number };
|
||||
| { kind: "detail"; bookId: number }
|
||||
| { kind: "reader"; book: import("./types").BookDetail };
|
||||
|
||||
function LoadingFallback() {
|
||||
return (
|
||||
@@ -32,13 +35,25 @@ export default function App() {
|
||||
setView({ kind: "library" });
|
||||
};
|
||||
|
||||
const handleStartReading = (book: import("./types").BookDetail) => {
|
||||
setView({ kind: "reader", book });
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="app">
|
||||
<Suspense fallback={<LoadingFallback />}>
|
||||
{view.kind === "library" ? (
|
||||
{view.kind === "library" && (
|
||||
<LibraryPage onBookSelect={handleBookSelect} />
|
||||
) : (
|
||||
<BookDetailPage bookId={view.bookId} onBack={handleBack} />
|
||||
)}
|
||||
{view.kind === "detail" && view.bookId !== undefined && (
|
||||
<BookDetailPage
|
||||
bookId={view.bookId}
|
||||
onBack={handleBack}
|
||||
onStartReading={handleStartReading}
|
||||
/>
|
||||
)}
|
||||
{view.kind === "reader" && view.book !== undefined && (
|
||||
<ReadingPage book={view.book} onBack={handleBack} />
|
||||
)}
|
||||
</Suspense>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user