mod: Phase 3 — Re-port unmerged upstream PRs

Re-applied upstream PRs not yet merged to upstream/master:

- #1055: Byte-level framebuffer writes (fillPhysicalHSpan*,
  optimized fillRect/drawLine/fillRectDither/fillPolygon)
- #1027: Word-width cache (FNV-1a, 128-entry) and hyphenation
  early exit in ParsedText for 7-9% layout speedup
- #1068: Already present in upstream — URL hyphenation fix
- #1019: Already present in upstream — file extensions in browser
- #1090/#1185/#1217: KOReader sync improvements — binary credential
  store, document hash caching, ChapterXPathIndexer integration
- #1209: OPDS multi-server — OpdsBookBrowserActivity accepts
  OpdsServer, directory picker for downloads, download-complete
  prompt with open/back options
- #857: Dictionary activities already ported in Phase 1/2
- #1003: Placeholder cover already integrated in Phase 2

Also fixed: STR_OFF i18n string, include paths, replaced
Epub::isValidThumbnailBmp with Storage.exists, replaced
StringUtils::checkFileExtension with FsHelpers equivalents.

Made-with: Cursor
This commit is contained in:
cottongin
2026-03-07 16:15:42 -05:00
parent 30473c27d3
commit 60a3e21c0e
25 changed files with 811 additions and 295 deletions

View File

@@ -6,6 +6,7 @@
#include <vector>
#include "../Activity.h"
#include "OpdsServerStore.h"
#include "util/ButtonNavigator.h"
/**
@@ -16,16 +17,19 @@
class OpdsBookBrowserActivity final : public Activity {
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)
DOWNLOADING, // Downloading selected EPUB
ERROR // Error state with message
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)
: Activity("OpdsBookBrowser", renderer, mappedInput) {}
explicit OpdsBookBrowserActivity(GfxRenderer& renderer, MappedInputManager& mappedInput,
const OpdsServer* server = nullptr)
: Activity("OpdsBookBrowser", renderer, mappedInput), server(server ? *server : OpdsServer{}) {}
void onEnter() override;
void onExit() override;
@@ -43,6 +47,11 @@ class OpdsBookBrowserActivity final : public Activity {
std::string statusMessage;
size_t downloadProgress = 0;
size_t downloadTotal = 0;
std::string downloadedFilePath;
int promptSelection = 0; // 0 = back to listing, 1 = open book
OpdsServer server; // Copied at construction — safe even if the store changes during browsing
OpdsEntry pendingBook;
void checkAndConnectWifi();
void launchWifiSelection();
@@ -50,6 +59,9 @@ class OpdsBookBrowserActivity final : public Activity {
void fetchFeed(const std::string& path);
void navigateToEntry(const OpdsEntry& entry);
void navigateBack();
void downloadBook(const OpdsEntry& book);
void launchDirectoryPicker(const OpdsEntry& book);
void onDirectoryPickerResult(const ActivityResult& result);
void downloadBook(const OpdsEntry& book, const std::string& directory);
void executePromptAction(int action);
bool preventAutoSleep() override { return true; }
};