Skip to content

Commit 74f83fd

Browse files
imshentasticclaude
andcommitted
docs: v4.2.1 -> single-variant ship + empty-shelf retry fix
Per release decision: drop the three-variant strategy. v4.2.1 ships only crumble-firmware-4.2.1.bin (Bitter). The build infra (platformio.ini envs for tiny-lexend / tiny-chareink, OMIT_BITTER_FONT guards) stays in source so anyone can rebuild a variant locally if needed -- it's just not part of the shipped artifact set. Also add CHANGELOG entry for the empty-shelf-after-sort retry fix. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 0ec637c commit 74f83fd

1 file changed

Lines changed: 2 additions & 2 deletions

File tree

CHANGELOG.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@
22

33
## [crumble-v4.2.1] - 2026-06-06
44

5-
### Three firmware variants
6-
v4.2.1 ships as **three slim variants**, each with a different built-in reader font: `crumble-firmware-4.2.1-tiny-bitter.bin`, `crumble-firmware-4.2.1-tiny-lexend.bin`, and `crumble-firmware-4.2.1-tiny-chareink.bin`. This pivot is the v4.2.1 answer to the Bluetooth + SD-card font heap-fragmentation issue: NimBLE's ~50 KB init scatters allocations that shatter contiguous heap below the 25 KB Page DOM threshold — but only the SD-font code path triggers this (built-in fonts use FontDecompressor, much smaller heap profile). By shipping a binary per font choice, users who want Bluetooth + their preferred font get a stable experience without touching the SD-font code path. Flash whichever variant matches your preferred font; switching fonts means re-flashing.
5+
Single firmware: `crumble-firmware-4.2.1.bin` (Bitter built-in, slim, fits the 6.25 MB OTA partition). The Lexend Deca and CharEink families remain installable as SD-card `.cpfont` bundles; the Bluetooth + SD-card font architectural fix (per-section glyph subset baking) is on the v4.3 roadmap.
76

87
### Fixed
98
- **WASM serving no longer mismatches MIME on every book upload.** `CrossPointWebServer::sendBufferGzip` was substituting an empty `text/html` body under low-heap conditions for *all* MIME types, which broke `WebAssembly.compile`'s strict MIME check. The substitution now fires only for `text/html` content; non-HTML responses (including `application/wasm`) return 503 if free heap is below 6 KB or stream from PROGMEM normally otherwise. Symptom before fix: "Incorrect response MIME type" on every book upload + optimize action.
@@ -20,6 +19,7 @@ v4.2.1 ships as **three slim variants**, each with a different built-in reader f
2019
- **Bookmark viewing no longer crashes** on heap-tight devices. A v4.2.1 regression: the V5 1024-byte preview field made each in-memory `Bookmark` struct ~1092 bytes, so opening a bookmark list on a book with 50+ highlights triggered a 55 KB contiguous allocation when the activity copied the bookmarks vector by value. After a BT/SD-font session (heap fragmented to ~12 KB max contiguous), this OOM-terminated inside `std::make_unique`. The in-memory representation is now `std::string preview`, sizing to actual content (24 bytes base + the actual preview length). On-disk V5 format unchanged; the 1024-byte field is just the write cap.
2120
- **AuthorAlpha sort now uses a persistent per-book author key cache** instead of loading each EPUB transiently. The v4.2.1 first-attempt's break-on-low-heap + yield pattern wasn't enough on field hardware — per-book loads still fragmented maxAlloc to ~12 KB which crashed `resolveShelfEntries` post-sort. Library index format bumped v1 → v2 with a new `authorKey` field per entry. Cache is populated lazily by `ensureWalked` (heap-aware, BREAKs cleanly under pressure) and proactively by `EpubReaderActivity::onEnter`. AuthorAlpha sort is now O(N) cache lookups with zero Epub loads. First boot after upgrade does a one-time population pass; subsequent boots load the v2 index with all authors pre-cached. v1 indices on disk load cleanly (empty authors, upgraded on next walk); v2 indices on v4.2.0 firmware force a rescan (same downgrade policy as section file v38 → v39).
2221
- **Quote Viewer button hints trimmed** from `< Prev page` / `Next page >` to `Prev page` / `Next page`. Angle-bracket decorations overflowed the hint container at typical sidebar widths; the dpad position next to each label already implies direction.
22+
- **Shelf no longer renders empty until the next click after sorting** on a heap-fragmented device. The v4.2.1 `resolveShelfEntries` heap pre-flight (added so the shelf-build can't bad_alloc under tight heap) was returning an empty vector that `HomeActivity::cachedShelfEntries` then committed as a "valid" cache entry — so subsequent renders hit the cache and returned empty, until something else invalidated the cache (an arbitrary click). `CollectionsStore` now exposes a `lastResolveHitHeapPressure()` signal that the caller uses to skip the cache commit and schedule one immediate retry via `requestUpdate()`. By the next frame, transient allocations from the previous render have freed and the rebuild succeeds. Retry counter capped at 5 to avoid infinite render loops on a permanently-stuck heap.
2323

2424
### Added
2525
- **Bookmark Quote Viewer.** Pressing Confirm on a bookmark in the bookmark list now opens a dedicated viewer activity. Up/Down walks between bookmarks (wraps around at top/bottom), Left/Right pages through long quotes, Confirm jumps to that location in the book, Back returns to the bookmark list with cursor preserved. Uses the built-in UI_12 font for the viewer chrome so the activity itself doesn't depend on SD-font availability.

0 commit comments

Comments
 (0)