v1.3.4#284
Conversation
* fix: suppress back release from reader settings screens * fix: avoid stale back suppression after font errors
Co-authored-by: zgredex <112968378+zgredex@users.noreply.github.com>
feat: add timestamps to X3 clipping exports
…t-reader#2321) (crosspoint-reader#2341) Co-authored-by: Uri Tauber <uritaube@gmail.com>
Co-authored-by: Rafael Santos <rmsantos@applaudostudios.com>
Co-authored-by: KymAndriy <test@notamail.ua>
Implements OEM-style settle pass between BW base frame and grayscale planes for X3 displays. The preconditioning can be applied to the full frame or windowed to a specific region in logical coordinates, which are then rotated to physical panel coordinates. This prevents particles from being set too firmly by the base refresh, allowing the weak X3 grayscale waveform to move them properly. No-op on X4 displays.
Introduces a new display method that prepares the framebuffer as a base frame for grayscale overlays. On X3 panels, this uses the OEM differential base waveform (AA-pre-BW) without forcing a resync. Other panels fall back to normal display with configurable refresh mode.
Co-authored-by: Julia <julia@uxj.io>
…-reader#1808) ## Summary - Hold the menu (Confirm) button for ≥1s while reading an EPUB to launch the existing `KOReaderSyncActivity` directly — replaces the three-step path (open reader menu → scroll to Sync → confirm) with a single gesture. - Reuses `ReaderUtils::GO_HOME_MS` (same 1s threshold used by long-press Back) and the existing `KOREADER_STORE.hasCredentials()` guard. - Adds a Controls picker **"Long-press Menu"** (`longPressMenuFunction`, default **Bookmark**) that **cycles through the available functions** bound to the long-press gesture: `KOSync → Disabled → Bookmark`. The field name and `LONG_PRESS_MENU_FUNCTION` enum are intentionally general so future actions (dictionary lookup, table of contents, etc.) can be appended without another schema migration. The setting is **not** a binary toggle. - Existing menu Sync entry still works — both call sites share one extracted helper (`launchKOReaderSync`); no logic duplication. - Short-press Confirm release is gated on duration so the reader menu does not also open after a long press that *acts*, mirroring the existing long-press Back pattern. - **No-credentials fall-through:** `launchKOReaderSync()` now returns whether it acted. When the function is set to KOSync but no KOReader credentials are stored, the long-press is a no-op that **falls through to open the reader menu** — so the menu stays reachable instead of the hold silently swallowing the gesture. The release is only suppressed when sync actually launched or surfaced a save error. ## Test plan - [x] `pio run` succeeds clean for the `default` ESP32-C3 environment. - [x] On-device, value **KOSync**, valid KOReader credentials: long-press Confirm ≥1s → sync screen launches; get + update progress return HTTP 200; release does **not** also open the reader menu; returns to the same page. - [x] On-device, value **KOSync**, **no** credentials: long-press Confirm falls through and **opens the reader menu** (regression fix); short-press also opens the menu. - [x] On-device: menu → Sync still launches the same screen (shared helper) and syncs (200/200). - [x] On-device, value **Bookmark**: long-press drops a bookmark and does **not** also open the menu. - [x] On-device, value **Disabled**: long-press Confirm opens the menu on release; no sync, no bookmark. - [x] On-device: long-press Back still goes to the file browser (unchanged path). - [x] Heap: epub is released before the TLS handshake (frees ~16 KB); min free heap stayed ~84 KB during sync, well above the safe floor. No panics/OOM across the session. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ader#2288) Co-authored-by: Uri Tauber <uritaube@gmail.com>
Co-authored-by: Rafael Santos <rmsantos@applaudostudios.com>
Co-authored-by: Julia <julia@uxj.io>
…ader#2288) Co-authored-by: Uri Tauber <uritaube@gmail.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b9cf3fe046
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: efae262e68
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
* fix: correct Vietnamese i18n string offsets * fix: add missing settings menu translations * fix: inaccurate KOReader sync when syncing at chapter start * fix: automatically attempt to sync clock * fix: stop counting backward page turns in reading stats * fix: only count page turns after 2 seconds * feat: display date for x3 * fix: recover bookmarks from legacy epub hash filenames * chore: bump version * fix: add more explicit KOReader sync error messaging * fix: improve book time-left estimates after quick navigations * fix: remove 'Go to Home' from in-reader menu * fix: make clock and battery top padding consistent * fix: remove duplicate nearby stats sync label * fix: lyra and lyra extended home menu icon alignment * feat: allow selecting a custom sleep folder (#227) * feat: allow selecting a custom sleep folder * feat: reapply tiled grayscale row-band rendering on X3 Re-applies the X3 row-band grayscale work that was temporarily reverted in 06ef4ca, now that open-x4-sdk is on 26648d6 (which includes the #13 row-band plane streaming the path depends on). Restores the strip render pipeline end to end: - GfxRenderer strip target (beginStripTarget/endStripTarget, getWriteTarget/ getWriteOriginY/getWriteRows), real glyphIntersectsStrip, and writeGrayscalePlaneStrip/supportsStripGrayscale - HalDisplay passthrough to EInkDisplay - DirectPixelWriter band-clipping writePixel - EpubReaderActivity tiled grayscale pass, gated on supportsStripGrayscale with a BW-snapshot fallback when unsupported or under memory pressure Also drops the temporary glyphIntersectsStrip stub that kept call sites compiling while the feature was reverted. Builds for the simulator. Needs on-device X3 verification that the current SDK AA path is fast enough and that grayscale image pages render without banding. * feat: skip loading popup for cached EPUB opens * feat: add more reading stats for X3 and add minimal stats sleep screen * fix: correct minimal stats streak wording * feat: add global stats backup * fix: add explicit error when syncing with older version of crossink * feat: update web interface and improve development workflow * feat: add dark reader mode * docs: minor formatting update to readme * fix: localize minimal stats streak label * fix: reposition stats and swap 'new reader' icon * fix: alignment and spacing fixes * fix: adjust reading stats padding again * feat: improve rendering of controls menu * feat: improve rendering of display menu * feat: improve rendering of reader menu * fix: reduce emoji coverage to more popular ones to reduce firmware size * feat: add hebrew support to UI fonts * fix: invert tilt-page-turn confirmation pop up in dark mode * fix: gate minimal stats to x3 devices only * fix: align book time-left with displayed progress * feat: show reader font sizes as point sizes * fix: tighten reading pace sample cutoff * fix: filter out reading pace samples greater than twice the average * fix: german translation for STR_INVERTED (crosspoint-reader#2269) * fix(epub): decode percent-encoded internal asset paths so assets render correctly (crosspoint-reader#2249) * **What is the goal of this PR?** * Fix EPUBs where internal file references are written in URL-style escaped form, like spaces appearing as `%20`, so the reader can find the right files instead of treating those references as missing. * **What changes are included?** * Added a small shared helper that converts those escaped EPUB-internal paths back into their normal filenames before we try to look them up. * Applied that cleanup step across the EPUB parsing flow wherever we resolve internal references, including cover images, manifest items, TOC links, spine entries, and inline HTML images. * Kept the change narrowly focused on EPUB-internal asset resolution rather than changing broader URL or networking behavior. * The user-facing bug here is that some books package their internal filenames in an escaped form, so a file like `Chapter 1.xhtml` may be referenced more like `Chapter%201.xhtml`. The reader was treating that escaped text as the literal filename, which means otherwise-valid books could lose images, covers, or chapter targets because the lookup no longer matched the real file inside the EPUB. * Risk is intentionally low. The helper only rewrites valid `%XX` escape sequences and leaves malformed input alone, so it should improve compatibility with escaped filenames without broadening the parser’s behavior in unrelated cases. * This was tested on my device with the user-provided optimized epub that was not rendering images within the text prior to this fix (cover image and chapter headers were rendering fine): [orv_main_baseline.epub.zip](https://github.com/user-attachments/files/28529545/orv_main_baseline.epub.zip) * This was also tested by the user with a local build and the affected epub and confirmed to be working * Try to open the affected epub (linked above) or any epub that has similar percent-encoding on a build prior to this fix. * Apply this fix, clear book cache, and re-open the affected book. * Images should render properly. --- While CrossPoint doesn't have restrictions on AI tools in contributing, please be transparent about their usage as it helps set the right context for reviewers. Did you use AI tools to help write this code? _**< YES >**_ * fix(epub): decode footnote href path before spine lookup (crosspoint-reader#2271) * docs: changelog cleanups * fix: clarify global reading stats backup label * feat: add dark mode shortcut actions * fix: prefer pace for epub book time-left * docs: readme cleanup * fix: free font catalog before SD font downloads; fixes #236 * fix: honor inverted side-button navigation in reader menus; fixes #235 * feat: improve calculations for reading time left * feat: reorganize reading stats backup settings feat: add all-time stats reset action * feat: add new menu and settings for reading stats including idle time threshold and reset all-time stats * fix: add missing translations for minimal stats sleep screen reader type and reading streak * fix: release SD fonts before wifi activities and release wifi memory on cancelled selection * fix: clean up preserved cache return condition * fix: invert quick resume markers in dark mode * fix: sync quick resume timeout from sleep screen picker * fix: replace crosspoint versions with crossink's * fix: update German translations Co-authored-by: Robert Janus<hallo@robertjanus.de> * fix: translate minimal home button labels * fix: use versioned s3 font downloads * fix: preserve heading alignment after inline images * fix: update spanish translations Co-authored-by: PlatinumPOST <PlatinumPOST@users.noreply.github.com> * fix: update translations for nearby stats sync * docs: update agents.md * fix: add missing translations for 'quick return from footnotes' * fix: show quick return from footnotes setting in web controls * docs: update readme * fix: invert clock settings * fix: stop book settings back button from skipping submenus * feat: long-press menu from home screen to swap between most recently open book (single cover themes) * fix: preview png files from file browser #251 * fix: generate sleep covers on demand #252 * feat: add custom device name; feat: hide OS metadata in file browser * feat: add additional shortcut options #222 * fix: close hal files under storage lock * fix: refresh carousel cache for dynamic home icons * fix: png page overlays causing long re-indexing #255 * feat: add noto sans regular * chore: merge upstream crosspoint * fix: preserve reading stats when clearing cache #253 * fix: clean up KOReader sync failure return #257 * fix: update font download sources * chore: bump version * feat: lower long-press threshold to 200ms * fix: guard file browser loads under low memory * docs: update docs to reference optimizations * fix: move boot order back * fix: use current screen for page overlay sleep background #260 * fix: add confirmation screen before clearing bookmark list * docs: update controls documentation * fix: resolve downloadable sd font sources * fix: prevent grayscale pass for page overlay images * fix: namespace CrossInk settings file * fix(koreader): resolve element XPath progress against visible body text (#261) * fix: handle KOReader element XPath offsets closes crosspoint-reader#2307 * fix(koreader): ignore non-body text when resolving xpath progress * fix: tighten KOReader anchor id parsing * feat: add setting to hide file extension #248 * feat: add file browser display row setting * fix: date overlapping the clock in roundedraff * fix: show remove read books setting in files cache * Update release catalog for v1.3.2 * fix: migrate epub state when moving finished books * ci: sign release catalog commits * fix: lower roundedraff's battery icon #263 * fix: consume release after reader long-press shortcuts #265 * fix: redraw carousel header after restoring cached frames * fix: suppress back release from reader settings screens * fix: suppress back release from reader settings screens * fix: avoid stale back suppression after font errors * feat: index large file browser folders on SD Co-authored-by: zgredex <112968378+zgredex@users.noreply.github.com> * fix(i18n): localize home empty-state strings (crosspoint-reader#2342) * fix: avoid oversized web multi-delete requests (fixes #269) * fix: improve handling of invisible codepoints * feat: add first pass for clipping support * fix: anchor clipping highlights to text after relayout * fix: clean clipping preview text feat: add timestamps to X3 clipping exports * ci: update release workflow for catalog publishing * fix: swap reader menu navigation direction in CCW/inverted (crosspoint-reader#2321) (crosspoint-reader#2341) Co-authored-by: Uri Tauber <uritaube@gmail.com> * fix: add missing HTML 4.01 named entities (crosspoint-reader#2352) Co-authored-by: Rafael Santos <rmsantos@applaudostudios.com> * fix(koreader): resolve element XPath progress against visible body text (crosspoint-reader#2308) * fix: Ukrainian translation (crosspoint-reader#2354) Co-authored-by: KymAndriy <test@notamail.ua> * fix: lower memory guard to what jpeg decoder actually needs * fix: preserve EPUB position across font-size reindex * fix: add epub compatibility mode that falls back to upstream's parsing methods * Add grayscale preconditioning for e-ink displays Implements OEM-style settle pass between BW base frame and grayscale planes for X3 displays. The preconditioning can be applied to the full frame or windowed to a specific region in logical coordinates, which are then rotated to physical panel coordinates. This prevents particles from being set too firmly by the base refresh, allowing the weak X3 grayscale waveform to move them properly. No-op on X4 displays. * Add displayGrayscaleBase method for differential refresh Introduces a new display method that prepares the framebuffer as a base frame for grayscale overlays. On X3 panels, this uses the OEM differential base waveform (AA-pre-BW) without forcing a resync. Other panels fall back to normal display with configurable refresh mode. * update sdk * fix: regenerate fonts to handle strange codepoints * fix: avoid overlapping Calibre transfer status * feat: save EPUB reader settings per book * fix: prewarm SD fonts for clipping selection * feat: new in-reader menu * fix: improve reader menu tab focus state * fix: exit reader menu from focused tab row * fix: align clipping highlights with SD font advances * fix: enable Shift key for URL keyboard input (crosspoint-reader#2178) (crosspoint-reader#2357) * feat: add drag-and-drop to upload modal (crosspoint-reader#2290) Co-authored-by: Julia <julia@uxj.io> * feat: long-press Confirm launches KOReader sync from EPUB (crosspoint-reader#1808) ## Summary - Hold the menu (Confirm) button for ≥1s while reading an EPUB to launch the existing `KOReaderSyncActivity` directly — replaces the three-step path (open reader menu → scroll to Sync → confirm) with a single gesture. - Reuses `ReaderUtils::GO_HOME_MS` (same 1s threshold used by long-press Back) and the existing `KOREADER_STORE.hasCredentials()` guard. - Adds a Controls picker **"Long-press Menu"** (`longPressMenuFunction`, default **Bookmark**) that **cycles through the available functions** bound to the long-press gesture: `KOSync → Disabled → Bookmark`. The field name and `LONG_PRESS_MENU_FUNCTION` enum are intentionally general so future actions (dictionary lookup, table of contents, etc.) can be appended without another schema migration. The setting is **not** a binary toggle. - Existing menu Sync entry still works — both call sites share one extracted helper (`launchKOReaderSync`); no logic duplication. - Short-press Confirm release is gated on duration so the reader menu does not also open after a long press that *acts*, mirroring the existing long-press Back pattern. - **No-credentials fall-through:** `launchKOReaderSync()` now returns whether it acted. When the function is set to KOSync but no KOReader credentials are stored, the long-press is a no-op that **falls through to open the reader menu** — so the menu stays reachable instead of the hold silently swallowing the gesture. The release is only suppressed when sync actually launched or surfaced a save error. ## Test plan - [x] `pio run` succeeds clean for the `default` ESP32-C3 environment. - [x] On-device, value **KOSync**, valid KOReader credentials: long-press Confirm ≥1s → sync screen launches; get + update progress return HTTP 200; release does **not** also open the reader menu; returns to the same page. - [x] On-device, value **KOSync**, **no** credentials: long-press Confirm falls through and **opens the reader menu** (regression fix); short-press also opens the menu. - [x] On-device: menu → Sync still launches the same screen (shared helper) and syncs (200/200). - [x] On-device, value **Bookmark**: long-press drops a bookmark and does **not** also open the menu. - [x] On-device, value **Disabled**: long-press Confirm opens the menu on release; no sync, no bookmark. - [x] On-device: long-press Back still goes to the file browser (unchanged path). - [x] Heap: epub is released before the TLS handshake (frees ~16 KB); min free heap stayed ~84 KB during sync, well above the safe floor. No panics/OOM across the session. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * feat: Support for Korean line breaks and glyph spacing (crosspoint-reader#2288) Co-authored-by: Uri Tauber <uritaube@gmail.com> * fix: protect incompatible reading stats files * chore: update docs for clippings/highlights * fix(i18n): localize home empty-state strings (crosspoint-reader#2342) * fix: add missing HTML 4.01 named entities (crosspoint-reader#2352) Co-authored-by: Rafael Santos <rmsantos@applaudostudios.com> * fix: enable Shift key for URL keyboard input (crosspoint-reader#2178) (crosspoint-reader#2357) * feat: add drag-and-drop to upload modal (crosspoint-reader#2290) Co-authored-by: Julia <julia@uxj.io> * feat: Support for Korean line breaks and glyph spacing (crosspoint-reader#2288) Co-authored-by: Uri Tauber <uritaube@gmail.com> * fix: persist reader time-left estimates for home stats * fix: prepare SD font metrics for clipping selection * fix: add stats.bin migration flow * fix: clippings not highlighting correctly with SD card fonts * fix: remove unlabeled clipping page number * fix: keep txt reader open at file boundary * feat: apply inverted filter to generated sleep screens * fix: move roundedraff clock down on home screen * fix: cppchecks * fix: export clippings with selected page number * v1.3.4 (#284) * fix: suppress back release from reader settings screens * fix: suppress back release from reader settings screens * fix: avoid stale back suppression after font errors * feat: index large file browser folders on SD Co-authored-by: zgredex <112968378+zgredex@users.noreply.github.com> * fix(i18n): localize home empty-state strings (crosspoint-reader#2342) * fix: avoid oversized web multi-delete requests (fixes #269) * fix: improve handling of invisible codepoints * feat: add first pass for clipping support * fix: anchor clipping highlights to text after relayout * fix: clean clipping preview text feat: add timestamps to X3 clipping exports * ci: update release workflow for catalog publishing * fix: swap reader menu navigation direction in CCW/inverted (crosspoint-reader#2321) (crosspoint-reader#2341) Co-authored-by: Uri Tauber <uritaube@gmail.com> * fix: add missing HTML 4.01 named entities (crosspoint-reader#2352) Co-authored-by: Rafael Santos <rmsantos@applaudostudios.com> * fix(koreader): resolve element XPath progress against visible body text (crosspoint-reader#2308) * fix: Ukrainian translation (crosspoint-reader#2354) Co-authored-by: KymAndriy <test@notamail.ua> * fix: lower memory guard to what jpeg decoder actually needs * fix: preserve EPUB position across font-size reindex * fix: add epub compatibility mode that falls back to upstream's parsing methods * Add grayscale preconditioning for e-ink displays Implements OEM-style settle pass between BW base frame and grayscale planes for X3 displays. The preconditioning can be applied to the full frame or windowed to a specific region in logical coordinates, which are then rotated to physical panel coordinates. This prevents particles from being set too firmly by the base refresh, allowing the weak X3 grayscale waveform to move them properly. No-op on X4 displays. * Add displayGrayscaleBase method for differential refresh Introduces a new display method that prepares the framebuffer as a base frame for grayscale overlays. On X3 panels, this uses the OEM differential base waveform (AA-pre-BW) without forcing a resync. Other panels fall back to normal display with configurable refresh mode. * update sdk * fix: regenerate fonts to handle strange codepoints * fix: avoid overlapping Calibre transfer status * feat: save EPUB reader settings per book * fix: prewarm SD fonts for clipping selection * feat: new in-reader menu * fix: improve reader menu tab focus state * fix: exit reader menu from focused tab row * fix: align clipping highlights with SD font advances * fix: enable Shift key for URL keyboard input (crosspoint-reader#2178) (crosspoint-reader#2357) * feat: add drag-and-drop to upload modal (crosspoint-reader#2290) Co-authored-by: Julia <julia@uxj.io> * feat: long-press Confirm launches KOReader sync from EPUB (crosspoint-reader#1808) ## Summary - Hold the menu (Confirm) button for ≥1s while reading an EPUB to launch the existing `KOReaderSyncActivity` directly — replaces the three-step path (open reader menu → scroll to Sync → confirm) with a single gesture. - Reuses `ReaderUtils::GO_HOME_MS` (same 1s threshold used by long-press Back) and the existing `KOREADER_STORE.hasCredentials()` guard. - Adds a Controls picker **"Long-press Menu"** (`longPressMenuFunction`, default **Bookmark**) that **cycles through the available functions** bound to the long-press gesture: `KOSync → Disabled → Bookmark`. The field name and `LONG_PRESS_MENU_FUNCTION` enum are intentionally general so future actions (dictionary lookup, table of contents, etc.) can be appended without another schema migration. The setting is **not** a binary toggle. - Existing menu Sync entry still works — both call sites share one extracted helper (`launchKOReaderSync`); no logic duplication. - Short-press Confirm release is gated on duration so the reader menu does not also open after a long press that *acts*, mirroring the existing long-press Back pattern. - **No-credentials fall-through:** `launchKOReaderSync()` now returns whether it acted. When the function is set to KOSync but no KOReader credentials are stored, the long-press is a no-op that **falls through to open the reader menu** — so the menu stays reachable instead of the hold silently swallowing the gesture. The release is only suppressed when sync actually launched or surfaced a save error. ## Test plan - [x] `pio run` succeeds clean for the `default` ESP32-C3 environment. - [x] On-device, value **KOSync**, valid KOReader credentials: long-press Confirm ≥1s → sync screen launches; get + update progress return HTTP 200; release does **not** also open the reader menu; returns to the same page. - [x] On-device, value **KOSync**, **no** credentials: long-press Confirm falls through and **opens the reader menu** (regression fix); short-press also opens the menu. - [x] On-device: menu → Sync still launches the same screen (shared helper) and syncs (200/200). - [x] On-device, value **Bookmark**: long-press drops a bookmark and does **not** also open the menu. - [x] On-device, value **Disabled**: long-press Confirm opens the menu on release; no sync, no bookmark. - [x] On-device: long-press Back still goes to the file browser (unchanged path). - [x] Heap: epub is released before the TLS handshake (frees ~16 KB); min free heap stayed ~84 KB during sync, well above the safe floor. No panics/OOM across the session. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * feat: Support for Korean line breaks and glyph spacing (crosspoint-reader#2288) Co-authored-by: Uri Tauber <uritaube@gmail.com> * fix: protect incompatible reading stats files * chore: update docs for clippings/highlights * fix(i18n): localize home empty-state strings (crosspoint-reader#2342) * fix: add missing HTML 4.01 named entities (crosspoint-reader#2352) Co-authored-by: Rafael Santos <rmsantos@applaudostudios.com> * fix: enable Shift key for URL keyboard input (crosspoint-reader#2178) (crosspoint-reader#2357) * feat: add drag-and-drop to upload modal (crosspoint-reader#2290) Co-authored-by: Julia <julia@uxj.io> * feat: Support for Korean line breaks and glyph spacing (crosspoint-reader#2288) Co-authored-by: Uri Tauber <uritaube@gmail.com> * fix: persist reader time-left estimates for home stats * fix: prepare SD font metrics for clipping selection * fix: add stats.bin migration flow * fix: clippings not highlighting correctly with SD card fonts * fix: remove unlabeled clipping page number * fix: keep txt reader open at file boundary * feat: apply inverted filter to generated sleep screens * fix: move roundedraff clock down on home screen * fix: cppchecks * fix: export clippings with selected page number --------- Co-authored-by: zgredex <112968378+zgredex@users.noreply.github.com> Co-authored-by: Mauvis Ledford <switchstatement@gmail.com> Co-authored-by: Ronin <6971304+TheCyberRonin@users.noreply.github.com> Co-authored-by: Uri Tauber <uritaube@gmail.com> Co-authored-by: rafaelmsse <rafaelmsse@gmail.com> Co-authored-by: Rafael Santos <rmsantos@applaudostudios.com> Co-authored-by: KymAndriy <32357131+KymAndriy@users.noreply.github.com> Co-authored-by: KymAndriy <test@notamail.ua> Co-authored-by: Justin Mitchell <justin@jmitch.com> Co-authored-by: Ankit <iankit17@gmail.com> Co-authored-by: darkbublu <davidcyprianhicks@gmail.com> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix: guide dots not showing up when bionic reading was on fix: custom settings not loading correctly * feat: add new EPUB rendering mode and fallback method * fix: start clock UTC offset picker on the sign field * fix: back button when viewing clippings goes back to menu as expected * fix: render clipping highlights across pages when layout changes * ci: remove no_emoji builds * fix: add Portuguese hyphenation support * feat: preserve epub publisher spacing * fix: preserve css during epub fallback layout * feat: serve OTA firmware from stable S3 manifest * fix: stream OTA updates and verify sha-256 hash * fix: route no_emoji OTA updates to tiny * fix: reduce epub conversion heap pressure * fix: revert rendering publisher's line-height settings * fix: smooth progressive JPEG cover BMP upscales * fix: refine progressive cover smoothing gate * chore: update version * feat: add CrossInk EPUB location metadata * wire in crossink-locations.json * feat: add stable epub reference pages * chore(release): prepare v1.3.4 * fix: update tilt page turn labels * fix: remove no_emoji references * feat: add create clipping reader shortcuts * fix: set sd file timestamps from x3 rtc * fix(epub): NFC-normalize EPUB text so NFD diacritics render correctly (crosspoint-reader#2277) Co-authored-by: Uri Tauber <uritaube@gmail.com> Co-authored-by: Julia <julia@uxj.io> * feat: add live font preview pane to font selection screen (crosspoint-reader#2349) * Adds a live font preview pane to the font selection screen so users can see how a font looks before committing to it. * Changes * A preview pane occupying the top 30% of the font selection screen, rendering sample pangram text in the previewed font * A two-step confirm flow: first press (enter button) previews the font, second press selects it * Back restores the original font settings, so browsing has no side effects * Layout dimensions cached in `onEnter()` to avoid redundant recalculation between `loop()` and `render()` * Preview sample text is hardcoded English; didn't want to use AI for translation as I would not be able to verify the output in most languages... * The preview pane reduces visible list height; this is compensated by passing the reserved height into `getNumberOfItemsPerPage` --- Did you use AI tools to help write this code? **PARTIALLY** AI use for assisting in coding and in writing the PR description. * feat: add Spacing Modifier Letters range to font presets (crosspoint-reader#2194) * fix: don't justify-stretch a leading no-break space (crosspoint-reader#2185) (crosspoint-reader#2298) * fix: update generated location filename * fix: epub crashes while indexing with bionic reading on * fix: use epub render fallbacks for silent indexing and avoid null final page serialization * fix: constrain EPUB clipping highlights * fix: handle sync long-press select release * fix: add guidance for bionic/guide dots during memory pressure * fix: preserve authored hyphens in clipping text * fix: align reader menu icons with orientation * fix: reduce epub layout buffering for reading aids * fix: avoid home cover refresh oom crash * update sdk * fix: preserve clipping highlights after relayout * fix: in-reader menu icons * fix: keep clipping highlights complete after font relayout * fix: reduce epub reading aid layout tokens * feat: add chained slab arena allocator * perf: wire parse arena into EPUB chapter style stacks Replace std::vector inlineStyleStack and blockStyleStack in ChapterHtmlSlimParser with arena-backed fixed-size arrays allocated from parseArena_ at the start of each chapter parse. The arena is initialized once, used for the full parse, then released in one shot instead of per-object frees. * fix: use arena inline style stack for table labels * fix: use arena scratch buffers for epub layout * chore: update changelog * fix: add epub safe mode fallback * fix: bound epub footnote preview indexing * fix(epub): flush displaced anchor before overwrite (crosspoint-reader#2336) (crosspoint-reader#2382) * **What is the goal of this PR?** (e.g., Implements the new feature for file uploading.) Fixes footnote links landing in start section instead of the specific foot note target. * **What changes are included?** ChapterHtmlSlimParser.cpp: call flushPendingAnchor() before overwriting pendingAnchorId. First id got lost due to consecutive non-block elements carry ids, the first id was lost and the reader had no page to jump to, so it defaulted to page 0. Tested with the epubs attached to to crosspoint-reader#2336. Need to clear .crosspoint/ cache after flashing so the anchor map gets rebuilt with the fix. * Add any other information that might be helpful for the reviewer (e.g., performance implications, potential risks, specific areas to focus on). --- While CrossPoint doesn't have restrictions on AI tools in contributing, please be transparent about their usage as it helps set the right context for reviewers. Did you use AI tools to help write this code? Partially assisted with writing documentation. * feat: footnote returns to original position on deep sleep to avoid losing reading position (crosspoint-reader#2394) * chore(release): prepare v1.3.4 * fix: report EPUB clipping save failures * fix: allow long EPUB section LUT growth and preserve section LUT low-memory fallback signal --------- Co-authored-by: Uri Tauber <uritaube@gmail.com> Co-authored-by: PlatinumPOST <PlatinumPOST@users.noreply.github.com> Co-authored-by: zgredex <112968378+zgredex@users.noreply.github.com> Co-authored-by: Mauvis Ledford <switchstatement@gmail.com> Co-authored-by: Ronin <6971304+TheCyberRonin@users.noreply.github.com> Co-authored-by: rafaelmsse <rafaelmsse@gmail.com> Co-authored-by: Rafael Santos <rmsantos@applaudostudios.com> Co-authored-by: KymAndriy <32357131+KymAndriy@users.noreply.github.com> Co-authored-by: KymAndriy <test@notamail.ua> Co-authored-by: Justin Mitchell <justin@jmitch.com> Co-authored-by: Ankit <iankit17@gmail.com> Co-authored-by: darkbublu <davidcyprianhicks@gmail.com> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Co-authored-by: gershalfred <gersh.alfred@gmail.com> Co-authored-by: Hoang Manh Linh <jetaudio.media@gmail.com> Co-authored-by: Paul Delestrac <40175004+PaulDelestrac@users.noreply.github.com> Co-authored-by: SurprisedDuck <jannik.theiss@googlemail.com> Co-authored-by: kygia <hi@kygiaha.com> Co-authored-by: Zeph <cloudedsprite@gmail.com>
* fix: correct Vietnamese i18n string offsets * fix: add missing settings menu translations * fix: inaccurate KOReader sync when syncing at chapter start * fix: automatically attempt to sync clock * fix: stop counting backward page turns in reading stats * fix: only count page turns after 2 seconds * feat: display date for x3 * fix: recover bookmarks from legacy epub hash filenames * chore: bump version * fix: add more explicit KOReader sync error messaging * fix: improve book time-left estimates after quick navigations * fix: remove 'Go to Home' from in-reader menu * fix: make clock and battery top padding consistent * fix: remove duplicate nearby stats sync label * fix: lyra and lyra extended home menu icon alignment * feat: allow selecting a custom sleep folder (#227) * feat: allow selecting a custom sleep folder * feat: reapply tiled grayscale row-band rendering on X3 Re-applies the X3 row-band grayscale work that was temporarily reverted in 06ef4ca, now that open-x4-sdk is on 26648d6 (which includes the #13 row-band plane streaming the path depends on). Restores the strip render pipeline end to end: - GfxRenderer strip target (beginStripTarget/endStripTarget, getWriteTarget/ getWriteOriginY/getWriteRows), real glyphIntersectsStrip, and writeGrayscalePlaneStrip/supportsStripGrayscale - HalDisplay passthrough to EInkDisplay - DirectPixelWriter band-clipping writePixel - EpubReaderActivity tiled grayscale pass, gated on supportsStripGrayscale with a BW-snapshot fallback when unsupported or under memory pressure Also drops the temporary glyphIntersectsStrip stub that kept call sites compiling while the feature was reverted. Builds for the simulator. Needs on-device X3 verification that the current SDK AA path is fast enough and that grayscale image pages render without banding. * feat: skip loading popup for cached EPUB opens * feat: add more reading stats for X3 and add minimal stats sleep screen * fix: correct minimal stats streak wording * feat: add global stats backup * fix: add explicit error when syncing with older version of crossink * feat: update web interface and improve development workflow * feat: add dark reader mode * docs: minor formatting update to readme * fix: localize minimal stats streak label * fix: reposition stats and swap 'new reader' icon * fix: alignment and spacing fixes * fix: adjust reading stats padding again * feat: improve rendering of controls menu * feat: improve rendering of display menu * feat: improve rendering of reader menu * fix: reduce emoji coverage to more popular ones to reduce firmware size * feat: add hebrew support to UI fonts * fix: invert tilt-page-turn confirmation pop up in dark mode * fix: gate minimal stats to x3 devices only * fix: align book time-left with displayed progress * feat: show reader font sizes as point sizes * fix: tighten reading pace sample cutoff * fix: filter out reading pace samples greater than twice the average * fix: german translation for STR_INVERTED (crosspoint-reader#2269) * fix(epub): decode percent-encoded internal asset paths so assets render correctly (crosspoint-reader#2249) * **What is the goal of this PR?** * Fix EPUBs where internal file references are written in URL-style escaped form, like spaces appearing as `%20`, so the reader can find the right files instead of treating those references as missing. * **What changes are included?** * Added a small shared helper that converts those escaped EPUB-internal paths back into their normal filenames before we try to look them up. * Applied that cleanup step across the EPUB parsing flow wherever we resolve internal references, including cover images, manifest items, TOC links, spine entries, and inline HTML images. * Kept the change narrowly focused on EPUB-internal asset resolution rather than changing broader URL or networking behavior. * The user-facing bug here is that some books package their internal filenames in an escaped form, so a file like `Chapter 1.xhtml` may be referenced more like `Chapter%201.xhtml`. The reader was treating that escaped text as the literal filename, which means otherwise-valid books could lose images, covers, or chapter targets because the lookup no longer matched the real file inside the EPUB. * Risk is intentionally low. The helper only rewrites valid `%XX` escape sequences and leaves malformed input alone, so it should improve compatibility with escaped filenames without broadening the parser’s behavior in unrelated cases. * This was tested on my device with the user-provided optimized epub that was not rendering images within the text prior to this fix (cover image and chapter headers were rendering fine): [orv_main_baseline.epub.zip](https://github.com/user-attachments/files/28529545/orv_main_baseline.epub.zip) * This was also tested by the user with a local build and the affected epub and confirmed to be working * Try to open the affected epub (linked above) or any epub that has similar percent-encoding on a build prior to this fix. * Apply this fix, clear book cache, and re-open the affected book. * Images should render properly. --- While CrossPoint doesn't have restrictions on AI tools in contributing, please be transparent about their usage as it helps set the right context for reviewers. Did you use AI tools to help write this code? _**< YES >**_ * fix(epub): decode footnote href path before spine lookup (crosspoint-reader#2271) * docs: changelog cleanups * fix: clarify global reading stats backup label * feat: add dark mode shortcut actions * fix: prefer pace for epub book time-left * docs: readme cleanup * fix: free font catalog before SD font downloads; fixes #236 * fix: honor inverted side-button navigation in reader menus; fixes #235 * feat: improve calculations for reading time left * feat: reorganize reading stats backup settings feat: add all-time stats reset action * feat: add new menu and settings for reading stats including idle time threshold and reset all-time stats * fix: add missing translations for minimal stats sleep screen reader type and reading streak * fix: release SD fonts before wifi activities and release wifi memory on cancelled selection * fix: clean up preserved cache return condition * fix: invert quick resume markers in dark mode * fix: sync quick resume timeout from sleep screen picker * fix: replace crosspoint versions with crossink's * fix: update German translations Co-authored-by: Robert Janus<hallo@robertjanus.de> * fix: translate minimal home button labels * fix: use versioned s3 font downloads * fix: preserve heading alignment after inline images * fix: update spanish translations Co-authored-by: PlatinumPOST <PlatinumPOST@users.noreply.github.com> * fix: update translations for nearby stats sync * docs: update agents.md * fix: add missing translations for 'quick return from footnotes' * fix: show quick return from footnotes setting in web controls * docs: update readme * fix: invert clock settings * fix: stop book settings back button from skipping submenus * feat: long-press menu from home screen to swap between most recently open book (single cover themes) * fix: preview png files from file browser #251 * fix: generate sleep covers on demand #252 * feat: add custom device name; feat: hide OS metadata in file browser * feat: add additional shortcut options #222 * fix: close hal files under storage lock * fix: refresh carousel cache for dynamic home icons * fix: png page overlays causing long re-indexing #255 * feat: add noto sans regular * chore: merge upstream crosspoint * fix: preserve reading stats when clearing cache #253 * fix: clean up KOReader sync failure return #257 * fix: update font download sources * chore: bump version * feat: lower long-press threshold to 200ms * fix: guard file browser loads under low memory * docs: update docs to reference optimizations * fix: move boot order back * fix: use current screen for page overlay sleep background #260 * fix: add confirmation screen before clearing bookmark list * docs: update controls documentation * fix: resolve downloadable sd font sources * fix: prevent grayscale pass for page overlay images * fix: namespace CrossInk settings file * fix(koreader): resolve element XPath progress against visible body text (#261) * fix: handle KOReader element XPath offsets closes crosspoint-reader#2307 * fix(koreader): ignore non-body text when resolving xpath progress * fix: tighten KOReader anchor id parsing * feat: add setting to hide file extension #248 * feat: add file browser display row setting * fix: date overlapping the clock in roundedraff * fix: show remove read books setting in files cache * Update release catalog for v1.3.2 * fix: migrate epub state when moving finished books * ci: sign release catalog commits * fix: lower roundedraff's battery icon #263 * fix: consume release after reader long-press shortcuts #265 * fix: redraw carousel header after restoring cached frames * fix: suppress back release from reader settings screens * fix: suppress back release from reader settings screens * fix: avoid stale back suppression after font errors * feat: index large file browser folders on SD Co-authored-by: zgredex <112968378+zgredex@users.noreply.github.com> * fix(i18n): localize home empty-state strings (crosspoint-reader#2342) * fix: avoid oversized web multi-delete requests (fixes #269) * fix: improve handling of invisible codepoints * feat: add first pass for clipping support * fix: anchor clipping highlights to text after relayout * fix: clean clipping preview text feat: add timestamps to X3 clipping exports * ci: update release workflow for catalog publishing * fix: swap reader menu navigation direction in CCW/inverted (crosspoint-reader#2321) (crosspoint-reader#2341) Co-authored-by: Uri Tauber <uritaube@gmail.com> * fix: add missing HTML 4.01 named entities (crosspoint-reader#2352) Co-authored-by: Rafael Santos <rmsantos@applaudostudios.com> * fix(koreader): resolve element XPath progress against visible body text (crosspoint-reader#2308) * fix: Ukrainian translation (crosspoint-reader#2354) Co-authored-by: KymAndriy <test@notamail.ua> * fix: lower memory guard to what jpeg decoder actually needs * fix: preserve EPUB position across font-size reindex * fix: add epub compatibility mode that falls back to upstream's parsing methods * Add grayscale preconditioning for e-ink displays Implements OEM-style settle pass between BW base frame and grayscale planes for X3 displays. The preconditioning can be applied to the full frame or windowed to a specific region in logical coordinates, which are then rotated to physical panel coordinates. This prevents particles from being set too firmly by the base refresh, allowing the weak X3 grayscale waveform to move them properly. No-op on X4 displays. * Add displayGrayscaleBase method for differential refresh Introduces a new display method that prepares the framebuffer as a base frame for grayscale overlays. On X3 panels, this uses the OEM differential base waveform (AA-pre-BW) without forcing a resync. Other panels fall back to normal display with configurable refresh mode. * update sdk * fix: regenerate fonts to handle strange codepoints * fix: avoid overlapping Calibre transfer status * feat: save EPUB reader settings per book * fix: prewarm SD fonts for clipping selection * feat: new in-reader menu * fix: improve reader menu tab focus state * fix: exit reader menu from focused tab row * fix: align clipping highlights with SD font advances * fix: enable Shift key for URL keyboard input (crosspoint-reader#2178) (crosspoint-reader#2357) * feat: add drag-and-drop to upload modal (crosspoint-reader#2290) Co-authored-by: Julia <julia@uxj.io> * feat: long-press Confirm launches KOReader sync from EPUB (crosspoint-reader#1808) ## Summary - Hold the menu (Confirm) button for ≥1s while reading an EPUB to launch the existing `KOReaderSyncActivity` directly — replaces the three-step path (open reader menu → scroll to Sync → confirm) with a single gesture. - Reuses `ReaderUtils::GO_HOME_MS` (same 1s threshold used by long-press Back) and the existing `KOREADER_STORE.hasCredentials()` guard. - Adds a Controls picker **"Long-press Menu"** (`longPressMenuFunction`, default **Bookmark**) that **cycles through the available functions** bound to the long-press gesture: `KOSync → Disabled → Bookmark`. The field name and `LONG_PRESS_MENU_FUNCTION` enum are intentionally general so future actions (dictionary lookup, table of contents, etc.) can be appended without another schema migration. The setting is **not** a binary toggle. - Existing menu Sync entry still works — both call sites share one extracted helper (`launchKOReaderSync`); no logic duplication. - Short-press Confirm release is gated on duration so the reader menu does not also open after a long press that *acts*, mirroring the existing long-press Back pattern. - **No-credentials fall-through:** `launchKOReaderSync()` now returns whether it acted. When the function is set to KOSync but no KOReader credentials are stored, the long-press is a no-op that **falls through to open the reader menu** — so the menu stays reachable instead of the hold silently swallowing the gesture. The release is only suppressed when sync actually launched or surfaced a save error. ## Test plan - [x] `pio run` succeeds clean for the `default` ESP32-C3 environment. - [x] On-device, value **KOSync**, valid KOReader credentials: long-press Confirm ≥1s → sync screen launches; get + update progress return HTTP 200; release does **not** also open the reader menu; returns to the same page. - [x] On-device, value **KOSync**, **no** credentials: long-press Confirm falls through and **opens the reader menu** (regression fix); short-press also opens the menu. - [x] On-device: menu → Sync still launches the same screen (shared helper) and syncs (200/200). - [x] On-device, value **Bookmark**: long-press drops a bookmark and does **not** also open the menu. - [x] On-device, value **Disabled**: long-press Confirm opens the menu on release; no sync, no bookmark. - [x] On-device: long-press Back still goes to the file browser (unchanged path). - [x] Heap: epub is released before the TLS handshake (frees ~16 KB); min free heap stayed ~84 KB during sync, well above the safe floor. No panics/OOM across the session. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * feat: Support for Korean line breaks and glyph spacing (crosspoint-reader#2288) Co-authored-by: Uri Tauber <uritaube@gmail.com> * fix: protect incompatible reading stats files * chore: update docs for clippings/highlights * fix(i18n): localize home empty-state strings (crosspoint-reader#2342) * fix: add missing HTML 4.01 named entities (crosspoint-reader#2352) Co-authored-by: Rafael Santos <rmsantos@applaudostudios.com> * fix: enable Shift key for URL keyboard input (crosspoint-reader#2178) (crosspoint-reader#2357) * feat: add drag-and-drop to upload modal (crosspoint-reader#2290) Co-authored-by: Julia <julia@uxj.io> * feat: Support for Korean line breaks and glyph spacing (crosspoint-reader#2288) Co-authored-by: Uri Tauber <uritaube@gmail.com> * fix: persist reader time-left estimates for home stats * fix: prepare SD font metrics for clipping selection * fix: add stats.bin migration flow * fix: clippings not highlighting correctly with SD card fonts * fix: remove unlabeled clipping page number * fix: keep txt reader open at file boundary * feat: apply inverted filter to generated sleep screens * fix: move roundedraff clock down on home screen * fix: cppchecks * fix: export clippings with selected page number * v1.3.4 (#284) * fix: suppress back release from reader settings screens * fix: suppress back release from reader settings screens * fix: avoid stale back suppression after font errors * feat: index large file browser folders on SD Co-authored-by: zgredex <112968378+zgredex@users.noreply.github.com> * fix(i18n): localize home empty-state strings (crosspoint-reader#2342) * fix: avoid oversized web multi-delete requests (fixes #269) * fix: improve handling of invisible codepoints * feat: add first pass for clipping support * fix: anchor clipping highlights to text after relayout * fix: clean clipping preview text feat: add timestamps to X3 clipping exports * ci: update release workflow for catalog publishing * fix: swap reader menu navigation direction in CCW/inverted (crosspoint-reader#2321) (crosspoint-reader#2341) Co-authored-by: Uri Tauber <uritaube@gmail.com> * fix: add missing HTML 4.01 named entities (crosspoint-reader#2352) Co-authored-by: Rafael Santos <rmsantos@applaudostudios.com> * fix(koreader): resolve element XPath progress against visible body text (crosspoint-reader#2308) * fix: Ukrainian translation (crosspoint-reader#2354) Co-authored-by: KymAndriy <test@notamail.ua> * fix: lower memory guard to what jpeg decoder actually needs * fix: preserve EPUB position across font-size reindex * fix: add epub compatibility mode that falls back to upstream's parsing methods * Add grayscale preconditioning for e-ink displays Implements OEM-style settle pass between BW base frame and grayscale planes for X3 displays. The preconditioning can be applied to the full frame or windowed to a specific region in logical coordinates, which are then rotated to physical panel coordinates. This prevents particles from being set too firmly by the base refresh, allowing the weak X3 grayscale waveform to move them properly. No-op on X4 displays. * Add displayGrayscaleBase method for differential refresh Introduces a new display method that prepares the framebuffer as a base frame for grayscale overlays. On X3 panels, this uses the OEM differential base waveform (AA-pre-BW) without forcing a resync. Other panels fall back to normal display with configurable refresh mode. * update sdk * fix: regenerate fonts to handle strange codepoints * fix: avoid overlapping Calibre transfer status * feat: save EPUB reader settings per book * fix: prewarm SD fonts for clipping selection * feat: new in-reader menu * fix: improve reader menu tab focus state * fix: exit reader menu from focused tab row * fix: align clipping highlights with SD font advances * fix: enable Shift key for URL keyboard input (crosspoint-reader#2178) (crosspoint-reader#2357) * feat: add drag-and-drop to upload modal (crosspoint-reader#2290) Co-authored-by: Julia <julia@uxj.io> * feat: long-press Confirm launches KOReader sync from EPUB (crosspoint-reader#1808) ## Summary - Hold the menu (Confirm) button for ≥1s while reading an EPUB to launch the existing `KOReaderSyncActivity` directly — replaces the three-step path (open reader menu → scroll to Sync → confirm) with a single gesture. - Reuses `ReaderUtils::GO_HOME_MS` (same 1s threshold used by long-press Back) and the existing `KOREADER_STORE.hasCredentials()` guard. - Adds a Controls picker **"Long-press Menu"** (`longPressMenuFunction`, default **Bookmark**) that **cycles through the available functions** bound to the long-press gesture: `KOSync → Disabled → Bookmark`. The field name and `LONG_PRESS_MENU_FUNCTION` enum are intentionally general so future actions (dictionary lookup, table of contents, etc.) can be appended without another schema migration. The setting is **not** a binary toggle. - Existing menu Sync entry still works — both call sites share one extracted helper (`launchKOReaderSync`); no logic duplication. - Short-press Confirm release is gated on duration so the reader menu does not also open after a long press that *acts*, mirroring the existing long-press Back pattern. - **No-credentials fall-through:** `launchKOReaderSync()` now returns whether it acted. When the function is set to KOSync but no KOReader credentials are stored, the long-press is a no-op that **falls through to open the reader menu** — so the menu stays reachable instead of the hold silently swallowing the gesture. The release is only suppressed when sync actually launched or surfaced a save error. ## Test plan - [x] `pio run` succeeds clean for the `default` ESP32-C3 environment. - [x] On-device, value **KOSync**, valid KOReader credentials: long-press Confirm ≥1s → sync screen launches; get + update progress return HTTP 200; release does **not** also open the reader menu; returns to the same page. - [x] On-device, value **KOSync**, **no** credentials: long-press Confirm falls through and **opens the reader menu** (regression fix); short-press also opens the menu. - [x] On-device: menu → Sync still launches the same screen (shared helper) and syncs (200/200). - [x] On-device, value **Bookmark**: long-press drops a bookmark and does **not** also open the menu. - [x] On-device, value **Disabled**: long-press Confirm opens the menu on release; no sync, no bookmark. - [x] On-device: long-press Back still goes to the file browser (unchanged path). - [x] Heap: epub is released before the TLS handshake (frees ~16 KB); min free heap stayed ~84 KB during sync, well above the safe floor. No panics/OOM across the session. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * feat: Support for Korean line breaks and glyph spacing (crosspoint-reader#2288) Co-authored-by: Uri Tauber <uritaube@gmail.com> * fix: protect incompatible reading stats files * chore: update docs for clippings/highlights * fix(i18n): localize home empty-state strings (crosspoint-reader#2342) * fix: add missing HTML 4.01 named entities (crosspoint-reader#2352) Co-authored-by: Rafael Santos <rmsantos@applaudostudios.com> * fix: enable Shift key for URL keyboard input (crosspoint-reader#2178) (crosspoint-reader#2357) * feat: add drag-and-drop to upload modal (crosspoint-reader#2290) Co-authored-by: Julia <julia@uxj.io> * feat: Support for Korean line breaks and glyph spacing (crosspoint-reader#2288) Co-authored-by: Uri Tauber <uritaube@gmail.com> * fix: persist reader time-left estimates for home stats * fix: prepare SD font metrics for clipping selection * fix: add stats.bin migration flow * fix: clippings not highlighting correctly with SD card fonts * fix: remove unlabeled clipping page number * fix: keep txt reader open at file boundary * feat: apply inverted filter to generated sleep screens * fix: move roundedraff clock down on home screen * fix: cppchecks * fix: export clippings with selected page number --------- Co-authored-by: zgredex <112968378+zgredex@users.noreply.github.com> Co-authored-by: Mauvis Ledford <switchstatement@gmail.com> Co-authored-by: Ronin <6971304+TheCyberRonin@users.noreply.github.com> Co-authored-by: Uri Tauber <uritaube@gmail.com> Co-authored-by: rafaelmsse <rafaelmsse@gmail.com> Co-authored-by: Rafael Santos <rmsantos@applaudostudios.com> Co-authored-by: KymAndriy <32357131+KymAndriy@users.noreply.github.com> Co-authored-by: KymAndriy <test@notamail.ua> Co-authored-by: Justin Mitchell <justin@jmitch.com> Co-authored-by: Ankit <iankit17@gmail.com> Co-authored-by: darkbublu <davidcyprianhicks@gmail.com> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix: guide dots not showing up when bionic reading was on fix: custom settings not loading correctly * feat: add new EPUB rendering mode and fallback method * fix: start clock UTC offset picker on the sign field * fix: back button when viewing clippings goes back to menu as expected * fix: render clipping highlights across pages when layout changes * ci: remove no_emoji builds * fix: add Portuguese hyphenation support * feat: preserve epub publisher spacing * fix: preserve css during epub fallback layout * feat: serve OTA firmware from stable S3 manifest * fix: stream OTA updates and verify sha-256 hash * fix: route no_emoji OTA updates to tiny * fix: reduce epub conversion heap pressure * fix: revert rendering publisher's line-height settings * fix: smooth progressive JPEG cover BMP upscales * fix: refine progressive cover smoothing gate * chore: update version * feat: add CrossInk EPUB location metadata * wire in crossink-locations.json * feat: add stable epub reference pages * chore(release): prepare v1.3.4 * fix: update tilt page turn labels * fix: remove no_emoji references * feat: add create clipping reader shortcuts * fix: set sd file timestamps from x3 rtc * fix(epub): NFC-normalize EPUB text so NFD diacritics render correctly (crosspoint-reader#2277) Co-authored-by: Uri Tauber <uritaube@gmail.com> Co-authored-by: Julia <julia@uxj.io> * feat: add live font preview pane to font selection screen (crosspoint-reader#2349) * Adds a live font preview pane to the font selection screen so users can see how a font looks before committing to it. * Changes * A preview pane occupying the top 30% of the font selection screen, rendering sample pangram text in the previewed font * A two-step confirm flow: first press (enter button) previews the font, second press selects it * Back restores the original font settings, so browsing has no side effects * Layout dimensions cached in `onEnter()` to avoid redundant recalculation between `loop()` and `render()` * Preview sample text is hardcoded English; didn't want to use AI for translation as I would not be able to verify the output in most languages... * The preview pane reduces visible list height; this is compensated by passing the reserved height into `getNumberOfItemsPerPage` --- Did you use AI tools to help write this code? **PARTIALLY** AI use for assisting in coding and in writing the PR description. * feat: add Spacing Modifier Letters range to font presets (crosspoint-reader#2194) * fix: don't justify-stretch a leading no-break space (crosspoint-reader#2185) (crosspoint-reader#2298) * fix: update generated location filename * fix: epub crashes while indexing with bionic reading on * fix: use epub render fallbacks for silent indexing and avoid null final page serialization * fix: constrain EPUB clipping highlights * fix: handle sync long-press select release * fix: add guidance for bionic/guide dots during memory pressure * fix: preserve authored hyphens in clipping text * fix: align reader menu icons with orientation * fix: reduce epub layout buffering for reading aids * fix: avoid home cover refresh oom crash * update sdk * fix: preserve clipping highlights after relayout * fix: in-reader menu icons * fix: keep clipping highlights complete after font relayout * fix: reduce epub reading aid layout tokens * feat: add chained slab arena allocator * perf: wire parse arena into EPUB chapter style stacks Replace std::vector inlineStyleStack and blockStyleStack in ChapterHtmlSlimParser with arena-backed fixed-size arrays allocated from parseArena_ at the start of each chapter parse. The arena is initialized once, used for the full parse, then released in one shot instead of per-object frees. * fix: use arena inline style stack for table labels * fix: use arena scratch buffers for epub layout * chore: update changelog * fix: add epub safe mode fallback * fix: bound epub footnote preview indexing * fix(epub): flush displaced anchor before overwrite (crosspoint-reader#2336) (crosspoint-reader#2382) * **What is the goal of this PR?** (e.g., Implements the new feature for file uploading.) Fixes footnote links landing in start section instead of the specific foot note target. * **What changes are included?** ChapterHtmlSlimParser.cpp: call flushPendingAnchor() before overwriting pendingAnchorId. First id got lost due to consecutive non-block elements carry ids, the first id was lost and the reader had no page to jump to, so it defaulted to page 0. Tested with the epubs attached to to crosspoint-reader#2336. Need to clear .crosspoint/ cache after flashing so the anchor map gets rebuilt with the fix. * Add any other information that might be helpful for the reviewer (e.g., performance implications, potential risks, specific areas to focus on). --- While CrossPoint doesn't have restrictions on AI tools in contributing, please be transparent about their usage as it helps set the right context for reviewers. Did you use AI tools to help write this code? Partially assisted with writing documentation. * feat: footnote returns to original position on deep sleep to avoid losing reading position (crosspoint-reader#2394) * chore(release): prepare v1.3.4 * fix: report EPUB clipping save failures * fix: allow long EPUB section LUT growth and preserve section LUT low-memory fallback signal --------- Co-authored-by: Uri Tauber <uritaube@gmail.com> Co-authored-by: PlatinumPOST <PlatinumPOST@users.noreply.github.com> Co-authored-by: zgredex <112968378+zgredex@users.noreply.github.com> Co-authored-by: Mauvis Ledford <switchstatement@gmail.com> Co-authored-by: Ronin <6971304+TheCyberRonin@users.noreply.github.com> Co-authored-by: rafaelmsse <rafaelmsse@gmail.com> Co-authored-by: Rafael Santos <rmsantos@applaudostudios.com> Co-authored-by: KymAndriy <32357131+KymAndriy@users.noreply.github.com> Co-authored-by: KymAndriy <test@notamail.ua> Co-authored-by: Justin Mitchell <justin@jmitch.com> Co-authored-by: Ankit <iankit17@gmail.com> Co-authored-by: darkbublu <davidcyprianhicks@gmail.com> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Co-authored-by: gershalfred <gersh.alfred@gmail.com> Co-authored-by: Hoang Manh Linh <jetaudio.media@gmail.com> Co-authored-by: Paul Delestrac <40175004+PaulDelestrac@users.noreply.github.com> Co-authored-by: SurprisedDuck <jannik.theiss@googlemail.com> Co-authored-by: kygia <hi@kygiaha.com> Co-authored-by: Zeph <cloudedsprite@gmail.com>
New
/My Clippings.txtfile. Create them from the in-reader menu. When clippings are present, they will show up alongside bookmarks. Note:My Clippings.txtworks just like it does on a Kindle today, which is that it only adds new clippings to the end of the file, it does not delete them. For more info go here.System > Readerstill apply to all books automatically until custom settings are applied.Minimalsleep screen andReading Statssleep screen, the default is white text on a black background, but you can now invert their colors by choosingInvertedin the Sleep ScreenColor Filtersetting.Fixed
./crossspoint/fileIndex. The recommendation is still to keep the number of files in each folder under 200 and ideally, closer to 100. (fixes Folder with 830 books gives Memory Error when selecting #268)Changed
Book Options(instead ofReader Optionsand avoids showing duplicateOrientationcontrols.