Commit graph

8 commits

Author SHA1 Message Date
Huang Xin
2813ad7e6a
fix: iOS reader polish for drawing dock, short sheets, bookshelf header and read aloud (#6778)
* fix(reader): fill the drawing dock's bottom safe area with its own background

The dock was lifted above the home indicator by the bottom inset, leaving a
transparent gap where the reader footer showed through. It now sits at the
bottom edge and pads the inset with its own background.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* feat(library): title the bookshelf editor with the selected shelf on phones

On phones the selected shelf's name becomes the page title beside the back
button and the tabs, icons only, get a centered row of their own, so the
built-in shelves and the add button fit on one line. Wrapped rows are now
centered on the screen rather than within the slot beside the back button.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(tts): keep a hidden mini player hidden through brief stalls between paragraphs

The buffering probe catches the short wait while the next paragraph loads,
which re-showed the card and re-armed its linger, and the end of buffering
showed it again. A hidden card now comes back only when a stall lasts 500ms,
and the end of buffering just restarts the countdown.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(ui): only full-height sheets clear the status bar and show a back button

A content-height sheet such as a confirmation, or a sheet snapped short of
the screen, rests at the bottom: it no longer pads its drag handle for the
status bar or shows the back button.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(tts): stop the word highlight stepping back at a sentence start on iOS

chunk-start fires as the item is handed to AVPlayer, which can take a few
hundred ms to open it. The media clock ran ahead from the event and lit the
second word, then the next poll pulled it back to the first. The clock now
holds until a poll sees the item playing, and the position reports playing
from timeControlStatus rather than the rate, which is set while loading.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(tts): preload the next chapter's opening for Edge TTS and custom voices

Only windowed engines carried preloads past a chapter end, so with Edge TTS
or a custom service a chapter change started with nothing synthesized. A new
preloadsAudio capability marks engines whose preloads keep the audio; they
now fill their usual handful of paragraphs from the next chapter too.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs: run selected unit test files with pnpm test --run

pnpm test -- <files> forwards the separator and runs more than the files
asked for.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* chore(agent): update agent memories

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(tts): keep the iOS word clock from stepping back on pause or running ahead on resume

Pausing froze the clock at the last poll, up to 250ms behind where it had
got, so the highlight could step back a word. Resuming restarted it before
AVPlayer was rendering again. Pause now freezes the extrapolated position,
and resume polls and lets the player report when it is playing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(tts): preload the next chunk's opening at the end of a chunk

A section over 512 KB of HTML is read in chunks, and the live document ends
at each chunk's end. The cross-boundary preload took that for the chapter's
end and preloaded the next section, so moving to the next chunk found nothing
synthesized. It now starts a throwaway reader at the next chunk's anchor in a
fresh copy of the section, and only goes on to the next section after the
last chunk.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(ui): drag a content-height sheet up instead of setting its height

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(tts): use the contrast button for play/pause in the full player

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(tts): preload the next section in the language it is read in, and more

- A section file with only xml:lang is rendered with the book's language as
  its lang, which is what the live read speaks it in. The fresh copy used to
  preload the next section kept xml:lang (zh-CN vs zh), so its audio was
  cached under keys playback never looked up and each new section started
  with a wait. The fresh copy now takes the book's language the same way.
- E-ink drops the tinted sentence under the word highlight in word mode.
- The lyric sheet follows the document read, not only the section index, so
  a section read in chunks no longer shows the first chunk's lines under the
  next chunk's position.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* feat(tts): resize the full player on desktop and size the lyric text

- A corner grip resizes the full Read Aloud player with the pointer on
  desktop, up to the whole window, and the size is kept for the next time
  it opens. Once sized, the lyric sheet takes the height it is given.
- A−/A+ in the lyric view step the line size from 12 to 38px, kept per
  device.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(tts): keep the lyric size and player size working when storage is blocked

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 00:25:00 +02:00
Huang Xin
2ce0522743
chore(linux): catch up the CEF runtime with upstream feat/cef, closes #6397 (#6487)
Some checks are pending
CodeQL Advanced / Analyze (actions) (push) Waiting to run
CodeQL Advanced / Analyze (javascript-typescript) (push) Waiting to run
CodeQL Advanced / Analyze (rust) (push) Waiting to run
Publish Docker image / build (linux/amd64, ubuntu-latest) (push) Waiting to run
Publish Docker image / build (linux/arm64, ubuntu-24.04-arm) (push) Waiting to run
Publish Docker image / merge (push) Blocked by required conditions
Build with Nix / tests (push) Waiting to run
PR checks / nix_flake_check (push) Waiting to run
PR checks / rust_lint (push) Waiting to run
PR checks / koplugin_rust_lint (push) Waiting to run
PR checks / build_web_app (push) Waiting to run
PR checks / test_web_app (1) (push) Waiting to run
PR checks / test_web_app (2) (push) Waiting to run
PR checks / test_extensions (push) Waiting to run
PR checks / build_tauri_app (push) Waiting to run
Scorecard supply-chain security / Scorecard analysis (push) Waiting to run
Deploy to vercel on merge / build_and_deploy (push) Waiting to run
2026-09-30 04:07:58 +08:00
Huang Xin
d05fb5338a
fix(sync): closing unclosed void tags before XML re-parsing, closes #5271 (#6122)
* chore: update agent memories

* chore: update agent memories

* fix(sync): closing unclosed void tags before XML re-parsing, closes #5271

* chore(agent): update agent memories

* fix(sync): preserve block starts for dropped XPointer whitespace

* docs(agent): sanitize support notes and correct review findings
2026-09-07 18:02:57 +02:00
Huang Xin
32c42100d0
feat(linux): debug the CEF build over CDP, and three fixes it found (#6087)
* feat(linux): debug the CEF build over the DevTools protocol

The Linux CEF runtime is Chromium, so the app window is a normal CDP
target — the only way to inspect the running desktop app on Linux, since
WebKitWebDriver (pnpm tauri:dev:test) drives the wry runtime instead.

`READEST_CDP_PORT=9222` passes the port to CEF as `--remote-debugging-port`
through the runtime's command-line args. CEF honours that switch straight
off argv too, but tauri-plugin-cli parses the same argv for open-with paths
and warns about the unknown argument on every launch, so the env var is the
supported way in. It works on any CEF build — a packaged .deb or the
Flatpak, not just `pnpm tauri:dev:cdp`.

scripts/cdp.mjs is the client, dependency-free (node's global fetch and
WebSocket): `pnpm cdp <targets|eval|click|screenshot|logs>`. The endpoint
listens on loopback only.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix(desktop): open the first window at 1280x800

macOS has always opened at 1280x800; Windows and Linux opened at 800x600,
which is cramped for the library grid and a two-page spread. Give every
desktop platform the same default, and clamp it to 90% of the monitor's
work area so it cannot open partly off-screen on a 1366x768 laptop — a
window whose title bar lands past the bottom edge can be impossible to
resize back. An unreported or empty work area keeps the default: a window
that is too large stays reachable, one sized from a bogus zero-height
screen does not.

Only the first launch is affected; later ones restore the saved geometry
through tauri_plugin_window_state.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix(opds): size the add catalog dialog like the catalog manager

The Add/Edit Catalog form took daisyUI's bare `modal-box` default: 512x889
against the 640x756 manager it opens on top of, so it sat narrower than the
window behind it and ran 89px off the bottom of a 1280x800 window, putting
its Cancel / Add Catalog row out of reach.

Both now size from one exported class string, so they cannot drift apart
again. `sm:max-h-full sm:max-w-full` is what defeats daisyUI's own max-w-lg
and max-height caps; everything is sm:-prefixed, leaving each dialog's
mobile treatment alone.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix(library): stop the native scrollbar flashing before OverlayScrollbars

Reloading the library showed the platform scrollbar for ~1.8s and then lost
it, shifting the grid 15px sideways as it went.

Virtuoso owns the scroller inside the OverlayScrollbars root and gives it
`overflow-y: auto` inline, so the native scrollbar paints for as long as
OverlayScrollbars' deferred init takes, then vanishes when OS marks that
same element `data-overlayscrollbars-viewport="scrollbarHidden ..."`.
OverlayScrollbars ships hiding rules for `[data-overlayscrollbars-initialize]`,
but that attribute sits on the root we hand it, never on the child that
actually scrolls.

Extend the same pre-init convention to the scroller child. Keyed on
attributes Virtuoso and OS already set, so it also covers the reader
sidebar's TOC and book-note lists, and `:not([data-overlayscrollbars])`
scopes it to the pre-init window — once OS owns the root, its own viewport
styling takes over. It lives in globals.css so it is there at first paint,
unlike the overlayscrollbars.css import inside the component chunk.

Measured on reload: scroller gutter went 0 -> 15 -> 0 before, and stays 0
throughout after.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix(cdp): clear the request timeout so the client exits when it is done

Every send() armed a 30s timer and nothing cleared it when the reply
arrived. A pending timer keeps node's event loop alive, so `pnpm cdp eval`
printed its answer and then sat there until the timer fired — 30.1s for a
command whose work took 0.1s. Clear it on reply, and drop the pending entry
when it does fire.

Measured against a stub CDP endpoint: `eval` went from 30.143s to 0.124s,
and a server that never answers still rejects with "timed out" at 30.1s.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-06 07:19:06 +02:00
Huang Xin
771b152e5b
feat(dictionaries): add bundled plugin and Yomitan support (#5764)
Some checks are pending
CodeQL Advanced / Analyze (actions) (push) Waiting to run
CodeQL Advanced / Analyze (javascript-typescript) (push) Waiting to run
CodeQL Advanced / Analyze (rust) (push) Waiting to run
Publish Docker image / build (linux/amd64, ubuntu-latest) (push) Waiting to run
Publish Docker image / build (linux/arm64, ubuntu-24.04-arm) (push) Waiting to run
Publish Docker image / merge (push) Blocked by required conditions
PR checks / rust_lint (push) Waiting to run
PR checks / koplugin_rust_lint (push) Waiting to run
PR checks / build_web_app (push) Waiting to run
PR checks / test_web_app (1) (push) Waiting to run
PR checks / test_web_app (2) (push) Waiting to run
PR checks / test_extensions (push) Waiting to run
PR checks / build_tauri_app (push) Waiting to run
Scorecard supply-chain security / Scorecard analysis (push) Waiting to run
Deploy to vercel on merge / build_and_deploy (push) Waiting to run
* feat: add bundled dictionary plugins and Yomitan support

* fix: serve browser plugin workers with COEP

* feat: add portable and batched Yomitan imports

* feat: show dictionary import progress

* fix: pre-landing review fixes

* fix: pre-landing review fixes

* fix: pre-landing review fixes

* fix: isolate malformed portable dictionary rows

* fix: bound and isolate portable plugin results

* fix: harden plugin data boundaries

* fix: isolate portable dictionary rows

* fix: isolate dictionary plugin failures

* fix: preserve dictionary rollback targets

* fix: guard dictionary generation recovery

* docs: document dictionary plugin architecture

Co-Authored-By: OpenAI Codex <noreply@openai.com>

---------

Co-authored-by: OpenAI Codex <noreply@openai.com>
2026-08-18 13:43:58 +02:00
Huang Xin
cfe2bb9116
fix(reader): Android text selection breaks on the first word of hyphenated paragraphs (#4545)
Some checks are pending
CodeQL Advanced / Analyze (actions) (push) Waiting to run
CodeQL Advanced / Analyze (javascript-typescript) (push) Waiting to run
CodeQL Advanced / Analyze (rust) (push) Waiting to run
Publish Docker image / build (linux/amd64, ubuntu-latest) (push) Waiting to run
Publish Docker image / build (linux/arm64, ubuntu-24.04-arm) (push) Waiting to run
Publish Docker image / merge (push) Blocked by required conditions
PR checks / rust_lint (push) Waiting to run
PR checks / build_web_app (push) Waiting to run
PR checks / test_web_app (push) Waiting to run
PR checks / build_tauri_app (push) Waiting to run
Scorecard supply-chain security / Scorecard analysis (push) Waiting to run
Deploy to vercel on merge / build_and_deploy (push) Waiting to run
2026-06-12 12:30:56 +08:00
Huang Xin
97cab2d70b
feat(database): support turso fts in tauri apps (#3484)
Some checks are pending
Deploy to vercel on merge / build_and_deploy (push) Waiting to run
2026-03-05 21:00:15 +01:00
Huang Xin
13588b4a65
chore(testing): add Tauri integration tests and E2E test infrastructure (#3483)
Set up WebDriver-based testing for the Tauri app with two tiers:
- Vitest browser-mode tests (*.tauri.test.ts) running inside the Tauri WebView
  for plugin IPC testing (libsql, smoke tests)
- WDIO E2E tests (*.e2e.ts) for UI-level interaction testing

Key changes:
- Add webdriver Cargo feature gating tauri-plugin-webdriver
- Add runtime capability for remote URLs (webdriver builds only)
- Add vitest.tauri.config.mts and wdio.conf.ts connecting to embedded
  WebDriver server on port 4445
- Add shared tauri-invoke helper for IPC from Vitest iframe context
- Add testing documentation in docs/testing.md
2026-03-05 19:14:01 +01:00