What's Changed
This release brings faithful rendering for all KOReader highlight styles, polishes the annotation editing toolbar, and fixes a few resilience issues around metadata parsing and file watching.
Highlight Styles
- Invert and strikeout highlights are now rendered with their actual KOReader styling instead of falling back to a plain highlight
- Unrecognized highlight colors (from custom-patched KOReader installs) show a rainbow gradient instead of silently defaulting to yellow
- Style icon badge in annotation card headers to tell highlight, underline, strikeout, and invert apart at a glance
- Color picker is disabled for invert highlights, matching KOReader behavior
Bug Fixes
- Invalid UTF-8 in metadata — truncated multi-byte sequences in KOReader highlight text no longer blow up the parser
- Stats ID fallback — reading statistics fall back to the canonical item ID when the MD5 hash is missing showing stats on the item detail page even without a sidecar file when available
- File watcher self-healing — the watcher recovers when a DB writeback fails instead of stalling
Internal
- Reading metrics and summaries are pre-computed at export time as JSON per week/month/year, so the frontend fetches them directly instead of reassembling from raw day-level data
build.rssplit intobuild/{main,shared,react,compress,licenses,locale}.rsapp/run.rssplit intobootstrap.rsand per-command modules (serve,export,set_password,licenses)- Removed render-time state sync patterns in favor of event-driven updates and keyed remounts
- Added optimistic-cache test coverage
Full Changelog: 2026.4.2...2026.4.3