Commit Graph
87 Commits
Author SHA1 Message Date
hectorqinandClaude Opus 5.5 1137b0d90d fix(web): paged mode lands on page boundaries; highlights draw and follow reflow; bottom bar stays visible
Paged mode
- Restoring the position after the viewport height changes (address bar,
  keyboard, rotation) wrote max * fraction, which is almost never a column
  boundary: the screen showed half of one page and half of the next. Every
  paged scrollLeft write (restore, TTS follow, revealBlock, search) now goes
  through one page-snapping helper, and a scroll the browser makes on its own
  (focus, selection autoscroll) is snapped back.

Highlights
- localSectionId prefixed `xhtml:` from the format alone, so a windowed book
  whose sections have no prefix saved highlights that matched no chapter and
  were never drawn (and its progress failed to restore). The loaded document's
  own section ids are now the authority.
- Highlight boxes are measured once; font size, margins, mode switch, resize
  or a late image moved the text under them. They are repainted after each.

Mobile bottom bar
- `.reader-route-host` had min-height: 100vh, which on a phone browser is
  taller than the visible viewport while the address bar shows, pushing the
  reader's bottom toolbar under it. Height is 100dvh with a 100vh fallback.
- Notices are bottom-centre, exactly over 朗读/外观; in the reader they now
  stack above the bottom bar instead of swallowing the next tap.

Tap to turn hides the toolbar
- A tap on the outer thirds turns the page and puts a showing toolbar away;
  the middle third still toggles it.

UI review scripts: page-turn-regression waits for login to finish rather than
for the shelf (the app now opens on media); reader-regression shows the
toolbar before pressing 下一章 after tap turns.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 09:24:49 +00:00
hectorqinandClaude Opus 5.5 fbb7298bf0 perf(web): split the reader and admin screens out of the first load
client.js was one 1.48 MB bundle (413 kB gzip) because the build assumed the
Android shell loads from file://. It no longer does: WebHost serves the
bundle from https://appassets.androidplatform.net/ via WebViewAssetLoader,
the service worker precaches every emitted file, and the server serves any
file under assets/ (caching hashed names forever).

- The reader, media library/task/item admin pages and source editor pages
  load on first visit (app/router/lazy-pages.tsx); wrappers keep the page
  names, so the route tree and its tests read unchanged.
- Chunks are content-hashed; the entry stays client.js and CSS stays one
  index.css, so no host-facing name changes and no unstyled flash.
- A tab running an old client after a deploy gets "应用已更新 · 重新加载"
  instead of a dynamic-import error.
- ui:review now opens a book and asserts the reader chunk loads and renders.

client.js: 1478 kB -> 777 kB (gzip 413 -> 231 kB).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 13:04:18 +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 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 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
Claude 16da95b243 feat(media): phone channel switch as segments; remove the old channel rail
The three media channels are a segmented control in the page header on phones
(the sidebar lists them from 701px up), and every channel page now has its
one h1. ChannelSwitcher, MediaChannelEntry, renderChannelLinks and the
legacy showChannelEntry are removed. Shell breakpoints move to 700/701px.

Review script react-app.mjs follows the new DOM (app-nav selectors, summary
and option roles for the favourites filter).
2026-10-19 22:33:28 +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 fdd3a70401 feat(media): one more-options entry, distinct lyrics and episode icons
The now-playing title row carried an ellipsis that opened the same sheet as
the header (or options-row) ellipsis. Drop it; the header one stays.

Lyrics no longer reuse the book icon that means chapters; episodes no longer
share the layers icon with versions. The v2 review script measures the
remaining more-options button.
2026-10-19 22:33:26 +08:00
Claude d4eb2e7a34 feat(media): V3 theme palettes with contrast guard
Retune the six media themes to the V3 semantic palette. Theme ids are
unchanged so saved choices keep working; only names change (暖砂 -> 暖纸,
深海 -> 深夜). System appearance now resolves to 暖纸 / 深夜.

Add a vitest guard that checks WCAG AA text pairs for every theme.
2026-10-19 22:33:17 +08:00
Claude faf0ffd17a fix(ui-review): use reply in reading-overrides fixture route
The reading-overrides fixture handler referenced an undefined res, so
npm run ui:review:reader crashed on startup.
2026-10-19 22:33:16 +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 cd003020f3 fix(web): align media continuation states 2026-10-04 11:40:26 +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 4f001ac2d4 fix(web): align React media screens with legacy UX 2026-10-03 18:24:12 +08:00
hectorqin fdba9a4c5d test(web): add React UI review harness 2026-10-03 15:42:56 +08:00
hectorqin 050b8e89db refactor(web): finish media feature migration 2026-10-03 15:04:34 +08:00
hectorqin 80124d8c4e chore: commit current workspace changes 2026-10-02 11:24:25 +08:00
hectorqin 352dccaabe feat(pwa): align app branding and add startup screen 2026-10-01 08:26:08 +08:00
hectorqin 71eef28e16 fix(pwa): align update prompt with app button styles 2026-09-28 16:40:42 +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 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
hectorqin 07f9a73698 fix(ui): use floating confirmations and notifications 2026-09-24 17:48:50 +08:00
hectorqin 902bc8c8d3 refactor(settings): separate system administration from shelf preferences 2026-09-24 17:34:06 +08:00
hectorqin 06b3d09e22 feat(admin): manage users and invite-based registration 2026-09-24 17:19:48 +08:00
hectorqin 316dd72611 fix(auth): retain renewable sessions and support LAN annotations 2026-09-24 16:59:28 +08:00
hectorqin d5aeef591d fix(reader): preserve mobile selections and resolve shadow ranges 2026-09-24 16:37:30 +08:00
hectorqin 1d86efab34 feat(reader): add selection annotations and server-side book search 2026-09-24 16:03:35 +08:00
hectorqin 9c83e3e013 feat(reader): simplify tools navigation and note workflows 2026-09-24 15:23:57 +08:00
hectorqin aa7aee051d feat(sources): organize source login and plugin management 2026-09-24 10:32:47 +08:00
hectorqin 05877aa4f5 fix(web): move external reader access into shelf settings 2026-09-24 09:43:33 +08:00
hectorqin 7bff77eaf8 feat(reader): deliver P0-P2 reading tools and ecosystem integrations
Add reliable reading progress, verified backup and restore, reading tools, offline downloads, source quality checks, personal credential status, OPDS serving and verified WebDAV backup uploads.
2026-09-24 07:47:32 +08:00
hectorqin e3cabf4b1f feat(web): add PWA installation and offline app shell 2026-09-24 06:34:21 +08:00
hectorqin 95cb3134db feat(sources): support default source and refine switching UI 2026-09-23 15:16:15 +08:00
hectorqin 77adffb160 fix(web): keep extension tabs readable on narrow screens 2026-09-23 14:00:43 +08:00
hectorqin f773b6e1fc feat(search): group books by title and authors with source selection 2026-09-23 13:40:38 +08:00
hectorqin 0a468992be feat(plugins): update installed packages while preserving source data 2026-09-23 12:42:14 +08:00
hectorqin 47baee014e feat(ui): unify page feedback with global Notyf notifications
Route login, shelf, library, file operations, reading, sources and extension feedback through one compact themed notification host. Keep native modal feedback in the top layer, escape remote text, update progress in place and let reading controls receive clicks beneath message text. Cover lifecycle, error handling and layout with unit and Chromium checks.
2026-09-23 10:13:03 +08:00
hectorqin 0782202dae fix(plugins): isolate search stop failures and float operation feedback
A searchCancel deadline previously killed the shared plugin process and prevented subsequent acquisition. Release only the stop request and allow late cleanup to finish. Keep ordinary hard cancellation unchanged. Cover process and HTTP acquisition regressions and compact extension feedback without layout shifts.
2026-09-23 09:46:02 +08:00
hectorqin 1fda200d69 fix(ui): show source operation feedback as compact floating notices 2026-09-23 09:33:45 +08:00
hectorqin d7ebc3c898 feat(plugins): support web npm and tgz installation 2026-09-22 19:21:37 +08:00
hectorqin dcf94c6709 test: validate generic host source extensions end to end 2026-09-22 18:10:46 +08:00
hectorqin d3a2f2a221 chore: remove provider-specific host UI fixtures 2026-09-22 18:04:56 +08:00
hectorqin 3d40d05a50 test: cover source workflows with standalone fixtures 2026-09-22 18:00:20 +08:00