fix: Wi-Fi Selection on Calibre Library launch

This commit is contained in:
danoooob 2026-01-10 22:38:15 +07:00
parent d4ae108d9b
commit 5160d16ea3
2 changed files with 51 additions and 36 deletions

View File

@ -7,7 +7,7 @@
#include "CrossPointSettings.h" #include "CrossPointSettings.h"
#include "MappedInputManager.h" #include "MappedInputManager.h"
#include "ScreenComponents.h" #include "ScreenComponents.h"
#include "WifiCredentialStore.h" #include "activities/network/WifiSelectionActivity.h"
#include "fontIds.h" #include "fontIds.h"
#include "network/HttpDownloader.h" #include "network/HttpDownloader.h"
#include "util/StringUtils.h" #include "util/StringUtils.h"
@ -25,7 +25,7 @@ void OpdsBookBrowserActivity::taskTrampoline(void* param) {
} }
void OpdsBookBrowserActivity::onEnter() { void OpdsBookBrowserActivity::onEnter() {
Activity::onEnter(); ActivityWithSubactivity::onEnter();
renderingMutex = xSemaphoreCreateMutex(); renderingMutex = xSemaphoreCreateMutex();
state = BrowserState::CHECK_WIFI; state = BrowserState::CHECK_WIFI;
@ -49,7 +49,7 @@ void OpdsBookBrowserActivity::onEnter() {
} }
void OpdsBookBrowserActivity::onExit() { void OpdsBookBrowserActivity::onExit() {
Activity::onExit(); ActivityWithSubactivity::onExit();
// Turn off WiFi when exiting // Turn off WiFi when exiting
WiFi.mode(WIFI_OFF); WiFi.mode(WIFI_OFF);
@ -66,13 +66,28 @@ void OpdsBookBrowserActivity::onExit() {
} }
void OpdsBookBrowserActivity::loop() { void OpdsBookBrowserActivity::loop() {
// Handle WiFi selection subactivity
if (state == BrowserState::WIFI_SELECTION) {
ActivityWithSubactivity::loop();
return;
}
// Handle error state - Confirm retries, Back goes back or home // Handle error state - Confirm retries, Back goes back or home
if (state == BrowserState::ERROR) { if (state == BrowserState::ERROR) {
if (mappedInput.wasReleased(MappedInputManager::Button::Confirm)) { if (mappedInput.wasReleased(MappedInputManager::Button::Confirm)) {
// Check if WiFi is still connected
if (WiFi.status() == WL_CONNECTED && WiFi.localIP() != IPAddress(0, 0, 0, 0)) {
// WiFi connected - just retry fetching the feed
Serial.printf("[%lu] [OPDS] Retry: WiFi connected, retrying fetch\n", millis());
state = BrowserState::LOADING; state = BrowserState::LOADING;
statusMessage = "Loading..."; statusMessage = "Loading...";
updateRequired = true; updateRequired = true;
fetchFeed(currentPath); fetchFeed(currentPath);
} else {
// WiFi not connected - launch WiFi selection
Serial.printf("[%lu] [OPDS] Retry: WiFi not connected, launching selection\n", millis());
launchWifiSelection();
}
} else if (mappedInput.wasReleased(MappedInputManager::Button::Back)) { } else if (mappedInput.wasReleased(MappedInputManager::Button::Back)) {
navigateBack(); navigateBack();
} }
@ -350,8 +365,8 @@ void OpdsBookBrowserActivity::downloadBook(const OpdsEntry& book) {
} }
void OpdsBookBrowserActivity::checkAndConnectWifi() { void OpdsBookBrowserActivity::checkAndConnectWifi() {
// Already connected? // Already connected? Verify connection is valid by checking IP
if (WiFi.status() == WL_CONNECTED) { if (WiFi.status() == WL_CONNECTED && WiFi.localIP() != IPAddress(0, 0, 0, 0)) {
state = BrowserState::LOADING; state = BrowserState::LOADING;
statusMessage = "Loading..."; statusMessage = "Loading...";
updateRequired = true; updateRequired = true;
@ -359,38 +374,34 @@ void OpdsBookBrowserActivity::checkAndConnectWifi() {
return; return;
} }
// Try to connect using saved credentials // Not connected - launch WiFi selection screen directly
statusMessage = "Connecting to WiFi..."; launchWifiSelection();
}
void OpdsBookBrowserActivity::launchWifiSelection() {
state = BrowserState::WIFI_SELECTION;
updateRequired = true; updateRequired = true;
WIFI_STORE.loadFromFile(); enterNewActivity(new WifiSelectionActivity(renderer, mappedInput, [this](const bool connected) {
const auto& credentials = WIFI_STORE.getCredentials(); onWifiSelectionComplete(connected);
if (credentials.empty()) { }));
state = BrowserState::ERROR; }
errorMessage = "No WiFi credentials saved";
updateRequired = true;
return;
}
// Use the first saved credential void OpdsBookBrowserActivity::onWifiSelectionComplete(const bool connected) {
const auto& cred = credentials[0]; exitActivity();
WiFi.mode(WIFI_STA);
WiFi.begin(cred.ssid.c_str(), cred.password.c_str());
// Wait for connection with timeout if (connected) {
constexpr int WIFI_TIMEOUT_MS = 10000; Serial.printf("[%lu] [OPDS] WiFi connected via selection, fetching feed\n", millis());
const unsigned long startTime = millis();
while (WiFi.status() != WL_CONNECTED && millis() - startTime < WIFI_TIMEOUT_MS) {
vTaskDelay(100 / portTICK_PERIOD_MS);
}
if (WiFi.status() == WL_CONNECTED) {
Serial.printf("[%lu] [OPDS] WiFi connected: %s\n", millis(), WiFi.localIP().toString().c_str());
state = BrowserState::LOADING; state = BrowserState::LOADING;
statusMessage = "Loading..."; statusMessage = "Loading...";
updateRequired = true; updateRequired = true;
fetchFeed(currentPath); fetchFeed(currentPath);
} else { } else {
Serial.printf("[%lu] [OPDS] WiFi selection cancelled/failed\n", millis());
// Force disconnect to ensure clean state for next retry
// This prevents stale connection status from interfering
WiFi.disconnect();
WiFi.mode(WIFI_OFF);
state = BrowserState::ERROR; state = BrowserState::ERROR;
errorMessage = "WiFi connection failed"; errorMessage = "WiFi connection failed";
updateRequired = true; updateRequired = true;

View File

@ -8,16 +8,18 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include "../Activity.h" #include "../ActivityWithSubactivity.h"
/** /**
* Activity for browsing and downloading books from an OPDS server. * Activity for browsing and downloading books from an OPDS server.
* Supports navigation through catalog hierarchy and downloading EPUBs. * Supports navigation through catalog hierarchy and downloading EPUBs.
* When WiFi connection fails, launches WiFi selection to let user connect.
*/ */
class OpdsBookBrowserActivity final : public Activity { class OpdsBookBrowserActivity final : public ActivityWithSubactivity {
public: public:
enum class BrowserState { enum class BrowserState {
CHECK_WIFI, // Checking WiFi connection CHECK_WIFI, // Checking WiFi connection
WIFI_SELECTION, // WiFi selection subactivity is active
LOADING, // Fetching OPDS feed LOADING, // Fetching OPDS feed
BROWSING, // Displaying entries (navigation or books) BROWSING, // Displaying entries (navigation or books)
DOWNLOADING, // Downloading selected EPUB DOWNLOADING, // Downloading selected EPUB
@ -26,7 +28,7 @@ class OpdsBookBrowserActivity final : public Activity {
explicit OpdsBookBrowserActivity(GfxRenderer& renderer, MappedInputManager& mappedInput, explicit OpdsBookBrowserActivity(GfxRenderer& renderer, MappedInputManager& mappedInput,
const std::function<void()>& onGoHome) const std::function<void()>& onGoHome)
: Activity("OpdsBookBrowser", renderer, mappedInput), onGoHome(onGoHome) {} : ActivityWithSubactivity("OpdsBookBrowser", renderer, mappedInput), onGoHome(onGoHome) {}
void onEnter() override; void onEnter() override;
void onExit() override; void onExit() override;
@ -54,6 +56,8 @@ class OpdsBookBrowserActivity final : public Activity {
void render() const; void render() const;
void checkAndConnectWifi(); void checkAndConnectWifi();
void launchWifiSelection();
void onWifiSelectionComplete(bool connected);
void fetchFeed(const std::string& path); void fetchFeed(const std::string& path);
void navigateToEntry(const OpdsEntry& entry); void navigateToEntry(const OpdsEntry& entry);
void navigateBack(); void navigateBack();