feat(reader): P1 前端——首页影视/阅读切换 + 书架/搜索/书源/详情/阅读器

- 首页顶部「影视/阅读」分段切换(zustand 持久化,阅读模式直渲染书架)
- /reader/* 独立全屏路由(不套影视 Layout):
  书架(响应式网格 3→8 列)、搜索页(结果流+失败书源明细)、
  书源管理(导入/启停/删除/快速调试日志)、详情页(目录+加书架)
- 阅读器仿 legado ReadMenu:6 套内置主题(日/夜色值对齐 readConfig.json)、
  CSS 多栏分页 + 平移翻页/滚动双模式、三区点击 + 键盘翻页(桌面)、
  上下章、目录抽屉(Virtuoso 虚拟滚动)、字号/行距/段距调节、
  进度记忆(服务端同步 + 下一章预取)
- 桌面兼容:内容列 900px 限宽居中、鼠标悬停态、键盘快捷键
- 后端:详情/目录/正文接口支持 source_url 定位书源(书架链路)
This commit is contained in:
truewhile
2026-09-30 16:07:28 +08:00
parent b8e6418326
commit d0b4255aa8
15 changed files with 1763 additions and 12 deletions
+12
View File
@@ -5,6 +5,7 @@ import { appRoutes, type AppRoute } from './appRoutes'
import { Layout } from './components/Layout'
import { RequireAdmin, RequireAuth } from './components/RequireAuth'
const LoginPage = lazy(() => import('./pages/LoginPage').then((m) => ({ default: m.LoginPage })))
const ReaderRoutes = lazy(() => import('./pages/reader/ReaderRoutes').then((m) => ({ default: m.default })))
const Loading = () => <p className="px-6 py-8 text-sand-500">加载中…</p>
@@ -62,6 +63,17 @@ export default function App() {
<Suspense fallback={<Loading />}>
<Routes>
<Route path="/login" element={<LoginPage />} />
{/* 阅读独立布局(不套影视 Layout,全屏沉浸) */}
<Route
path="/reader/*"
element={
<RequireAuth>
<Suspense fallback={<Loading />}>
<ReaderRoutes />
</Suspense>
</RequireAuth>
}
/>
<Route
path="/"
element={