mod: Phase 2a - add mod settings, I18n strings, and main.cpp integration

CrossPointSettings: Add mod-specific enums and fields:
- Clock: CLOCK_FORMAT, CLOCK_SIZE, TIMEZONE, clockFormat, clockSize,
  timezone, timezoneOffsetHours, autoNtpSync
- Sleep: SLEEP_SCREEN_LETTERBOX_FILL, sleepScreenLetterboxFill
- Reader: preferredPortrait, preferredLandscape
- Indexing: INDEXING_DISPLAY, indexingDisplay
- getTimezonePosixStr() for POSIX TZ string generation

main.cpp: Integrate mod initialization:
- OPDS store loading, boot NTP sync, timezone application
- Clock refresh loop (re-render on minute change)
- RTC time logging on boot

SettingsList.h: Add clock, timezone, and letterbox fill settings
JsonSettingsIO.cpp: Handle int8_t timezoneOffsetHours separately
I18n: Add ~80 mod string keys (english.yaml + regenerated I18nKeys.h)

Made-with: Cursor
This commit is contained in:
cottongin
2026-03-07 15:14:35 -05:00
parent dfbc931c14
commit 66a754dabd
6 changed files with 232 additions and 0 deletions

View File

@@ -12,17 +12,21 @@
#include <SPI.h>
#include <builtinFonts/all.h>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include "CrossPointSettings.h"
#include "CrossPointState.h"
#include "KOReaderCredentialStore.h"
#include "MappedInputManager.h"
#include "OpdsServerStore.h"
#include "RecentBooksStore.h"
#include "activities/Activity.h"
#include "activities/ActivityManager.h"
#include "components/UITheme.h"
#include "fontIds.h"
#include "util/BootNtpSync.h"
#include "util/ButtonNavigator.h"
#include "util/ScreenshotUtil.h"
@@ -255,8 +259,15 @@ void setup() {
HalSystem::clearPanic(); // TODO: move this to an activity when we have one to display the panic info
SETTINGS.loadFromFile();
// Apply saved timezone setting on boot
setenv("TZ", SETTINGS.getTimezonePosixStr(), 1);
tzset();
I18N.loadSettings();
KOREADER_STORE.loadFromFile();
OPDS_STORE.loadFromFile();
BootNtpSync::start();
UITheme::getInstance().reload();
ButtonNavigator::setMappedInputManager(mappedInputManager);
@@ -281,6 +292,18 @@ void setup() {
// First serial output only here to avoid timing inconsistencies for power button press duration verification
LOG_DBG("MAIN", "Starting CrossPoint version " CROSSPOINT_VERSION);
// Log RTC time on boot for debugging
{
time_t now = time(nullptr);
struct tm* t = localtime(&now);
if (t != nullptr && t->tm_year > 100) {
LOG_DBG("MAIN", "RTC time: %04d-%02d-%02d %02d:%02d:%02d", t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
t->tm_hour, t->tm_min, t->tm_sec);
} else {
LOG_DBG("MAIN", "RTC time not set (epoch)");
}
}
setupDisplayAndFonts();
activityManager.goToBoot();
@@ -376,6 +399,28 @@ void loop() {
return;
}
// Refresh screen when the displayed minute changes (clock in header)
if (SETTINGS.clockFormat != CrossPointSettings::CLOCK_OFF) {
static int lastRenderedMinute = -1;
static bool sawInvalidTime = false;
time_t now = time(nullptr);
struct tm* t = localtime(&now);
if (t != nullptr && t->tm_year > 100) {
const int currentMinute = t->tm_hour * 60 + t->tm_min;
if (lastRenderedMinute < 0) {
lastRenderedMinute = currentMinute;
if (sawInvalidTime) {
activityManager.requestUpdate();
}
} else if (currentMinute != lastRenderedMinute) {
activityManager.requestUpdate();
lastRenderedMinute = currentMinute;
}
} else {
sawInvalidTime = true;
}
}
const unsigned long activityStartTime = millis();
activityManager.loop();
const unsigned long activityDuration = millis() - activityStartTime;