feat: Implement silent pre-indexing for the next chapter in EpubReaderActivity (#979)
## Summary * A simple tweak to pre-index the next chapter silently during normal reading. * Triggers silent pre-indexing of the next chapter when the penultimate page of a chapter is rendered to reduce visible interruptions. * Keeps existing indexing with popup when a reader jumps directly into an unindexed chapter. ## Additional Context * Reader input is temporarily blocked during silent indexing to avoid navigation/index state conflicts. * The penultimate page is used because readers typically spend longer there than on the final page. * This change optimizes linear reading flow while preserving reliable indexing for non-linear navigation. ## Possible Improvements * Add a setting for First Page Indexing vs Penultimate Page Pre-indexing * Display an indexing icon in the status bar instead of using a popup that overlaps book text. Tested on device: https://www.dropbox.com/scl/fi/29g5kjqgsi5e4hgujv38u/Silent-Indexing.MOV?rlkey=yemi4mosmev5vicaa7gpe49qw&dl=0 --- ### AI Usage While CrossPoint doesn't have restrictions on AI tools in contributing, please be transparent about their usage as it helps set the right context for reviewers. Did you use AI tools to help write this code? _**YES**_ --------- Co-authored-by: Jake Kenneally <jakekenneally@gmail.com>
This commit is contained in:
@@ -530,14 +530,14 @@ void EpubReaderActivity::render(RenderLock&& lock) {
|
|||||||
orientedMarginBottom += std::max(SETTINGS.screenMargin, statusBarHeight);
|
orientedMarginBottom += std::max(SETTINGS.screenMargin, statusBarHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const uint16_t viewportWidth = renderer.getScreenWidth() - orientedMarginLeft - orientedMarginRight;
|
||||||
|
const uint16_t viewportHeight = renderer.getScreenHeight() - orientedMarginTop - orientedMarginBottom;
|
||||||
|
|
||||||
if (!section) {
|
if (!section) {
|
||||||
const auto filepath = epub->getSpineItem(currentSpineIndex).href;
|
const auto filepath = epub->getSpineItem(currentSpineIndex).href;
|
||||||
LOG_DBG("ERS", "Loading file: %s, index: %d", filepath.c_str(), currentSpineIndex);
|
LOG_DBG("ERS", "Loading file: %s, index: %d", filepath.c_str(), currentSpineIndex);
|
||||||
section = std::unique_ptr<Section>(new Section(epub, currentSpineIndex, renderer));
|
section = std::unique_ptr<Section>(new Section(epub, currentSpineIndex, renderer));
|
||||||
|
|
||||||
const uint16_t viewportWidth = renderer.getScreenWidth() - orientedMarginLeft - orientedMarginRight;
|
|
||||||
const uint16_t viewportHeight = renderer.getScreenHeight() - orientedMarginTop - orientedMarginBottom;
|
|
||||||
|
|
||||||
if (!section->loadSectionFile(SETTINGS.getReaderFontId(), SETTINGS.getReaderLineCompression(),
|
if (!section->loadSectionFile(SETTINGS.getReaderFontId(), SETTINGS.getReaderLineCompression(),
|
||||||
SETTINGS.extraParagraphSpacing, SETTINGS.paragraphAlignment, viewportWidth,
|
SETTINGS.extraParagraphSpacing, SETTINGS.paragraphAlignment, viewportWidth,
|
||||||
viewportHeight, SETTINGS.hyphenationEnabled, SETTINGS.embeddedStyle,
|
viewportHeight, SETTINGS.hyphenationEnabled, SETTINGS.embeddedStyle,
|
||||||
@@ -635,6 +635,7 @@ void EpubReaderActivity::render(RenderLock&& lock) {
|
|||||||
renderContents(std::move(p), orientedMarginTop, orientedMarginRight, orientedMarginBottom, orientedMarginLeft);
|
renderContents(std::move(p), orientedMarginTop, orientedMarginRight, orientedMarginBottom, orientedMarginLeft);
|
||||||
LOG_DBG("ERS", "Rendered page in %dms", millis() - start);
|
LOG_DBG("ERS", "Rendered page in %dms", millis() - start);
|
||||||
}
|
}
|
||||||
|
silentIndexNextChapterIfNeeded(viewportWidth, viewportHeight);
|
||||||
saveProgress(currentSpineIndex, section->currentPage, section->pageCount);
|
saveProgress(currentSpineIndex, section->currentPage, section->pageCount);
|
||||||
|
|
||||||
if (pendingScreenshot) {
|
if (pendingScreenshot) {
|
||||||
@@ -643,6 +644,38 @@ void EpubReaderActivity::render(RenderLock&& lock) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EpubReaderActivity::silentIndexNextChapterIfNeeded(const uint16_t viewportWidth, const uint16_t viewportHeight) {
|
||||||
|
if (!epub || !section || section->pageCount < 2) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build the next chapter cache while the penultimate page is on screen.
|
||||||
|
if (section->currentPage != section->pageCount - 2) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int nextSpineIndex = currentSpineIndex + 1;
|
||||||
|
if (nextSpineIndex < 0 || nextSpineIndex >= epub->getSpineItemsCount()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Section nextSection(epub, nextSpineIndex, renderer);
|
||||||
|
if (nextSection.loadSectionFile(SETTINGS.getReaderFontId(), SETTINGS.getReaderLineCompression(),
|
||||||
|
SETTINGS.extraParagraphSpacing, SETTINGS.paragraphAlignment, viewportWidth,
|
||||||
|
viewportHeight, SETTINGS.hyphenationEnabled, SETTINGS.embeddedStyle,
|
||||||
|
SETTINGS.imageRendering)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_DBG("ERS", "Silently indexing next chapter: %d", nextSpineIndex);
|
||||||
|
if (!nextSection.createSectionFile(SETTINGS.getReaderFontId(), SETTINGS.getReaderLineCompression(),
|
||||||
|
SETTINGS.extraParagraphSpacing, SETTINGS.paragraphAlignment, viewportWidth,
|
||||||
|
viewportHeight, SETTINGS.hyphenationEnabled, SETTINGS.embeddedStyle,
|
||||||
|
SETTINGS.imageRendering)) {
|
||||||
|
LOG_ERR("ERS", "Failed silent indexing for chapter: %d", nextSpineIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void EpubReaderActivity::saveProgress(int spineIndex, int currentPage, int pageCount) {
|
void EpubReaderActivity::saveProgress(int spineIndex, int currentPage, int pageCount) {
|
||||||
FsFile f;
|
FsFile f;
|
||||||
if (Storage.openFileForWrite("ERS", epub->getCachePath() + "/progress.bin", f)) {
|
if (Storage.openFileForWrite("ERS", epub->getCachePath() + "/progress.bin", f)) {
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ class EpubReaderActivity final : public Activity {
|
|||||||
void renderContents(std::unique_ptr<Page> page, int orientedMarginTop, int orientedMarginRight,
|
void renderContents(std::unique_ptr<Page> page, int orientedMarginTop, int orientedMarginRight,
|
||||||
int orientedMarginBottom, int orientedMarginLeft);
|
int orientedMarginBottom, int orientedMarginLeft);
|
||||||
void renderStatusBar() const;
|
void renderStatusBar() const;
|
||||||
|
void silentIndexNextChapterIfNeeded(uint16_t viewportWidth, uint16_t viewportHeight);
|
||||||
void saveProgress(int spineIndex, int currentPage, int pageCount);
|
void saveProgress(int spineIndex, int currentPage, int pageCount);
|
||||||
// Jump to a percentage of the book (0-100), mapping it to spine and page.
|
// Jump to a percentage of the book (0-100), mapping it to spine and page.
|
||||||
void jumpToPercent(int percent);
|
void jumpToPercent(int percent);
|
||||||
|
|||||||
Reference in New Issue
Block a user