Commit Graph

636 Commits

Author SHA1 Message Date
Huang Xin 9cd88fe839 fix(progress): show correct progress info for subsections in FB2, closes #3136 (#3145) 2026-02-02 17:53:26 +01:00
Huang Xin fca3917a12 fix(toc): prevent unintentional scrolling in the TOC, closes #3124 (#3144) 2026-02-02 14:28:11 +01:00
boludo00 bbbd378f9b feat: rsvp speed reading (#3121)
* feat: add RSVP speed reading feature

Implements Rapid Serial Visual Presentation (RSVP) speed reading mode:

- Display words one at a time with ORP (Optimal Recognition Point) highlighting
- Adjustable WPM speed (100-1000) with keyboard/button controls
- Punctuation pause settings (25-200ms)
- Progress tracking with chapter navigation
- Context panel showing surrounding text when paused
- Keyboard shortcuts (Space, Escape, arrows) and touch gestures
- Chapter selector for quick navigation
- Respects current theme colors
- Persists settings (WPM, pause duration, position) per book

New files:
- services/rsvp/RSVPController.ts - Main controller with playback logic
- services/rsvp/types.ts - TypeScript interfaces
- components/rsvp/RSVPOverlay.tsx - Full-screen RSVP reader UI
- components/rsvp/RSVPControl.tsx - Integration component
- components/rsvp/RSVPStartDialog.tsx - Start position selection

Closes #3111

* fix(rsvp): use portal to fix overlay stacking context issue

- Render RSVP overlay and start dialog via React Portal to document.body
- This ensures the overlay appears above all other content regardless of
  parent component CSS transforms or stacking contexts
- Add fallback colors for theme values to ensure solid background

* fix(rsvp): improve UX with progress sync, sentence highlight, and better dialogs

- Fix start dialog transparency by using solid opaque background with proper
  fallback colors for both light and dark modes
- Increase context words from 50 to 100 words before/after current word
- Add progress sync on RSVP exit - navigates reader to the last word position
- Add temporary bright green sentence underline on exit (5 second duration)
  to easily locate where reading left off
- Helper function to expand word range to full sentence boundaries

* fix(rsvp): store full BookNote for proper annotation removal

The addAnnotation API requires the full BookNote object (including CFI)
when removing annotations, not just the ID. Changed tempHighlightIdRef
to tempHighlightRef to store the complete BookNote object.

* test(rsvp): add Playwright e2e tests for RSVP feature

- Set up Playwright test infrastructure with config
- Add comprehensive e2e tests for RSVP speed reading:
  - Opening RSVP from View menu
  - Start dialog options
  - Play/pause toggle
  - Speed adjustment
  - Skip navigation
  - Keyboard shortcuts
  - Progress bar
  - Chapter navigation
  - Accessibility tests
- Add test data attributes and ARIA labels to RSVPOverlay
- Add test scripts to package.json

* fix(rsvp): clarify start dialog option labels

Update the RSVP start dialog to use clearer language:
- "From Beginning" → "From Chapter Start" (since it starts from chapter beginning)
- "From Current Position" → "From Current Page" (starts from visible page)

* fix(rsvp): use correct theme colors from themeCode

The RSVP components were using incorrect palette key names (camelCase
like `base100` instead of hyphenated like `base-100`), causing the
fallback colors to always be used instead of the reader's actual theme.

Fix by using themeCode.bg, themeCode.fg, and themeCode.primary directly,
which are already resolved from the palette with correct keys.

* fix(rsvp): use theme accent color for sentence underline and persist until page change

- Change underline color from hardcoded green (#22c55e) to theme accent
  color (themeCode.primary), matching the ORP focal point highlight
- Remove 5-second timeout that auto-removed the underline
- Add cleanup on page navigation, new RSVP session start, and unmount
- Add removeRsvpHighlight helper function for consistent cleanup

* fix(rsvp): transition to next chapter when reaching end of section

When RSVP reached the end of a chapter, it would restart the current
chapter instead of moving to the next one. This happened because RSVP
extracts ALL words from the current section via renderer.getContents(),
so when words run out, the entire chapter is done.

- Always use view.renderer.nextSection() when RSVP exhausts words
- This moves to the next chapter instead of staying in the current one

* refactor: remove test files, unsure of use case for now

* chore: remove Playwright e2e test scripts from package.json

- Deleted e2e test scripts related to Playwright from package.json as they are no longer needed.
- Removed Playwright as a dev dependency to streamline the project.

* fix(rsvp): ensure CFI retrieval occurs before navigation

- Updated comments to clarify the necessity of obtaining CFI for both the navigation and sentence highlight before invoking the goTo() method, as it may re-render the document and invalidate Range objects.
- Introduced a new variable for sentence text to enhance readability and maintainability of the code.

* chore: sync pnpm-lock.yaml after removing @playwright/test

* style: format RSVP components

* fix: lint errors and timezone-aware date formatting

* i18n: support CJK text and add translations

---------

Co-authored-by: Huang Xin <chrox.huang@gmail.com>
2026-02-01 18:22:24 +01:00
Huang Xin 9f7147f8f8 fix(layout): fix z index for dropdown (#3135) 2026-02-01 16:36:03 +01:00
Huang Xin c848a319ff fix(layout): fix centered dropdown menu (#3133) 2026-02-01 15:52:51 +01:00
Huang Xin 1294ef90c1 fix(macOS): fix traffic lights position and visibility on macOS, closes #3129 (#3130) 2026-02-01 05:38:40 +01:00
Huang Xin 570598520f fix(a11y): fix accessibility in dropdown menus for TalkBack, closes #3035 (#3126) 2026-01-31 19:05:56 +01:00
Huang Xin fb387c2384 fix(layout): fixed layout of book reading progress and reader footer bar (#3117) 2026-01-30 06:54:20 +01:00
Mohammed Efaz 4ce1ebe477 feat: paragraph by paragraph reading mode (#3096)
* feat: add index

* feat: add bottom nav bar

* feat: add paragraph iterator

* feat: add para mode shortcut

* feat: add paragraph control into foliateviewer

* feat: add paragraph mode toggle to view menu

* feat: add paragraph bar for navigation controls

* feat: add paragraph control wrapper component

* feat: add pargraph overlay for the focused display

* feat: integrate paragraph mode into keyboard navigation

* feat: add paragraph mode state management hook

* feat: add paragraph mode type definition

* feat: add default paragraph mode config

* fix: replace previous storage system with sytem one and fix sync issues

* fix: format
2026-01-30 05:24:23 +01:00
Mohammed Efaz 19f9f5ea24 feat: auto position reader ruler to top of page and some fixes (#3075)
* fix(settings): ensure latest config is used when saving view settings

* fix: reader ruler appearing before other book reading contents

* feat(reader): dispatch reader-closing event during book close

* feat(reader) add auto reposition to top when changing pages and position persistence on book close

* fix(reader): add rtl prop to ReadingRuler component

* fix(reader): handle vertical ltr writing mode in ruler auto positioning

* chore: revert redundant changes to settings.ts

* refactor: remove redundant reader-closing

* refactor: use store progress for ruler positioning with throttled saving
2026-01-26 08:38:06 +01:00
Huang Xin ffc51e75de feat(ruler): support vertical ruler and transparent ruler (#3076) 2026-01-25 20:15:47 +01:00
Huang Xin 2100071991 feat(eink): support color E-ink mode to display more colors, closes #3037 (#3074) 2026-01-25 17:44:41 +01:00
Huang Xin 563d3478ba feat(gamepad): support gamepad input to paginate, closes #2432 (#3073) 2026-01-25 16:32:05 +01:00
Mohammed Efaz c31ece6742 feat: more highlight colours (#3062)
* feat(highlight): extend types and constants for custom hex colours

* feat(highlight): update colour to support hex strings

* refactor(annotator): update component to accept hex colours

* feat(highlight): add colour picker with max 4 custom colors

* feat(settings): add custom colour editor with limit

* refactor: custom highlight colors can only be modified in settings

---------

Co-authored-by: Huang Xin <chrox.huang@gmail.com>
2026-01-25 07:52:29 +01:00
Mohammed Efaz aba9e87fc1 feat: line highlight to guide reading (reading ruler) (#3063)
* feat: add increment decrement numbers for opacity

* feat: add reading ruler colours

* feat: add reading ruler config to book config

* feat: reading Ruler settings panel (in layout section)

* feat: draggable reading ruler

* feat: reading ruler in reader view
2026-01-25 06:48:13 +01:00
Huang Xin 2c4df601d8 refactor: rename components/ui to components/primitives (#3064)
Move Radix/shadcn-based UI primitives into a dedicated
`components/primitives` directory to better reflect
their low-level, composable nature.
Imports remain ergonomic via an alias to `components/ui`.
App-level components should continue to use PascalCase filenames.
2026-01-25 06:41:18 +01:00
Mohammed Efaz 8bea05478a feat(ai): AI reading assistant phase 2.1 (minor UI/UX updates) (#3059)
* refactor(ai): remove chat icons from conversation list items

* feat(ai): add scroll-to-bottom button with animations and dynamic spacer

* fix(ai): align connection status icon with text in settings

* feat(ai): scroll to bottom on chat panel open and improve scroll behavior

* feat(ai): add loading overlay with blur transition for chat history

* feat(ai): pass loading state through component chain for history loading
2026-01-24 17:57:00 +01:00
Huang Xin 42fee90a27 feat(annotation): export annotations with style and color fields in annotation template, closes #1734 (#3060) 2026-01-24 17:44:40 +01:00
Mohammed Efaz 5bbc5ceccc feat(ai): AI reading assistant phase 2 (#3023)
* feat(ai): add dependencies

* chore: bump zod version to default version

* feat(ai): define types and model constants

* feat(ai): ollama provider for local LLM

* feat(ai): implement openrouter provider for cloud models

* feat(settings): register ai settings panel in global dialog

* refactor(ai): expose provider factory and service layer entry point

* test(ai): add unit tests for the providers

* test(ai): add unit tests for the providers

* feat(ai): settings panel for ai configurations

* refactor(ai): rewrite aipanel with autosave and greyed out disabled state

* fix: remove unused onClose prop from aipanel

* test(ai): update mock data

* refactor(ai): remove models

* refactor: use centralised defaults in system defaults

* chore(ai): remove comments

* fix(ai): merge default ai settings on load to prevent undefined values

* refactor(ai): rewrite settings panel with autosave and model input

* feat(ai): add ai tab with simplified highlighting

* feat(sidebar): render AIAssistant for ai tab

* feat(ai): add chat UI

* feat(ai); add chat service with RAG context

* feat(ai): temp debug logger

* feat(ai): add RAG service

* feat(ai): add text chunking utility

* feat(ai): add structured method

* feat(ai): add chatstructured method

* feat(ai): add rag types nd structured output schema

* feat(ai): add aistore, indexdb, bm25

* fix: update lock file

* feat(ai): update types for AI SDK v5

* feat(ai): add placeholder gateway model constants

* refactor(ai): update OllamaProvider for AI SDK

* feat(ai): add native gateway provider

* refactor(ai): update provider exports

* refactor(ai): use streamText from AI SDK

* refactor(ai): use embed from AI sdk

* refactor(ai): update provider factory exports

* feat(ai): add AI Elements and shadcn components

* config: add shadcn component config

* deps: add AI SDK and AI Elements dependencies

* config: add ai packages to transpilePackages

* refactor(ai): remove OpenRouterProvider and old tests

* feat(ai):add assistant-ui components

* feat(ai): add TauriChatAdapter for assistant-ui runtime

* refactor(ai): remove ai-elements components

* dep(ai): install assistant-ui and update next config

* chore(ai): export adapters from service index

* feat(ui): enhance ui components for assistant integration

* feat(settings): migrate ai settings to gateway

* feat(sidebar): integrate assistant-ui

* feat: add ai settings toggle to sidebar content

* feat: conditionally show ai tab in sidebar navigation

* feat: update ai model constants for cheaper options

* feat: add gateway provider with proxied embedding

* feat: add timeouts to ollama provider health checks

* feat: add retry logic to rag service embeddings

* feat: add error recovery to ai store

* feat: add ai feature tests

* feat: add ai api endpoints

* feat: add proxied gateway embedding provider

* feat: add ai runtime utilities

* feat: add ai retry utilities

* feat: add tauri env example template

* feat: add web env example template

* chore: add env

* feat(ai): update models and pricing, remove GLM-4.7-FlashX

* feat(ai): improve system prompt with official headings and no numeric citations

* feat(ai): optimize system prompt for tauri chat

* feat(ui): refine ai chat UI and relocate sources

* feat(ui): update ai settings panel with model pricing and custom model support

* feat(ai): add custom model support to ai settings

* test(ai): update constants tests for removed model

* feat(api): implement ai chat proxy route

* feat(api): implement ai embedding proxy route

* feat(ai): implement ai gateway health check and proxy logic

* feat(ai): simplify proxied embedding provider

* feat(ui): improve markdown text rendering

* feat(ui): add input group component

* test(ai): update ai provider tests

* feat(ai): add pageNumber to text chunk schema

* feat(ai): implement page-based chunking with 1500 char formula

* feat(ai): bump db to v2 and add store reset migration

* feat(ai): transition rag pipeline to page level spoiler filtering

* feat(ai): overhaul readest persona and antijailbreak prompt

* feat(ai): update tauri adapter for page tracking and persona

* chore(ai): export aiStore and logger from core index

* feat(reader): integrate page tracking and manual index reset

* feat(ui): add re-index action and reset logic to chat

* chore: sync pnpm lockfile with ai dependencies

* feat(utils): add browser-safe file utilities for web builds

* refactor(utils): use dynamic tauri fs import to prevent web crashes

* refactor(services): defer osType call to init() for web compatibility

* refactor(services): import RemoteFile from file.web

* refactor(services): import ClosableFile from file.web

* fix(libs): cast Entry to any for getData access

* fix(annotator): cast Overlayer to any for bubble access

* refactor(ai): replace SparklesIcon with BookOpenIcon for index prompt

* test(ai): add pageNumber to TextChunk mocks

* test(ai): fix chunkSection signature in tests

* chore: update files

* fix(ai): prevent useLocalRuntime crash when adapter is null

* refactor: optimize annotator overlay drawing

* feat: stabilize AI assistant runtime and adapter

* refactor: improve document zip loader type safety

* feat: update tauri chat adapter for dynamic options

* fix: restore architecture comments and refine platform properties

* build: update lockfile with assistant-ui patch

* fix(library): patch @assistant-ui/react for runtime initialization

* build: update dependencies in readest-app

* build: update root dependencies and patch configuration

* fix(ai): patch @assistant-ui/react for thread deletion and runtime init

* fix(ai): update assistant-ui patch with dist guards and deletion fallback

* build: sync lockfile with assistant-ui patch updates

* chore(env): update .gitignore by removing .env files from it

* chore(env): update .gitignore by adding .env.local

* chore(env): update .gitignore by adding .env*.local

* fix: restore static osType import

* chore: sync submodules with upstream/main

* refactor: remove redundant file.web module and revert import

* chore: update pnpm-lock.yaml

* refactor: revert guards

* refactor; remove deprecated codes and extract prompts.ts

* refactor(ai): remove unused ragservice exports

* refactor: remove unused ollama and embedding models

* refactor: remove unused type

* test: remove test for the now deleted constants

* refactor: remove unused export

* style: fix ui component formatting

* style: fix core and style file formatting

* test: fix broken ai provider import

* fix: typescript error

* fix: add eslint disable command

* fix(deps): remove unused ai sdk provider util after v6 ai sdk migration

* fix(patch): add lookbehind regex patch

* feat(dep): upgrade vercel ai sdk to v6 and ai-sdk-ollama to v3

* chore: update lockfile for vercel ai sdk v6

* refactor(ai): remove EmbeddingModel generic for ai sdk v6

* refactor(ai): remove EmbeddingModel generic for ai sdk v6

* test(ai): update mock to use embeddingModel

* fix(patch): add lookbehind regex patch for email autolinks in markdown

* refactor(ai): use ai sdk v6 syntax

* fix: prettier formatting

* chore: revert cargo.lock

* fix(ai): update proxied embedding model to v3 spec

* feat(ai): add aiconversation types for chat persistence

* feat(ai): add conversation/message indexeddb and crud operations

* feat(ai): create aiChatStore zustand store for chat state management

* feat(notebook): add notebookactivetab state for Notes/AI

* refactor(ai): refine conversation and message types for persistence

* feat(types): add notebookActiveTab to ReadSettings type

* chore: update deps

* feat: add notebookactive tab default value

* feat: add hook for ai chat

* feat: update left side panel with history/chat icon

* feat: integrate ChatHistoryView into sidebar content

* feat: create UI for managing AI chat history

* feat: implement persistent history with assistant-ui adapter

* feat: create tab navigation component for notes and AI

* feat: add tab navigation and AI assistant view

* feat: update header to display active tab title

* fix: formatting

* feat: remove title and update new chat button

* fix: formatting

* fix: revert tooltip and styling

* feat: implement cross-platform ask dialog bridge

* feat(ai): preserve history during ui clear & use native dialogs

* fix: align notebook navigation height with sidebar tabs

* fix(ai): add missing dependency to handleDeleteConversation hook

* docs: update PROJECT.md with session highlights

* chore: delete projectmd

* chore: update package.json and lock file

* chore: update package.json

* chore: remove patch

* chore: upgrade react types to 19 and show ai features only in development mode for now

---------

Co-authored-by: Huang Xin <chrox.huang@gmail.com>
2026-01-24 11:38:48 +01:00
Huang Xin 6c0f1b8b5f fix(annotator): fix instant action on Android (#3042) 2026-01-23 17:18:51 +01:00
Huang Xin a71347c897 fix(layout): more responsive layout on smaller screens, closes #3029 (#3034) 2026-01-22 17:32:34 +01:00
Huang Xin d9a6cffe78 feat(discord): support show reading status with Discord Rich Presence, closes #1538 (#2998) 2026-01-19 17:42:19 +01:00
Huang Xin 6ce9a263ee fix(a11y): add missing aria labels for some buttons on TTS panel (#2994) 2026-01-19 04:29:02 +01:00
Huang Xin 038eca4267 fix(eink): resolved an issue where the dropdown menu would occasionally fail to expand on some Eink devices (#2991) 2026-01-18 19:57:09 +01:00
Huang Xin fd299a61a7 feat(notes): export notes with custom template, closes #1734 (#2989) 2026-01-18 16:56:32 +01:00
Huang Xin c44705e269 perf(pdf): pre-render next page for PDFs (#2984)
This should close #1911 and #13.
2026-01-18 08:58:00 +01:00
Huang Xin b28ac99a9e feat(pdf): support panning on PDFs (#2981)
This also closes #2978 and closes #2875.
2026-01-17 09:11:33 +01:00
Huang Xin 32ea42a835 fix: remove non-breaking space in book title (#2974) 2026-01-16 12:02:41 +01:00
Huang Xin 3146ae48a7 fix(proofread): support replace text with space (#2965) 2026-01-15 14:10:05 +01:00
Huang Xin 7f26e45ae7 feat(sync): cloud deletion in transfer queue (#2964) 2026-01-15 13:50:24 +01:00
Huang Xin 7d97826e4b feat(tts): replace words for TTS, closes #2057 (#2952) 2026-01-14 16:42:11 +01:00
Huang Xin 44b4f7995b fix(android): fix annotator on Android, closes #2927 (#2946) 2026-01-14 11:56:38 +01:00
Huang Xin da5e3a0bd3 perf(fonts): cache first for font cache (#2945) 2026-01-14 07:34:00 +01:00
Huang Xin ed77b0bc7f fix(android): only dismiss unpinned sidebar and notebook with back key, closes #2920 (#2939) 2026-01-13 15:42:03 +01:00
Huang Xin 434a44e62c feat(proofread): add an option for whole word replacement, closes #2934 (#2938) 2026-01-13 15:35:57 +01:00
Huang Xin c04f19ffb4 feat: add support for exporting book files in book details dialog, closes #2919 (#2930) 2026-01-12 16:26:32 +01:00
Huang Xin 30385ee5ec fix(settings): correctly setting configs for selected book in parallel read, closes #2825 (#2908) 2026-01-10 15:01:04 +01:00
Huang Xin b868146129 feat(config): add an option to toggle footbar by tapping on the footbar (#2891) 2026-01-09 03:22:34 +01:00
Huang Xin 462ca46fee feat(eink): optimize color and layout for e-ink mode (#2887) 2026-01-08 17:29:33 +01:00
Huang Xin 2ff10f781f feat(annotator): support vertical layout for annotation editor (#2882) 2026-01-07 16:18:57 +01:00
Huang Xin 9614c62360 feat(annotator): instant highlighting with mouse, touch or pen (#2881) 2026-01-07 16:13:37 +01:00
Huang Xin 71af91608f feat(annotator): support editing text range of highlights (#2870) 2026-01-05 16:25:58 +01:00
Huang Xin 9603b61776 refactor(annotatot): more cleaner text selector on Android (#2867) 2026-01-05 08:53:38 +01:00
Huang Xin eed84a059a fix(search): should be able to terminate search when sidebar is invisible (#2863) 2026-01-04 17:10:49 +01:00
Huang Xin 604ef65719 perf(search): use cache for search results (#2861) 2026-01-04 12:56:40 +01:00
Huang Xin 483d536ca4 feat(search): support search terms history, closes #2836 (#2859) 2026-01-04 07:47:43 +01:00
Huang Xin 8a263235ed feat(search): add annotations navigation bar, closes #2060 (#2849) 2026-01-03 14:57:10 +01:00
Huang Xin a5e09e8454 feat(search): add search results navigation bar, closes #1183 (#2842)
Add a floating navigation component that appears when search results exist.
The component includes:
   - Top bar: displays search term and current section with TOC and close buttons
   - Bottom bar: search results, previous, and next navigation buttons
   - Page-based navigation using isCfiInLocation to skip between pages with results
2026-01-03 08:10:23 +01:00
Huang Xin 730ee21651 fix(android): don't navigate back with the back button for more predictable navigation (#2835)
This will revert the link navigation with back button in #2454.
This will close #2833 and more user reports that found back link navigation confusing.
2026-01-02 15:44:47 +01:00
André Angelantoni e21ef53a3d fix(settings): ensure global settings sync across all open panes (#2818)
* fix(settings): ensure global settings sync across all open panes

Previously, changing a global setting (like font size) only updated the currently active book pane, causing split-view panes to desynchronize.

This commit updates the settings logic to propagate global changes to all open book instances immediately. It also ensures that settings UI panels correctly re-render when preferences are updated from outside the component.

* refactor to reuse some code

* fix: pointer in doc check

---------

Co-authored-by: André Angelantoni <andre.angelantoni@performantlabs.com>
Co-authored-by: Huang Xin <chrox.huang@gmail.com>
2026-01-01 07:12:07 +01:00