#include "ClockSyncActivity.h" #include #include #include #include #include #include #include "CrossPointSettings.h" #include "MappedInputManager.h" #include "components/UITheme.h" #include "fontIds.h" void ClockSyncActivity::onEnter() { Activity::onEnter(); state = SYNCING; syncedTime[0] = '\0'; requestUpdate(); } void ClockSyncActivity::onExit() { Activity::onExit(); } void ClockSyncActivity::runSync() { if (WiFi.status() != WL_CONNECTED) { LOG_INF("CLK", "Manual sync requested but WiFi is not connected"); state = NO_WIFI; requestUpdate(); return; } const bool ok = halClock.syncFromNTP(); if (!ok) { state = FAILED; requestUpdate(); return; } // Mark as synced so the auto-sync hook stops firing on future WiFi connects. SETTINGS.clockHasBeenSynced = 1; SETTINGS.saveToFile(); // Read the freshly synced time back for the user-facing confirmation. char buf[9]; if (halClock.formatTime(buf, sizeof(buf), SETTINGS.clockUtcOffsetQ, SETTINGS.clockFormat == 1)) { snprintf(syncedTime, sizeof(syncedTime), "%s", buf); } state = SUCCESS; requestUpdate(); } void ClockSyncActivity::loop() { if (state == SYNCING) { // First-tick: render the "Syncing..." screen, then perform the (blocking) sync. // requestUpdateAndWait below forces the render before we block on WiFi. requestUpdateAndWait(); runSync(); return; } if (mappedInput.wasPressed(MappedInputManager::Button::Back) || mappedInput.wasPressed(MappedInputManager::Button::Confirm)) { finish(); return; } int tapX = 0; int tapY = 0; if (mappedInput.wasScreenTapped(tapX, tapY)) { finish(); } } void ClockSyncActivity::render(RenderLock&&) { const auto& metrics = UITheme::getInstance().getMetrics(); const auto pageWidth = renderer.getScreenWidth(); const auto pageHeight = renderer.getScreenHeight(); renderer.clearScreen(); GUI.drawHeader(renderer, Rect{0, metrics.topPadding, pageWidth, metrics.headerHeight}, tr(STR_CLOCK_SYNC)); const int midY = pageHeight / 2; switch (state) { case SYNCING: renderer.drawCenteredText(UI_12_FONT_ID, midY, tr(STR_CLOCK_SYNCING)); break; case SUCCESS: { renderer.drawCenteredText(UI_12_FONT_ID, midY - 20, tr(STR_CLOCK_SYNC_OK), true, EpdFontFamily::BOLD); if (syncedTime[0] != '\0') { char line[32]; snprintf(line, sizeof(line), "%s %s", tr(STR_CURRENT_TIME), syncedTime); renderer.drawCenteredText(UI_10_FONT_ID, midY + 10, line); } break; } case NO_WIFI: renderer.drawCenteredText(UI_12_FONT_ID, midY - 20, tr(STR_CLOCK_SYNC_NO_WIFI), true, EpdFontFamily::BOLD); renderer.drawCenteredText(UI_10_FONT_ID, midY + 10, tr(STR_CLOCK_SYNC_NO_WIFI_HINT)); break; case FAILED: renderer.drawCenteredText(UI_12_FONT_ID, midY - 20, tr(STR_CLOCK_SYNC_FAIL), true, EpdFontFamily::BOLD); renderer.drawCenteredText(UI_10_FONT_ID, midY + 10, tr(STR_CHECK_SERIAL_OUTPUT)); break; } if (state != SYNCING) { const auto labels = mappedInput.mapLabels(tr(STR_BACK), tr(STR_OK_BUTTON), "", ""); GUI.drawButtonHints(renderer, labels.btn1, labels.btn2, labels.btn3, labels.btn4); } renderer.displayBuffer(); }