From 6420570aaa0adbef6a30d28ba7ee681a5bfe2409 Mon Sep 17 00:00:00 2001 From: Zach Nelson Date: Wed, 15 Jul 2026 18:27:38 -0500 Subject: [PATCH] fix: Unify book-progress percent across reader screens --- lib/Epub/Epub.cpp | 12 +++++++++ lib/Epub/Epub.h | 9 +++++++ src/activities/reader/EpubReaderActivity.cpp | 26 +++++++++----------- 3 files changed, 32 insertions(+), 15 deletions(-) diff --git a/lib/Epub/Epub.cpp b/lib/Epub/Epub.cpp index 3dd7400319..c68c716e99 100644 --- a/lib/Epub/Epub.cpp +++ b/lib/Epub/Epub.cpp @@ -967,6 +967,18 @@ float Epub::calculateProgress(const uint16_t currentSpineIndex, const float curr return totalProgress / static_cast(bookSize); } +float Epub::calculateProgressForPage(const uint16_t spineIndex, const uint16_t pageInSpine, + const uint16_t spinePageCount) const { + if (spinePageCount == 0) { + return calculateProgress(spineIndex, 0.0f); + } + float intra = static_cast(pageInSpine + 1) / static_cast(spinePageCount); + if (intra > 1.0f) { + intra = 1.0f; + } + return calculateProgress(spineIndex, intra); +} + std::optional Epub::resolveHrefToSpineIndex(const std::string& href) const { if (!bookMetadataCache || !bookMetadataCache->isLoaded()) return std::nullopt; diff --git a/lib/Epub/Epub.h b/lib/Epub/Epub.h index 5f1f546e15..934b832d86 100644 --- a/lib/Epub/Epub.h +++ b/lib/Epub/Epub.h @@ -82,7 +82,16 @@ class Epub { uint16_t getSpineIndexForTextReference() const; size_t getBookSize() const; + + // Byte-weighted primitive: maps a [0,1] fraction through a spine to book + // progress. Page-based callers use calculateProgressForPage (public) instead. float calculateProgress(uint16_t currentSpineIndex, float currentSpineRead) const; + + // Book progress (0.0-1.0) for a 0-based page within a spine. The 1-based + // fraction ((pageInSpine + 1) / spinePageCount) makes the final page read as + // a full 1.0. Shared by all progress readouts so the convention can't drift. + float calculateProgressForPage(uint16_t spineIndex, uint16_t pageInSpine, uint16_t spinePageCount) const; + CssParser* getCssParser() const { return cssParser.get(); } std::optional resolveHrefToSpineIndex(const std::string& href) const; }; diff --git a/src/activities/reader/EpubReaderActivity.cpp b/src/activities/reader/EpubReaderActivity.cpp index 3e282dbaf1..c8166f203c 100644 --- a/src/activities/reader/EpubReaderActivity.cpp +++ b/src/activities/reader/EpubReaderActivity.cpp @@ -250,9 +250,9 @@ void EpubReaderActivity::loop() { const int totalPages = getChapterTotalPages(); float bookProgress = 0.0f; if (epub->getBookSize() > 0 && spineItem && spineItem->getPageCount() > 0) { - const float chapterProgress = - static_cast(spineItem->currentPage) / static_cast(spineItem->getPageCount()); - bookProgress = epub->calculateProgress(currentSpineIndex, chapterProgress) * 100.0f; + bookProgress = + epub->calculateProgressForPage(currentSpineIndex, spineItem->currentPage, spineItem->getPageCount()) * + 100.0f; } const int bookProgressPercent = clampPercent(static_cast(bookProgress + 0.5f)); startActivityForResult(std::make_unique(renderer, mappedInput, epub->getTitle(), @@ -543,9 +543,9 @@ void EpubReaderActivity::onReaderMenuConfirm(EpubReaderMenuActivity::MenuAction case EpubReaderMenuActivity::MenuAction::GO_TO_PERCENT: { float bookProgress = 0.0f; if (epub && epub->getBookSize() > 0 && spineItem && spineItem->getPageCount() > 0) { - const float chapterProgress = - static_cast(spineItem->currentPage) / static_cast(spineItem->getPageCount()); - bookProgress = epub->calculateProgress(currentSpineIndex, chapterProgress) * 100.0f; + bookProgress = + epub->calculateProgressForPage(currentSpineIndex, spineItem->currentPage, spineItem->getPageCount()) * + 100.0f; } const int initialPercent = clampPercent(static_cast(bookProgress + 0.5f)); startActivityForResult(std::make_unique(renderer, mappedInput, initialPercent), @@ -999,10 +999,8 @@ void EpubReaderActivity::renderContents(std::unique_ptr page, const uint16 void EpubReaderActivity::renderStatusBar() const { // Calculate progress in book - const int currentPage = spineItem->currentPage + 1; - const float pageCount = spineItem->getPageCount(); - const float sectionChapterProg = (pageCount > 0) ? (static_cast(currentPage) / pageCount) : 0; - const float bookProgress = epub->calculateProgress(currentSpineIndex, sectionChapterProg) * 100; + const float bookProgress = + epub->calculateProgressForPage(currentSpineIndex, spineItem->currentPage, spineItem->getPageCount()) * 100; // Use chapter-relative page counts when available const int chapterPage = getChapterRelativePage() + 1; @@ -1253,11 +1251,9 @@ ScreenshotInfo EpubReaderActivity::getScreenshotInfo() const { info.currentPage = spineItem->currentPage + 1; info.totalPages = spineItem->getPageCount(); if (epub && epub->getBookSize() > 0 && info.totalPages > 0) { - const float chapterProgress = static_cast(spineItem->currentPage) / static_cast(info.totalPages); - int pct = static_cast(epub->calculateProgress(currentSpineIndex, chapterProgress) * 100.0f + 0.5f); - if (pct < 0) pct = 0; - if (pct > 100) pct = 100; - info.progressPercent = pct; + const int pct = static_cast( + epub->calculateProgressForPage(currentSpineIndex, spineItem->currentPage, info.totalPages) * 100.0f + 0.5f); + info.progressPercent = clampPercent(pct); } } return info;