ESP32: добавить NAV v8 с account и Wi-Fi reconnect

This commit is contained in:
AidarKC
2026-06-09 16:14:24 +04:00
parent e385bb6bf9
commit f4e7210a40
4 changed files with 386 additions and 35 deletions
@@ -25,11 +25,14 @@
#define TAP_CANCEL_THRESHOLD 18
#define MAX_SCAN_RESULTS 8
#define WIFI_CONNECT_TIMEOUT_MS 12000
#define WIFI_RECONNECT_FAST_MS 10000
#define WIFI_RECONNECT_SLOW_MS 30000
#define WIFI_RECONNECT_SLOW_AFTER_MS 90000
#define TEXT_EDIT_PANEL_X 10
#define TEXT_EDIT_PANEL_Y 126
#define TEXT_EDIT_PANEL_Y 112
#define TEXT_EDIT_PANEL_W 460
#define TEXT_EDIT_PANEL_H 344
#define TEST_VERSION "NAV v6"
#define TEXT_EDIT_PANEL_H 330
#define TEST_VERSION "NAV v8"
enum Screen {
SCREEN_HOME,
@@ -37,6 +40,8 @@ enum Screen {
SCREEN_WIFI,
SCREEN_SERVER,
SCREEN_ACCOUNT,
SCREEN_ACCOUNT_SUBSERVER,
SCREEN_ACCOUNT_SECRET,
SCREEN_TEXT_EDIT,
};
@@ -60,6 +65,12 @@ enum ActionId {
ACTION_WIFI_CLEAR,
ACTION_SERVER_EDIT_SOLANA,
ACTION_SERVER_EDIT_SHINE,
ACTION_ACCOUNT_EDIT_LOGIN,
ACTION_ACCOUNT_EDIT_SUBSERVER,
ACTION_ACCOUNT_EDIT_SECRET,
ACTION_ACCOUNT_SUBSERVER_USE_DEFAULT,
ACTION_ACCOUNT_SUBSERVER_EDIT_MANUAL,
ACTION_BACK_ACCOUNT,
ACTION_EDITOR_SAVE,
ACTION_EDITOR_CANCEL,
};
@@ -74,6 +85,8 @@ enum EditContext {
EDIT_CONTEXT_WIFI_PASSWORD,
EDIT_CONTEXT_SOLANA_RPC,
EDIT_CONTEXT_SHINE_SERVER,
EDIT_CONTEXT_LOGIN,
EDIT_CONTEXT_SUBSERVER,
};
enum KeyboardMode {
@@ -118,6 +131,16 @@ static WifiViewMode gWifiViewMode = WIFI_VIEW_OVERVIEW;
static String gSolanaRpcUrl = "https://api.devnet.solana.com";
static String gShineServerUrl = "https://shineup.me";
static String gServerStatusMessage = "Edit RPC or shine host";
static String gLoginValue;
static String gSubserverValue = "subserver1";
static bool gSecretConfigured = false;
static String gAccountStatusMessage = "Edit account fields";
static bool gWifiKnownGood = false;
static bool gWifiReconnectEnabled = false;
static bool gWifiOperationBusy = false;
static unsigned long gWifiDisconnectedSinceMs = 0;
static unsigned long gWifiLastReconnectAttemptMs = 0;
static wl_status_t gLastWifiStatus = WL_IDLE_STATUS;
static EditContext gEditContext = EDIT_CONTEXT_NONE;
static Screen gEditReturnScreen = SCREEN_HOME;
@@ -136,11 +159,14 @@ static void loadPrefs();
static void saveWifiPrefs();
static void clearWifiPrefs();
static void saveServerPrefs();
static void saveAccountPrefs();
static void beginSavedWifi();
static void scanWifiNetworks();
static bool connectWifiNow(const String &ssid, const String &password);
static String wifiHomeStatus();
static String wifiSavedLabel();
static void updateWifiReconnectState();
static void manageWifiReconnect();
static void openEditor(EditContext context,
Screen returnScreen,
const String &title,
@@ -149,6 +175,13 @@ static void openEditor(EditContext context,
bool isPassword);
static void applyEditorValue();
static bool isTextEditKeyboardSwipeArea(int16_t x, int16_t y);
static void syncEditValueFromTextarea();
static void keepCursorAtEnd();
static void restoreTextareaFromEditValue();
static String loginDisplayValue();
static String subserverDisplayValue();
static String homeSecretStatus();
static String secretButtonValue();
static void lvglFlushCb(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *colorP) {
uint32_t w = area->x2 - area->x1 + 1;
@@ -263,13 +296,18 @@ static void showMessageAt(const String &text, lv_coord_t y) {
static void loadPrefs() {
gWifiSavedSsid = gPrefs.getString("wifi_ssid", "");
gWifiSavedPassword = gPrefs.getString("wifi_pass", "");
gWifiKnownGood = gPrefs.getBool("wifi_known_good", false);
gSolanaRpcUrl = gPrefs.getString("solana_rpc", "https://api.devnet.solana.com");
gShineServerUrl = gPrefs.getString("shine_server", "https://shineup.me");
gLoginValue = gPrefs.getString("login", "");
gSubserverValue = gPrefs.getString("subserver", "subserver1");
gSecretConfigured = gPrefs.getBool("secret_set", false);
}
static void saveWifiPrefs() {
gPrefs.putString("wifi_ssid", gWifiSavedSsid);
gPrefs.putString("wifi_pass", gWifiSavedPassword);
gPrefs.putBool("wifi_known_good", gWifiKnownGood);
}
static void saveServerPrefs() {
@@ -277,22 +315,36 @@ static void saveServerPrefs() {
gPrefs.putString("shine_server", gShineServerUrl);
}
static void saveAccountPrefs() {
gPrefs.putString("login", gLoginValue);
gPrefs.putString("subserver", gSubserverValue);
gPrefs.putBool("secret_set", gSecretConfigured);
}
static void clearWifiPrefs() {
gWifiSavedSsid = "";
gWifiSavedPassword = "";
gWifiSelectedSsid = "";
gWifiKnownGood = false;
gWifiReconnectEnabled = false;
gWifiDisconnectedSinceMs = 0;
gWifiLastReconnectAttemptMs = 0;
saveWifiPrefs();
WiFi.disconnect(true, false);
gWifiStatusMessage = "Saved Wi-Fi cleared";
}
static void beginSavedWifi() {
if (gWifiSavedSsid.isEmpty()) {
if (gWifiSavedSsid.isEmpty() || !gWifiKnownGood) {
gWifiReconnectEnabled = false;
return;
}
WiFi.mode(WIFI_STA);
WiFi.begin(gWifiSavedSsid.c_str(), gWifiSavedPassword.c_str());
gWifiReconnectEnabled = true;
gWifiDisconnectedSinceMs = millis();
gWifiLastReconnectAttemptMs = millis();
}
static String wifiHomeStatus() {
@@ -312,9 +364,78 @@ static String wifiSavedLabel() {
return String("Saved: ") + gWifiSavedSsid;
}
static String loginDisplayValue() {
return gLoginValue.isEmpty() ? "login not set" : gLoginValue;
}
static String subserverDisplayValue() {
return gSubserverValue.isEmpty() ? "subserver not set" : gSubserverValue;
}
static String homeSecretStatus() {
return gSecretConfigured ? "" : "secret not set";
}
static String secretButtonValue() {
return gSecretConfigured ? "*****" : "not set";
}
static void updateWifiReconnectState() {
wl_status_t status = WiFi.status();
if (status == WL_CONNECTED) {
if (gLastWifiStatus != WL_CONNECTED) {
gWifiStatusMessage = String("Connected: ") + WiFi.localIP().toString();
}
gWifiDisconnectedSinceMs = 0;
gLastWifiStatus = status;
return;
}
if (gLastWifiStatus == WL_CONNECTED && gWifiReconnectEnabled) {
gWifiDisconnectedSinceMs = millis();
gWifiLastReconnectAttemptMs = 0;
gWifiStatusMessage = "Wi-Fi lost. Reconnecting...";
}
gLastWifiStatus = status;
}
static void manageWifiReconnect() {
updateWifiReconnectState();
if (!gWifiReconnectEnabled || gWifiSavedSsid.isEmpty() || gWifiOperationBusy) {
return;
}
if (WiFi.status() == WL_CONNECTED) {
return;
}
if (gWifiDisconnectedSinceMs == 0) {
gWifiDisconnectedSinceMs = millis();
}
unsigned long disconnectedFor = millis() - gWifiDisconnectedSinceMs;
unsigned long interval = disconnectedFor >= WIFI_RECONNECT_SLOW_AFTER_MS
? WIFI_RECONNECT_SLOW_MS
: WIFI_RECONNECT_FAST_MS;
if (gWifiLastReconnectAttemptMs != 0 &&
millis() - gWifiLastReconnectAttemptMs < interval) {
return;
}
gWifiLastReconnectAttemptMs = millis();
gWifiStatusMessage = disconnectedFor >= WIFI_RECONNECT_SLOW_AFTER_MS
? "Wi-Fi retry every 30s"
: "Wi-Fi retry every 10s";
WiFi.disconnect(false, false);
WiFi.mode(WIFI_STA);
WiFi.begin(gWifiSavedSsid.c_str(), gWifiSavedPassword.c_str());
}
static void scanWifiNetworks() {
gScanResultCount = 0;
gWifiStatusMessage = "Scanning networks...";
gWifiOperationBusy = true;
WiFi.mode(WIFI_STA);
WiFi.disconnect(false, false);
delay(100);
@@ -323,6 +444,7 @@ static void scanWifiNetworks() {
if (found <= 0) {
gWifiStatusMessage = "No networks found";
gWifiViewMode = WIFI_VIEW_OVERVIEW;
gWifiOperationBusy = false;
return;
}
@@ -333,6 +455,7 @@ static void scanWifiNetworks() {
WiFi.scanDelete();
gWifiStatusMessage = String("Found ") + found + " networks";
gWifiViewMode = WIFI_VIEW_SCAN_RESULTS;
gWifiOperationBusy = false;
}
static bool connectWifiNow(const String &ssid, const String &password) {
@@ -340,6 +463,7 @@ static bool connectWifiNow(const String &ssid, const String &password) {
rebuildScreen();
lv_timer_handler();
gWifiOperationBusy = true;
WiFi.mode(WIFI_STA);
WiFi.disconnect(false, false);
delay(150);
@@ -350,8 +474,14 @@ static bool connectWifiNow(const String &ssid, const String &password) {
if (WiFi.status() == WL_CONNECTED) {
gWifiSavedSsid = ssid;
gWifiSavedPassword = password;
gWifiKnownGood = true;
gWifiReconnectEnabled = true;
gWifiDisconnectedSinceMs = 0;
gWifiLastReconnectAttemptMs = 0;
gLastWifiStatus = WL_CONNECTED;
saveWifiPrefs();
gWifiStatusMessage = String("Connected: ") + WiFi.localIP().toString();
gWifiOperationBusy = false;
return true;
}
delay(200);
@@ -359,6 +489,7 @@ static bool connectWifiNow(const String &ssid, const String &password) {
WiFi.disconnect(false, false);
gWifiStatusMessage = "Connection failed";
gWifiOperationBusy = false;
return false;
}
@@ -409,6 +540,24 @@ static void applyEditorValue() {
showScreen(SCREEN_SERVER);
return;
}
if (gEditContext == EDIT_CONTEXT_LOGIN) {
value.trim();
gLoginValue = value;
saveAccountPrefs();
gAccountStatusMessage = gLoginValue.isEmpty() ? "Login cleared" : "Login saved";
showScreen(SCREEN_ACCOUNT);
return;
}
if (gEditContext == EDIT_CONTEXT_SUBSERVER) {
value.trim();
gSubserverValue = value;
saveAccountPrefs();
gAccountStatusMessage = gSubserverValue.isEmpty() ? "Subserver cleared" : "Subserver saved";
showScreen(SCREEN_ACCOUNT);
return;
}
}
static void cancelEditor() {
@@ -419,6 +568,25 @@ static void cancelEditor() {
}
}
static void syncEditValueFromTextarea() {
if (gInputTextArea) {
gEditValue = String(lv_textarea_get_text(gInputTextArea));
}
}
static void keepCursorAtEnd() {
if (gInputTextArea) {
lv_textarea_set_cursor_pos(gInputTextArea, LV_TEXTAREA_CURSOR_LAST);
}
}
static void restoreTextareaFromEditValue() {
if (gInputTextArea) {
lv_textarea_set_text(gInputTextArea, gEditValue.c_str());
keepCursorAtEnd();
}
}
static void networkSelectCb(lv_event_t *event) {
if (lv_event_get_code(event) != LV_EVENT_CLICKED || gBlockClick) {
return;
@@ -450,10 +618,14 @@ static void editorKeyCb(lv_event_t *event) {
if (strcmp(token, "<DEL>") == 0) {
lv_textarea_del_char(gInputTextArea);
syncEditValueFromTextarea();
keepCursorAtEnd();
return;
}
if (strcmp(token, "<CLR>") == 0) {
lv_textarea_set_text(gInputTextArea, "");
syncEditValueFromTextarea();
keepCursorAtEnd();
return;
}
if (strcmp(token, "<SAVE>") == 0) {
@@ -465,12 +637,14 @@ static void editorKeyCb(lv_event_t *event) {
return;
}
if (strcmp(token, "<MODE>") == 0) {
syncEditValueFromTextarea();
gKeyboardMode = (gKeyboardMode == KEYBOARD_MODE_ALPHA) ? KEYBOARD_MODE_SYMBOLS : KEYBOARD_MODE_ALPHA;
gKeyboardPage = 0;
rebuildScreen();
return;
}
if (strcmp(token, "<SHIFT>") == 0) {
syncEditValueFromTextarea();
gKeyboardShift = !gKeyboardShift;
rebuildScreen();
return;
@@ -481,7 +655,10 @@ static void editorKeyCb(lv_event_t *event) {
out.toUpperCase();
}
keepCursorAtEnd();
lv_textarea_add_text(gInputTextArea, out.c_str());
syncEditValueFromTextarea();
keepCursorAtEnd();
}
static void actionButtonCb(lv_event_t *event) {
@@ -504,6 +681,9 @@ static void actionButtonCb(lv_event_t *event) {
case ACTION_OPEN_ACCOUNT:
showScreen(SCREEN_ACCOUNT);
break;
case ACTION_BACK_ACCOUNT:
showScreen(SCREEN_ACCOUNT);
break;
case ACTION_BACK_HOME:
showScreen(SCREEN_HOME);
break;
@@ -524,7 +704,7 @@ static void actionButtonCb(lv_event_t *event) {
openEditor(EDIT_CONTEXT_SOLANA_RPC,
SCREEN_SERVER,
"EDIT SOLANA RPC",
"Cursor starts at the end.",
"",
gSolanaRpcUrl,
false);
break;
@@ -532,10 +712,38 @@ static void actionButtonCb(lv_event_t *event) {
openEditor(EDIT_CONTEXT_SHINE_SERVER,
SCREEN_SERVER,
"EDIT SHINE HOST",
"Cursor starts at the end.",
"",
gShineServerUrl,
false);
break;
case ACTION_ACCOUNT_EDIT_LOGIN:
openEditor(EDIT_CONTEXT_LOGIN,
SCREEN_ACCOUNT,
"EDIT LOGIN",
"",
gLoginValue,
false);
break;
case ACTION_ACCOUNT_EDIT_SUBSERVER:
showScreen(SCREEN_ACCOUNT_SUBSERVER);
break;
case ACTION_ACCOUNT_EDIT_SECRET:
showScreen(SCREEN_ACCOUNT_SECRET);
break;
case ACTION_ACCOUNT_SUBSERVER_USE_DEFAULT:
gSubserverValue = "subserver1";
saveAccountPrefs();
gAccountStatusMessage = "Subserver set to subserver1";
showScreen(SCREEN_ACCOUNT);
break;
case ACTION_ACCOUNT_SUBSERVER_EDIT_MANUAL:
openEditor(EDIT_CONTEXT_SUBSERVER,
SCREEN_ACCOUNT,
"EDIT SUBSERVER",
"",
gSubserverValue,
false);
break;
case ACTION_EDITOR_SAVE:
applyEditorValue();
break;
@@ -569,6 +777,9 @@ static lv_obj_t *makeButton(const char *text,
lv_obj_t *label = lv_label_create(btn);
lv_label_set_text(label, text);
lv_obj_set_width(label, w - 24);
lv_obj_set_style_text_align(label, LV_TEXT_ALIGN_CENTER, 0);
lv_label_set_long_mode(label, LV_LABEL_LONG_WRAP);
lv_obj_set_style_text_font(label, font, 0);
lv_obj_set_style_text_color(label, lv_color_hex(0xFFFFFF), 0);
lv_obj_center(label);
@@ -622,17 +833,25 @@ static void drawHome() {
setRootStyle();
lv_obj_t *login = lv_label_create(gRoot);
lv_label_set_text(login, "login");
lv_label_set_text(login, loginDisplayValue().c_str());
lv_obj_set_style_text_font(login, &lv_font_montserrat_18, 0);
lv_obj_set_style_text_color(login, lv_color_hex(0xFFFFFF), 0);
lv_obj_align(login, LV_ALIGN_TOP_LEFT, 24, 18);
lv_obj_t *subserver = lv_label_create(gRoot);
lv_label_set_text(subserver, "subserver1");
lv_label_set_text(subserver, subserverDisplayValue().c_str());
lv_obj_set_style_text_font(subserver, &lv_font_montserrat_18, 0);
lv_obj_set_style_text_color(subserver, lv_color_hex(0xD5DEE7), 0);
lv_obj_align_to(subserver, login, LV_ALIGN_OUT_BOTTOM_LEFT, 0, 6);
if (!gSecretConfigured) {
lv_obj_t *secret = lv_label_create(gRoot);
lv_label_set_text(secret, homeSecretStatus().c_str());
lv_obj_set_style_text_font(secret, &lv_font_montserrat_16, 0);
lv_obj_set_style_text_color(secret, lv_color_hex(0xB8C6D3), 0);
lv_obj_align_to(secret, subserver, LV_ALIGN_OUT_BOTTOM_LEFT, 0, 6);
}
makeTopIcons();
makeTitle("STATUS", 150, &lv_font_montserrat_28);
showMessageAt(wifiHomeStatus(), 204);
@@ -747,10 +966,38 @@ static void drawServerScreen() {
static void drawAccountScreen() {
setRootStyle();
makeTitle("ACCOUNT", 56, &lv_font_montserrat_28);
makeBody("Account screen", 132, 400);
makeBody("Swipe right to return to Settings.", 204, 400);
makeButton("BACK", 140, 344, 200, 72, 0x5A6570, ACTION_BACK_SETTINGS, &lv_font_montserrat_22);
makeTitle("ACCOUNT", 18, &lv_font_montserrat_24);
showMessageAt(gAccountStatusMessage, 56);
String loginButton = String("Login (") + (gLoginValue.isEmpty() ? "not set" : gLoginValue) + ")";
String subserverButton = String("Subserver (") + (gSubserverValue.isEmpty() ? "not set" : gSubserverValue) + ")";
String secretButton = String("Secret (") + secretButtonValue() + ")";
makeButton(loginButton.c_str(), 22, 118, 436, 84, 0x355C7D, ACTION_ACCOUNT_EDIT_LOGIN, &lv_font_montserrat_20);
makeButton(subserverButton.c_str(), 22, 222, 436, 84, 0x355C7D, ACTION_ACCOUNT_EDIT_SUBSERVER, &lv_font_montserrat_20);
makeButton(secretButton.c_str(), 22, 326, 436, 84, 0x355C7D, ACTION_ACCOUNT_EDIT_SECRET, &lv_font_montserrat_20);
makeBody("Swipe right to return to Settings.", 420, 420);
makeVersionTag();
}
static void drawAccountSubserverScreen() {
setRootStyle();
makeTitle("SUBSERVER", 18, &lv_font_montserrat_24);
showMessageAt(String("Current: ") + subserverDisplayValue(), 56);
makeBody("If you only use one subserver, keep the default name subserver1.", 98, 420);
makeButton("USE SUBSERVER1", 22, 202, 436, 84, 0x2A9D8F, ACTION_ACCOUNT_SUBSERVER_USE_DEFAULT, &lv_font_montserrat_22);
makeButton("EDIT MANUALLY", 22, 306, 436, 84, 0x355C7D, ACTION_ACCOUNT_SUBSERVER_EDIT_MANUAL, &lv_font_montserrat_22);
makeButton("BACK", 140, 402, 200, 54, 0x5A6570, ACTION_BACK_ACCOUNT, &lv_font_montserrat_20);
makeVersionTag();
}
static void drawAccountSecretScreen() {
setRootStyle();
makeTitle("SECRET", 18, &lv_font_montserrat_24);
showMessageAt(String("Status: ") + (gSecretConfigured ? "set" : "not set"), 56);
makeBody("Secret setup is not implemented yet.", 116, 420);
makeButton("BACK", 140, 360, 200, 72, 0x5A6570, ACTION_BACK_ACCOUNT, &lv_font_montserrat_22);
makeVersionTag();
}
@@ -788,14 +1035,14 @@ static void drawTextEditorKeyboard(lv_coord_t originY) {
static const char *symRightRow1[] = {"?", "&", "=", "+", "-"};
static const char *symRightRow2[] = {"%", "#", "~", ":", "/"};
const lv_coord_t keyH = 50;
const lv_coord_t keyH = 62;
const lv_coord_t keyW5 = 84;
const lv_coord_t keyW4 = 104;
const lv_coord_t keyW4 = 84;
const lv_coord_t gap = 8;
const lv_coord_t row0Y = originY;
const lv_coord_t row1Y = originY + 58;
const lv_coord_t row2Y = originY + 116;
const lv_coord_t row3Y = originY + 180;
const lv_coord_t row1Y = originY + 68;
const lv_coord_t row2Y = originY + 136;
const lv_coord_t row3Y = originY + 208;
const bool uppercase = gKeyboardMode == KEYBOARD_MODE_ALPHA && gKeyboardShift;
if (gKeyboardMode == KEYBOARD_MODE_ALPHA) {
@@ -820,11 +1067,11 @@ static void drawTextEditorKeyboard(lv_coord_t originY) {
}
}
makeKeyboardButton(gKeyboardMode == KEYBOARD_MODE_ALPHA ? "123" : "ABC", "<MODE>", 20, row3Y, 88, 54, 0x5C6F82, &lv_font_montserrat_18);
makeKeyboardButton(gKeyboardShift ? "SHIFT*" : "SHIFT", "<SHIFT>", 116, row3Y, 88, 54, 0x7A5C9B, &lv_font_montserrat_16);
makeKeyboardButton("DEL", "<DEL>", 212, row3Y, 76, 54, 0x7D3A3A, &lv_font_montserrat_18);
makeKeyboardButton("SAVE", "<SAVE>", 296, row3Y, 76, 54, 0x2A9D8F, &lv_font_montserrat_18);
makeKeyboardButton("CANCEL", "<CANCEL>", 380, row3Y, 80, 54, 0x5A6570, &lv_font_montserrat_16);
makeKeyboardButton(gKeyboardMode == KEYBOARD_MODE_ALPHA ? "123" : "ABC", "<MODE>", 20, row3Y, 88, 64, 0x5C6F82, &lv_font_montserrat_18);
makeKeyboardButton(gKeyboardShift ? "SHIFT*" : "SHIFT", "<SHIFT>", 116, row3Y, 88, 64, 0x7A5C9B, &lv_font_montserrat_16);
makeKeyboardButton("DEL", "<DEL>", 212, row3Y, 76, 64, 0x7D3A3A, &lv_font_montserrat_18);
makeKeyboardButton("SAVE", "<SAVE>", 296, row3Y, 76, 64, 0x2A9D8F, &lv_font_montserrat_18);
makeKeyboardButton("CANCEL", "<CANCEL>", 380, row3Y, 80, 64, 0x5A6570, &lv_font_montserrat_16);
}
static void drawTextEditScreen() {
@@ -839,13 +1086,21 @@ static void drawTextEditScreen() {
lv_textarea_set_one_line(gInputTextArea, true);
lv_textarea_set_text(gInputTextArea, gEditValue.c_str());
lv_textarea_set_cursor_pos(gInputTextArea, LV_TEXTAREA_CURSOR_LAST);
lv_textarea_set_password_mode(gInputTextArea, gEditIsPassword);
lv_textarea_set_password_mode(gInputTextArea, false);
lv_textarea_set_cursor_click_pos(gInputTextArea, false);
lv_textarea_set_text_selection(gInputTextArea, false);
lv_obj_set_style_text_font(gInputTextArea, &lv_font_montserrat_18, 0);
lv_obj_set_style_bg_color(gInputTextArea, lv_color_hex(0x132131), 0);
lv_obj_set_style_text_color(gInputTextArea, lv_color_hex(0xFFFFFF), 0);
lv_obj_set_style_border_color(gInputTextArea, lv_color_hex(0x6E8AA3), 0);
lv_obj_set_style_border_width(gInputTextArea, 2, 0);
lv_obj_set_style_bg_opa(gInputTextArea, LV_OPA_TRANSP, LV_PART_CURSOR);
lv_obj_set_style_border_opa(gInputTextArea, LV_OPA_TRANSP, LV_PART_CURSOR);
lv_obj_set_style_outline_opa(gInputTextArea, LV_OPA_TRANSP, LV_PART_CURSOR);
lv_obj_set_style_pad_left(gInputTextArea, 12, 0);
lv_obj_set_style_pad_right(gInputTextArea, 12, 0);
lv_obj_add_state(gInputTextArea, LV_STATE_FOCUSED);
restoreTextareaFromEditValue();
lv_obj_t *panel = lv_obj_create(gRoot);
lv_obj_set_size(panel, TEXT_EDIT_PANEL_W, TEXT_EDIT_PANEL_H);
@@ -857,7 +1112,7 @@ static void drawTextEditScreen() {
lv_obj_set_style_border_color(panel, lv_color_hex(0x2E455A), 0);
lv_obj_clear_flag(panel, LV_OBJ_FLAG_SCROLLABLE);
drawTextEditorKeyboard(TEXT_EDIT_PANEL_Y + 10);
drawTextEditorKeyboard(TEXT_EDIT_PANEL_Y + 8);
makeVersionTag();
}
@@ -885,6 +1140,12 @@ static void rebuildScreen() {
case SCREEN_ACCOUNT:
drawAccountScreen();
break;
case SCREEN_ACCOUNT_SUBSERVER:
drawAccountSubserverScreen();
break;
case SCREEN_ACCOUNT_SECRET:
drawAccountSecretScreen();
break;
case SCREEN_TEXT_EDIT:
drawTextEditScreen();
break;
@@ -945,10 +1206,17 @@ static void handleAccountSwipe(SwipeDirection swipe) {
}
}
static void handleAccountSubscreenSwipe(SwipeDirection swipe) {
if (swipe == SWIPE_RIGHT) {
showScreen(SCREEN_ACCOUNT);
}
}
static void handleTextEditSwipe(SwipeDirection swipe) {
if (!isTextEditKeyboardSwipeArea(gTouchStartX, gTouchStartY)) {
return;
}
syncEditValueFromTextarea();
if (swipe == SWIPE_LEFT) {
gKeyboardPage = min(gKeyboardPage + 1, 1);
rebuildScreen();
@@ -986,6 +1254,10 @@ static void handleSwipe(SwipeDirection swipe) {
case SCREEN_ACCOUNT:
handleAccountSwipe(swipe);
break;
case SCREEN_ACCOUNT_SUBSERVER:
case SCREEN_ACCOUNT_SECRET:
handleAccountSubscreenSwipe(swipe);
break;
case SCREEN_TEXT_EDIT:
handleTextEditSwipe(swipe);
break;
@@ -1010,6 +1282,7 @@ void setup() {
gPrefs.begin("shine-nav-ui", false);
loadPrefs();
beginSavedWifi();
gLastWifiStatus = WiFi.status();
lv_init();
@@ -1047,6 +1320,7 @@ void setup() {
void loop() {
lv_timer_handler();
manageWifiReconnect();
if (gPendingSwipe != SWIPE_NONE) {
SwipeDirection swipe = gPendingSwipe;