From 1fead92ccf71593bae336c3f3e961469fdcab4d2 Mon Sep 17 00:00:00 2001 From: Matthijs Mars Date: Fri, 9 Jan 2026 21:32:41 +0100 Subject: [PATCH] Revert "merge branch 'main' into feature/track-reading-time" This reverts commit b3ab864102f7064726940c25e06abbc69560421d. --- lib/Epub/Epub/Page.cpp | 10 ---- lib/Epub/Epub/Page.h | 2 - lib/Epub/Epub/Section.cpp | 61 -------------------- lib/Epub/Epub/Section.h | 6 -- lib/Epub/Epub/blocks/TextBlock.h | 1 - src/CrossPointSettings.cpp | 17 +----- src/CrossPointSettings.h | 4 -- src/activities/reader/EpubReaderActivity.cpp | 13 +---- src/activities/settings/SettingsActivity.cpp | 21 ++----- src/activities/settings/SettingsActivity.h | 25 ++++---- 10 files changed, 20 insertions(+), 140 deletions(-) diff --git a/lib/Epub/Epub/Page.cpp b/lib/Epub/Epub/Page.cpp index b8acd701..92839eb7 100644 --- a/lib/Epub/Epub/Page.cpp +++ b/lib/Epub/Epub/Page.cpp @@ -31,16 +31,6 @@ void Page::render(GfxRenderer& renderer, const int fontId, const int xOffset, co } } -size_t Page::wordCount() const { - size_t count = 0; - for (const auto& element : elements) { - // Only PageLine is stored in elements; avoid RTTI to stay compatible with -fno-rtti - const auto* line = static_cast(element.get()); - count += line->wordCount(); - } - return count; -} - bool Page::serialize(FsFile& file) const { const uint16_t count = elements.size(); serialization::writePod(file, count); diff --git a/lib/Epub/Epub/Page.h b/lib/Epub/Epub/Page.h index 1e65796b..20061941 100644 --- a/lib/Epub/Epub/Page.h +++ b/lib/Epub/Epub/Page.h @@ -29,7 +29,6 @@ class PageLine final : public PageElement { PageLine(std::shared_ptr block, const int16_t xPos, const int16_t yPos) : PageElement(xPos, yPos), block(std::move(block)) {} void render(GfxRenderer& renderer, int fontId, int xOffset, int yOffset) override; - size_t wordCount() const { return block ? block->wordCount() : 0; } bool serialize(FsFile& file) override; static std::unique_ptr deserialize(FsFile& file); }; @@ -39,7 +38,6 @@ class Page { // the list of block index and line numbers on this page std::vector> elements; void render(GfxRenderer& renderer, int fontId, int xOffset, int yOffset) const; - size_t wordCount() const; bool serialize(FsFile& file) const; static std::unique_ptr deserialize(FsFile& file); }; diff --git a/lib/Epub/Epub/Section.cpp b/lib/Epub/Epub/Section.cpp index 059d095a..18b81aae 100644 --- a/lib/Epub/Epub/Section.cpp +++ b/lib/Epub/Epub/Section.cpp @@ -233,64 +233,3 @@ std::unique_ptr Section::loadPageFromSectionFile() { file.close(); return page; } - -std::unique_ptr Section::loadPageAt(const uint16_t pageIndex) const { - FsFile localFile; - if (!SdMan.openFileForRead("SCT", filePath, localFile)) { - return nullptr; - } - - localFile.seek(HEADER_SIZE - sizeof(uint32_t)); - uint32_t lutOffset; - serialization::readPod(localFile, lutOffset); - if (pageIndex >= pageCount) { - localFile.close(); - return nullptr; - } - - localFile.seek(lutOffset + sizeof(uint32_t) * pageIndex); - uint32_t pagePos; - serialization::readPod(localFile, pagePos); - localFile.seek(pagePos); - - auto page = Page::deserialize(localFile); - localFile.close(); - return page; -} - -bool Section::ensureWordCountsLoaded() const { - if (wordCountsLoaded) { - return true; - } - - pageWordCounts.clear(); - pageWordCounts.reserve(pageCount); - - for (uint16_t i = 0; i < pageCount; i++) { - auto page = loadPageAt(i); - if (!page) { - pageWordCounts.clear(); - return false; - } - pageWordCounts.push_back(static_cast(page->wordCount())); - } - - wordCountsLoaded = true; - return true; -} - -uint32_t Section::getWordsLeftFrom(const uint16_t pageIndex) const { - if (pageIndex >= pageCount) { - return 0; - } - - if (!ensureWordCountsLoaded()) { - return 0; - } - - uint32_t total = 0; - for (size_t i = pageIndex; i < pageWordCounts.size(); i++) { - total += pageWordCounts[i]; - } - return total; -} diff --git a/lib/Epub/Epub/Section.h b/lib/Epub/Epub/Section.h index 6deaddc0..bac95efd 100644 --- a/lib/Epub/Epub/Section.h +++ b/lib/Epub/Epub/Section.h @@ -1,7 +1,6 @@ #pragma once #include #include -#include #include "Epub.h" @@ -14,8 +13,6 @@ class Section { GfxRenderer& renderer; std::string filePath; FsFile file; - mutable std::vector pageWordCounts; - mutable bool wordCountsLoaded = false; void writeSectionFileHeader(int fontId, float lineCompression, bool extraParagraphSpacing, uint8_t paragraphAlignment, uint16_t viewportWidth, uint16_t viewportHeight); @@ -39,7 +36,4 @@ class Section { const std::function& progressSetupFn = nullptr, const std::function& progressFn = nullptr); std::unique_ptr loadPageFromSectionFile(); - std::unique_ptr loadPageAt(uint16_t pageIndex) const; - bool ensureWordCountsLoaded() const; - uint32_t getWordsLeftFrom(uint16_t pageIndex) const; }; diff --git a/lib/Epub/Epub/blocks/TextBlock.h b/lib/Epub/Epub/blocks/TextBlock.h index 7535c888..415a18f3 100644 --- a/lib/Epub/Epub/blocks/TextBlock.h +++ b/lib/Epub/Epub/blocks/TextBlock.h @@ -36,7 +36,6 @@ class TextBlock final : public Block { // given a renderer works out where to break the words into lines void render(const GfxRenderer& renderer, int fontId, int x, int y) const; BlockType getType() override { return TEXT_BLOCK; } - size_t wordCount() const { return words.size(); } bool serialize(FsFile& file) const; static std::unique_ptr deserialize(FsFile& file); }; diff --git a/src/CrossPointSettings.cpp b/src/CrossPointSettings.cpp index ee90dbbf..cd8b56f7 100644 --- a/src/CrossPointSettings.cpp +++ b/src/CrossPointSettings.cpp @@ -12,9 +12,9 @@ CrossPointSettings CrossPointSettings::instance; namespace { -constexpr uint8_t SETTINGS_FILE_VERSION = 2; +constexpr uint8_t SETTINGS_FILE_VERSION = 1; // Increment this when adding new persisted settings fields -constexpr uint8_t SETTINGS_COUNT = 19; +constexpr uint8_t SETTINGS_COUNT = 17; constexpr char SETTINGS_FILE[] = "/.crosspoint/settings.bin"; } // namespace @@ -46,8 +46,6 @@ bool CrossPointSettings::saveToFile() const { serialization::writePod(outputFile, sleepScreenCoverMode); serialization::writeString(outputFile, std::string(opdsServerUrl)); serialization::writePod(outputFile, textAntiAliasing); - serialization::writePod(outputFile, readingSpeedWpm); - serialization::writePod(outputFile, showTimeLeftInChapter); outputFile.close(); Serial.printf("[%lu] [CPS] Settings saved to file\n", millis()); @@ -62,7 +60,7 @@ bool CrossPointSettings::loadFromFile() { uint8_t version; serialization::readPod(inputFile, version); - if (version != SETTINGS_FILE_VERSION && version != 1) { + if (version != SETTINGS_FILE_VERSION) { Serial.printf("[%lu] [CPS] Deserialization failed: Unknown version %u\n", millis(), version); inputFile.close(); return false; @@ -112,15 +110,6 @@ bool CrossPointSettings::loadFromFile() { } serialization::readPod(inputFile, textAntiAliasing); if (++settingsRead >= fileSettingsCount) break; - if (version == 1) { - uint8_t wpmV1; - serialization::readPod(inputFile, wpmV1); - readingSpeedWpm = wpmV1; - } else { - serialization::readPod(inputFile, readingSpeedWpm); - } - if (++settingsRead >= fileSettingsCount) break; - serialization::readPod(inputFile, showTimeLeftInChapter); } while (false); inputFile.close(); diff --git a/src/CrossPointSettings.h b/src/CrossPointSettings.h index 8d66a3e0..3a2a3503 100644 --- a/src/CrossPointSettings.h +++ b/src/CrossPointSettings.h @@ -61,10 +61,6 @@ class CrossPointSettings { // Text rendering settings uint8_t extraParagraphSpacing = 1; uint8_t textAntiAliasing = 1; - // Reading speed (words per minute) for time-left estimate - uint16_t readingSpeedWpm = 200; - // Toggle to show time remaining in the current chapter - uint8_t showTimeLeftInChapter = 0; // Duration of the power button press uint8_t shortPwrBtn = 0; // EPUB reading orientation settings diff --git a/src/activities/reader/EpubReaderActivity.cpp b/src/activities/reader/EpubReaderActivity.cpp index d0b31e83..0a6054f3 100644 --- a/src/activities/reader/EpubReaderActivity.cpp +++ b/src/activities/reader/EpubReaderActivity.cpp @@ -24,6 +24,7 @@ namespace { constexpr unsigned long skipChapterMs = 700; constexpr unsigned long goHomeMs = 1000; constexpr int statusBarMargin = 19; +constexpr const char* readingStatsFilePath = "/ReadingStats.csv"; std::string formatMinutes(const float minutes) { if (minutes <= 0.0f) { @@ -571,20 +572,10 @@ void EpubReaderActivity::renderStatusBar(const int orientedMarginRight, const in if (showProgress) { // Calculate progress in book const float sectionChapterProg = static_cast(section->currentPage) / section->pageCount; - std::string timeLeftText; const uint8_t bookProgress = epub->calculateProgress(currentSpineIndex, sectionChapterProg); - if (SETTINGS.showTimeLeftInChapter && SETTINGS.readingSpeedWpm > 0) { - const uint32_t wordsLeft = section->getWordsLeftFrom(section->currentPage); - if (wordsLeft > 0) { - const float minutesLeft = - static_cast(wordsLeft) / static_cast(std::max(1, SETTINGS.readingSpeedWpm)); - timeLeftText = formatMinutes(minutesLeft); - } - } // Right aligned text for progress counter - const std::string progress = (timeLeftText.empty() ? std::string() : timeLeftText + " ") + - std::to_string(section->currentPage + 1) + "/" + std::to_string(section->pageCount) + + const std::string progress = std::to_string(section->currentPage + 1) + "/" + std::to_string(section->pageCount) + " " + std::to_string(bookProgress) + "%"; progressTextWidth = renderer.getTextWidth(SMALL_FONT_ID, progress.c_str()); renderer.drawText(SMALL_FONT_ID, renderer.getScreenWidth() - orientedMarginRight - progressTextWidth, textY, diff --git a/src/activities/settings/SettingsActivity.cpp b/src/activities/settings/SettingsActivity.cpp index 83c2e33a..702db172 100644 --- a/src/activities/settings/SettingsActivity.cpp +++ b/src/activities/settings/SettingsActivity.cpp @@ -13,7 +13,7 @@ // Define the static settings list namespace { -constexpr int settingsCount = 20; +constexpr int settingsCount = 18; const SettingInfo settingsList[settingsCount] = { // Should match with SLEEP_SCREEN_MODE SettingInfo::Enum("Sleep Screen", &CrossPointSettings::sleepScreen, {"Dark", "Light", "Custom", "Cover", "None"}), @@ -35,8 +35,6 @@ const SettingInfo settingsList[settingsCount] = { SettingInfo::Value("Reader Screen Margin", &CrossPointSettings::screenMargin, {5, 40, 5}), SettingInfo::Enum("Reader Paragraph Alignment", &CrossPointSettings::paragraphAlignment, {"Justify", "Left", "Center", "Right"}), - SettingInfo::Value("Reading Speed (WPM)", &CrossPointSettings::readingSpeedWpm, {150, 300, 5}), - SettingInfo::Toggle("Show Time Left In Chapter", &CrossPointSettings::showTimeLeftInChapter), SettingInfo::Enum("Time to Sleep", &CrossPointSettings::sleepTimeout, {"1 min", "5 min", "10 min", "15 min", "30 min"}), SettingInfo::Enum("Refresh Frequency", &CrossPointSettings::refreshFrequency, @@ -129,21 +127,14 @@ void SettingsActivity::toggleCurrentSetting() { } else if (setting.type == SettingType::ENUM && setting.valuePtr != nullptr) { const uint8_t currentValue = SETTINGS.*(setting.valuePtr); SETTINGS.*(setting.valuePtr) = (currentValue + 1) % static_cast(setting.enumValues.size()); - } else if (setting.type == SettingType::VALUE && setting.valuePtr16 != nullptr) { + } else if (setting.type == SettingType::VALUE && setting.valuePtr != nullptr) { // Decreasing would also be nice for large ranges I think but oh well can't have everything - const uint16_t currentValue = SETTINGS.*(setting.valuePtr16); + const int8_t currentValue = SETTINGS.*(setting.valuePtr); // Wrap to minValue if exceeding setting value boundary if (currentValue + setting.valueRange.step > setting.valueRange.max) { - SETTINGS.*(setting.valuePtr16) = setting.valueRange.min; + SETTINGS.*(setting.valuePtr) = setting.valueRange.min; } else { - SETTINGS.*(setting.valuePtr16) = currentValue + setting.valueRange.step; - } - } else if (setting.type == SettingType::VALUE && setting.valuePtr != nullptr) { - const uint16_t currentValue = SETTINGS.*(setting.valuePtr); - if (currentValue + setting.valueRange.step > setting.valueRange.max) { - SETTINGS.*(setting.valuePtr) = static_cast(setting.valueRange.min); - } else { - SETTINGS.*(setting.valuePtr) = static_cast(currentValue + setting.valueRange.step); + SETTINGS.*(setting.valuePtr) = currentValue + setting.valueRange.step; } } else if (setting.type == SettingType::ACTION) { if (strcmp(setting.name, "Calibre Settings") == 0) { @@ -211,8 +202,6 @@ void SettingsActivity::render() const { } else if (settingsList[i].type == SettingType::ENUM && settingsList[i].valuePtr != nullptr) { const uint8_t value = SETTINGS.*(settingsList[i].valuePtr); valueText = settingsList[i].enumValues[value]; - } else if (settingsList[i].type == SettingType::VALUE && settingsList[i].valuePtr16 != nullptr) { - valueText = std::to_string(SETTINGS.*(settingsList[i].valuePtr16)); } else if (settingsList[i].type == SettingType::VALUE && settingsList[i].valuePtr != nullptr) { valueText = std::to_string(SETTINGS.*(settingsList[i].valuePtr)); } diff --git a/src/activities/settings/SettingsActivity.h b/src/activities/settings/SettingsActivity.h index c4fb3da3..157689e3 100644 --- a/src/activities/settings/SettingsActivity.h +++ b/src/activities/settings/SettingsActivity.h @@ -15,37 +15,32 @@ enum class SettingType { TOGGLE, ENUM, ACTION, VALUE }; // Structure to hold setting information struct SettingInfo { - const char* name; // Display name of the setting - SettingType type; // Type of setting - uint8_t CrossPointSettings::* valuePtr; // Pointer for 8-bit settings (TOGGLE/ENUM) - uint16_t CrossPointSettings::* valuePtr16; // Pointer for 16-bit VALUE settings + const char* name; // Display name of the setting + SettingType type; // Type of setting + uint8_t CrossPointSettings::* valuePtr; // Pointer to member in CrossPointSettings (for TOGGLE/ENUM/VALUE) std::vector enumValues; struct ValueRange { - uint16_t min; - uint16_t max; - uint16_t step; + uint8_t min; + uint8_t max; + uint8_t step; }; // Bounds/step for VALUE type settings ValueRange valueRange; // Static constructors static SettingInfo Toggle(const char* name, uint8_t CrossPointSettings::* ptr) { - return {name, SettingType::TOGGLE, ptr, nullptr}; + return {name, SettingType::TOGGLE, ptr}; } static SettingInfo Enum(const char* name, uint8_t CrossPointSettings::* ptr, std::vector values) { - return {name, SettingType::ENUM, ptr, nullptr, std::move(values)}; + return {name, SettingType::ENUM, ptr, std::move(values)}; } - static SettingInfo Action(const char* name) { return {name, SettingType::ACTION, nullptr, nullptr}; } - - static SettingInfo Value(const char* name, uint16_t CrossPointSettings::* ptr, const ValueRange valueRange) { - return {name, SettingType::VALUE, nullptr, ptr, {}, valueRange}; - } + static SettingInfo Action(const char* name) { return {name, SettingType::ACTION, nullptr}; } static SettingInfo Value(const char* name, uint8_t CrossPointSettings::* ptr, const ValueRange valueRange) { - return {name, SettingType::VALUE, ptr, nullptr, {}, valueRange}; + return {name, SettingType::VALUE, ptr, {}, valueRange}; } };