1
0
forked from iarv/Meck

Fixed accidental regressions caused by commit f0dc218 and minor bug fixes

This commit is contained in:
pelgraine
2026-02-11 11:34:12 +11:00
parent fa747bfce2
commit 6c3fb569f4
4 changed files with 103 additions and 97 deletions

View File

@@ -72,11 +72,6 @@
/* -------------------------------------------------------------------------------------- */
// SD-backed settings persistence (defined in main.cpp for T-Deck Pro)
#if defined(LilyGo_TDeck_Pro) && defined(HAS_SDCARD)
extern void backupSettingsToSD();
#endif
#define REQ_TYPE_GET_STATUS 0x01 // same as _GET_STATS
#define REQ_TYPE_KEEP_ALIVE 0x02
#define REQ_TYPE_GET_TELEMETRY_DATA 0x03
@@ -174,12 +169,7 @@ protected:
}
public:
void savePrefs() {
_store->savePrefs(_prefs, sensors.node_lat, sensors.node_lon);
#if defined(LilyGo_TDeck_Pro) && defined(HAS_SDCARD)
backupSettingsToSD();
#endif
}
void savePrefs() { _store->savePrefs(_prefs, sensors.node_lat, sensors.node_lon); }
void saveChannels() {
_store->saveChannels(this);
#if defined(LilyGo_TDeck_Pro) && defined(HAS_SDCARD)

View File

@@ -13,6 +13,7 @@
#include "TextReaderScreen.h"
#include "ContactsScreen.h"
#include "ChannelScreen.h"
#include "SettingsScreen.h"
extern SPIClass displaySpi; // From GxEPDDisplay.cpp, shared SPI bus
TCA8418Keyboard keyboard(I2C_ADDR_KEYBOARD, &Wire);
@@ -512,6 +513,23 @@ void setup() {
}
#endif
// ---------------------------------------------------------------------------
// First-boot onboarding detection
// Check if node name is still the default hex prefix (first 4 bytes of pub key)
// If so, launch onboarding wizard to set name and radio preset
// ---------------------------------------------------------------------------
#if defined(LilyGo_TDeck_Pro)
{
char defaultName[10];
mesh::Utils::toHex(defaultName, the_mesh.self_id.pub_key, 4);
NodePrefs* prefs = the_mesh.getNodePrefs();
if (strcmp(prefs->node_name, defaultName) == 0) {
MESH_DEBUG_PRINTLN("setup() - Default node name detected, launching onboarding");
ui_task.gotoOnboarding();
}
}
#endif
// GPS duty cycle — honour saved pref, default to enabled on first boot
#if HAS_GPS
{
@@ -787,20 +805,28 @@ void handleKeyboardInput() {
return;
}
// C key: allow entering compose mode from reader
if (key == 'c' || key == 'C') {
composeDM = false;
composeDMContactIdx = -1;
composeMode = true;
composeBuffer[0] = '\0';
composePos = 0;
Serial.printf("Entering compose mode from reader, channel %d\n", composeChannelIdx);
drawComposeScreen();
lastComposeRefresh = millis();
// All other keys pass through to the reader screen
ui_task.injectKey(key);
return;
}
// *** SETTINGS MODE ***
if (ui_task.isOnSettingsScreen()) {
SettingsScreen* settings = (SettingsScreen*)ui_task.getSettingsScreen();
// Q key: exit settings (when not editing)
if (!settings->isEditing() && (key == 'q' || key == 'Q')) {
if (settings->hasRadioChanges()) {
// Let settings show "apply changes?" confirm dialog
ui_task.injectKey(key);
} else {
Serial.println("Exiting settings");
ui_task.gotoHomeScreen();
}
return;
}
// All other keys pass through to the reader screen
// All other keys → settings screen via injectKey
ui_task.injectKey(key);
return;
}
@@ -809,36 +835,9 @@ void handleKeyboardInput() {
switch (key) {
case 'c':
case 'C':
// Enter compose mode - DM if on contacts screen, channel otherwise
if (ui_task.isOnContactsScreen()) {
ContactsScreen* cs = (ContactsScreen*)ui_task.getContactsScreen();
int idx = cs->getSelectedContactIdx();
uint8_t ctype = cs->getSelectedContactType();
if (idx >= 0 && ctype == ADV_TYPE_CHAT) {
composeDM = true;
composeDMContactIdx = idx;
cs->getSelectedContactName(composeDMName, sizeof(composeDMName));
composeMode = true;
composeBuffer[0] = '\0';
composePos = 0;
Serial.printf("Entering DM compose to %s (idx %d)\n", composeDMName, idx);
drawComposeScreen();
lastComposeRefresh = millis();
}
} else {
composeDM = false;
composeDMContactIdx = -1;
composeMode = true;
composeBuffer[0] = '\0';
composePos = 0;
// If on channel screen, sync compose channel with viewed channel
if (ui_task.isOnChannelScreen()) {
composeChannelIdx = ui_task.getChannelScreenViewIdx();
}
Serial.printf("Entering compose mode, channel %d\n", composeChannelIdx);
drawComposeScreen();
lastComposeRefresh = millis();
}
// Open contacts list
Serial.println("Opening contacts");
ui_task.gotoContactsScreen();
break;
case 'm':
@@ -848,20 +847,24 @@ void handleKeyboardInput() {
ui_task.gotoChannelScreen();
break;
case 'r':
case 'R':
// Open text reader
case 'e':
case 'E':
// Open text reader (ebooks)
Serial.println("Opening text reader");
ui_task.gotoTextReader();
break;
case 'n':
case 'N':
// Open contacts list
Serial.println("Opening contacts");
ui_task.gotoContactsScreen();
case 's':
case 'S':
// Open settings (from home), or navigate down on channel/contacts
if (ui_task.isOnChannelScreen() || ui_task.isOnContactsScreen()) {
ui_task.injectKey('s'); // Pass directly for channel/contacts scrolling
} else {
Serial.println("Opening settings");
ui_task.gotoSettingsScreen();
}
break;
case 'w':
case 'W':
// Navigate up/previous (scroll on channel screen)
@@ -872,17 +875,6 @@ void handleKeyboardInput() {
ui_task.injectKey(0xF2); // KEY_PREV
}
break;
case 's':
case 'S':
// Navigate down/next (scroll on channel screen)
if (ui_task.isOnChannelScreen() || ui_task.isOnContactsScreen()) {
ui_task.injectKey('s'); // Pass directly for channel/contacts switching
} else {
Serial.println("Nav: Next");
ui_task.injectKey(0xF1); // KEY_NEXT
}
break;
case 'a':
case 'A':
@@ -907,7 +899,7 @@ void handleKeyboardInput() {
break;
case '\r':
// Select/Enter - if on contacts screen, enter DM compose for chat contacts
// Enter = compose (only from channel or contacts screen)
if (ui_task.isOnContactsScreen()) {
ContactsScreen* cs = (ContactsScreen*)ui_task.getContactsScreen();
int idx = cs->getSelectedContactIdx();
@@ -923,12 +915,21 @@ void handleKeyboardInput() {
drawComposeScreen();
lastComposeRefresh = millis();
} else if (idx >= 0) {
// Non-chat contact selected (repeater, room, etc.) - future use
Serial.printf("Selected non-chat contact type=%d idx=%d\n", ctype, idx);
}
} else if (ui_task.isOnChannelScreen()) {
composeDM = false;
composeDMContactIdx = -1;
composeChannelIdx = ui_task.getChannelScreenViewIdx();
composeMode = true;
composeBuffer[0] = '\0';
composePos = 0;
Serial.printf("Entering compose mode, channel %d\n", composeChannelIdx);
drawComposeScreen();
lastComposeRefresh = millis();
} else {
Serial.println("Nav: Enter/Select");
ui_task.injectKey(13); // KEY_ENTER
// Other screens: pass Enter as generic select
ui_task.injectKey(13);
}
break;
@@ -939,12 +940,6 @@ void handleKeyboardInput() {
Serial.println("Nav: Back to home");
ui_task.gotoHomeScreen();
break;
case 'u':
case 'U':
// Forward to UI for UTC offset editor on GPS page
ui_task.injectKey('u');
break;
case ' ':
// Space - also acts as next/select
@@ -1099,9 +1094,9 @@ void drawEmojiPicker() {
void sendComposedMessage() {
if (composePos == 0) return;
cpuPower.setBoost(); // Boost CPU for crypto + radio TX
cpuPower.setBoost(); // Boost CPU for crypto + radio TX
// Convert escape bytes back to UTF-8 for mesh transmission and BLE app
char utf8Buf[512];
emojiUnescape(composeBuffer, utf8Buf, sizeof(utf8Buf));

View File

@@ -603,7 +603,7 @@ private:
_currentPage = cache->lastReadPage;
}
// Already fully indexed open immediately
// Already fully indexed — open immediately
if (cache->fullyIndexed) {
_totalPages = _pagePositions.size();
_mode = READING;
@@ -613,7 +613,7 @@ private:
return;
}
// Partially indexed finish indexing with splash
// Partially indexed — finish indexing with splash
Serial.printf("TextReader: Finishing index for %s (have %d pages so far)\n",
actualFilename.c_str(), (int)_pagePositions.size());
@@ -629,7 +629,7 @@ private:
drawSplash("Indexing...", "Please wait", shortName);
if (_pagePositions.empty()) {
// Cache had no pages (e.g. dummy entry) full index from scratch
// Cache had no pages (e.g. dummy entry) — full index from scratch
_pagePositions.push_back(0);
indexPagesWordWrap(_file, 0, _pagePositions,
_linesPerPage, _charsPerLine, 0);
@@ -639,7 +639,7 @@ private:
_linesPerPage, _charsPerLine, 0);
}
} else {
// No cache full index from scratch
// No cache — full index from scratch
Serial.printf("TextReader: Full index for %s\n", actualFilename.c_str());
char shortName[28];
@@ -878,9 +878,8 @@ private:
display.drawRect(0, footerY - 2, display.width(), 1);
display.setColor(DisplayDriver::YELLOW);
char status[30];
int pct = _totalPages > 1 ? (_currentPage * 100) / (_totalPages - 1) : 100;
sprintf(status, "%d/%d %d%%", _currentPage + 1, _totalPages, pct);
char status[20];
sprintf(status, "%d/%d", _currentPage + 1, _totalPages);
display.setCursor(0, footerY);
display.print(status);
@@ -997,7 +996,7 @@ public:
// --- Pass 1: Fast cache load (no per-file splash screens) ---
// Try to load existing .idx files from SD for every file.
// This is just SD reads no indexing, no e-ink refreshes.
// This is just SD reads — no indexing, no e-ink refreshes.
_fileCache.clear();
_fileCache.resize(_fileList.size()); // Pre-allocate slots to maintain alignment with _fileList
@@ -1026,7 +1025,7 @@ public:
// Skip files that loaded from cache
if (_fileCache[i].filename.length() > 0) continue;
// Skip .epub files they'll be converted on first open via openBook()
// Skip .epub files — they'll be converted on first open via openBook()
if (_fileList[i].endsWith(".epub") || _fileList[i].endsWith(".EPUB")) {
needsIndexCount--; // Don't count epubs in progress display
continue;

View File

@@ -34,6 +34,7 @@
#include "ChannelScreen.h"
#include "ContactsScreen.h"
#include "TextReaderScreen.h"
#include "SettingsScreen.h"
class SplashScreen : public UIScreen {
UITask* _task;
@@ -372,7 +373,7 @@ public:
display.drawTextRightAlign(display.width()-1, y, buf);
y = y + 12;
// NMEA sentence counter confirms baud rate and data flow
// NMEA sentence counter — confirms baud rate and data flow
display.drawTextLeftAlign(0, y, "sentences");
if (gpsDuty.isHardwareOn()) {
uint16_t sps = gpsStream.getSentencesPerSec();
@@ -746,6 +747,7 @@ void UITask::begin(DisplayDriver* display, SensorManager* sensors, NodePrefs* no
channel_screen = new ChannelScreen(this, &rtc_clock);
contacts_screen = new ContactsScreen(this, &rtc_clock);
text_reader = new TextReaderScreen(this);
settings_screen = new SettingsScreen(this, &rtc_clock, node_prefs);
setCurrScreen(splash);
}
@@ -1078,13 +1080,13 @@ void UITask::toggleGPS() {
if (_sensors != NULL) {
if (_node_prefs->gps_enabled) {
// Disable GPS cut hardware power
// Disable GPS — cut hardware power
_sensors->setSettingValue("gps", "0");
_node_prefs->gps_enabled = 0;
gpsDuty.disable();
notify(UIEventType::ack);
} else {
// Enable GPS start duty cycle
// Enable GPS — start duty cycle
_sensors->setSettingValue("gps", "1");
_node_prefs->gps_enabled = 1;
gpsDuty.enable();
@@ -1182,6 +1184,26 @@ void UITask::gotoTextReader() {
_next_refresh = 100;
}
void UITask::gotoSettingsScreen() {
((SettingsScreen *) settings_screen)->enter();
setCurrScreen(settings_screen);
if (_display != NULL && !_display->isOn()) {
_display->turnOn();
}
_auto_off = millis() + AUTO_OFF_MILLIS;
_next_refresh = 100;
}
void UITask::gotoOnboarding() {
((SettingsScreen *) settings_screen)->enterOnboarding();
setCurrScreen(settings_screen);
if (_display != NULL && !_display->isOn()) {
_display->turnOn();
}
_auto_off = millis() + AUTO_OFF_MILLIS;
_next_refresh = 100;
}
uint8_t UITask::getChannelScreenViewIdx() const {
return ((ChannelScreen *) channel_screen)->getViewChannelIdx();
}