Improving KOReader sync

This commit is contained in:
jpirnay
2026-05-10 15:46:33 +02:00
parent b5ea8d3550
commit fe60b12d86
18 changed files with 252 additions and 54 deletions
+26 -5
View File
@@ -925,6 +925,8 @@ void EpubReaderActivity::applyPendingSyncSession() {
int restorePage = sync.page;
pendingParagraphLookup = false;
pendingParagraphIndex = 0;
pendingListItemLookup = false;
pendingListItemIndex = 0;
if (restoreSpineIndex < 0 || restoreSpineIndex >= epub->getSpineItemsCount()) {
LOG_ERR("ERS", "Invalid sync restore spine index %d, resetting to 0", restoreSpineIndex);
@@ -932,6 +934,8 @@ void EpubReaderActivity::applyPendingSyncSession() {
restorePage = 0;
pendingParagraphLookup = false;
pendingParagraphIndex = 0;
pendingListItemLookup = false;
pendingListItemIndex = 0;
}
if (sync.outcome == KOReaderSyncOutcomeState::APPLIED_REMOTE) {
@@ -939,8 +943,11 @@ void EpubReaderActivity::applyPendingSyncSession() {
restorePage = sync.resultPage;
pendingParagraphLookup = sync.resultHasParagraphIndex;
pendingParagraphIndex = sync.resultParagraphIndex;
LOG_DBG("ERS", "Applied synced remote position: spine=%d page=%d paragraph=%u hasParagraph=%s", restoreSpineIndex,
restorePage, pendingParagraphIndex, pendingParagraphLookup ? "yes" : "no");
pendingListItemLookup = sync.resultHasListItemIndex;
pendingListItemIndex = sync.resultListItemIndex;
LOG_DBG("ERS", "Applied synced remote position: spine=%d page=%d paragraph=%u hasParagraph=%s liIdx=%u hasLi=%s",
restoreSpineIndex, restorePage, pendingParagraphIndex, pendingParagraphLookup ? "yes" : "no",
pendingListItemIndex, pendingListItemLookup ? "yes" : "no");
} else {
LOG_DBG("ERS", "Restored local pre-sync position: spine=%d page=%d", restoreSpineIndex, restorePage);
}
@@ -1369,16 +1376,30 @@ void EpubReaderActivity::render(RenderLock&& lock) {
pendingAnchor.clear();
}
// Resolve pending KOReader sync paragraph index to accurate page via Section paragraph LUT
if (pendingParagraphLookup) {
// Resolve pending KOReader sync position via Section LUTs.
// <li>-anchored XPaths can't be expressed in the body-child <p> LUT, so try the
// li LUT first when set; fall back to the paragraph LUT (which handles direct
// <p> children of <body>) on miss.
bool resolvedFromLut = false;
if (pendingListItemLookup) {
if (const auto page = section->getPageForListItemIndex(pendingListItemIndex)) {
section->currentPage = *page;
LOG_DBG("ERS", "Resolved li[%u] to page %d (was %d)", pendingListItemIndex, *page, nextPageNumber);
resolvedFromLut = true;
} else {
LOG_DBG("ERS", "Li index %u not found in section LUT", pendingListItemIndex);
}
pendingListItemLookup = false;
}
if (!resolvedFromLut && pendingParagraphLookup) {
if (const auto page = section->getPageForParagraphIndex(pendingParagraphIndex)) {
section->currentPage = *page;
LOG_DBG("ERS", "Resolved p[%u] to page %d (was %d)", pendingParagraphIndex, *page, nextPageNumber);
} else {
LOG_DBG("ERS", "Paragraph LUT not available, using estimated page %d", nextPageNumber);
}
pendingParagraphLookup = false;
}
pendingParagraphLookup = false;
// handles changes in reader settings and reset to approximate position based on cached progress
if (cachedChapterTotalPageCount > 0) {
@@ -122,6 +122,11 @@ class EpubReaderActivity final : public Activity {
// Pending paragraph index from KOReader sync (resolved to page via Section paragraph LUT)
bool pendingParagraphLookup = false;
uint16_t pendingParagraphIndex = 0;
// Pending list-item index for KOReader-supplied XPaths whose deepest element is /li[N].
// Preferred over pendingParagraphLookup when set because <li>-anchored XPaths are not
// representable in the body-child <p> LUT.
bool pendingListItemLookup = false;
uint16_t pendingListItemIndex = 0;
bool pendingScreenshot = false;
bool skipNextButtonCheck = false; // Skip button processing for one frame after subactivity exit
ReaderUtils::InputDrainGuard inputDrainGuard;
+11 -2
View File
@@ -220,6 +220,8 @@ void KOReaderSyncActivity::performFetchAndCompare() {
remotePosition.totalPages = 0;
remotePosition.paragraphIndex = 0;
remotePosition.hasParagraphIndex = false;
remotePosition.listItemIndex = 0;
remotePosition.hasListItemIndex = false;
remoteChapterLabel.clear();
if (syncIntent == KOReaderSyncIntentState::PULL_REMOTE || syncIntent == KOReaderSyncIntentState::AUTO_PULL) {
@@ -249,6 +251,8 @@ void KOReaderSyncActivity::performFetchAndCompare() {
sync.resultPage = remotePosition.pageNumber;
sync.resultParagraphIndex = remotePosition.paragraphIndex;
sync.resultHasParagraphIndex = remotePosition.hasParagraphIndex;
sync.resultListItemIndex = remotePosition.listItemIndex;
sync.resultHasListItemIndex = remotePosition.hasListItemIndex;
APP_STATE.saveToFile();
if (syncIntent == KOReaderSyncIntentState::AUTO_PULL) {
@@ -503,6 +507,8 @@ void KOReaderSyncActivity::resumeReader(const KOReaderSyncOutcomeState outcome,
sync.resultPage = appliedResult->page;
sync.resultParagraphIndex = appliedResult->paragraphIndex;
sync.resultHasParagraphIndex = appliedResult->hasParagraphIndex;
sync.resultListItemIndex = appliedResult->listItemIndex;
sync.resultHasListItemIndex = appliedResult->hasListItemIndex;
} else if (outcome != KOReaderSyncOutcomeState::APPLIED_REMOTE) {
// Only zero the result fields when not resuming an already-applied remote
// position. The PULL_REMOTE path pre-saves the mapped result into APP_STATE
@@ -511,6 +517,8 @@ void KOReaderSyncActivity::resumeReader(const KOReaderSyncOutcomeState outcome,
sync.resultPage = 0;
sync.resultParagraphIndex = 0;
sync.resultHasParagraphIndex = false;
sync.resultListItemIndex = 0;
sync.resultHasListItemIndex = false;
}
// Honor exit-to-home flag set by reader-close auto-sync — bouncing back into the reader
// the user just left would be jarring. The session state is consumed and cleared by the
@@ -792,8 +800,9 @@ void KOReaderSyncActivity::loop() {
return;
}
// Wifi will be turned off in onExit()
const SyncResult result = {remotePosition.spineIndex, remotePosition.pageNumber, remotePosition.paragraphIndex,
remotePosition.hasParagraphIndex};
const SyncResult result = {remotePosition.spineIndex, remotePosition.pageNumber,
remotePosition.paragraphIndex, remotePosition.hasParagraphIndex,
remotePosition.listItemIndex, remotePosition.hasListItemIndex};
resumeReader(KOReaderSyncOutcomeState::APPLIED_REMOTE, &result);
} else if (selectedOption == 1) {
// Upload local progress
+2
View File
@@ -149,6 +149,8 @@ void ReaderActivity::onGoToEpubReader(std::unique_ptr<Epub> epub) {
sync.resultPage = 0;
sync.resultParagraphIndex = 0;
sync.resultHasParagraphIndex = false;
sync.resultListItemIndex = 0;
sync.resultHasListItemIndex = false;
sync.exitToHomeAfterSync = false;
APP_STATE.saveToFile();
// Drop the loaded Epub before TLS — sync activity will reload it for remote-position