Port PR #979's silent pre-indexing and add an Indexing Display setting
(Popup / Status Bar Text / Status Bar Icon) so users can choose how
indexing feedback is shown.
Silent pre-indexing runs on text-only penultimate pages when a status
bar option is selected, with a standard requestUpdate to clear the
indicator. Image pages skip silent indexing to avoid e-ink grayscale
pipeline conflicts; the normal popup handles those transitions. Direct
chapter jumps always show the original small popup regardless of setting.
Co-authored-by: Cursor <cursoragent@cursor.com>
Port 6 upstream PRs (PR #939 was already ported):
- #852: Complete HalPowerManager with RAII Lock class, WiFi check in
setPowerSaving, skipLoopDelay overrides for ClearCache/OtaUpdate,
and power lock in Activity render task loops
- #965: Fix paragraph formatting inside list items by tracking
listItemUntilDepth to prevent unwanted line breaks
- #972: Micro-optimizations: std::move in insertFont, const ref for
getDataFromBook parameter
- #971: Remove redundant hasPrintableChars pre-rendering pass from
EpdFont, EpdFontFamily, and GfxRenderer
- #977: Skip unsupported image formats before extraction, add
PARSE_BUFFER_SIZE constant and chapter parse timing
- #975: Fix UITheme memory leak by replacing raw pointer with
std::unique_ptr for currentTheme
Co-authored-by: Cursor <cursoragent@cursor.com>
Fix clock persistence bug caused by stale legacy read in settings
deserialization. Add clock size setting (Small/Medium/Large) and
timezone selection with North American presets plus custom UTC offset.
Move all clock-related settings into a dedicated Clock tab, rename
"Home Screen Clock" to "Clock", and move minute-change detection to
main loop so the header clock updates on every screen.
Co-authored-by: Cursor <cursoragent@cursor.com>
- Fix SetTimeActivity immediately dismissing by changing wasReleased to
wasPressed for all button inputs (matching other subactivities)
- Extract NTP sync into shared TimeSync utility (startNtpSync,
waitForNtpSync, stopNtpSync) and trigger non-blocking NTP sync on
every WiFi connection
- Move clock rendering into drawHeader (BaseTheme + LyraTheme) so it
appears on all screens with a header, positioned symmetrically with
the battery icon (12px margin, same Y offset, SMALL_FONT_ID)
- Add per-minute auto-refresh on home screen so clock updates without
button press
- Add RTC time debug log on boot to verify time persistence across
deep sleep
Co-authored-by: Cursor <cursoragent@cursor.com>
Skip the reader menu when long-pressing Confirm (700ms) to jump
straight to the chapter selection screen. Short press behavior
(opening the menu) is unchanged. Extracts shared openChapterSelection()
helper to eliminate duplicated construction across three call sites.
Co-authored-by: Cursor <cursoragent@cursor.com>
- 1-book view: horizontal layout with cover left, title/author right
- 2-3 book view: fix cover stretching by preserving aspect ratio
- 0-book view: show "Choose something to read" placeholder
- Selection highlight now fully contains title and author text
- Add optional clock display in home screen header (AM/PM or 24H)
- Add "Home Screen Clock" setting under Display
- Add "Set Time" activity for manual clock setting via Settings
- Increase homeCoverTileHeight to 310 for title/author breathing room
Co-authored-by: Cursor <cursoragent@cursor.com>
Consolidate dictionary items: remove "Lookup Word History" and
"Delete Dictionary Cache" from the menu. Long-press on "Lookup Word"
opens history; delete-dict-cache is now a sentinel entry at the bottom
of the history list.
Replace "Reading Orientation" with "Toggle Portrait/Landscape" that
toggles between two configurable preferred orientations (new settings:
Preferred Portrait, Preferred Landscape). Long-press opens a manual
4-option orientation sub-menu.
Add "Toggle Font Size" menu item that cycles through font sizes and
applies on menu exit (with section re-layout).
Rename "Letterbox Fill" to "Override Letterbox Fill" and
"Sync Progress" to "Sync Reading Progress" in reader menu.
All long-press flows use ignoreNextConfirmRelease to prevent the
button release from triggering actions on the subsequent screen.
Co-authored-by: Cursor <cursoragent@cursor.com>
Migrate 5 mod Activity subclasses from old polling-based
display task pattern to the upstream render() super-class
pattern with freeRTOS notification:
- EpubReaderBookmarkSelectionActivity
- DictionaryWordSelectActivity
- DictionarySuggestionsActivity
- DictionaryDefinitionActivity
- LookedUpWordsActivity
Changes: remove own TaskHandle/SemaphoreHandle/updateRequired,
use requestUpdate() + render(RenderLock&&) override, fix
potential deadlocks around enterNewActivity() calls.
Also fix stale conflict marker in EpubReaderMenuActivity.h.
Co-authored-by: Cursor <cursoragent@cursor.com>
Issues solved: #729 and #739
## Summary
* **What is the goal of this PR?**
Currently, the battery icon and charge percentage were aligned to the
left even for the UI, where they were positioned on the right side of
the screen. This meant that when changing values of different numbers of
digits, the battery would shift, creating a block of icons and text that
was illegible.
* **What changes are included?**
- Add drawBatteryUi() method for right-aligned battery display in UI
headers
- Keep drawBattery() for left-aligned display in reader mode
- Extract drawBatteryIcon() helper to reduce code duplication
- Battery icon now stays fixed at right edge regardless of percentage
digits
- Text adjusts to left of icon in UI mode, to right of icon in reader
mode
## Additional Context
* Add any other information that might be helpful for the reviewer
* This fix applies to both themes (Base and Lyra).
---
### AI Usage
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 >**_
**What is the goal of this PR?**
This PR introduces Internationalization (i18n) support, enabling users
to switch the UI language dynamically.
**What changes are included?**
- Core Logic: Added I18n class (`lib/I18n/I18n.h/cpp`) to manage
language state and string retrieval.
- Data Structures:
- `lib/I18n/I18nStrings.h/cpp`: Static string arrays for each supported
language.
- `lib/I18n/I18nKeys.h`: Enum definitions for type-safe string access.
- `lib/I18n/translations.csv`: single source of truth.
- Documentation: Added `docs/i18n.md` detailing the workflow for
developers and translators.
- New Settings activity:
`src/activities/settings/LanguageSelectActivity.h/cpp`
This implementation (building on concepts from #505) prioritizes
performance and memory efficiency.
The core approach is to store all localized strings for each language in
dedicated arrays and access them via enums. This provides O(1) access
with zero runtime overhead, and avoids the heap allocations, hashing,
and collision handling required by `std::map` or `std::unordered_map`.
The main trade-off is that enums and string arrays must remain perfectly
synchronized—any mismatch would result in incorrect strings being
displayed in the UI.
To eliminate this risk, I added a Python script that automatically
generates `I18nStrings.h/.cpp` and `I18nKeys.h` from a CSV file, which
will serve as the single source of truth for all translations. The full
design and workflow are documented in `docs/i18n.md`.
- [x] Python script `generate_i18n.py` to auto-generate C++ files from
CSV
- [x] Populate translations.csv with initial translations.
Currently available translations: English, Español, Français, Deutsch,
Čeština, Português (Brasil), Русский, Svenska.
Thanks, community!
**Status:** EDIT: ready to be merged.
As a proof of concept, the SPANISH strings currently mirror the English
ones, but are fully uppercased.
---
Did you use AI tools to help write this code? _**< PARTIALLY >**_
I used AI for the black work of replacing strings with I18n references
across the project, and for generating the documentation. EDIT: also
some help with merging changes from master.
---------
Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
Co-authored-by: yeyeto2788 <juanernestobiondi@gmail.com>
Follow-up to
https://github.com/crosspoint-reader/crosspoint-reader/pull/774
---
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? **NO**
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
* **Refactor**
* Modernized internal synchronization mechanisms across multiple
components to improve code reliability and maintainability. All
functionality remains unchanged.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Currently, each activity has to manage their own `displayTaskLoop` which
adds redundant boilerplate code. The loop is a wait loop which is also
not the best practice, as the `updateRequested` boolean is not protected
by a mutex.
In this PR:
- Move `displayTaskLoop` to the super `Activity` class
- Replace `updateRequested` with freeRTOS's [direct to task
notification](https://www.freertos.org/Documentation/02-Kernel/02-Kernel-features/03-Direct-to-task-notifications/01-Task-notifications)
- For `ActivityWithSubactivity`, whenever a sub-activity is present, the
parent's `render()` automatically goes inactive
With this change, activities now only need to expose `render()`
function, and anywhere in the code base can call `requestUpdate()` to
request a new rendering pass.
In theory, this change may also make the battery life a bit better,
since one wait loop is removed. Although the equipment in my home lab
wasn't been able to verify it (the electric current is too noisy and
small). Would appreciate if anyone has any insights on this subject.
Update: I managed to hack [a small piece of
code](https://github.com/ngxson/crosspoint-reader/tree/xsn/measure_cpu_usage)
that allow tracking CPU idle time.
The CPU load does decrease a bit (1.47% down to 1.39%), which make
sense, because the display task is now sleeping most of the time unless
notified. This should translate to a slightly increase in battery life
in the long run.
```
PR:
[40012] [MEM] Free: 185856 bytes, Total: 231004 bytes, Min Free: 123316 bytes
[40012] [IDLE] Idle time: 98.61% (CPU load: 1.39%)
[50017] [MEM] Free: 185856 bytes, Total: 231004 bytes, Min Free: 123316 bytes
[50017] [IDLE] Idle time: 98.61% (CPU load: 1.39%)
[60022] [MEM] Free: 185856 bytes, Total: 231004 bytes, Min Free: 123316 bytes
[60022] [IDLE] Idle time: 98.61% (CPU load: 1.39%)
master:
[20012] [MEM] Free: 195016 bytes, Total: 231532 bytes, Min Free: 132460 bytes
[20012] [IDLE] Idle time: 98.53% (CPU load: 1.47%)
[30017] [MEM] Free: 195016 bytes, Total: 231532 bytes, Min Free: 132460 bytes
[30017] [IDLE] Idle time: 98.53% (CPU load: 1.47%)
[40022] [MEM] Free: 195016 bytes, Total: 231532 bytes, Min Free: 132460 bytes
[40022] [IDLE] Idle time: 98.53% (CPU load: 1.47%)
```
---
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? **NO**
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
* **Refactor**
* Streamlined rendering architecture by consolidating update mechanisms
across all activities, improving efficiency and consistency.
* Modernized synchronization patterns for display updates to ensure
reliable, conflict-free rendering.
* **Bug Fixes**
* Enhanced rendering stability through improved locking mechanisms and
explicit update requests.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: znelson <znelson@users.noreply.github.com>
Remove empty sentinel BMP file from generateThumbBmp() that blocked
placeholder generation for books without covers. Add removeBook() to
RecentBooksStore and clear book from recents on cache delete. Ensure
home screen always generates placeholder when thumbnail generation fails.
Co-authored-by: Cursor <cursoragent@cursor.com>
Cherry-pick merge from pablohc/crosspoint-reader@2d8cbcf, based on
upstream PR #556 by martinbrook with pablohc's refresh optimization.
- Add JPEG decoder (picojpeg) and PNG decoder (PNGdec) with 4-level
grayscale Bayer dithering for e-ink display
- Add pixel caching system (.pxc files) for fast image re-rendering
- Integrate image extraction from EPUB HTML parser (<img> tag support)
- Add ImageBlock/PageImage types with serialization support
- Add image-aware refresh optimization (double FAST_REFRESH technique)
- Add experimental displayWindow() partial refresh support
- Bump section cache version 12->13 to invalidate stale caches
- Resolve TAG_PageImage=3 to avoid conflict with mod's TAG_PageTableRow=2
Co-authored-by: Cursor <cursoragent@cursor.com>
Prevent the device from dropping to 10MHz CPU during first-time chapter
indexing, cover prerendering, and other CPU-intensive reader operations.
Three issues addressed:
- ActivityWithSubactivity now delegates preventAutoSleep() and
skipLoopDelay() to the active subactivity, so EpubReaderActivity's
signal is visible through the ReaderActivity wrapper
- Added post-loop() re-check of preventAutoSleep() in main.cpp to
catch activity transitions that happen mid-loop
- EpubReaderActivity uses both !section and a loadingSection flag to
cover the full duration from activity entry through section file
creation; TxtReaderActivity uses !initialized similarly
Also syncs HalPowerManager.cpp log messages with upstream PR #852.
Co-authored-by: Cursor <cursoragent@cursor.com>
## Summary
Closes#766. Thank you for the help @bramschulting!
**What is the goal of this PR?**
- First and foremost, fix issue #766.
- Through working on that, I realized the current CSS parsing/loading
code can be improved dramatically for large files and still had
additional performance improvements to be made, even with EPUBs with
small CSS.
**What changes are included?**
- Stream CSS parsing and reuse normalization buffers to cut allocations
- Add rule limits and selector validation to release rules and free up
memory when needed
- Skip CSS parsing/loading entirely when "Book's Embedded Style" is off
## Additional Context
- My test EPUB has been updated
[here](https://github.com/jdk2pq/css-test-epub) to include a very large
CSS file to test this out
---
### AI Usage
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**_, Codex
Add OMIT_BOOKERLY, OMIT_NOTOSANS, OMIT_OPENDYSLEXIC flags to
selectively exclude font families, and OMIT_HYPH_DE/EN/ES/FR/IT/RU
flags to exclude individual hyphenation language tries.
The mod build environment excludes OpenDyslexic (~1.03 MB) and all
hyphenation tries (~282 KB), reducing flash usage by ~1.3 MB.
Font Family setting switched from Enum to DynamicEnum with
index-to-value mapping to handle arbitrary font exclusion without
breaking the settings UI or persisted values.
Co-authored-by: Cursor <cursoragent@cursor.com>
Generate styled placeholder covers (title, author, book icon) when a
book has no embedded cover image, instead of showing a blank rectangle.
- Add PlaceholderCoverGenerator lib with 1-bit BMP rendering, scaled
fonts, word-wrap, and a book icon bitmap
- Integrate as fallback in Epub/Xtc/Txt reader activities and
SleepActivity after format-specific cover generation fails
- Add fallback in HomeActivity::loadRecentCovers() so the home screen
also shows placeholder thumbnails when cache is cleared
- Add Txt::getThumbBmpPath() for TXT thumbnail support
- Add helper scripts for icon and layout preview generation
Co-authored-by: Cursor <cursoragent@cursor.com>
Introduce BookSettings utility for per-book settings stored in
the book's cache directory (book_settings.bin). Add "Letterbox Fill"
option to the EPUB reader menu that cycles Default/Dithered/Solid/None.
At sleep time, the per-book override is loaded and takes precedence
over the global setting for all book types (EPUB, XTC, TXT).
Co-authored-by: Cursor <cursoragent@cursor.com>
Pixel-level Bayer dithering in the 171-254 gray range creates a
high-frequency checkerboard in the BW pass that causes e-ink display
crosstalk during HALF_REFRESH, washing out cover images. Replace with
2x2 hash-based block dithering for this specific gray range — each
block gets a uniform level (2 or 3) via a spatial hash, avoiding
single-pixel alternation while approximating the target gray. Standard
Bayer dithering remains for all other gray ranges.
Also removes all debug instrumentation from the investigation.
Co-authored-by: Cursor <cursoragent@cursor.com>
Simplify letterbox fill modes back to Dithered (default), Solid, and
None. Remove the Extend Edges mode and all per-pixel edge replication
code. Restore Bayer ordered dithering for the Dithered fill mode.
Re-introduce edge average caching so cover edge computations persist
across sleep cycles, stored as a small binary file alongside the cover
BMP.
Co-authored-by: Cursor <cursoragent@cursor.com>
## Summary
* Definition and use of a central LOG function, that can later be
extended or completely be removed (for public use where debugging
information may not be required) to save flash by suppressing the
-DENABLE_SERIAL_LOG like in the slim branch
* **What changes are included?**
## Additional Context
* By using the central logger the usual:
```
#include <HardwareSerial.h>
...
Serial.printf("[%lu] [WCS] Obfuscating/deobfuscating %zu bytes\n", millis(), data.size());
```
would then become
```
#include <Logging.h>
...
LOG_DBG("WCS", "Obfuscating/deobfuscating %zu bytes", data.size());
```
You do have ``LOG_DBG`` for debug messages, ``LOG_ERR`` for error
messages and ``LOG_INF`` for informational messages. Depending on the
verbosity level defined (see below) soe of these message types will be
suppressed/not-compiled.
* The normal compilation (default) will create a firmware.elf file of
42.194.356 bytes, the same code via slim will create 42.024.048 bytes -
170.308 bytes less
* Firmware.bin : 6.469.984 bytes for default, 6.418.672 bytes for slim -
51.312 bytes less
### AI Usage
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? _NO_
---------
Co-authored-by: Xuan Son Nguyen <son@huggingface.co>
Replace bookmark stubs with full add/remove/navigate implementation:
- BookmarkStore: per-book binary persistence on SD card with v2 format
supporting text snippets (backward-compatible with v1)
- Visual bookmark ribbon indicator drawn on bookmarked pages via fillPolygon
- Reader menu dynamically shows Add/Remove Bookmark based on current page state
- Bookmark selection activity with chapter name, first sentence snippet, and
page number display; long-press to delete with confirmation
- Go to Bookmark falls back to Table of Contents when no bookmarks exist
- Smart snippet extraction: skips partial sentences (lowercase first word)
to capture the first full sentence on the page
- Label truncation reserves space for page suffix so it's never cut off
- Half refresh forced on menu exit to clear popup/menu artifacts
Co-authored-by: Cursor <cursoragent@cursor.com>
Implements StarDict-based dictionary lookup from the reader menu,
adapted from upstream PR #857 with /.dictionary/ folder path,
std::vector compatibility (PR #802), HTML definition rendering,
orientation-aware button hints, side button hints with CCW text
rotation, sparse index caching to SD card, pronunciation line
filtering, and reorganized reader menu with bookmark stubs.
Co-authored-by: Cursor <cursoragent@cursor.com>
Moves cover/thumbnail generation from lazy (Home screen, Sleep screen) into
each reader activity's onEnter(). On first open, generates all needed BMPs
(cover, cover_crop, thumbnails for all theme heights) with a "Preparing
book..." progress popup. Subsequent opens skip instantly when files exist.
Co-authored-by: Cursor <cursoragent@cursor.com>
Resolve single conflict in SleepActivity.cpp: adopt upstream millis()
timestamp log format while preserving mod's edgeCachePath argument to
renderBitmapSleepScreen().
Upstream changes (14 commits): unified navigation handling, Italian
hyphenation, natural file sort, auto WiFi reconnect, power saving on
idle, OPDS fixes, uniform debug logging, and more.
Co-authored-by: Cursor <cursoragent@cursor.com>
## Summary
* Unify all serial port debug messages
## Additional Context
* All messages sent to the serial port now follow the "[timestamp]
[origin] payload" format (notable exception framework messages)
---
### AI Usage
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? No
## Summary
Show "Back" in file browser if not in root, "Home" otherwise.
---
### AI Usage
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
## Summary
* Manually trigger GPIO update in File Browser mode
* Previously just assumed that the GPIO data would update automatically
(presumably via yield), the data is currently updated in the main loop
(and now here as well during the middle of the processing loop).
* This allows the back button to be correctly detected instead of only
being checked once every 100ms or so for the button state.
## Additional Context
* Fixes
https://github.com/crosspoint-reader/crosspoint-reader/issues/579
---
### AI Usage
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? No
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Enhanced input state detection in the web server interface for more
responsive and accurate user command recognition during high-frequency
operations.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Summary
* Prevent sleeping when in OPDS browser / downloading books
## Additional Context
* Raised in
https://github.com/crosspoint-reader/crosspoint-reader/discussions/673
---
### AI Usage
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? No
## Summary
* **What is the goal of this PR?** (e.g., Implements the new feature for
file uploading.)
Implement natural sort (e.g. "file1.txt, file2.txt, file10.txt" instead
of "file1.txt, file10.txt, file2.txt") for files in the
MyLibraryActivity menu
* **What changes are included?**
Modifies the `sortFileList` function under
`src/activities/home/MyLibraryActivity.cpp` to use natural sort as
opposed to lexicographical sort
## Additional Context
I wasn't entirely sure whether or not i should make this a configurable
option, but most file browsers and directory listing tools have this set
as an immutable default, so I opted against it.
* Add any other information that might be helpful for the reviewer
(e.g., performance implications, potential risks,
specific areas to focus on).
---
### AI Usage
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? _**NO**_
Add configurable letterbox fill for sleep screen cover images that don't
match the display aspect ratio. Four fill modes are available: Solid
(single dominant edge shade), Blended (per-pixel edge colors), Gradient
(edge colors interpolated toward white/black), and None.
Enable upscaling of cover images smaller than the display in Fit mode by
modifying drawBitmap/drawBitmap1Bit to support both up and downscaling
via a unified block-fill approach.
Edge sampling data is cached to .crosspoint alongside the cover BMP to
avoid redundant bitmap scanning on subsequent sleeps. Cache is validated
against screen dimensions and auto-regenerated when stale.
New settings: Letterbox Fill (None/Solid/Blended/Gradient) and Gradient
Direction (To White/To Black).
Co-authored-by: Cursor <cursoragent@cursor.com>
This PR unifies navigation handling & adds system-wide support for
continuous navigation.
## Summary
Holding down a navigation button now continuously advances through items
until the button is released. This removes the need for repeated
press-and-release actions and makes navigation faster and smoother,
especially in long menus or documents.
When page-based navigation is available, it will navigate through pages.
If not, it will progress through menu items or similar list-based UI
elements.
Additionally, this PR fixes inconsistencies in wrap-around behavior and
navigation index calculations.
Places where the navigation system was updated:
- Home Page
- Settings Pages
- My Library Page
- WiFi Selection Page
- OPDS Browser Page
- Keyboard
- File Transfer Page
- XTC Chapter Selector Page
- EPUB Chapter Selector Page
I’ve tested this on the device as much as possible and tried to match
the existing behavior. Please let me know if I missed anything. Thanks 🙏

---
Following the request from @osteotek and @daveallie for system-wide
support, the old PR (#379) has been closed in favor of this
consolidated, system-wide implementation.
---
### AI Usage
Did you use AI tools to help write this code? _**PARTIALLY**_
---------
Co-authored-by: Dave Allie <dave@daveallie.com>
## Summary
This is an updated version of @itsthisjustin's #346 that builds on
current master and also deduplicates the settings list so we don't have
two copies of the settings. In the Web UI, it should organize the
settings a little closer to what you see on device.
## Additional Context
I tested this live on device and it seems to play nicely for me. It's
re-based on master since master's settings stuff has moved somewhat
since the original PR and addresses the sole review comment #346 - it
also means that I don't need to manually key in the URL for my OPDS
server. :)
---
### AI Usage
My changes were implemented with Claude Opus 4.5 and Claude Code 2.1.25.
I don't know if @itsthisjustin's original work used AI assistance.
Co-authored-by: Dave Allie <dave@daveallie.com>
## Summary
Continue my changes to introduce the HAL infrastructure from
https://github.com/crosspoint-reader/crosspoint-reader/pull/522
This PR touches quite a lot of files, but most of them are just name
changing. It should not have any impacts to the end behavior.
## Additional Context
My plan is to firstly add this small shim layer, which sounds useless at
first, but then I'll implement an emulated driver which can be helpful
for testing and for development.
Currently, on my fork, I'm using a FS driver that allow "mounting" a
local directory from my computer to the device, much like the `-v` mount
option on docker. This allows me to quickly reset `.crosspoint`
directory if anything goes wrong. I plan to upstream this feature when
this PR get merged.
---
### AI Usage
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? NO
## Summary
Fix for the page skip issue detected
https://github.com/crosspoint-reader/crosspoint-reader/pull/700#issuecomment-3856374323
by user @whyte-j
Skipping down on the last page now skips to the last item, and up on the
first page to the first item, rather than wrapping around the list in a
weird way.
## Additional Context
The calculation was outdated after several changes were added afterwards
---
### AI Usage
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? _**NO**_
## Summary
**What is the goal of this PR?**
- Just a simple rename after feedback in #738
**What changes are included?**
- Renamed "Embedded Style" to "Book's Embedded Style" to more clearly
associate it with "Book's Style" option in "Paragraph Alignment"
settings
---
### AI Usage
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? _**NO**_
## Summary
* Inverts back button behaviour while reading - short press to go home,
long press to open file browser
## Additional Context
* It seems counterintuitive that going into a book from home screen and
pressing back doesn’t take you back to the home screen. With the recent
books now displayed in the home view and a separate recents view, going
directly to the file browser is less necessary.
## Summary
Reduce/fix the lag on the home screen before recent book covers are
rendered
## Additional Context
We were previously rendering the screen in two steps, delaying the
recent book covers render to avoid a lag before the screen loads.
In this PR, we are now doing that only if at least one book doesn't have
the cover thumbnail generated yet. If all thumbs are already generated,
we load and display them right away, with no lag.
---
### AI Usage
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? _**NO **_
Closes#712
## Summary
**What is the goal of this PR?**
- To add new settings for toggling on/off embedded CSS styles in the
reader. This gives more control and customization to the user over how
the ereader experience looks.
**What changes are included?**
- Added new "Embedded Style" option to the Reader settings
- Added new "Book's Style" option for "Paragraph Alignment"
- User's selected "Paragraph Alignment" will take precedence and
override the embedded CSS `text-align` property, _unless_ the user has
"Book's Style" set as their "Paragraph Alignment"
## Additional Context

https://github.com/user-attachments/assets/9e404b13-c7e0-41c7-9406-4715f389166a
Addresses feedback from the community about the new CSS feature:
https://github.com/crosspoint-reader/crosspoint-reader/pull/700
---
### AI Usage
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**_, Claude Code