From 8e4ce5225cabf1d35942ebb75e7a9489de88769a Mon Sep 17 00:00:00 2001 From: Eunchurn Park Date: Sat, 27 Dec 2025 16:25:26 +0900 Subject: [PATCH] perf(ui): skip progress bar for chapters under 50KB Always show "Indexing..." text, only add progress bar for >= 50KB chapters. --- lib/Epub/Epub/Section.cpp | 13 ++++++-- lib/Epub/Epub/Section.h | 1 + src/activities/reader/EpubReaderActivity.cpp | 33 +++++++++++++------- 3 files changed, 34 insertions(+), 13 deletions(-) diff --git a/lib/Epub/Epub/Section.cpp b/lib/Epub/Epub/Section.cpp index 533437c..bd46d35 100644 --- a/lib/Epub/Epub/Section.cpp +++ b/lib/Epub/Epub/Section.cpp @@ -115,12 +115,15 @@ bool Section::clearCache() const { bool Section::persistPageDataToSD(const int fontId, const float lineCompression, const int marginTop, const int marginRight, const int marginBottom, const int marginLeft, - const bool extraParagraphSpacing, const std::function& progressFn) { + const bool extraParagraphSpacing, const std::function& progressSetupFn, + const std::function& progressFn) { + constexpr size_t MIN_SIZE_FOR_PROGRESS = 50 * 1024; // 50KB const auto localPath = epub->getSpineItem(spineIndex).href; const auto tmpHtmlPath = epub->getCachePath() + "/.tmp_" + std::to_string(spineIndex) + ".html"; // Retry logic for SD card timing issues bool success = false; + size_t fileSize = 0; for (int attempt = 0; attempt < 3 && !success; attempt++) { if (attempt > 0) { Serial.printf("[%lu] [SCT] Retrying stream (attempt %d)...\n", millis(), attempt + 1); @@ -137,6 +140,7 @@ bool Section::persistPageDataToSD(const int fontId, const float lineCompression, continue; } success = epub->readItemContentsToStream(localPath, tmpHtml, 1024); + fileSize = tmpHtml.size(); tmpHtml.close(); // If streaming failed, remove the incomplete file immediately @@ -151,7 +155,12 @@ bool Section::persistPageDataToSD(const int fontId, const float lineCompression, return false; } - Serial.printf("[%lu] [SCT] Streamed temp HTML to %s\n", millis(), tmpHtmlPath.c_str()); + Serial.printf("[%lu] [SCT] Streamed temp HTML to %s (%d bytes)\n", millis(), tmpHtmlPath.c_str(), fileSize); + + // Only show progress bar for larger chapters where rendering overhead is worth it + if (progressSetupFn && fileSize >= MIN_SIZE_FOR_PROGRESS) { + progressSetupFn(); + } ChapterHtmlSlimParser visitor( tmpHtmlPath, renderer, fontId, lineCompression, marginTop, marginRight, marginBottom, marginLeft, diff --git a/lib/Epub/Epub/Section.h b/lib/Epub/Epub/Section.h index d4e76c6..09a2f90 100644 --- a/lib/Epub/Epub/Section.h +++ b/lib/Epub/Epub/Section.h @@ -33,6 +33,7 @@ class Section { bool clearCache() const; bool persistPageDataToSD(int fontId, float lineCompression, int marginTop, int marginRight, int marginBottom, int marginLeft, bool extraParagraphSpacing, + const std::function& progressSetupFn = nullptr, const std::function& progressFn = nullptr); std::unique_ptr loadPageFromSD() const; }; diff --git a/src/activities/reader/EpubReaderActivity.cpp b/src/activities/reader/EpubReaderActivity.cpp index cc9b9fc..dce606a 100644 --- a/src/activities/reader/EpubReaderActivity.cpp +++ b/src/activities/reader/EpubReaderActivity.cpp @@ -224,26 +224,37 @@ void EpubReaderActivity::renderScreen() { constexpr int barHeight = 10; constexpr int boxMargin = 20; const int textWidth = renderer.getTextWidth(READER_FONT_ID, "Indexing..."); - const int boxWidth = (barWidth > textWidth ? barWidth : textWidth) + boxMargin * 2; - const int boxHeight = renderer.getLineHeight(READER_FONT_ID) + barHeight + boxMargin * 3; - const int boxX = (GfxRenderer::getScreenWidth() - boxWidth) / 2; + const int boxWidthWithBar = (barWidth > textWidth ? barWidth : textWidth) + boxMargin * 2; + const int boxWidthNoBar = textWidth + boxMargin * 2; + const int boxHeightWithBar = renderer.getLineHeight(READER_FONT_ID) + barHeight + boxMargin * 3; + const int boxHeightNoBar = renderer.getLineHeight(READER_FONT_ID) + boxMargin * 2; + const int boxXWithBar = (GfxRenderer::getScreenWidth() - boxWidthWithBar) / 2; + const int boxXNoBar = (GfxRenderer::getScreenWidth() - boxWidthNoBar) / 2; constexpr int boxY = 50; - const int barX = boxX + (boxWidth - barWidth) / 2; + const int barX = boxXWithBar + (boxWidthWithBar - barWidth) / 2; const int barY = boxY + renderer.getLineHeight(READER_FONT_ID) + boxMargin * 2; - // Draw initial indexing box with 0% progress + // Always show "Indexing..." text first { - renderer.fillRect(boxX, boxY, boxWidth, boxHeight, false); - renderer.drawText(READER_FONT_ID, boxX + boxMargin, boxY + boxMargin, "Indexing..."); - renderer.drawRect(boxX + 5, boxY + 5, boxWidth - 10, boxHeight - 10); - // Draw empty progress bar outline - renderer.drawRect(barX, barY, barWidth, barHeight); + renderer.fillRect(boxXNoBar, boxY, boxWidthNoBar, boxHeightNoBar, false); + renderer.drawText(READER_FONT_ID, boxXNoBar + boxMargin, boxY + boxMargin, "Indexing..."); + renderer.drawRect(boxXNoBar + 5, boxY + 5, boxWidthNoBar - 10, boxHeightNoBar - 10); renderer.displayBuffer(); pagesUntilFullRefresh = 0; } section->setupCacheDir(); + // Setup callback - only called for chapters >= 50KB, redraws with progress bar + auto progressSetup = [this, boxXWithBar, boxWidthWithBar, boxHeightWithBar, boxMargin, barX, barY, barWidth, + barHeight]() { + renderer.fillRect(boxXWithBar, boxY, boxWidthWithBar, boxHeightWithBar, false); + renderer.drawText(READER_FONT_ID, boxXWithBar + boxMargin, boxY + boxMargin, "Indexing..."); + renderer.drawRect(boxXWithBar + 5, boxY + 5, boxWidthWithBar - 10, boxHeightWithBar - 10); + renderer.drawRect(barX, barY, barWidth, barHeight); + renderer.displayBuffer(); + }; + // Progress callback to update progress bar auto progressCallback = [this, barX, barY, barWidth, barHeight](int progress) { const int fillWidth = (barWidth - 2) * progress / 100; @@ -252,7 +263,7 @@ void EpubReaderActivity::renderScreen() { }; if (!section->persistPageDataToSD(READER_FONT_ID, lineCompression, marginTop, marginRight, marginBottom, - marginLeft, SETTINGS.extraParagraphSpacing, progressCallback)) { + marginLeft, SETTINGS.extraParagraphSpacing, progressSetup, progressCallback)) { Serial.printf("[%lu] [ERS] Failed to persist page data to SD\n", millis()); section.reset(); return;