Commit Graph
143 Commits
Author SHA1 Message Date
hectorqinandClaude Opus 5.5 a904bb5a83 feat(web): 点击区域设置 — a 3×3 tap grid with a per-cell action
The two-way 左退右进 / 左进右退 switch becomes nine cells, each 上一页, 下一页,
菜单, 上一章, 下一章 or 无操作, edited as a small page in 阅读设置 → 翻页 with
左右互换 and 恢复默认. The default grid is the old standard layout and a stored
`tapZone: 'reversed'` is folded into its grid. At least one 菜单 cell is kept,
right-to-left books mirror the grid, and the gesture layer now reports the row
as well as the column, from layout geometry like before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 10:27:51 +00:00
hectorqinandClaude Opus 5.5 21e2509c86 feat(web): 阅读记录 in 书籍信息 brings back an overwritten reading position
Tapping the title opens 书籍信息, which now ends with 阅读记录: the places this
account has been in the book on any device, newest first, each with its
chapter, percentage, device and time. The position on screen is pushed
before the list is read, so its entry is marked 当前; pressing another entry
goes back there and saves it as the position. Offline the section says the
history cannot be read; a failed read offers 重试.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 03:51:42 +00:00
hectorqinandClaude Opus 5.5 842331684a feat(server): keep a per-book reading-progress history
reading_progress keeps one row per book and last-writer-wins, which answers
"where am I" and loses "where was I": a stale device, a mistapped 目录 entry
or a clock running ahead overwrote the place for good (P0: 进度历史).

Every valid progress write now also lands in reading_progress_history,
including a write that lost the merge. A device reading on through one
chapter updates its latest entry (same chapter, within 5% and 30 minutes)
instead of adding rows; another chapter, a jump, another device or an
out-of-order write is a new entry. The newest 50 per book are kept.
GET /api/v1/sync/progress/:bookId/history lists them, newest first, for the
signed-in account only.

The table is new (CREATE TABLE IF NOT EXISTS), so the schema change is
additive and older builds sharing the database ignore it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 03:51:42 +00:00
hectorqinandClaude Opus 5.5 0115dbd81a feat(web): in scroll mode, pulling past a chapter's end opens the next one
Taps and keys already crossed chapters, but a reader scrolling by hand reached
the last line and had to find 下一章 (#702, #698). A touch pull of more than
72px that starts at the end of a chapter, or wheel scrolling past it, now
opens the next chapter; the same at the top goes back. Only a gesture that
begins at the edge counts, so arriving at the end does not turn by itself,
and a cooldown keeps trackpad momentum from turning a second chapter. Touch
events are used because the browser cancels pointers once it scrolls.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 02:56:36 +00:00
hectorqinandClaude Opus 5.5 d8b3491e95 chore(web): remove the reading engine and helpers nothing runs
An import graph from main.tsx shows a previous reader still in the tree:
render/{reader,paged,pdf,text,container,theme}.ts with lib/{events,locator}.ts,
ui/settings.ts and bridge.ts — superseded by ReaderScreen/ReaderView and
never imported. Also unreachable: render/paginator.ts, render/window.ts and
ui/shelf-order.ts (only their own tests used them; the shelf sorts on the
server), formats/remote-zip.ts (re-exported, never called; chapters are
fetched per section), ui/source-capabilities.tsx and the sources pages barrel.

Inside live modules: PrefetchCache (only shouldPrefetch is used),
textToParagraphs / paragraphElement / endsAtParagraphBreak (the streaming
TXT reader's carry), txt.ts's textToHtml alias, and ChunkCursor. Their tests
go with them; the node:test list, the Vitest excludes and the docs that
named these files are updated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 09:49:37 +00:00
hectorqinandClaude Opus 5.5 12fbe0cbcd chore(web): remove the icon font toolchain and unused icon names
The UI draws Lucide SVGs through ui/icon.tsx and has not loaded the icon
font for a while; the font, its code-point table and the generator only fed
their own tests. Removed: tools/icons (generator, glyph paths, stroker),
src/styles/reader-icons.ttf, src/ui/icon-names.ts, the `icons` npm script and
the font/metrics tests. icons.test.ts keeps the contracts that still apply:
no borrowed names (now checked against ICONS), only icon.tsx imports
lucide-react, the .icon rule and icon buttons. The .icon rule drops its
font-era declarations.

ICONS loses the names nothing draws (the Font Awesome spellings kept as
aliases, add-circle, film, line-height, indent, sign-out); the reader's 朗读
button is `read-aloud` rather than `volume`. Docs and CLAUDE.md describe
adding an icon in icon.tsx.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 09:48:04 +00:00
hectorqinandClaude Opus 5.5 97429ddeed refactor(web): ui/icon.tsx owns the icon set — names, sizes and stroke
IconName came from the legacy font's code-point table, so a new icon meant a
new font glyph, while 59 files imported lucide-react directly with their own
glyphs, 17 sizes and strokes from 1.4 to Lucide's default 2. icon.tsx now
defines every name (in the product's words: video, audiobook, lock,
folder-browse, …), each drawn by one Lucide glyph; IconName is its keys.
Icon gains a six-step size scale (14–32), `filled`, and `strong` for the
current navigation item; the stroke is 1.8 everywhere, 1.4 at the 32px
empty-state size. ui.md §1 describes the rules.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 07:26:51 +00:00
hectorqinandClaude Opus 5.5 4a6b7a3858 feat(web): 书库 can be browsed into its subfolders
The browsing page asked /library/browse for the folder's entries but drew only
its crumbs, and the crumbs appear only once you are already in a subfolder:
a shareable #/library?path=科幻 scope existed, but nothing on screen led to it.
Subfolders are now a row of chips under the search field; one press narrows
the scope a level and the crumbs widen it again. Folders excluded by a scan
rule are not shown.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 05:04:02 +00:00
hectorqinandClaude Opus 5.5 c1056743ad feat: the reader shows AI 总结 only when the server can answer it
The top bar always drew AI 总结, although AI is off by default, so most
readers pressed it only to be told AI_DISABLED (ui.md §4/§5: a control the
reader cannot use is not drawn). GET /api/v1/ai/capabilities tells any signed-in
account whether chapter summaries are enabled and configured, without exposing
the configuration; the reader asks once per book and leaves the button out
when the answer is no. Against an older server (404) the button stays.

The busy line while a summary is generated is a global notice like every other
one, instead of a hand-drawn .floating-notice.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 04:36:01 +00:00
hectorqinandClaude Opus 5.5 923adcc006 docs(ui): describe the reader's footer, slider, failure state and keys as built
§3.10 gains the 工具 button and the 朗读中 state, the comic exception to the
page slider, the open-failure state with 重试/返回, and the keyboard map.
§3.9 no longer mentions a 快捷 row the settings panel does not have; the TXT
rows live under 更多排版.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 04:19:00 +00:00
hectorqinandClaude Opus 5.5 120827bad6 docs: bring every document in line with the code
Audit of README, docs/, android/README.md, android/contract.md and CLAUDE.md
against the current server, web and Android code: V3 navigation and settings
locations, Docker Hub release images, GitHub clone URL and CI, missing API
endpoints and error codes, architecture of lazy chunks/themes/sources, media
pages and routes, the Android bridge contract, and the new file-management and
member-upload permissions.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 02:03:45 +00:00
hectorqinandClaude Opus 5.5 f50ce1b765 fix(web): rework the media library manager and scan & scrape pages
媒体库管理: 新建媒体库 and 扫描与刮削 are visible above the list, an empty
state offers 新建媒体库, and cards get a channel-coloured kind icon, a
指定用户 tag, a one-line directory, missing files in the warning colour,
开始扫描 for never-scanned libraries, and 扫描记录 in the ⋯ menu. Cards
take the full width when the server has no 扫描与元数据 switches.

扫描与刮削: scan and AI scan share one toolbar (library in ?library=,
refresh, a single primary action) instead of duplicated buttons; scan
records show their time, keep title/state/action on one line, put the
failure in a warning box followed by 重试, and have an empty state.
刮削 preselects the page's library, lays the form out in two columns
when wide, and keeps 已选 N and 开始批量匹配 pinned under the item list.

Styles live in features/media/styles/manager.css, loaded after v2.css.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 08:10:45 +00:00
hectorqinandClaude Opus 5.5 ff8d289185 docs(web): source chapter cleaning is decided by the plugin's source type
The Legado plugin now cleans by bookSourceType (text paragraphed, image
sources untouched); the reader only re-typesets text-only chapters, which
never includes a comic chapter.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 06:34:11 +00:00
hectorqinandClaude Opus 5.5 60d4b41bf1 fix(web): typeset book-source HTML chapters like TXT
Source chapters are scraped fragments (`<div>  text<br><br><br><br>`) served
as text/html, so the TXT cleanup never ran: every paragraph was followed by
three empty lines and the indent setting did nothing. Like legado-E, a
text-only chapter of a `chapters` book is read back as characters when it
is loaded (htmlToText) and typeset by the TXT path. Done at read time, so
chapters the server cached earlier are cleaned too; chapters with images
or tables keep their markup and EPUBs never take this path.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 06:20:27 +00:00
hectorqinandClaude Opus 5.5 52b757bbd3 fix(web): clean web-page markup out of TXT chapters before typesetting
Novels saved from a site keep the page's <div>, <br/> and &nbsp; in the
TXT. Escaped, the tags were drawn as text and the chapter ran together
as one paragraph. cleanTextMarkup turns block tags into line breaks,
drops inline tags, decodes common entities and treats whitespace-only
lines as blank, before paragraphs and the chapter heading are inferred.
Only real tag names match; other markup is still escaped as text.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 05:51:18 +00:00
hectorqinandClaude Opus 5.5 6514387f9e fix(web): PWA orientation, media swipes and follow-finger page turns
- Manifest: drop orientation "any" (Chrome maps it to the full sensor, so the
  installed app ignored the phone's rotation lock); the service worker serves
  the manifest network-first so installed apps can pick up manifest changes.
- Media: derive the channel from the path for static routes (演播者 showed 影视);
  keep the tab bar on audiobook/narrators; a channel with no library swipes a
  whole channel at a time.
- Reader (paged mode): the column strip follows the finger; release turns on a
  flick or past 30% of the width, otherwise springs back; chapter edges fall
  through to the normal turn.
- PWA smoke test stubs the current window.__readerFlush hook.
- Docs: ui.md §3.8 drag-follow and media swipe rules; pwa.zh-CN.md orientation
  and manifest caching.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 09:05:18 +00:00
hectorqinandClaude Opus 5.5 2f784d1d4e fix(web): mobile PWA style review fixes
- Reader (scroll paging): mask the line the page's bottom edge cuts through
  (clip-path, --reader-page-mask) so no page shows a half-sliced last line;
  re-measured after page-turn animations.
- Landscape sidebar layout: the sidebar owns the left safe-area inset, the page
  column the right one; fix .shelf-head's swapped left/right padding; reader
  top/bottom bars respect left/right insets.
- Guard all :hover rules with (hover: hover) and (pointer: fine), enforced by
  test/design-tokens.test.ts.
- PWA update banner sits above the phone tab bar and reader toolbar.
- Top safe-area on sources header and phone media pages; 16px sidebar search
  on touch (iOS focus zoom); larger hit areas for chips and cover controls.
- Manifest: unified launch colour #FDF9F6, maskable icon, drop
  window-controls-overlay; regenerate branding assets.
- Docs: ui.md safe-area/touch/hover/reader rules, pwa.zh-CN.md icons and
  window notes, CLAUDE.md stale bundle notes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 07:35:51 +00:00
hectorqinandClaude Opus 5.5 a634e9e955 fix(web): every search field says its scope
The side-nav global search and the shelf's own field sat side by side on
desktop and both read "搜索书名、…"; the shelf one was even labelled
搜索书库 while it only filters the shelf.

- Global (side nav, /search): 搜索书籍和影音 — also no longer truncated in
  the 216px rail.
- Shelf: 在书架中筛选书名、作者、系列, labelled 筛选书架; results are 筛选结果.
- Library: 在书库中搜索书名、作者.
- ui.md §4 records the rule.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 13:15:20 +08:00
hectorqinandClaude Opus 5.5 81ec4ba6bc refactor(web): seven role-named type sizes replace ~50 literal font sizes
ui.md's four type roles only governed the reading side; the media sheets
used every integer from 8 to 24px plus dozens of rem values. Every font size
up to 24px now reads one of --text-display/title/body/ui/label/meta/micro.

- --text-ui (14px) is the media list/settings body; --text-display (22px) the
  page hero; --text-micro (10px) only for cover/icon badges.
- --text-meta moves 0.72rem -> 0.75rem, so the 200+ media 12px lines land on
  it unchanged and the reading side's meta grows by half a pixel.
- Inputs that were 16px land on --text-title (16.8px), keeping the iOS
  focus-zoom floor; ui.md says so explicitly.
- Sizes above 24px (player initials, hero numerals) and the decorative serif
  shorthands stay literal; the token test rejects literals <= 24px.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 13:10:31 +08:00
hectorqinandClaude Opus 5.5 7e8b0ea278 feat(web): placeholder covers take a stable per-title tint
A shelf of TXT books (or a media library before scraping) was a wall of
identical panels, so finding one meant reading every placeholder. Titles now
hash to one of twelve hues 30° apart (ui/cover-tint.ts), mixed 10-20% into
the theme surface, so the tint follows light/dark and the text on it keeps
its contrast. Shelf, library and media covers share it. ui.md §2.7.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 12:10:46 +08:00
hectorqinandClaude Opus 5.5 c5125792d7 refactor(web): six-step radius tokens replace ~40 literal corner sizes
The stylesheets used 2/3/4/5/6/7/8/9/10/11/12/13/14/15/18/19/20/22/24px plus
a dozen rem values for corners, so the same kind of control differed by a
pixel or two between neighbouring screens. --radius-xs/sm/md/lg/xl/pill
(4/8/10/14/20/999px) now carry every corner; --reader-radius is --radius-md.
Controls whose radius was half their height (switches, the role tag, the
home hero action, the nav icon pill) use --radius-pill so they stay capsules
if their height changes. ui.md §2.6 documents the scale; a test fails on any
new literal border-radius.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 12:06:19 +08:00
hectorqinandClaude Opus 5.5 92cfabe740 feat(web): primary buttons fill with brand-text so they outweigh secondaries
The light themes' brand fill (#F2B79F etc.) is softer than the white
secondary button beside it, so 保存/播放 read as the quieter choice. Primary
buttons now use brand-text with bg on it, the same recipe as danger, and a
pair the token spec already holds to 4.5:1 in every theme. brand stays for
state fills (selected, progress, switches). Spec updated (rule 6).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 11:54:48 +08:00
hectorqin 92f26ba122 feat(web): ⋯ menus drop down; drop 影音设置; rebuild 插件管理
- ActionMenu is an anchored dropdown on every width (popover, no title bar or backdrop; closes on pick, Escape, Tab or a press outside; arrow keys). ActionSheet stays for question-style picks. Styles in styles/action-menu.css.
- Remove the media settings home and its ⋯ entry: panels live only at /me/:panel; /media/:channel/settings[/:panel] redirects to 我的. Library and task pages return to 我的 or the channel.
- 插件管理: one list with status tags and a per-row ⋯ menu (启用/停用, 卸载 with confirmation); install moves into a Sheet (npm / local file, trust switch). Old plugin styles removed from reader.css.
- 首页: drop the redundant 继续阅读 pill on the reading card.
- Docs, unit tests and ui:review updated (stub admin settings in the media review).
2026-10-21 15:26:49 +08:00
hectorqin 2d7e858ecc refactor(web): drop Mantine; one ActionMenu for every ⋯ menu
- Replace every Mantine component with the toolkit (Button, Callout, IconButton) or plain markup; remove MantineProvider, its stylesheet and the --mantine variable bridge; keep its form-font reset in reader.css. Uninstall @mantine/core and @mantine/hooks.
- ActionMenu/ActionSheet (ui/action-menu.tsx): the file manager's Mantine Menu, the shelf pick dialog and the media <details> menus (catalog, narrators, detail, libraries, library rows, folders, chapters, queue, resource panel, favorites filter) are one compact Sheet menu.
- Toolkit Callout for page-level messages; operation failures go to FloatingNotice; .page-state for whole-page loading/error.
- Shared SourcesHeader and SourceBookDetailSheet; source editor and credentials pages rebuilt without Mantine, deleting a source now asks first.
- Remove dead code: SettingsPage (unrouted), MiniPlayer, ui/dom.ts (formatters moved to lib/format.ts), the unused metadata form dialog, useAppThemeDark.
- ui:review react-app passes again: fixed stale steps (/settings, mini player, login race, missing-edition detail).
2026-10-21 11:38:12 +08:00
hectorqin fbb6dc65cf feat(ui): one Sheet for every overlay; drop 来源与刮削
- ui/sheet.tsx Sheet/ConfirmSheet replace the centred Modal, SweetAlert confirms, DialogView overlays, the reader Panel, the shelf settings floating card, the two media dialogs and Mantine Modal.
- Phones: bottom sheet. Wide windows: right-edge drawer; compact sheets (confirm, prompt, pick) open next to the tap or focused control.
- One set of exits (close, Escape, backdrop), 关闭 label, focus starts on 取消, danger confirms.
- Remove sweetalert2 and the unused @mantine/notifications.
- Remove the 来源与刮削 media settings panel and its entries in 我的 and 影音设置; TMDB and MusicBrainz stay configurable in 系统设置 > 服务配置.
- docs/ui.md 3.7 describes the rule; tests and review scripts follow the new markup.
2026-10-21 07:30:27 +08:00
hectorqin 05762208d9 docs(prototype): 我的 as the settings hub and one page column
- 8 我的(手机): 内容 / 偏好 / 管理 / 账号 as in the app; the list scrolls above the tab bar.
- New 20b 我的(桌面 · 设置中心): groups two to a row in the page column.
- Desktop 首页 / 书架 / 媒体库管理 use the shared 32px gutter (was 40px).
- 设计系统 notes the shared page column and that settings live in 我的.
2026-10-20 18:27:11 +08:00
hectorqin 1f534ee4c3 feat(shell): one page column for the four tabs, 我的 as the settings hub
- 首页/书架/影音/我的 share --page-measure and --page-gutter, so content edges stay put across tabs at every width; 我的 lays its groups two per row on wide screens.
- 我的 gathers every setting (偏好 / 管理 / 账号); its panels live at /me/:panel and return to 我的.
- 影音设置 keeps only media settings and links to 我的; 来源与刮削 is now reachable.
- 系统设置 moves from the shelf header to 我的 → 管理.
2026-10-20 14:58:00 +08:00
Kiro Agent f15365d03c feat(shelf): 在读 / 想读 / 已读 and 分组 (prototypes 2 and 19)
Server: user_books gains reading_status. The shelf list computes each
book's readingState — an explicit 在读/已读 mark wins, otherwise progress
decides (>=99% 已读, started 在读), and 想读 gives way once reading starts —
filters by ?status=, and PUT /api/v1/books/:id/reading-status sets or
clears the mark.

Client: chips 全部/在读/想读/已读 and 分组 (a series or a tag from the
shelf's facets) above the toolbar, all kept in the URL; a state label on
each cover; the ⋯ menu marks 想读/在读/已读, clears the mark, or takes the
book off the shelf.

Docs: API, UI and media user guide for this and the other V3.1 gaps.
2026-10-20 04:47:06 +00:00
Kiro Agent c30e07c270 feat(reader): reading papers as a reader setting
白纸 / 暖黄 / 浅绿 / 灰调 / 夜间 (prototypes 4 and 23) tint only the reading
page — paper, ink, readouts — while the chrome keeps the reading theme.
Stored per device in AppSettings (paper, paperFollowsDark), set from the
reader's 外观 sheet or 外观与主题. 夜间 makes the reader dark; a light paper
gives way to the theme's dark values while the app is dark unless
跟随系统深色模式 is off. Old sepia/green/dark page themes migrate to the
matching paper. Tokens are mirrored in TS and CSS and held to contrast by
theme-tokens.test.ts.
2026-10-20 04:26:51 +00:00
Kiro Agent 858a7479bf feat(theme): V3.1 semantic tokens, four themes and a reading theme
Implements docs/prototypes/Reader V3 主题语义令牌.md (v3.1):

- 暖陶 (default), 雾蓝, 青绿 app themes plus the reading-only 黑白灰, each
  light and dark. Components read --color-* tokens from
  styles/theme-tokens.css, selected by data-theme + data-mode; the
  TypeScript mirror lives in shared/theme/theme.ts.
- Brand is split per the spec: brand/ch-* only fill (with on-brand/on-ch on
  top), brand-text/ch-*-text for text. --reader-accent/--media-accent are now
  brand text; --reader-fill/--media-fill are brand fills. Selected segmented
  controls use brand-soft + brand-text.
- One preference per server+account (reader.theme.v2): app theme, mode
  (system/light/dark), the follow-system light/dark pair, and the reading
  theme. V3 choices migrate per spec §8 (rose falls back to 暖陶 light).
- 外观与主题 rebuilt from prototype 23: follow-system switch with the
  light/dark pair, app-theme cards with light/dark previews, and the
  reading theme (跟随应用 / 黑白灰).
- Reader: 黑白灰 is set on the reader container only; the appearance panel
  offers 跟随应用/黑白灰 and 明暗; day/night sets the mode; the e-ink preset
  uses 黑白灰 light.
- Video and music players wear the current theme's dark values (§4.7).
- Removed the legacy light/sepia/green/dark palettes and the
  <html data-theme> writes from reader settings, which would now collide
  with data-theme="green".
- Tests: theme-tokens.test.ts keeps CSS and TS values identical and checks
  the §5 contrast pairs for all 8 palettes; theme.test.tsx covers migration,
  resolution, the controller and the settings page.
2026-10-20 04:05:35 +00:00
hectorqin be0f20064f 新增V3原型和主题语义令牌 2026-10-20 10:20:32 +08:00
hectorqin 5ffee3db51 feat(media): add play modes and customizable system themes 2026-10-20 10:17:18 +08:00
Claude db6ea15727 docs(ui): shell sidebar breakpoint is 701px 2026-10-19 22:33:29 +08:00
Claude c0dc54efab feat(reader): one theme for reading and media, V3 reader chrome
The book now wears the same six app themes as every other page (plus
follow-system); the separate white/sepia/green/dark reading themes are gone.
The 外观 sheet's swatches are the app themes drawn in their own colours and
the day/night rail button switches between 暖纸 and 深夜. The bottom bar
becomes a rounded sheet. 界面 is renamed 外观 in the bar, panel, review
scripts and spec.

Shelf title is 书架 in the serif face and loses the now-redundant headphones
link. docs/ui.md gains the V3 shell section.
2026-10-19 22:33:27 +08:00
Claude bf325ec072 feat(reader): reorder appearance and read-aloud sheets by use
Appearance: font size, line height, theme (drawn as swatches in each theme's
own paper and ink) and brightness now fill the first screen. Margins,
alignment, font, TXT rows and the four readouts move into closed <details>.

Read aloud: the start button is first and primary; rate gains preset steps;
pitch and volume are folded under 更多. Capability hiding is unchanged.

Spec updated in docs/ui.md; chrome tests cover order, folds and swatches.
2026-10-19 22:33:17 +08:00
hectorqin 875fec84dd fix(media): sync prototype routes and review tooling 2026-10-08 09:51:42 +08:00
hectorqin 8584d7b4e3 fix(web): align React UI with legacy reader UX
Unify media secondary page chrome, loading states, playback controls, favorites filtering, and source/library screens with the legacy reader experience.
2026-10-05 13:23:27 +08:00
hectorqin 007cc3c754 fix(web): finish media UX alignment
Align the React media detail, player, history, queue, shelf, and resource flows with the legacy UX. Refresh the migration validation record and add focused route, resource, and shelf parity coverage.
2026-10-04 11:02:23 +08:00
hectorqin c0af84a00f test(web): verify React media flows against legacy UX 2026-10-03 20:19:52 +08:00
hectorqin 050b8e89db refactor(web): finish media feature migration 2026-10-03 15:04:34 +08:00
hectorqin 2aaa4280c7 refactor(web): migrate client to React architecture 2026-10-03 12:12:30 +08:00
hectorqin 80124d8c4e chore: commit current workspace changes 2026-10-02 11:24:25 +08:00
hectorqin 385e68de78 feat(media): add directory recognition rules and reviewed reidentification 2026-09-28 17:53:30 +08:00
hectorqin f583b32e46 feat(media): clean missing resources by directory 2026-09-28 17:24:04 +08:00
hectorqin 5db43d2da0 fix(media): recover blocked direct playback through CORS and proxy 2026-09-28 14:43:26 +08:00
hectorqin 501ca71f6b fix(media): prefer OpenList direct playback and open player before buffering 2026-09-28 13:39:47 +08:00
hectorqin ff976a4cf6 feat(settings): manage business configuration from admin pages 2026-09-28 12:38:54 +08:00
hectorqin dec8ec8c44 docs: document media features and remove remote source plugin guides 2026-09-28 10:32:52 +08:00
hectorqin 001dc3ddbe feat(pwa): allow immediate updates after saving reading progress 2026-09-28 10:32:34 +08:00
hectorqin 73f9eb6e20 feat(media): add isolated media libraries and playback
Support local and OpenList libraries, metadata, independent media navigation, themes, and audio/video playback. Preserve approved v2 prototypes and current documentation; archive superseded review artifacts and keep generated validation output outside version control.
2026-09-27 18:22:51 +08:00