Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 30 additions & 8 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,17 +44,21 @@ All commits MUST use a Conventional Commits message. Follow these structural rul

## Current Task

Upstream Feature Integration Roadmap (2026-08-19) - ✅ COMPLETED
Upstream Feature Integration Roadmap & Post-Merge Hardening (2026-09-05) - ✅ COMPLETED

- **Phase 1: In-Chapter Search & RTL Support** - ✅ COMPLETED
- **In-Chapter Search (#1877)**: Non-destructive WebView search engine (`window.readerSearch`), match counters, steppers, MD3 scaled `ReaderSearchbar.tsx`, hardware back dismissal (`932638119`)
- **RTL Language Support (#1717)**: Native and WebView layout direction for RTL locales (ar, he, fa, ur), reader CSS alignment (`6ddfe3d2e`)
- **In-Chapter Search (#1877)**: Non-destructive WebView search engine (`window.readerSearch`), match counters, steppers, MD3 scaled `ReaderSearchbar.tsx`, hardware back dismissal (`932638119`), bounded tree walk DOM preservation & virtualization (`a11e42bf1`), animated return anchor banner (`74404ed43`, `fbf73b4e3`, `dd53eeb3e`)
- **RTL Language Support (#1717)**: Native and WebView layout direction for RTL locales (ar, he, fa, ur), reader CSS alignment (`6ddfe3d2e`), RTL paging/gestures and navigation mirroring (`111fa901a`, `a8895e63c`)
- **Phase 2: Analytics & Statistics** - ✅ COMPLETED
- **Reading Time Tracking (#1899)**: Migration 006 `ReadingSession` table with cascading deletes, `useTimeTracking.ts` foreground activity listener with inactivity pause & TTS synergy (`cde0aa1ff`)
- **Statistics Overhaul & Charts (#1919)**: Raw-SQL aggregate queries in `StatsQueries.ts`, Overview/Time/Plugins tabs, `react-native-svg` donut distribution charts, genre taxonomy exploration (`caa1645cd`)
- **Phase 3: Background Updates** - ✅ COMPLETED
- **Scheduled Library Updates**: Persisted interval settings, `ServiceManager` opportunistic foreground checks and task deduplication (`8fecb06a9`)
- **Tests**: 1628 passing across 109 test suites (zero regressions)
- **Reading Time Tracking (#1899)**: Migration 006 `ReadingSession` table with cascading deletes, `useTimeTracking.ts` foreground activity listener with inactivity pause & TTS synergy (`cde0aa1ff`), periodic checkpoints and Doze drift capping (`09a966a35`, `b30abcc12`)
- **Statistics Overhaul & Charts (#1919)**: Raw-SQL aggregate queries in `StatsQueries.ts`, Migration 007 (`idx_novel_inLibrary`), Overview/Time/Plugins tabs, `react-native-svg` donut distribution charts, reading velocity using active chapters, sub-minute seconds resolution (`caa1645cd`, `cf76883ae`, `317e6e1ce`)
- **Phase 3: Background Updates & Gesture Hardening** - ✅ COMPLETED
- **Scheduled Library Updates**: Persisted interval settings, `ServiceManager` opportunistic foreground checks and task deduplication (`8fecb06a9`), category-only update time isolation (`a8895e63c`)
- **Gesture Arbitration**: Slider responder deferral and `sliderDragState` event bus to eliminate TabView swipe conflicts (`d16880e17`, `31e0f1d54`)
- **Packaging**: CommonJS Metro bundle configuration in Gradle (`9e737c9f4`)
- **Branch Health**: All 14 ahead commits clean, well-tested, free of leftover debug logs/code, and compile without errors. Branch is in a stable, merge-ready state.
- **Translation Key Sync**: English strings (`strings/languages/en/strings.json`) received new keys for seconds formatting, search return behavior, and RTL restart notes; secondary locales queued for downstream translation string synchronization in a subsequent localization pass.
- **Tests**: 1684 passing across 118 test suites (zero regressions, +56 new tests)
- **Docs**: PRD at PRD.md

### Previous Completed Tasks
Expand Down Expand Up @@ -140,6 +144,24 @@ Upstream Feature Integration Roadmap (2026-08-19) - ✅ COMPLETED

## Recent Fixes

### Background TTS Reading Time Reconciliation (2026-09-05) - ✅ COMPLETED

- **Bug**: Background TTS listening recorded ~zero time in Statistics → Time.
- **Root Cause**: `useTimeTracking` checkpoints/flushes run on the JS thread, which freezes under Android Doze while `TTSForegroundService` keeps speaking. When TTS stopped mid-background (notification stop, queue drain, audio-focus loss), the first poll after revive capped the flush to `lastHeartbeat + 700ms` (`tts-inactive-poll` Doze guard) — wiping hours of listening.
- **Fix**: Native monotonic speaking clock in `TTSForegroundService` (segment opens on utterance `onStart`, closes on queue drain/stop/pause; `speak`/`speakBatch` flush boundaries close stale segments), exposed via `TTSHighlightModule.getTtsPlaybackClock()` as `{spokenMs, speaking}`. Hook snapshots the clock on app-background entry and inserts the delta-minus-JS-recorded top-up on foreground/unmount (wall-clock capped, 12h sanitized, `<1s` dropped). Background flushes are native-capped to the same attestation; session restart after foreground requires native `speaking` (no phantom sessions); repeat background events settle instead of resetting.
- **Fail-open**: Null/unbound clock or service restart disables caps and top-ups — behavior identical to before.
- **Files**: `TTSForegroundService.kt` (+clock), `TTSHighlightModule.kt` (+bridge), `useTimeTracking.ts` (+reconcile protocol), `WebViewReader.tsx` (comment)
- **Tests**: 1688 passing across 119 suites (+4 reconcile tests: no double-count, frozen-JS recovery, no phantom session, fail-open); native `TTSSpeakingClockTest` 4/4 via Robolectric

### Upstream Integration Hardening & Post-Merge Polish (2026-09-05) - ✅ COMPLETED

- **In-Chapter Search UX & Virtualization**: Bounded DOM tree walk replacing `cloneContents`, 200-match virtualization window, wrap-around stepper, and animated return-to-position banner with hardware back button dismissal (`74404ed43`, `fbf73b4e3`, `dd53eeb3e`, `a11e42bf1`).
- **RTL Support & Inverted Controls**: Native navigation icon mirroring (`I18nManager.isRTL`), CSS layout flipping, tap zone and swipe direction inversion, seekbar direction flip (`111fa901a`, `a8895e63c`, `cf76883ae`).
- **Reading Time & Analytics Hardening**: Heartbeat-based background tracking (700ms polling, 2s grace) preserving background TTS playback duration; Doze sleep drift capping; 60s periodic checkpoints; Migration 007 (`idx_novel_inLibrary`); seconds resolution and auto-refresh on screen focus (`09a966a35`, `cf76883ae`, `317e6e1ce`, `b30abcc12`).
- **Gesture Arbitration & Persistence Protection**: `sliderDragState` event bus preventing bottom sheet TabView horizontal swipe conflict; 400ms fallback drag release; `flushPendingProgressSave` guard preventing 0% overwrite on chapter load (`d16880e17`, `05c5e24f4`, `31e0f1d54`).
- **Build Packaging**: Configured CommonJS Metro bundle resolution in Gradle for release packaging (`9e737c9f4`).
- **Tests**: 1684 passing across 118 test suites (+56 tests, zero regressions).

### TTS Text Cleanup Pipeline (2026-08-02) - ✅ COMPLETED

- **Feature**: Declarative, length-preserving text cleanup applied to every paragraph before it reaches the native TTS engine across ALL playback paths (initial queue, WebView tts-queue refills, fallback single-speak)
Expand Down
20 changes: 15 additions & 5 deletions GEMINI.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,13 @@ pnpm run test:tts-wake-cycle
```

## Current Task
Upstream Feature Integration Roadmap (2026-08-19) - ✅ COMPLETED
- **Phase 1**: In-Chapter Search (#1877) + RTL Language Support (#1717)
- **Phase 2**: Reading Time Tracking & Inactivity Detection (#1899) + Stats Overhaul & Donut Charts (#1919)
- **Phase 3**: Scheduled Background Library Updates
- **Tests**: 1628 passing across 109 test suites (zero regressions)
Upstream Feature Integration Roadmap & Post-Merge Hardening (2026-09-05) - ✅ COMPLETED
- **Phase 1**: In-Chapter Search (#1877) + RTL Language Support (#1717) + Return Anchor Banner & Virtualization
- **Phase 2**: Reading Time Tracking & Inactivity Detection (#1899) + Stats Overhaul, Migration 007 & Doze Drift Capping (#1919)
- **Phase 3**: Scheduled Background Updates + Gesture Arbitration & Android Metro CJS Packaging
- **Branch Health**: All 14 ahead commits clean, well-tested, free of leftover debug logs/code, and compile without errors. Branch is in a stable, merge-ready state.
- **Translation Key Sync**: English strings (`strings/languages/en/strings.json`) updated with keys for seconds formatting, search return behavior, and RTL restart notes; secondary locales queued for downstream sync.
- **Tests**: 1684 passing across 118 test suites (zero regressions, +56 new tests)
- **Docs**: PRD.md in root

## TTS Architecture (3-Layer Hybrid)
Expand Down Expand Up @@ -68,6 +70,14 @@ Upstream Feature Integration Roadmap (2026-08-19) - ✅ COMPLETED

## Recent Fixes

### Upstream Integration Hardening & Post-Merge Polish (2026-09-05) - ✅ COMPLETED
- **Search UX & Virtualization**: Bounded DOM walk, 200-match virtualization, return anchor banner with hardware back dismissal (`74404ed43`, `fbf73b4e3`, `dd53eeb3e`, `a11e42bf1`).
- **RTL Support & Gestures**: Navigation icon mirroring (`I18nManager.isRTL`), CSS layout flipping, inverted pageReader swipes & seekbars (`111fa901a`, `a8895e63c`, `cf76883ae`).
- **Reading Time & Analytics**: Heartbeat-based background tracking (700ms polling, 2s grace) for lockscreen/headset TTS; Doze drift capping; 60s checkpoints; Migration 007 (`idx_novel_inLibrary`); seconds resolution and auto-refresh on focus (`09a966a35`, `cf76883ae`, `317e6e1ce`, `b30abcc12`).
- **Gesture Arbitration & Persistence**: `sliderDragState` event bus preventing TabView swipe conflict; 400ms fallback drag release; `flushPendingProgressSave` 0% overwrite guard (`d16880e17`, `05c5e24f4`, `31e0f1d54`).
- **Build Packaging**: Configured Metro bundle config for CommonJS in Gradle (`9e737c9f4`).
- **Tests**: 1684 passing across 118 test suites (+56 tests, zero regressions).

### MainActivity Startup Crash (2025-12-27)
- **Cause**: `window.insetsController` accessed before `super.onCreate()` → NPE when DecorView null
- **Fix**: Move `super.onCreate()` first in `MainActivity.kt`
Expand Down
47 changes: 27 additions & 20 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
@@ -1,28 +1,35 @@
## What's New

This release delivers the **Unified Visible Text & TTS Cleanup** (issue #19) — one declarative ruleset now governs both the on-screen text and TTS audio, eliminating the need to maintain two separate cleanup configs. It also brings a sweeping **Material 3 UI modernization** (dynamic Material You colors, MD3 sliders, M3 top tab indicators, standardized bottom sheets), new **Kitsu tracker support**, faster library updates, smarter reader navigation, and a major round of **database reliability fixes** hardened during the 52-commit merge verification.
**v2.1.5 consolidates the post-2.1.4 roadmap into a polished release — In-Chapter Search, RTL layout, reading analytics with charts, and scheduled background updates land alongside deep hardening of progress persistence, DoH networking, and upstream sync integrity.**

### ✨ Features

- **Unified Visible Text & TTS Cleanup (issue #19):** The declarative JSON ruleset now applies to the visible DOM as well as TTS audio — cleaned display text while keeping paragraph indexing count-preserving so TTS always reads pristine, fully-cleaned text
- **Material 3 UI Overhaul:** Dynamic Material You color theming, MD3 slider replacing the community slider (no more post-release flicker), M3 top tab indicators, and standardized bottom sheet UX with modernized menu styling
- **Kitsu Tracker Support:** New tracker integration with request restoration on submit and null-safe chapter progress handling
- **Faster Library Updates:** Parallel updates across sources, configurable chapter download cooldown, and skip-version update notifications
- **Reader & Novel Enhancements:** Jump to first unread chapter via the read button and FAB, unloaded chapters load on demand in the jump modal and drawer, more novel statuses and icons
- **EPUB Improvements:** Chapter numbers in EPUB chapter titles, range export fixes, and sanitized EPUB filenames

### 🛡️ Robustness & Reliability

- **Database Hardening:** Exclusive transactions with awaited `runAsync`, julianday trigger migration (004), date-correct library updates and sorting, numerically stable chapter page ordering, scoped download deletion, and preserved default categories after reordering
- **Build System Fixes:** `expo-material3-theme` patched for AGP deprecations (Gradle namespace + `abortOnError`)
- **Stability Fixes:** Reader table overflow and white drawer seam prevention, bottom nav alignment with M3, crash-free native file operations, corrected notification throttling, and TTS quote-stripping in normalized text
* **In-Chapter Search**: Non-destructive WebView search engine (`window.readerSearch`), live match counters, steppers, and MD3 `ReaderSearchbar` with hardware-back dismissal.
* **RTL Language Support**: Native + WebView layout direction for ar/he/fa/ur with CSS alignment fixes and inset handling.
* **Reading Time Tracking**: Dual-mode foreground tracking (inactivity pause + TTS synergy), `ReadingSession` table (migration 006, cascading deletes), and `useTimeTracking` listener.
* **Statistics Overhaul & Charts**: Raw-SQL aggregates in `StatsQueries`, Overview/Time/Plugins tabs, `react-native-svg` donut distribution, genre taxonomy exploration, and reading velocity metrics.
* **Scheduled Library Updates**: Persisted interval settings with `ServiceManager` opportunistic foreground checks and task deduplication.
* **Reader UX Polish**: Tab swipe gestures enabled with slider-drag protection, UI scale live-dragging, and tab indicator/appbar inset fixes.

### 🛠 Fixes & Hardening
* **Progress Persistence**: Tightened and hardened background progress flush (3 commits) — reliable saves when app backgrounds, regression-tested.
* **Plugin & Queue Reliability**: Deterministic FIFO queues with reset gate, stale update badge clearing, and `refreshPlugins` cold-start rejection handling.
* **Networking & Backups**: DoH routing for remote backups, streamed backup archive completion, and hardened archive/restore input validation.
* **UI & Gestures**: Fixed RTL/scheduler/inset issues, UI scale slider range/sync, skeleton loading color neutralization, and library fetch stuck-loading prevention.
* **Novel & Reader Fixes**: Preserved TTS paused paragraph, stabilized update-card navigation deps, select-all across lazy batches, and category-to-library addition.

### 🔄 Upstream Sync
* **Merge Waves 1-3**: Consolidated CSV parsing, relaxed summary limit, predicate-split clarification (M15 Option B), and deferred audit nit remediation (H5/M12/M13/LOW-7/9/10).
* **Plugin & i18n**: Repository enable/disable controls (#1628), plugin selector extraction, and translation restoration across locales.
* **Media & Content**: EPUB image-format/cover support (#1622/#1946/#1948), novel cover image headers (#1977), and media session test activation.

### 📜 Commits

- **Core Updates**: Unified the visible-text and TTS cleanup rulesets (issue #19), resolving 9 audit findings from the 52-commit merge verification; refactored the theme layer to a context-based provider with ID migration
- **UI Polishing**: Rolled out Material 3 across the app — dynamic Material You colors, MD3 slider (flicker-free), M3 top tab indicators, standardized bottom sheets, modernized menus, and stable browse tab bar with capped modal height
- **New Features**: Added Kitsu tracker support, parallel library updates, skip-version update notifications, configurable download cooldown, jump-to-first-unread via read button/FAB, on-demand chapter loading in jump modal/drawer, chapter numbers in EPUB titles, and additional novel statuses/icons
- **Bug Fixes**: Hardened the database layer (exclusive transactions, julianday trigger migration, date-correct updates/sorting, order-stable chapter pages, download deletion scoping, category preservation); fixed reader table overflow, white drawer seam, slider flicker, tracker search restoration, and crash-prone native file operations
- **Build & Testing**: Patched `expo-material3-theme` for AGP deprecations, added type-safe fixtures for download deletion tests, and restored chapter progress from the database on reader open
* **Core Reader & Analytics**: Added in-chapter search (932638119), RTL support (6ddfe3d2e), reading time tracking (cde0aa1ff), stats overhaul with charts (caa1645cd), scheduled updates (8fecb06a9), and tab-gesture/slider safeguards (4e6feb8cc) — completing the upstream feature roadmap.
* **UI & Settings Polish**: Fixed UI scale slider range and live sync (4dd63579b), tab indicator/insets (296e6492c), hardening of RTL/scheduler/insets (384cdef45), and analytics UI dual-mode polish (e00cd22d9).
* **Progress & Persistence Hardening**: Tightened background progress saves (653a9e9f9), hardened flush logic (5baef20a6), and added background flush regression test (d090bef38) plus audit-driven validation/gesture fixes (710249981, 25a5186bd).
* **Plugin / DB / Queue Stability**: Made FIFO queues deterministic (29d20cd4e), extracted plugin selectors and cleared stale badges (06852a6a8), and consolidated DB CSV parsing with docs alignment (82ab55b7f, da8110cec).
* **Networking, Security & Backups**: Routed remote backups through DoH (64be3eef5), finished streamed archives (d4c5525bc), wired DoH with restore hardening (ffddaa1b5), and hardened archive/restore inputs (1dea15cad).
* **Tests & Coverage**: Added minimal search/RTL coverage (91011becd), reading velocity/navigation regressions (3466bfecc), and closed harden-commit gaps for plugins/db/epub with harden-commit burn-down fixtures (a54ddae1c, 54b36d5da, daa0b204d).
* **Upstream & Housekeeping**: Pulled 12+ upstream fixes (library loading, DB freeze, EPUB covers, translations, navigation deps) from `lnreader/lnreader`, recorded sync waves and POV audits, and documented features/roadmap (433830717, 6b7b213bb, ad242c988, 02f0127de — 55 commits since v2.1.4).

**Full Changelog**: https://github.com/bizzkoot/lnreader/compare/v2.1.3...v2.1.4
> **Full diff:** https://github.com/bizzkoot/lnreader/compare/v2.1.4...v2.1.5 — 55 commits, zero regressions (1628 tests passing).
1 change: 1 addition & 0 deletions android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ react {
// debuggableVariants = ["liteDebug", "prodDebug"]

/* Bundling */
bundleConfig = file("../../metro.config.cjs")
// A list containing the node command and its flags. Default is just 'node'.
// nodeExecutableAndArgs = ["node"]
//
Expand Down
7 changes: 7 additions & 0 deletions android/app/src/main/assets/css/pageReader.css
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,10 @@ body.page-reader > #LNReader-chapter {
z-index: 888888;
background-color: var(--readerSettings-theme);
}

/* RTL: mirror off-screen chapter transition (physical left → logical inline-end) */
html[dir='rtl'] .transition-chapter,
body[dir='rtl'] .transition-chapter {
left: auto;
right: 100vw;
}
14 changes: 14 additions & 0 deletions android/app/src/main/assets/css/toolWrapper.css
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,20 @@
transform: translate(-0.95rem, -1rem);
}

/* RTL: thumb must anchor from inline-end so progress-right expansion stays on track */
html[dir='rtl'] #ToolWrapper.horizontal > #ScrollBar #scrollbar-thumb-wrapper,
body[dir='rtl'] #ToolWrapper.horizontal > #ScrollBar #scrollbar-thumb-wrapper {
left: auto;
right: 100%;
transform: translate(0.95rem, -1rem);
}

/* RTL: progress fills from the right edge (page 1 at right) */
html[dir='rtl'] #ToolWrapper.horizontal > #ScrollBar #scrollbar-progress,
body[dir='rtl'] #ToolWrapper.horizontal > #ScrollBar #scrollbar-progress {
margin-left: auto;
}

#ToolWrapper.horizontal > #ScrollBar #scrollbar-thumb {
top: 100%;
height: 1rem;
Expand Down
Loading
Loading