🔧 Features
⌨️ Aligned Long-Press Options (Front + Side Buttons)
- Reordered both
LONG_PRESS_BUTTON_BEHAVIORandFRONT_LONG_PRESS_BEHAVIORenums to a unified 6-option list: Off → Bookmarks → Clippings → Chapter Skip → Orientation → Font Size (new) LONG_PRESS_FONTSIZE/FRONT_LONG_PRESS_FONTSIZE: DOWN/Right = increase, UP/Left = decrease font size!fromFrontButtonguard on side-button handlers so front buttons use their own independent setting- Chapter Skip, Orientation, and Font Size added to the front button long-press handler block
EpubReaderActivity::adjustFontSize()callsensureSdFontLoaded()so SD fonts reload at the new point sizeXtcReaderActivity:fromFrontButtonguard on skip-pagesTxtReaderActivity: front button orientation handling viaReaderUtils::applyOrientation()- All option lists updated:
SettingsList.cpp,SettingsActivity.cpp,CrossPointWebServer.cpp
🕒 X3 Clock: Status Bar Settings (on-device)
- Clock position (Hide / Right / Left), Clock format (24h / 12h), and Sync clock now added to the on-device Customize Status Bar activity (was web-only)
- Sync clock now launches
ClockSyncActivity— connects WiFi if needed, performs NTP sync, returns - All 3 settings gated by
halClock.isAvailable()(visible only on X3/X4 with RTC)
🌐 i18n
STR_LONG_PRESS_BEHAVIOR_FONTSIZE:"Font size"(EN / IT)STR_LONG_PRESS_BEHAVIOR_ORIENTATION: shortened to"Orientation"/"Orientamento"- Regenerated i18n headers
🐛 Bug Fixes
🏛️ Library Crush Fix — Fragmented Heap Abort
- Problem:
std::bad_allocfromvector::emplace_backduring incremental scan with 1784 entries on a fragmented heap →abort()at PC0x421eb70b - Fix: Pre-allocate
newScanvector capacity usingprevScan.size()hint for incremental scans, avoiding uncaughtstd::bad_allocfrom incremental vector growth - Fix: Pass
trailingNullByte=truetoZipFile::readFileToMemory()inEpubParser::readDirectFromZip()sostrstr()operates on null-terminated buffers — prevents buffer overread on corrupt ZIP entries - Files:
src/components/LibraryIndex.cpp,src/components/EpubParser.cpp
⏰ DS3231 RTC: System Clock Without Prior NTP Sync
- Removed the
SETTINGS.clockHasBeenSyncedguard fromTimeUtils::applySystemClockFromRtc() - Effect: X3 with DS3231 now sets the ESP32 system clock on first RTC access even without NTP sync — fixes invisible top header date
- Safety: DS3231 value still validated by
isClockValid()(epoch ≥ 2024-01-01)
🛡️ JSON Save/Load Hardening (upstream 1.5.0.3 sync)
copyVerifiedJsonTempToTarget()— verified temp-to-target copy fallback whenStorage.rename()fails on FATsaveJsonDocumentToFile(): overflow pre-write check,measureJson()expected-size detection, incomplete-write detection (not just 0 bytes)loadJsonDocumentFromFile(): overflow detection in parse errorsloadReadingStats(): const-correct validation (JsonObjectConst/JsonArrayConst):- Root type check,
formatVersionrange validation (1–6) - Array key presence check for all 4 required arrays
- Per-entry type validation for
books[]andsessionLog[] - All Steroids-specific fields preserved (
avgSecondsPerForwardPage,paceSampleCount)
- Root type check,
ReadingStatsStore::importFromFile(): split empty-path / missing-file checks, event logging for all failure paths- Files:
src/JsonSettingsIO.cpp,src/ReadingStatsStore.cpp
🔄 Upstream CPR-vCodex Alignment
- Base: upstream
1.5.0.2→1.5.0.3 - Delta applied: 1 code commit —
fix(stats): restore valid JSON imports(096bc73) - All Steroids-specific features preserved:
- Library subsystem (JSON index, collections, cover generation)
- Reading pace tracking (
avgSecondsPerForwardPage,paceSampleCount) - Custom icons, themes, branding
- Long-press expanded enums
- Clock settings and DS3231 RTC integration
applySystemClockFromRtc()withoutclockHasBeenSyncedguard
- Protected files untouched:
CrossPointSettings.h,main.cpp,ActivityManager,WebServer, HTML pages, Library cache, Clippings, Bookmarks, Epub parser, themes, icons