mirror of
https://github.com/pelgraine/Meck.git
synced 2026-03-28 17:42:44 +01:00
fix repeater admin screen timeout buffer t5s3; minor ui fixes web reader screen t5s3
This commit is contained in:
@@ -604,6 +604,49 @@ MyMesh the_mesh(radio_driver, fast_rng, rtc_clock, tables, store
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef MECK_WEB_READER
|
||||
// Web reader: context-dependent taps (VKB for text fields, navigation elsewhere)
|
||||
if (ui_task.isOnWebReader()) {
|
||||
WebReaderScreen* wr = (WebReaderScreen*)ui_task.getWebReaderScreen();
|
||||
if (wr) {
|
||||
if (wr->isReading()) {
|
||||
// Footer zone tap → open link VKB (if links exist)
|
||||
if (vy >= 113 && wr->getLinkCount() > 0) {
|
||||
ui_task.showVirtualKeyboard(VKB_WEB_LINK, "Link #", "", 3);
|
||||
return 0;
|
||||
}
|
||||
return 'd'; // Tap reading area → next page
|
||||
}
|
||||
|
||||
if (wr->isHome()) {
|
||||
int sel = wr->getHomeSelected();
|
||||
if (sel == 1) {
|
||||
// URL bar → open VKB for URL entry
|
||||
ui_task.showVirtualKeyboard(VKB_WEB_URL, "Enter URL",
|
||||
wr->getUrlText(), WEB_MAX_URL_LEN - 1);
|
||||
return 0;
|
||||
}
|
||||
if (sel == 2) {
|
||||
// Search → open VKB for DuckDuckGo search
|
||||
ui_task.showVirtualKeyboard(VKB_WEB_SEARCH, "Search DuckDuckGo", "", 127);
|
||||
return 0;
|
||||
}
|
||||
return KEY_ENTER; // IRC, bookmarks, history: select
|
||||
}
|
||||
|
||||
if (wr->isWifiSetup()) {
|
||||
if (wr->isPasswordEntry()) {
|
||||
// Open VKB for WiFi password entry
|
||||
ui_task.showVirtualKeyboard(VKB_WEB_WIFI_PASS, "WiFi Password", "", 63);
|
||||
return 0;
|
||||
}
|
||||
return KEY_ENTER; // SSID list: select, failed: retry
|
||||
}
|
||||
}
|
||||
return KEY_ENTER;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Channel screen: tap footer area → hop path, tap elsewhere → no action
|
||||
if (ui_task.isOnChannelScreen()) {
|
||||
ChannelScreen* chScr = (ChannelScreen*)ui_task.getChannelScreen();
|
||||
@@ -637,6 +680,24 @@ MyMesh the_mesh(radio_driver, fast_rng, rtc_clock, tables, store
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef MECK_WEB_READER
|
||||
// Web reader: page turn in reading mode, list scroll elsewhere
|
||||
if (ui_task.isOnWebReader()) {
|
||||
WebReaderScreen* wr = (WebReaderScreen*)ui_task.getWebReaderScreen();
|
||||
if (wr && wr->isReading()) {
|
||||
if (horizontal) {
|
||||
return (dx < 0) ? 'd' : 'a'; // swipe left=next page, right=prev
|
||||
}
|
||||
return (dy > 0) ? 'd' : 'a'; // swipe down=next, up=prev
|
||||
}
|
||||
// HOME / WIFI_SETUP / other: vertical swipe = scroll list
|
||||
if (!horizontal) {
|
||||
return (dy > 0) ? 's' : 'w';
|
||||
}
|
||||
return 0; // Ignore horizontal swipes on non-reading modes
|
||||
}
|
||||
#endif
|
||||
|
||||
// Home screen: swipe left = next page, swipe right = previous page
|
||||
if (ui_task.isOnHomeScreen()) {
|
||||
if (horizontal) {
|
||||
@@ -685,6 +746,33 @@ MyMesh the_mesh(radio_driver, fast_rng, rtc_clock, tables, store
|
||||
return KEY_ENTER; // file list: open
|
||||
}
|
||||
|
||||
#ifdef MECK_WEB_READER
|
||||
// Web reader: long press for back navigation
|
||||
if (ui_task.isOnWebReader()) {
|
||||
WebReaderScreen* wr = (WebReaderScreen*)ui_task.getWebReaderScreen();
|
||||
if (wr) {
|
||||
if (wr->isReading()) {
|
||||
return 'b'; // Back to previous page, or HOME if no history
|
||||
}
|
||||
if (wr->isHome()) {
|
||||
int sel = wr->getHomeSelected();
|
||||
int bmEnd = 3 + wr->getBookmarkCount();
|
||||
if (sel >= 3 && sel < bmEnd) {
|
||||
return '\b'; // Long press on bookmark → delete
|
||||
}
|
||||
return 'q'; // All others: exit web reader
|
||||
}
|
||||
if (wr->isWifiSetup()) {
|
||||
return 'q'; // Back from WiFi setup
|
||||
}
|
||||
if (wr->isIRCMode()) {
|
||||
return 'q'; // Back from IRC
|
||||
}
|
||||
}
|
||||
return 'q'; // Default: back out
|
||||
}
|
||||
#endif
|
||||
|
||||
// Channel screen: long press → compose to current channel
|
||||
if (ui_task.isOnChannelScreen()) {
|
||||
uint8_t chIdx = ui_task.getChannelScreenViewIdx();
|
||||
|
||||
@@ -1213,9 +1213,10 @@ inline bool RepeaterAdminScreen::doLogin() {
|
||||
if (the_mesh.uiLoginToRepeater(_contactIdx, _password, timeout_ms)) {
|
||||
_state = STATE_LOGGING_IN;
|
||||
_cmdSentAt = millis();
|
||||
// Add a 1.5s buffer over the mesh estimate; fall back to ADMIN_TIMEOUT_MS
|
||||
// if the estimate came back zero for any reason.
|
||||
_loginTimeoutMs = (timeout_ms > 0) ? timeout_ms + 1500 : ADMIN_TIMEOUT_MS;
|
||||
// Add a 5s buffer over the mesh estimate to account for blocking e-ink
|
||||
// refreshes (FastEPD ~1-2s per frame, VKB dismiss + login render = 2-3 frames).
|
||||
// Fall back to ADMIN_TIMEOUT_MS if the estimate came back zero.
|
||||
_loginTimeoutMs = (timeout_ms > 0) ? timeout_ms + 5000 : ADMIN_TIMEOUT_MS;
|
||||
_waitingForLogin = true;
|
||||
return true;
|
||||
} else {
|
||||
|
||||
@@ -4,6 +4,9 @@
|
||||
#include "NotesScreen.h"
|
||||
#include "RepeaterAdminScreen.h"
|
||||
#include "DiscoveryScreen.h"
|
||||
#ifdef MECK_WEB_READER
|
||||
#include "WebReaderScreen.h"
|
||||
#endif
|
||||
#if HAS_GPS
|
||||
#include "MapScreen.h"
|
||||
#endif
|
||||
@@ -1843,6 +1846,50 @@ void UITask::onVKBSubmit() {
|
||||
if (_screenBeforeVKB) setCurrScreen(_screenBeforeVKB);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#ifdef MECK_WEB_READER
|
||||
case VKB_WEB_URL: {
|
||||
WebReaderScreen* wr = (WebReaderScreen*)getWebReaderScreen();
|
||||
if (wr && strlen(text) > 0) {
|
||||
wr->setUrlText(text); // Copy text + set _urlEditing = true
|
||||
wr->handleInput('\r'); // Triggers auto-prefix + fetch
|
||||
}
|
||||
if (_screenBeforeVKB) setCurrScreen(_screenBeforeVKB);
|
||||
break;
|
||||
}
|
||||
case VKB_WEB_SEARCH: {
|
||||
WebReaderScreen* wr = (WebReaderScreen*)getWebReaderScreen();
|
||||
if (wr && strlen(text) > 0) {
|
||||
wr->setSearchText(text); // Copy text + set _searchEditing = true
|
||||
wr->handleInput('\r'); // Triggers DDG search URL build + fetch
|
||||
}
|
||||
if (_screenBeforeVKB) setCurrScreen(_screenBeforeVKB);
|
||||
break;
|
||||
}
|
||||
case VKB_WEB_WIFI_PASS: {
|
||||
WebReaderScreen* wr = (WebReaderScreen*)getWebReaderScreen();
|
||||
if (wr && strlen(text) > 0) {
|
||||
wr->setWifiPassText(text); // Copy password text
|
||||
wr->handleInput('\r'); // Triggers WiFi connect
|
||||
}
|
||||
if (_screenBeforeVKB) setCurrScreen(_screenBeforeVKB);
|
||||
break;
|
||||
}
|
||||
case VKB_WEB_LINK: {
|
||||
WebReaderScreen* wr = (WebReaderScreen*)getWebReaderScreen();
|
||||
if (wr && strlen(text) > 0) {
|
||||
// Activate link input mode, feed digits, then submit
|
||||
wr->handleInput('l'); // Enter link selection mode
|
||||
for (int i = 0; text[i]; i++) {
|
||||
if (text[i] >= '0' && text[i] <= '9') {
|
||||
wr->handleInput(text[i]);
|
||||
}
|
||||
}
|
||||
wr->handleInput('\r'); // Confirm link number → navigate
|
||||
}
|
||||
if (_screenBeforeVKB) setCurrScreen(_screenBeforeVKB);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
_screenBeforeVKB = nullptr;
|
||||
|
||||
@@ -2754,7 +2754,10 @@ private:
|
||||
display.setCursor(0, footerY);
|
||||
display.setColor(DisplayDriver::YELLOW);
|
||||
#if defined(LilyGo_T5S3_EPaper_Pro)
|
||||
display.print("Swipe:Nav Tap:Select");
|
||||
if (_wifiState == WIFI_ENTERING_PASS)
|
||||
display.print("Tap:Type Pass Hold:Bk");
|
||||
else
|
||||
display.print("Swipe:Nav Tap:Select");
|
||||
#else
|
||||
display.print("Q:Back W/S:Nav Ent:Select");
|
||||
#endif
|
||||
@@ -3142,10 +3145,16 @@ private:
|
||||
char footerBuf[48];
|
||||
#if defined(LilyGo_T5S3_EPaper_Pro)
|
||||
bool onBookmark = (_homeSelected >= 3 && _homeSelected < 3 + (int)_bookmarks.size());
|
||||
if (onBookmark)
|
||||
bool onUrl = (_homeSelected == 1);
|
||||
bool onSearch = (_homeSelected == 2);
|
||||
if (onUrl)
|
||||
snprintf(footerBuf, sizeof(footerBuf), "Tap:Enter URL Hold:Bk");
|
||||
else if (onSearch)
|
||||
snprintf(footerBuf, sizeof(footerBuf), "Tap:Search Hold:Bk");
|
||||
else if (onBookmark)
|
||||
snprintf(footerBuf, sizeof(footerBuf), "Swipe:Nav Tap:Go Hold:Del");
|
||||
else
|
||||
snprintf(footerBuf, sizeof(footerBuf), "Swipe:Nav Tap:Go");
|
||||
snprintf(footerBuf, sizeof(footerBuf), "Swipe:Nav Tap:Go Hold:Bk");
|
||||
#else
|
||||
bool hasData = (_cookieCount > 0 || !_history.empty());
|
||||
bool onBookmark = (_homeSelected >= 3 && _homeSelected < 3 + (int)_bookmarks.size());
|
||||
@@ -3413,12 +3422,10 @@ private:
|
||||
snprintf(linkBuf, sizeof(linkBuf), "#%d_ Ent:Go", _linkInput);
|
||||
hint = linkBuf;
|
||||
#if defined(LilyGo_T5S3_EPaper_Pro)
|
||||
} else if (_formCount > 0 && _linkCount > 0) {
|
||||
hint = "Swipe:Pg Hold:Bk";
|
||||
} else if (_linkCount > 0) {
|
||||
hint = "Swipe:Pg Hold:Bk";
|
||||
hint = "Tap:Pg/Lnk Hold:Bk";
|
||||
} else {
|
||||
hint = "Swipe:Pg Hold:Bk";
|
||||
hint = "Tap:Pg Hold:Bk";
|
||||
}
|
||||
#else
|
||||
} else if (_formCount > 0 && _linkCount > 0) {
|
||||
@@ -5237,6 +5244,33 @@ public:
|
||||
return (_mode == IRC_CHAT && _ircComposing) ||
|
||||
(_mode == IRC_SETUP && _ircSetupEditing);
|
||||
}
|
||||
|
||||
// ---- Accessors for T5S3 touch mapping and VKB integration ----
|
||||
int getHomeSelected() const { return _homeSelected; }
|
||||
int getLinkCount() const { return _linkCount; }
|
||||
int getBookmarkCount() const { return (int)_bookmarks.size(); }
|
||||
const char* getUrlText() const { return _urlBuffer; }
|
||||
|
||||
// Set URL text and activate editing mode (for VKB submit)
|
||||
void setUrlText(const char* text) {
|
||||
strncpy(_urlBuffer, text, WEB_MAX_URL_LEN - 1);
|
||||
_urlBuffer[WEB_MAX_URL_LEN - 1] = '\0';
|
||||
_urlLen = strlen(_urlBuffer);
|
||||
_urlEditing = true;
|
||||
}
|
||||
// Set search text and activate editing mode (for VKB submit)
|
||||
void setSearchText(const char* text) {
|
||||
strncpy(_searchBuffer, text, sizeof(_searchBuffer) - 1);
|
||||
_searchBuffer[sizeof(_searchBuffer) - 1] = '\0';
|
||||
_searchLen = strlen(_searchBuffer);
|
||||
_searchEditing = true;
|
||||
}
|
||||
// Set WiFi password text (for VKB submit)
|
||||
void setWifiPassText(const char* text) {
|
||||
strncpy(_wifiPass, text, WEB_WIFI_PASS_LEN - 1);
|
||||
_wifiPass[WEB_WIFI_PASS_LEN - 1] = '\0';
|
||||
_wifiPassLen = strlen(_wifiPass);
|
||||
}
|
||||
// Returns true if a password reveal is active and needs a refresh after expiry
|
||||
bool needsRevealRefresh() const {
|
||||
if (_formLastCharAt > 0 && (millis() - _formLastCharAt) < 900) {
|
||||
|
||||
@@ -29,7 +29,13 @@ enum VKBPurpose {
|
||||
VKB_ADMIN_CLI, // Repeater admin CLI command
|
||||
VKB_NOTES, // Insert text into notes
|
||||
VKB_SETTINGS_NAME, // Edit node name
|
||||
VKB_WIFI_PASSWORD // WiFi password entry (settings screen)
|
||||
VKB_WIFI_PASSWORD, // WiFi password entry (settings screen)
|
||||
#ifdef MECK_WEB_READER
|
||||
VKB_WEB_URL, // Web reader URL entry
|
||||
VKB_WEB_SEARCH, // Web reader DuckDuckGo search query
|
||||
VKB_WEB_WIFI_PASS, // Web reader WiFi password
|
||||
VKB_WEB_LINK, // Web reader link number entry
|
||||
#endif
|
||||
};
|
||||
|
||||
class VirtualKeyboard {
|
||||
|
||||
Reference in New Issue
Block a user