Commit Graph

6 Commits

Author SHA1 Message Date
Huang Xin c27245e980 feat(reader): support deeplink and web link in annotation export (#4067)
Expose `annotation.appLink` (readest://) and `annotation.webLink`
(https://web.readest.com) as template variables for custom export
templates. The shipped default template now emits the readest:// app
deeplink for the page link so exported notes open the native app.
The non-template export mode keeps the universal https link.

Preview links also gain target="_blank" so they open in a new tab
instead of replacing the dialog.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 19:39:26 +02:00
Huang Xin 486659a1ca feat(annotations): deep links for highlight exports (#4018)
* feat(annotations): deep links for highlight exports

Embed an HTTPS deep link in markdown export so clicking a highlight in
Obsidian / Notion / Mail launches Readest at the exact CFI position.
Mobile App Links / Universal Links open the native app silently when
installed; desktop attempts the readest:// scheme automatically with a
manual fallback.

- Markdown export wraps the page-number text in a per-annotation link:
  https://web.readest.com/o/book/{hash}/annotation/{id}?cfi=...
- New /o/... smart landing page handles platform routing (intent:// on
  Android Chrome, scheme + visibility-cancel on other Android, auto
  scheme + 1 s fallback on desktop, manual button on iOS).
- Reader honors a ?cfi= query param on initial load (overrides the
  saved last-position for the primary book only).
- New useOpenAnnotationLink hook handles incoming readest:// and
  https://web.readest.com/o/... URLs, including cold-start (getCurrent)
  and library-load deferral; supports the legacy flat shape
  readest://annotation/{hash}/{id} from previous Readwise syncs.
- ReadwiseClient now emits the HTTPS deep link instead of the legacy
  custom scheme.
- AASA extended with /o/* matcher; Android intent-filter for the host
  has no pathPrefix so it already covers it.

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

* i18n: translate annotation deep-link strings across all locales

Translates the 13 new keys introduced for the annotation deep-link
feature into all 31 supported locales. Replaces all 403
__STRING_NOT_TRANSLATED__ placeholders.

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

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 07:26:47 +02:00
Huang Xin f7b2a2432c fix(export): apply block quote syntax to every line in annotation export, closes #3534 (#3536)
Add formatBlockQuote utility and blockquote nunjucks filter so both
default and custom template exports prefix every line with `>`.
Document all available formatters in the custom template help panel.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-14 15:23:17 +01:00
Huang Xin 8850e6c00f feat(pdf): support TTS and annotation on PDFs, closes #2149 & #3462 (#3493)
* chore: bump jsdom to the latest version

* feat(pdf): support TTS and annotation on PDFs, closes #2149 & closes #3462
2026-03-09 10:28:19 +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 42fee90a27 feat(annotation): export annotations with style and color fields in annotation template, closes #1734 (#3060) 2026-01-24 17:44:40 +01:00