#pragma once #include #include #include #include #include "../ActivityWithSubactivity.h" #include "OpdsServerStore.h" #include "util/ButtonNavigator.h" /** * Activity for browsing and downloading books from an OPDS server. * Supports navigation through catalog hierarchy and downloading EPUBs. * When WiFi connection fails, launches WiFi selection to let user connect. */ class OpdsBookBrowserActivity final : public ActivityWithSubactivity { public: enum class BrowserState { CHECK_WIFI, // Checking WiFi connection WIFI_SELECTION, // WiFi selection subactivity is active LOADING, // Fetching OPDS feed BROWSING, // Displaying entries (navigation or books) PICKING_DIRECTORY, // Directory picker subactivity is active DOWNLOADING, // Downloading selected EPUB DOWNLOAD_COMPLETE, // Prompt: open book or go back to listing ERROR // Error state with message }; explicit OpdsBookBrowserActivity(GfxRenderer& renderer, MappedInputManager& mappedInput, const std::function& onGoHome, const std::function& onGoToReader, const OpdsServer& server) : ActivityWithSubactivity("OpdsBookBrowser", renderer, mappedInput), onGoHome(onGoHome), onGoToReader(onGoToReader), server(server) {} void onEnter() override; void onExit() override; void loop() override; void render(Activity::RenderLock&&) override; private: ButtonNavigator buttonNavigator; BrowserState state = BrowserState::LOADING; std::vector entries; std::vector navigationHistory; // Stack of previous feed paths for back navigation std::string currentPath; // Current feed path being displayed int selectorIndex = 0; std::string errorMessage; std::string statusMessage; size_t downloadProgress = 0; size_t downloadTotal = 0; std::string downloadedFilePath; unsigned long downloadCompleteTime = 0; int promptSelection = 0; // 0 = back to listing, 1 = open book bool countdownActive = false; int lastCountdownSecond = -1; const std::function onGoHome; const std::function onGoToReader; OpdsServer server; // Copied at construction — safe even if the store changes during browsing void checkAndConnectWifi(); void launchWifiSelection(); void onWifiSelectionComplete(bool connected); void fetchFeed(const std::string& path); void navigateToEntry(const OpdsEntry& entry); void navigateBack(); void launchDirectoryPicker(const OpdsEntry& book); void onDirectorySelected(const std::string& directory); void onDirectoryPickerCancelled(); void downloadBook(const OpdsEntry& book, const std::string& directory); void executePromptAction(int action); bool preventAutoSleep() override { return true; } OpdsEntry pendingBook; };