diff --git a/src/CrossPointSettings.cpp b/src/CrossPointSettings.cpp index f5e8ded5..38bc09bf 100644 --- a/src/CrossPointSettings.cpp +++ b/src/CrossPointSettings.cpp @@ -45,6 +45,7 @@ bool CrossPointSettings::saveToFile() const { serialization::writePod(outputFile, screenMargin); serialization::writePod(outputFile, sleepScreenCoverMode); serialization::writeString(outputFile, std::string(opdsServerUrl)); + serialization::writeString(outputFile, std::string(opdsPath)); serialization::writePod(outputFile, textAntiAliasing); serialization::writePod(outputFile, hideBatteryPercentage); serialization::writePod(outputFile, longPressChapterSkip); @@ -112,6 +113,14 @@ bool CrossPointSettings::loadFromFile() { opdsServerUrl[sizeof(opdsServerUrl) - 1] = '\0'; } if (++settingsRead >= fileSettingsCount) break; + { + std::string urlPath; + serialization::readString(inputFile, urlPath); + strncpy(opdsPath, urlPath.c_str(), sizeof(opdsPath) - 1); + opdsPath[sizeof(opdsPath) - 1] = '\0'; + + } + if (++settingsRead >= fileSettingsCount) break; serialization::readPod(inputFile, textAntiAliasing); if (++settingsRead >= fileSettingsCount) break; serialization::readPod(inputFile, hideBatteryPercentage); diff --git a/src/CrossPointSettings.h b/src/CrossPointSettings.h index 8ce32a2c..d4f0de76 100644 --- a/src/CrossPointSettings.h +++ b/src/CrossPointSettings.h @@ -90,6 +90,7 @@ class CrossPointSettings { uint8_t screenMargin = 5; // OPDS browser settings char opdsServerUrl[128] = ""; + char opdsPath[128] = ""; // Hide battery percentage uint8_t hideBatteryPercentage = HIDE_NEVER; // Long-press chapter skip on side buttons diff --git a/src/activities/browser/OpdsBookBrowserActivity.cpp b/src/activities/browser/OpdsBookBrowserActivity.cpp index 555cba91..ed207a19 100644 --- a/src/activities/browser/OpdsBookBrowserActivity.cpp +++ b/src/activities/browser/OpdsBookBrowserActivity.cpp @@ -18,7 +18,7 @@ namespace { constexpr int PAGE_ITEMS = 23; constexpr int SKIP_PAGE_MS = 700; -constexpr char OPDS_ROOT_PATH[] = "opds"; // No leading slash - relative to server URL +constexpr char DEFAULT_OPDS_ROOT_PATH[] = "opds"; // No leading slash - relative to server URL } // namespace void OpdsBookBrowserActivity::taskTrampoline(void* param) { @@ -33,7 +33,7 @@ void OpdsBookBrowserActivity::onEnter() { state = BrowserState::CHECK_WIFI; entries.clear(); navigationHistory.clear(); - currentPath = OPDS_ROOT_PATH; + currentPath = strcmp(SETTINGS.opdsPath, "") ? SETTINGS.opdsPath : DEFAULT_OPDS_ROOT_PATH; selectorIndex = 0; errorMessage.clear(); statusMessage = "Checking WiFi..."; @@ -172,7 +172,7 @@ void OpdsBookBrowserActivity::render() const { const auto pageWidth = renderer.getScreenWidth(); const auto pageHeight = renderer.getScreenHeight(); - renderer.drawCenteredText(UI_12_FONT_ID, 15, "Calibre Library", true, EpdFontFamily::BOLD); + renderer.drawCenteredText(UI_12_FONT_ID, 15, "Remote", true, EpdFontFamily::BOLD); if (state == BrowserState::CHECK_WIFI) { renderer.drawCenteredText(UI_10_FONT_ID, pageHeight / 2, statusMessage.c_str()); diff --git a/src/activities/home/HomeActivity.cpp b/src/activities/home/HomeActivity.cpp index eb11ba95..49e7a8b0 100644 --- a/src/activities/home/HomeActivity.cpp +++ b/src/activities/home/HomeActivity.cpp @@ -503,7 +503,7 @@ void HomeActivity::render() { std::vector menuItems = {"My Library", "File Transfer", "Settings"}; if (hasOpdsUrl) { // Insert Calibre Library after My Library - menuItems.insert(menuItems.begin() + 1, "Calibre Library"); + menuItems.insert(menuItems.begin() + 1, "Remote Library"); } const int menuTileWidth = pageWidth - 2 * margin; diff --git a/src/activities/settings/CalibreSettingsActivity.cpp b/src/activities/settings/CalibreSettingsActivity.cpp index 4f614ffc..0952b1c0 100644 --- a/src/activities/settings/CalibreSettingsActivity.cpp +++ b/src/activities/settings/CalibreSettingsActivity.cpp @@ -13,8 +13,8 @@ #include "fontIds.h" namespace { -constexpr int MENU_ITEMS = 2; -const char* menuNames[MENU_ITEMS] = {"Calibre Web URL", "Connect as Wireless Device"}; +constexpr int MENU_ITEMS = 3; +const char* menuNames[MENU_ITEMS] = {"Server URL", "OPDS Path", "Connect as Wireless Device"}; } // namespace void CalibreSettingsActivity::taskTrampoline(void* param) { @@ -80,10 +80,10 @@ void CalibreSettingsActivity::handleSelection() { xSemaphoreTake(renderingMutex, portMAX_DELAY); if (selectedIndex == 0) { - // Calibre Web URL + // Server URL exitActivity(); enterNewActivity(new KeyboardEntryActivity( - renderer, mappedInput, "Calibre Web URL", SETTINGS.opdsServerUrl, 10, + renderer, mappedInput, "Server URL", SETTINGS.opdsServerUrl, 10, 127, // maxLength false, // not password [this](const std::string& url) { @@ -97,7 +97,26 @@ void CalibreSettingsActivity::handleSelection() { exitActivity(); updateRequired = true; })); - } else if (selectedIndex == 1) { + } else if (selectedIndex == 1) { + // OPDS Path + exitActivity(); + enterNewActivity(new KeyboardEntryActivity( + renderer, mappedInput, "OPDS Path", SETTINGS.opdsPath, 10, + 127, // maxLength + false, // not password + [this](const std::string& url) { + strncpy(SETTINGS.opdsPath, url.c_str(), sizeof(SETTINGS.opdsServerUrl) - 1); + SETTINGS.opdsPath[sizeof(SETTINGS.opdsPath) - 1] = '\0'; + SETTINGS.saveToFile(); + exitActivity(); + updateRequired = true; + }, + [this]() { + exitActivity(); + updateRequired = true; + })); + + } else if (selectedIndex == 2) { // Wireless Device - launch the activity (handles WiFi connection internally) exitActivity(); if (WiFi.status() != WL_CONNECTED) { @@ -141,7 +160,7 @@ void CalibreSettingsActivity::render() { const auto pageWidth = renderer.getScreenWidth(); // Draw header - renderer.drawCenteredText(UI_12_FONT_ID, 15, "Calibre", true, EpdFontFamily::BOLD); + renderer.drawCenteredText(UI_12_FONT_ID, 15, "Remote Library", true, EpdFontFamily::BOLD); // Draw selection highlight renderer.fillRect(0, 60 + selectedIndex * 30 - 2, pageWidth - 1, 30); diff --git a/src/activities/settings/CategorySettingsActivity.cpp b/src/activities/settings/CategorySettingsActivity.cpp index a6182b5c..09de13bf 100644 --- a/src/activities/settings/CategorySettingsActivity.cpp +++ b/src/activities/settings/CategorySettingsActivity.cpp @@ -103,7 +103,7 @@ void CategorySettingsActivity::toggleCurrentSetting() { updateRequired = true; })); xSemaphoreGive(renderingMutex); - } else if (strcmp(setting.name, "Calibre Settings") == 0) { + } else if (strcmp(setting.name, "Remote Library") == 0) { xSemaphoreTake(renderingMutex, portMAX_DELAY); exitActivity(); enterNewActivity(new CalibreSettingsActivity(renderer, mappedInput, [this] { diff --git a/src/activities/settings/SettingsActivity.cpp b/src/activities/settings/SettingsActivity.cpp index 943fdb4c..ab2a7999 100644 --- a/src/activities/settings/SettingsActivity.cpp +++ b/src/activities/settings/SettingsActivity.cpp @@ -48,7 +48,7 @@ constexpr int systemSettingsCount = 5; const SettingInfo systemSettings[systemSettingsCount] = { SettingInfo::Enum("Time to Sleep", &CrossPointSettings::sleepTimeout, {"1 min", "5 min", "10 min", "15 min", "30 min"}), - SettingInfo::Action("KOReader Sync"), SettingInfo::Action("Calibre Settings"), SettingInfo::Action("Clear Cache"), + SettingInfo::Action("KOReader Sync"), SettingInfo::Action("Remote Library"), SettingInfo::Action("Clear Cache"), SettingInfo::Action("Check for updates")}; } // namespace