feat: Connect to last wifi by default (#752)
## Summary * **What is the goal of this PR?** Use last connected network as default * **What changes are included?** - Refactor how an action type of Settings are handled - Add a new System Settings option → Network - Add the ability to forget a network in the Network Selection Screen - Add the ability to Refresh network list - Save the last connected network SSID - Use the last connection whenever network is needed (OPDS, Koreader sync, update etc) ## Additional Context * Add any other information that might be helpful for the reviewer (e.g., performance implications, potential risks, specific areas to focus on).   https://github.com/user-attachments/assets/95bf34a8-44ce-4279-8cd8-f78524ce745b --- ### AI Usage Did you use AI tools to help write this code? _** PARTIALLY: I wrote most of it but I also used Gemini as assist. --------- Co-authored-by: Eliz Kilic <elizk@google.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -9,7 +9,7 @@ WifiCredentialStore WifiCredentialStore::instance;
|
||||
|
||||
namespace {
|
||||
// File format version
|
||||
constexpr uint8_t WIFI_FILE_VERSION = 1;
|
||||
constexpr uint8_t WIFI_FILE_VERSION = 2; // Increased version
|
||||
|
||||
// WiFi credentials file path
|
||||
constexpr char WIFI_FILE[] = "/.crosspoint/wifi.bin";
|
||||
@@ -38,6 +38,7 @@ bool WifiCredentialStore::saveToFile() const {
|
||||
|
||||
// Write header
|
||||
serialization::writePod(file, WIFI_FILE_VERSION);
|
||||
serialization::writeString(file, lastConnectedSsid); // Save last connected SSID
|
||||
serialization::writePod(file, static_cast<uint8_t>(credentials.size()));
|
||||
|
||||
// Write each credential
|
||||
@@ -67,12 +68,18 @@ bool WifiCredentialStore::loadFromFile() {
|
||||
// Read and verify version
|
||||
uint8_t version;
|
||||
serialization::readPod(file, version);
|
||||
if (version != WIFI_FILE_VERSION) {
|
||||
if (version > WIFI_FILE_VERSION) {
|
||||
Serial.printf("[%lu] [WCS] Unknown file version: %u\n", millis(), version);
|
||||
file.close();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (version >= 2) {
|
||||
serialization::readString(file, lastConnectedSsid);
|
||||
} else {
|
||||
lastConnectedSsid.clear();
|
||||
}
|
||||
|
||||
// Read credential count
|
||||
uint8_t count;
|
||||
serialization::readPod(file, count);
|
||||
@@ -128,6 +135,9 @@ bool WifiCredentialStore::removeCredential(const std::string& ssid) {
|
||||
if (cred != credentials.end()) {
|
||||
credentials.erase(cred);
|
||||
Serial.printf("[%lu] [WCS] Removed credentials for: %s\n", millis(), ssid.c_str());
|
||||
if (ssid == lastConnectedSsid) {
|
||||
clearLastConnectedSsid();
|
||||
}
|
||||
return saveToFile();
|
||||
}
|
||||
return false; // Not found
|
||||
@@ -146,8 +156,25 @@ const WifiCredential* WifiCredentialStore::findCredential(const std::string& ssi
|
||||
|
||||
bool WifiCredentialStore::hasSavedCredential(const std::string& ssid) const { return findCredential(ssid) != nullptr; }
|
||||
|
||||
void WifiCredentialStore::setLastConnectedSsid(const std::string& ssid) {
|
||||
if (lastConnectedSsid != ssid) {
|
||||
lastConnectedSsid = ssid;
|
||||
saveToFile();
|
||||
}
|
||||
}
|
||||
|
||||
const std::string& WifiCredentialStore::getLastConnectedSsid() const { return lastConnectedSsid; }
|
||||
|
||||
void WifiCredentialStore::clearLastConnectedSsid() {
|
||||
if (!lastConnectedSsid.empty()) {
|
||||
lastConnectedSsid.clear();
|
||||
saveToFile();
|
||||
}
|
||||
}
|
||||
|
||||
void WifiCredentialStore::clearAll() {
|
||||
credentials.clear();
|
||||
lastConnectedSsid.clear();
|
||||
saveToFile();
|
||||
Serial.printf("[%lu] [WCS] Cleared all WiFi credentials\n", millis());
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ class WifiCredentialStore {
|
||||
private:
|
||||
static WifiCredentialStore instance;
|
||||
std::vector<WifiCredential> credentials;
|
||||
std::string lastConnectedSsid;
|
||||
|
||||
static constexpr size_t MAX_NETWORKS = 8;
|
||||
|
||||
@@ -48,6 +49,11 @@ class WifiCredentialStore {
|
||||
// Check if a network is saved
|
||||
bool hasSavedCredential(const std::string& ssid) const;
|
||||
|
||||
// Last connected network
|
||||
void setLastConnectedSsid(const std::string& ssid);
|
||||
const std::string& getLastConnectedSsid() const;
|
||||
void clearLastConnectedSsid();
|
||||
|
||||
// Clear all credentials
|
||||
void clearAll();
|
||||
};
|
||||
|
||||
@@ -21,7 +21,8 @@ void WifiSelectionActivity::onEnter() {
|
||||
|
||||
renderingMutex = xSemaphoreCreateMutex();
|
||||
|
||||
// Load saved WiFi credentials - SD card operations need lock as we use SPI for both
|
||||
// Load saved WiFi credentials - SD card operations need lock as we use SPI
|
||||
// for both
|
||||
xSemaphoreTake(renderingMutex, portMAX_DELAY);
|
||||
WIFI_STORE.loadFromFile();
|
||||
xSemaphoreGive(renderingMutex);
|
||||
@@ -37,6 +38,7 @@ void WifiSelectionActivity::onEnter() {
|
||||
usedSavedPassword = false;
|
||||
savePromptSelection = 0;
|
||||
forgetPromptSelection = 0;
|
||||
autoConnecting = false;
|
||||
|
||||
// Cache MAC address for display
|
||||
uint8_t mac[6];
|
||||
@@ -46,9 +48,7 @@ void WifiSelectionActivity::onEnter() {
|
||||
mac[5]);
|
||||
cachedMacAddress = std::string(macStr);
|
||||
|
||||
// Trigger first update to show scanning message
|
||||
updateRequired = true;
|
||||
|
||||
// Task creation
|
||||
xTaskCreate(&WifiSelectionActivity::taskTrampoline, "WifiSelectionTask",
|
||||
4096, // Stack size (larger for WiFi operations)
|
||||
this, // Parameters
|
||||
@@ -56,7 +56,26 @@ void WifiSelectionActivity::onEnter() {
|
||||
&displayTaskHandle // Task handle
|
||||
);
|
||||
|
||||
// Start WiFi scan
|
||||
// Attempt to auto-connect to the last network
|
||||
if (allowAutoConnect) {
|
||||
const std::string lastSsid = WIFI_STORE.getLastConnectedSsid();
|
||||
if (!lastSsid.empty()) {
|
||||
const auto* cred = WIFI_STORE.findCredential(lastSsid);
|
||||
if (cred) {
|
||||
Serial.printf("[%lu] [WIFI] Attempting to auto-connect to %s\n", millis(), lastSsid.c_str());
|
||||
selectedSSID = cred->ssid;
|
||||
enteredPassword = cred->password;
|
||||
selectedRequiresPassword = !cred->password.empty();
|
||||
usedSavedPassword = true;
|
||||
autoConnecting = true;
|
||||
attemptConnection();
|
||||
updateRequired = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback to scanning
|
||||
startWifiScan();
|
||||
}
|
||||
|
||||
@@ -70,15 +89,17 @@ void WifiSelectionActivity::onExit() {
|
||||
WiFi.scanDelete();
|
||||
Serial.printf("[%lu] [WIFI] [MEM] Free heap after scanDelete: %d bytes\n", millis(), ESP.getFreeHeap());
|
||||
|
||||
// Note: We do NOT disconnect WiFi here - the parent activity (CrossPointWebServerActivity)
|
||||
// manages WiFi connection state. We just clean up the scan and task.
|
||||
// Note: We do NOT disconnect WiFi here - the parent activity
|
||||
// (CrossPointWebServerActivity) manages WiFi connection state. We just clean
|
||||
// up the scan and task.
|
||||
|
||||
// Acquire mutex before deleting task to ensure task isn't using it
|
||||
// This prevents hangs/crashes if the task holds the mutex when deleted
|
||||
Serial.printf("[%lu] [WIFI] Acquiring rendering mutex before task deletion...\n", millis());
|
||||
xSemaphoreTake(renderingMutex, portMAX_DELAY);
|
||||
|
||||
// Delete the display task (we now hold the mutex, so task is blocked if it needs it)
|
||||
// Delete the display task (we now hold the mutex, so task is blocked if it
|
||||
// needs it)
|
||||
Serial.printf("[%lu] [WIFI] Deleting display task...\n", millis());
|
||||
if (displayTaskHandle) {
|
||||
vTaskDelete(displayTaskHandle);
|
||||
@@ -96,6 +117,7 @@ void WifiSelectionActivity::onExit() {
|
||||
}
|
||||
|
||||
void WifiSelectionActivity::startWifiScan() {
|
||||
autoConnecting = false;
|
||||
state = WifiSelectionState::SCANNING;
|
||||
networks.clear();
|
||||
updateRequired = true;
|
||||
@@ -181,6 +203,7 @@ void WifiSelectionActivity::selectNetwork(const int index) {
|
||||
selectedRequiresPassword = network.isEncrypted;
|
||||
usedSavedPassword = false;
|
||||
enteredPassword.clear();
|
||||
autoConnecting = false;
|
||||
|
||||
// Check if we have saved credentials for this network
|
||||
const auto* savedCred = WIFI_STORE.findCredential(selectedSSID);
|
||||
@@ -223,7 +246,7 @@ void WifiSelectionActivity::selectNetwork(const int index) {
|
||||
}
|
||||
|
||||
void WifiSelectionActivity::attemptConnection() {
|
||||
state = WifiSelectionState::CONNECTING;
|
||||
state = autoConnecting ? WifiSelectionState::AUTO_CONNECTING : WifiSelectionState::CONNECTING;
|
||||
connectionStartTime = millis();
|
||||
connectedIP.clear();
|
||||
connectionError.clear();
|
||||
@@ -239,7 +262,7 @@ void WifiSelectionActivity::attemptConnection() {
|
||||
}
|
||||
|
||||
void WifiSelectionActivity::checkConnectionStatus() {
|
||||
if (state != WifiSelectionState::CONNECTING) {
|
||||
if (state != WifiSelectionState::CONNECTING && state != WifiSelectionState::AUTO_CONNECTING) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -251,6 +274,13 @@ void WifiSelectionActivity::checkConnectionStatus() {
|
||||
char ipStr[16];
|
||||
snprintf(ipStr, sizeof(ipStr), "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
|
||||
connectedIP = ipStr;
|
||||
autoConnecting = false;
|
||||
|
||||
// Save this as the last connected network - SD card operations need lock as
|
||||
// we use SPI for both
|
||||
xSemaphoreTake(renderingMutex, portMAX_DELAY);
|
||||
WIFI_STORE.setLastConnectedSsid(selectedSSID);
|
||||
xSemaphoreGive(renderingMutex);
|
||||
|
||||
// If we entered a new password, ask if user wants to save it
|
||||
// Otherwise, immediately complete so parent can start web server
|
||||
@@ -260,7 +290,10 @@ void WifiSelectionActivity::checkConnectionStatus() {
|
||||
updateRequired = true;
|
||||
} else {
|
||||
// Using saved password or open network - complete immediately
|
||||
Serial.printf("[%lu] [WIFI] Connected with saved/open credentials, completing immediately\n", millis());
|
||||
Serial.printf(
|
||||
"[%lu] [WIFI] Connected with saved/open credentials, "
|
||||
"completing immediately\n",
|
||||
millis());
|
||||
onComplete(true);
|
||||
}
|
||||
return;
|
||||
@@ -299,7 +332,7 @@ void WifiSelectionActivity::loop() {
|
||||
}
|
||||
|
||||
// Check connection progress
|
||||
if (state == WifiSelectionState::CONNECTING) {
|
||||
if (state == WifiSelectionState::CONNECTING || state == WifiSelectionState::AUTO_CONNECTING) {
|
||||
checkConnectionStatus();
|
||||
return;
|
||||
}
|
||||
@@ -368,17 +401,16 @@ void WifiSelectionActivity::loop() {
|
||||
}
|
||||
}
|
||||
// Go back to network list (whether Cancel or Forget network was selected)
|
||||
state = WifiSelectionState::NETWORK_LIST;
|
||||
updateRequired = true;
|
||||
startWifiScan();
|
||||
} else if (mappedInput.wasPressed(MappedInputManager::Button::Back)) {
|
||||
// Skip forgetting, go back to network list
|
||||
state = WifiSelectionState::NETWORK_LIST;
|
||||
updateRequired = true;
|
||||
startWifiScan();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle connected state (should not normally be reached - connection completes immediately)
|
||||
// Handle connected state (should not normally be reached - connection
|
||||
// completes immediately)
|
||||
if (state == WifiSelectionState::CONNECTED) {
|
||||
// Safety fallback - immediately complete
|
||||
onComplete(true);
|
||||
@@ -389,12 +421,14 @@ void WifiSelectionActivity::loop() {
|
||||
if (state == WifiSelectionState::CONNECTION_FAILED) {
|
||||
if (mappedInput.wasPressed(MappedInputManager::Button::Back) ||
|
||||
mappedInput.wasPressed(MappedInputManager::Button::Confirm)) {
|
||||
// If we used saved credentials, offer to forget the network
|
||||
if (usedSavedPassword) {
|
||||
// If we were auto-connecting or using a saved credential, offer to forget
|
||||
// the network
|
||||
if (autoConnecting || usedSavedPassword) {
|
||||
autoConnecting = false;
|
||||
state = WifiSelectionState::FORGET_PROMPT;
|
||||
forgetPromptSelection = 0; // Default to "Cancel"
|
||||
} else {
|
||||
// Go back to network list on failure
|
||||
// Go back to network list on failure for non-saved credentials
|
||||
state = WifiSelectionState::NETWORK_LIST;
|
||||
}
|
||||
updateRequired = true;
|
||||
@@ -420,6 +454,23 @@ void WifiSelectionActivity::loop() {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mappedInput.wasPressed(MappedInputManager::Button::Right)) {
|
||||
startWifiScan();
|
||||
return;
|
||||
}
|
||||
|
||||
const bool leftPressed = mappedInput.wasPressed(MappedInputManager::Button::Left);
|
||||
if (leftPressed) {
|
||||
const bool hasSavedPassword = !networks.empty() && networks[selectedNetworkIndex].hasSavedPassword;
|
||||
if (hasSavedPassword) {
|
||||
selectedSSID = networks[selectedNetworkIndex].ssid;
|
||||
state = WifiSelectionState::FORGET_PROMPT;
|
||||
forgetPromptSelection = 0; // Default to "Cancel"
|
||||
updateRequired = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Handle navigation
|
||||
buttonNavigator.onNext([this] {
|
||||
selectedNetworkIndex = ButtonNavigator::nextIndex(selectedNetworkIndex, networks.size());
|
||||
@@ -479,6 +530,9 @@ void WifiSelectionActivity::render() const {
|
||||
renderer.clearScreen();
|
||||
|
||||
switch (state) {
|
||||
case WifiSelectionState::AUTO_CONNECTING:
|
||||
renderConnecting();
|
||||
break;
|
||||
case WifiSelectionState::SCANNING:
|
||||
renderConnecting(); // Reuse connecting screen with different message
|
||||
break;
|
||||
@@ -582,7 +636,11 @@ void WifiSelectionActivity::renderNetworkList() const {
|
||||
|
||||
// Draw help text
|
||||
renderer.drawText(SMALL_FONT_ID, 20, pageHeight - 75, "* = Encrypted | + = Saved");
|
||||
const auto labels = mappedInput.mapLabels("« Back", "Connect", "", "");
|
||||
|
||||
const bool hasSavedPassword = !networks.empty() && networks[selectedNetworkIndex].hasSavedPassword;
|
||||
const char* forgetLabel = hasSavedPassword ? "Forget" : "";
|
||||
|
||||
const auto labels = mappedInput.mapLabels("« Back", "Connect", forgetLabel, "Refresh");
|
||||
GUI.drawButtonHints(renderer, labels.btn1, labels.btn2, labels.btn3, labels.btn4);
|
||||
}
|
||||
|
||||
@@ -686,8 +744,7 @@ void WifiSelectionActivity::renderForgetPrompt() const {
|
||||
const auto height = renderer.getLineHeight(UI_10_FONT_ID);
|
||||
const auto top = (pageHeight - height * 3) / 2;
|
||||
|
||||
renderer.drawCenteredText(UI_12_FONT_ID, top - 40, "Connection Failed", true, EpdFontFamily::BOLD);
|
||||
|
||||
renderer.drawCenteredText(UI_12_FONT_ID, top - 40, "Forget Network", true, EpdFontFamily::BOLD);
|
||||
std::string ssidInfo = "Network: " + selectedSSID;
|
||||
if (ssidInfo.length() > 28) {
|
||||
ssidInfo.replace(25, ssidInfo.length() - 25, "...");
|
||||
|
||||
@@ -22,6 +22,7 @@ struct WifiNetworkInfo {
|
||||
|
||||
// WiFi selection states
|
||||
enum class WifiSelectionState {
|
||||
AUTO_CONNECTING, // Trying to connect to the last known network
|
||||
SCANNING, // Scanning for networks
|
||||
NETWORK_LIST, // Displaying available networks
|
||||
PASSWORD_ENTRY, // Entering password for selected network
|
||||
@@ -70,6 +71,12 @@ class WifiSelectionActivity final : public ActivityWithSubactivity {
|
||||
// Whether network was connected using a saved password (skip save prompt)
|
||||
bool usedSavedPassword = false;
|
||||
|
||||
// Whether to attempt auto-connect on entry
|
||||
const bool allowAutoConnect;
|
||||
|
||||
// Whether we are attempting to auto-connect
|
||||
bool autoConnecting = false;
|
||||
|
||||
// Save/forget prompt selection (0 = Yes, 1 = No)
|
||||
int savePromptSelection = 0;
|
||||
int forgetPromptSelection = 0;
|
||||
@@ -98,8 +105,10 @@ class WifiSelectionActivity final : public ActivityWithSubactivity {
|
||||
|
||||
public:
|
||||
explicit WifiSelectionActivity(GfxRenderer& renderer, MappedInputManager& mappedInput,
|
||||
const std::function<void(bool connected)>& onComplete)
|
||||
: ActivityWithSubactivity("WifiSelection", renderer, mappedInput), onComplete(onComplete) {}
|
||||
const std::function<void(bool connected)>& onComplete, bool autoConnect = true)
|
||||
: ActivityWithSubactivity("WifiSelection", renderer, mappedInput),
|
||||
onComplete(onComplete),
|
||||
allowAutoConnect(autoConnect) {}
|
||||
void onEnter() override;
|
||||
void onExit() override;
|
||||
void loop() override;
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "MappedInputManager.h"
|
||||
#include "OtaUpdateActivity.h"
|
||||
#include "SettingsList.h"
|
||||
#include "activities/network/WifiSelectionActivity.h"
|
||||
#include "components/UITheme.h"
|
||||
#include "fontIds.h"
|
||||
|
||||
@@ -46,11 +47,13 @@ void SettingsActivity::onEnter() {
|
||||
}
|
||||
|
||||
// Append device-only ACTION items
|
||||
controlsSettings.insert(controlsSettings.begin(), SettingInfo::Action("Remap Front Buttons"));
|
||||
systemSettings.push_back(SettingInfo::Action("KOReader Sync"));
|
||||
systemSettings.push_back(SettingInfo::Action("OPDS Browser"));
|
||||
systemSettings.push_back(SettingInfo::Action("Clear Cache"));
|
||||
systemSettings.push_back(SettingInfo::Action("Check for updates"));
|
||||
controlsSettings.insert(controlsSettings.begin(),
|
||||
SettingInfo::Action("Remap Front Buttons", SettingAction::RemapFrontButtons));
|
||||
systemSettings.push_back(SettingInfo::Action("Network", SettingAction::Network));
|
||||
systemSettings.push_back(SettingInfo::Action("KOReader Sync", SettingAction::KOReaderSync));
|
||||
systemSettings.push_back(SettingInfo::Action("OPDS Browser", SettingAction::OPDSBrowser));
|
||||
systemSettings.push_back(SettingInfo::Action("Clear Cache", SettingAction::ClearCache));
|
||||
systemSettings.push_back(SettingInfo::Action("Check for updates", SettingAction::CheckForUpdates));
|
||||
|
||||
// Reset selection to first category
|
||||
selectedCategoryIndex = 0;
|
||||
@@ -178,46 +181,45 @@ void SettingsActivity::toggleCurrentSetting() {
|
||||
SETTINGS.*(setting.valuePtr) = currentValue + setting.valueRange.step;
|
||||
}
|
||||
} else if (setting.type == SettingType::ACTION) {
|
||||
if (strcmp(setting.name, "Remap Front Buttons") == 0) {
|
||||
auto enterSubActivity = [this](Activity* activity) {
|
||||
xSemaphoreTake(renderingMutex, portMAX_DELAY);
|
||||
exitActivity();
|
||||
enterNewActivity(new ButtonRemapActivity(renderer, mappedInput, [this] {
|
||||
exitActivity();
|
||||
updateRequired = true;
|
||||
}));
|
||||
enterNewActivity(activity);
|
||||
xSemaphoreGive(renderingMutex);
|
||||
} else if (strcmp(setting.name, "KOReader Sync") == 0) {
|
||||
xSemaphoreTake(renderingMutex, portMAX_DELAY);
|
||||
};
|
||||
|
||||
auto onComplete = [this] {
|
||||
exitActivity();
|
||||
enterNewActivity(new KOReaderSettingsActivity(renderer, mappedInput, [this] {
|
||||
exitActivity();
|
||||
updateRequired = true;
|
||||
}));
|
||||
xSemaphoreGive(renderingMutex);
|
||||
} else if (strcmp(setting.name, "OPDS Browser") == 0) {
|
||||
xSemaphoreTake(renderingMutex, portMAX_DELAY);
|
||||
updateRequired = true;
|
||||
};
|
||||
|
||||
auto onCompleteBool = [this](bool) {
|
||||
exitActivity();
|
||||
enterNewActivity(new CalibreSettingsActivity(renderer, mappedInput, [this] {
|
||||
exitActivity();
|
||||
updateRequired = true;
|
||||
}));
|
||||
xSemaphoreGive(renderingMutex);
|
||||
} else if (strcmp(setting.name, "Clear Cache") == 0) {
|
||||
xSemaphoreTake(renderingMutex, portMAX_DELAY);
|
||||
exitActivity();
|
||||
enterNewActivity(new ClearCacheActivity(renderer, mappedInput, [this] {
|
||||
exitActivity();
|
||||
updateRequired = true;
|
||||
}));
|
||||
xSemaphoreGive(renderingMutex);
|
||||
} else if (strcmp(setting.name, "Check for updates") == 0) {
|
||||
xSemaphoreTake(renderingMutex, portMAX_DELAY);
|
||||
exitActivity();
|
||||
enterNewActivity(new OtaUpdateActivity(renderer, mappedInput, [this] {
|
||||
exitActivity();
|
||||
updateRequired = true;
|
||||
}));
|
||||
xSemaphoreGive(renderingMutex);
|
||||
updateRequired = true;
|
||||
};
|
||||
|
||||
switch (setting.action) {
|
||||
case SettingAction::RemapFrontButtons:
|
||||
enterSubActivity(new ButtonRemapActivity(renderer, mappedInput, onComplete));
|
||||
break;
|
||||
case SettingAction::KOReaderSync:
|
||||
enterSubActivity(new KOReaderSettingsActivity(renderer, mappedInput, onComplete));
|
||||
break;
|
||||
case SettingAction::OPDSBrowser:
|
||||
enterSubActivity(new CalibreSettingsActivity(renderer, mappedInput, onComplete));
|
||||
break;
|
||||
case SettingAction::Network:
|
||||
enterSubActivity(new WifiSelectionActivity(renderer, mappedInput, onCompleteBool, false));
|
||||
break;
|
||||
case SettingAction::ClearCache:
|
||||
enterSubActivity(new ClearCacheActivity(renderer, mappedInput, onComplete));
|
||||
break;
|
||||
case SettingAction::CheckForUpdates:
|
||||
enterSubActivity(new OtaUpdateActivity(renderer, mappedInput, onComplete));
|
||||
break;
|
||||
case SettingAction::None:
|
||||
// Do nothing
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
return;
|
||||
@@ -289,4 +291,4 @@ void SettingsActivity::render() const {
|
||||
|
||||
// Always use standard refresh for settings screen
|
||||
renderer.displayBuffer();
|
||||
}
|
||||
}
|
||||
@@ -14,11 +14,22 @@ class CrossPointSettings;
|
||||
|
||||
enum class SettingType { TOGGLE, ENUM, ACTION, VALUE, STRING };
|
||||
|
||||
enum class SettingAction {
|
||||
None,
|
||||
RemapFrontButtons,
|
||||
KOReaderSync,
|
||||
OPDSBrowser,
|
||||
Network,
|
||||
ClearCache,
|
||||
CheckForUpdates,
|
||||
};
|
||||
|
||||
struct SettingInfo {
|
||||
const char* name;
|
||||
SettingType type;
|
||||
uint8_t CrossPointSettings::* valuePtr = nullptr;
|
||||
std::vector<std::string> enumValues;
|
||||
SettingAction action = SettingAction::None;
|
||||
|
||||
struct ValueRange {
|
||||
uint8_t min;
|
||||
@@ -63,10 +74,11 @@ struct SettingInfo {
|
||||
return s;
|
||||
}
|
||||
|
||||
static SettingInfo Action(const char* name) {
|
||||
static SettingInfo Action(const char* name, SettingAction action) {
|
||||
SettingInfo s;
|
||||
s.name = name;
|
||||
s.type = SettingType::ACTION;
|
||||
s.action = action;
|
||||
return s;
|
||||
}
|
||||
|
||||
@@ -156,4 +168,4 @@ class SettingsActivity final : public ActivityWithSubactivity {
|
||||
void onEnter() override;
|
||||
void onExit() override;
|
||||
void loop() override;
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user