Skip to content

Commit ac8545d

Browse files
authored
Merge pull request #23 from imshentastic/fix/4.1.1-sd-fonts-preflight
fix(optimizer): include SD-card fonts in preflight modal
2 parents 22d0b6b + 7d463ea commit ac8545d

3 files changed

Lines changed: 54 additions & 7 deletions

File tree

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
# Changelog
22

3+
## [crumble-v4.1.1] - 2026-06-04
4+
5+
### Fixed
6+
- **Optimizer preflight modal now includes SD-card fonts.** Users with a custom `.cpfont` family (e.g. the CharEink SD-card bundle, or any community font dropped into `/fonts/` on the SD card) can now confirm or change their font in the "Lock in reader settings?" dialog that fires before each EPUB optimization. Previously the dropdown hardcoded only the three built-in families (Lexend Deca / Bitter / CharEink) and silently dropped SD selections. The fix pulls the family list from `/api/fonts` at modal open and routes the saved selection through `sdFontFamilyName` when an SD font is picked.
7+
38
## [crumble-v4.1.0] - 2026-06-04
49

510
### Added

platformio.ini

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ crossink_version = 1.3.0
3535
; the last book page in as a background unless you slept from a book.
3636
; Also adds X4/X3 simulator envs + tooling (dev-only; X3 runtime support
3737
; already shipped in 3.0.0).
38-
crumble_version = 4.1.0
38+
crumble_version = 4.1.1
3939

4040
[base]
4141
platform = https://github.com/pioarduino/platform-espressif32/releases/download/55.03.37/platform-espressif32.zip

src/network/html/js/optimizer.js

Lines changed: 48 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1872,11 +1872,34 @@ async function showOptimizerPreflightModal(renderInfo, fileName) {
18721872
// Enum tables. Indexes match the CrossPointSettings.h enums byte-for-byte
18731873
// -- the device validates the same ranges in handleSaveReaderSettings, so
18741874
// any drift here would be caught server-side. Keep in sync with that file.
1875+
//
1876+
// Font-family is special: the dropdown carries STRING tags rather than
1877+
// numeric values so we can represent both built-in fonts ("builtin:N")
1878+
// and SD-card fonts ("sd:<family-name>") in the same select. Built-in
1879+
// tags map to numeric fontFamily on save; SD tags map to
1880+
// sdFontFamilyName. See the confirm.onclick handler below.
18751881
const FONT_FAMILY = [
1876-
{ v: 0, label: 'Lexend Deca' },
1877-
{ v: 1, label: 'Bitter' },
1878-
{ v: 2, label: 'CharE-Ink' },
1882+
{ v: 'builtin:0', label: 'Lexend Deca' },
1883+
{ v: 'builtin:1', label: 'Bitter' },
1884+
{ v: 'builtin:2', label: 'CharE-Ink' },
18791885
];
1886+
1887+
// CrumBLE 4.1.1: pull SD-card font families from the device so users
1888+
// with a custom .cpfont can confirm / pick it in this dialog. Missing
1889+
// or failed /api/fonts response just falls through to built-ins only.
1890+
try {
1891+
const fontsResp = await fetch('/api/fonts');
1892+
if (fontsResp.ok) {
1893+
const fontsData = await fontsResp.json();
1894+
for (const family of (fontsData.families || [])) {
1895+
if (family && typeof family.name === 'string' && family.name.length > 0) {
1896+
FONT_FAMILY.push({ v: `sd:${family.name}`, label: `${family.name} (SD)` });
1897+
}
1898+
}
1899+
}
1900+
} catch (e) {
1901+
console.warn('Preflight: /api/fonts unavailable; SD-card font families will be missing from the picker', e);
1902+
}
18801903
const FONT_SIZE = [
18811904
{ v: 0, label: 'Tiny (8pt)' },
18821905
{ v: 1, label: 'Small (10pt)' },
@@ -1990,7 +2013,12 @@ async function showOptimizerPreflightModal(renderInfo, fileName) {
19902013
form.appendChild(wrap);
19912014
};
19922015

1993-
makeSelect('Font family', 'fontFamily', FONT_FAMILY, renderInfo.fontFamily | 0);
2016+
// CrumBLE 4.1.1: pick the current font tag based on whether an SD
2017+
// font is selected (sdFontFamilyName non-empty) or a built-in one.
2018+
const currentFontTag = (renderInfo.sdFontFamilyName && renderInfo.sdFontFamilyName.length > 0)
2019+
? `sd:${renderInfo.sdFontFamilyName}`
2020+
: `builtin:${renderInfo.fontFamily | 0}`;
2021+
makeSelect('Font family', 'fontFamily', FONT_FAMILY, currentFontTag);
19942022
makeSelect('Font size', 'fontSize', FONT_SIZE, renderInfo.fontSize | 0);
19952023
makeSelect('Orientation', 'orientation', ORIENTATION, renderInfo.orientation | 0);
19962024
makeNumber('Screen margin (px)', 'screenMargin', renderInfo.screenMargin | 0, 0, 50);
@@ -2036,8 +2064,22 @@ async function showOptimizerPreflightModal(renderInfo, fileName) {
20362064
const val = (el.type === 'checkbox') ? (el.checked ? '1' : '0') : el.value;
20372065
if (val !== cur) {
20382066
dirtyKeys.push(key);
2039-
if (el.type === 'checkbox') updates[key] = el.checked ? 1 : 0;
2040-
else updates[key] = Number(val);
2067+
if (el.type === 'checkbox') {
2068+
updates[key] = el.checked ? 1 : 0;
2069+
} else if (key === 'fontFamily' && typeof val === 'string' && val.startsWith('sd:')) {
2070+
// CrumBLE 4.1.1: SD-card font selection. Route the picked
2071+
// family name to sdFontFamilyName; keep fontFamily at its
2072+
// current built-in value so the device's font-resolution
2073+
// path knows to consult the SD registry.
2074+
updates.sdFontFamilyName = val.substring(3);
2075+
} else if (key === 'fontFamily' && typeof val === 'string' && val.startsWith('builtin:')) {
2076+
// Built-in font selection. Clear any prior SD selection so
2077+
// the device falls back to the numeric fontFamily enum.
2078+
updates.fontFamily = Number(val.substring(8));
2079+
updates.sdFontFamilyName = '';
2080+
} else {
2081+
updates[key] = Number(val);
2082+
}
20412083
}
20422084
});
20432085
if (dirtyKeys.length === 0) {

0 commit comments

Comments
 (0)