mirror of
https://github.com/bookorbit/bookorbit.git
synced 2026-11-03 00:11:37 -06:00
fix(reader): fall back to percentage jump when kosync response has no xpointer (#777)
* fix(reader): fall back to percentage jump when kosync response has no xpointer The KOReader plugin's progress pull calls syncToProgress(body.progress), which fires GotoXPointer(nil) or GotoPage(nil) when body.progress is nil. Both silently no-op, so the reader position does not move and the user sees 'Progress has been synchronized.' with nothing changing. This happens whenever the kosync response has percentage-only progress (e.g. progress written by the BookOrbit web reader, or by an external audiobook->ebook progress bridge that only knows the percentage, not an EPUB xpointer). hasUsableRemoteProgress already guards this case in reconcileProgressBeforeBookSync, but getProgress / applyRemoteProgress never got the same guard. Extend syncToProgress to accept an optional percentage_fallback (0-1, kosync scale). When there is no usable xpointer/page but a fallback percentage is present, fire GotoPercent (0-100 scale) so the reader actually jumps. * fix(reader): apply percentage fallback in pre-book-sync reconcile Drop the hasUsableRemoteProgress short-circuit so the reconcile that runs before a manual book sync behaves like the pull paths. Now that syncToProgress falls back to a percentage jump, the two flows disagreed on identical data: a manual pull moved the reader while the pre-sync reconcile reported "no exact location" and changed nothing, which also left the percentage argument passed to applyRemoteProgress unreachable. An earlier guard already returns when body.percentage is absent, so every response reaching this point can resolve a target. The strategy branches keep the conservative path intact: DISABLE still skips the progress push when the remote is newer. --------- Co-authored-by: neon <18559658+neonsolstice@users.noreply.github.com>
This commit is contained in:
@@ -68,8 +68,15 @@ function ProgressSync:getDocumentDigest()
|
||||
return computed
|
||||
end
|
||||
|
||||
function ProgressSync:syncToProgress(progress)
|
||||
logger.dbg("BookOrbit: syncing to progress", progress)
|
||||
function ProgressSync:syncToProgress(progress, percentage_fallback)
|
||||
logger.dbg("BookOrbit: syncing to progress", progress, "percent", percentage_fallback)
|
||||
local has_position = progress ~= nil and progress ~= ""
|
||||
if not has_position and percentage_fallback then
|
||||
-- No exact position (push came from web/audio sync); jump by percentage.
|
||||
-- kosync percentage is 0-1; GotoPercent expects 0-100.
|
||||
self.ui:handleEvent(Event:new("GotoPercent", percentage_fallback * 100))
|
||||
return
|
||||
end
|
||||
if self.ui.document.info.has_pages then
|
||||
self.ui:handleEvent(Event:new("GotoPage", tonumber(progress)))
|
||||
else
|
||||
@@ -77,10 +84,6 @@ function ProgressSync:syncToProgress(progress)
|
||||
end
|
||||
end
|
||||
|
||||
local function hasUsableRemoteProgress(progress)
|
||||
return progress ~= nil and progress ~= ""
|
||||
end
|
||||
|
||||
function ProgressSync:remoteProgressIsNewer(body, local_percentage)
|
||||
local local_timestamp = self.last_page_turn_timestamp or 0
|
||||
if body.timestamp ~= nil then
|
||||
@@ -93,7 +96,7 @@ function ProgressSync:remoteProgressIsNewer(body, local_percentage)
|
||||
end
|
||||
|
||||
function ProgressSync:applyRemoteProgress(body, on_done)
|
||||
self:syncToProgress(body.progress)
|
||||
self:syncToProgress(body.progress, body.percentage)
|
||||
if on_done then
|
||||
UIManager:scheduleIn(0.1, function()
|
||||
on_done(false)
|
||||
@@ -142,19 +145,6 @@ function ProgressSync:reconcileProgressBeforeBookSync(digest, on_done)
|
||||
end
|
||||
|
||||
local remote_newer = self:remoteProgressIsNewer(body, local_percentage)
|
||||
if not hasUsableRemoteProgress(body.progress) then
|
||||
if remote_newer then
|
||||
UIManager:show(InfoMessage:new{
|
||||
text = _("BookOrbit has newer progress but no exact location. Syncing book data without changing progress."),
|
||||
timeout = 4,
|
||||
})
|
||||
on_done(true)
|
||||
else
|
||||
on_done(false)
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
local strategy = remote_newer and self.settings.sync_forward or self.settings.sync_backward
|
||||
if strategy == SYNC_STRATEGY.SILENT then
|
||||
self:applyRemoteProgress(body, on_done)
|
||||
@@ -331,7 +321,7 @@ function ProgressSync:getProgress(ensure_networking, interactive)
|
||||
end
|
||||
|
||||
if interactive then
|
||||
self:syncToProgress(body.progress)
|
||||
self:syncToProgress(body.progress, body.percentage)
|
||||
if self.recordSyncSuccess then
|
||||
self:recordSyncSuccess("progress_pull", _("Progress pulled"))
|
||||
end
|
||||
@@ -348,7 +338,7 @@ function ProgressSync:getProgress(ensure_networking, interactive)
|
||||
|
||||
local strategy = self_older and self.settings.sync_forward or self.settings.sync_backward
|
||||
if strategy == SYNC_STRATEGY.SILENT then
|
||||
self:syncToProgress(body.progress)
|
||||
self:syncToProgress(body.progress, body.percentage)
|
||||
if self.recordSyncSuccess then
|
||||
self:recordSyncSuccess("progress_pull", _("Progress pulled"))
|
||||
end
|
||||
@@ -359,7 +349,7 @@ function ProgressSync:getProgress(ensure_networking, interactive)
|
||||
UIManager:show(ConfirmBox:new{
|
||||
text = T(template, Math.round(body.percentage * 100), body.device),
|
||||
ok_callback = function()
|
||||
self:syncToProgress(body.progress)
|
||||
self:syncToProgress(body.progress, body.percentage)
|
||||
if self.recordSyncSuccess then
|
||||
self:recordSyncSuccess("progress_pull", _("Progress pulled"))
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user