## Summary
Adds support for browsing and downloading books from a Calibre-web
server via OPDS.
How it works
1. Configure server URL in Settings → Calibre Web URL (e.g.,
https://myserver.com:port I use Cloudflare tunnel to make my server
accessible anywhere fwiw)
2. "Calibre Library" will now show on the the home screen
3. Browse the catalog - navigate through categories like "By Newest",
"By Author", "By Series", etc.
4. Download books - select a book and press Confirm to download the EPUB
to your device
Navigation
- Up/Down - Move through entries
- Confirm - Open folder or download book
- Back - Go to parent catalog, or exit to home if at root
- Navigation entries show with > prefix, books show title and author
- Button hints update dynamically ("Open" for folders, "Download" for
books)
Technical details
- Fetches OPDS catalog from {server_url}/opds
- Parses both navigation feeds (catalog links) and acquisition feeds
(downloadable books)
- Maintains navigation history stack for back navigation
- Handles absolute paths in OPDS links correctly (e.g.,
/books/opds/navcatalog/...)
- Downloads EPUBs directly to the SD card root
Note
The server URL should be typed to include https:// if the server
requires it - HTTP→HTTPS redirects may cause SSL errors on ESP32.
## Additional Context
* I also changed the home titles to use uppercase for each word and
added a setting to change the size of the side margins
---------
Co-authored-by: Dave Allie <dave@daveallie.com>
## Summary
* **What is the goal of this PR?** (e.g., Fixes a bug in the user
authentication module, Implements the new feature for
file uploading.)
This PR refactors the semantic version comparison logic used during OTA
update checks.
Memory stats before :
RAM: [=== ] 30.8% (used 101068 bytes from 327680 bytes)
Flash: [========= ] 85.7% (used **5617830** bytes from 6553600 bytes)
Memory stats before :
RAM: [=== ] 30.8% (used 101068 bytes from 327680 bytes)
Flash: [========= ] 85.7% (used **5616870** bytes from 6553600 bytes)
* **What changes are included?**
Replaced std::string::substr() and std::stoi() based parsing with a
lightweight, heap-free approach.
Version parsing is now done in a single pass without creating temporary
std::string objects.
Behavior remains identical: versions are still compared as
MAJOR.MINOR.PATCH.
## Additional Context
`std::string::substr() ` creates a new string and performs heap
allocation
* Add any other information that might be helpful for the reviewer
(e.g., performance implications, potential risks, specific areas to
focus on).
## Summary
* Swap to updated SDCardManager which uses SdFat
* Add exFAT support
* Swap to using FsFile everywhere
* Use newly exposed `SdMan` macro to get to static instance of
SDCardManager
* Move a bunch of FsHelpers up to SDCardManager
## Summary
* **What is the goal of this PR?** Adds WiFi Access Point (AP) mode
support for File Transfer, allowing the device to create its own WiFi
network that users can connect to directly - useful when no existing
WiFi network is available. And in my experience is faster when the
device is right next to your laptop (but maybe further from your wifi)
* **What changes are included?**
- New `NetworkModeSelectionActivity` - an interstitial screen asking
users to choose between:
- "Join a Network" - connects to an existing WiFi network (existing
behavior)
- "Create Hotspot" - creates a WiFi access point named
"CrossPoint-Reader"
- Modified `CrossPointWebServerActivity` to:
- Launch the network mode selection screen before proceeding
- Support starting an Access Point with mDNS (`crosspoint.local`) and
DNS server for captive portal behavior
- Display appropriate connection info for both modes
- Modified `CrossPointWebServer` to support starting when WiFi is in AP
mode (not just STA connected mode)
## Additional Context
* **AP Mode Details**: The device creates an open WiFi network named
"CrossPoint-Reader". Once connected, users can access the file transfer
page at `http://crosspoint.local/` or `http://192.168.4.1/`
* **DNS Captive Portal**: A DNS server redirects all domain requests to
the device's IP, enabling captive portal behavior on some devices
* **mDNS**: Hostname resolution via `crosspoint.local` is enabled for
both AP and STA modes
* **No breaking changes**: The "Join a Network" option preserves the
existing WiFi connection flow
* **Memory impact**: Minimal - the AP mode uses roughly the same
resources as STA mode
## Summary
* Adds support for OTA
* Gets latest firmware bin from latest GitHub release
* I have noticed it be a little flaky unpacking the JSON and
occasionally failing to start
## Summary
* HTML files are now static, streamed directly to the client without
modification
* For any dynamic values, load via JSON APIs
* For files page, we stream the JSON content as we scan the directory to
avoid holding onto too much data
## Additional details
* We were previously building up a very large string all generated on
the X4 directly, we should be leveraging the browser
* Fixes https://github.com/daveallie/crosspoint-reader/issues/94