fix(sync): bootstrap book UUID via push before first pull

On the first open of a freshly downloaded book there is no cached
bookhoard UUID yet, since it is only learned from a successful push
response. Pulling at that point simply failed with "Push progress
first", which also broke auto sync on open.

- onReaderReady auto sync: if no UUID is cached, push once to
  bootstrap identity (the server resolves the book by format-aware
  SHA-256 and returns the UUID, which we then cache); otherwise pull
  as before
- getProgress: when no UUID is cached, instead of showing the dead-end
  "Push progress first" message, show "Linking this book to Bookhoard
  first…", push once via _bootstrapUUIDThenPull, and retry the pull
  once the UUID is cached
- _bootstrapUUIDThenPull: new helper that pushes, waits 2s for the
  UUID to be cached, then performs the originally-requested pull,
  falling back to an error message on failure

After this bootstrap both push and pull work without ordering.
This commit is contained in:
2026-08-18 09:52:32 -04:00
parent 9d7b0f689f
commit c79868cffb
+33 -2
View File
@@ -100,7 +100,17 @@ end
function Bookhoard:onReaderReady()
if self.settings.auto_sync then
UIManager:nextTick(function()
self:getProgress(true, false)
-- On the first open of a freshly downloaded book there is no cached
-- bookhoard UUID yet (it is only learned from a successful push
-- response). Pulling now would just fail with "Push progress first".
-- Instead, push once to bootstrap identity: the server resolves the
-- book by SHA-256 (format-aware) and returns the UUID, which we then
-- cache. After that, push and pull both work without ordering.
if not self:getBookhoardUUID() then
self:updateProgress(true, false)
else
self:getProgress(true, false)
end
end)
end
self:registerEvents()
@@ -992,12 +1002,16 @@ function Bookhoard:getProgress(ensure_networking, interactive)
local book_uuid = self:getBookhoardUUID()
if not book_uuid then
-- No cached UUID yet (first open of a freshly downloaded book). Bootstrap
-- it by pushing once: the server resolves the book by SHA-256 and returns
-- the UUID, which the push handler caches. Then retry the pull.
if interactive then
UIManager:show(InfoMessage:new{
text = _("No Bookhoard UUID for this document. Push progress first."),
text = _("Linking this book to Bookhoard first"),
timeout = 3,
})
end
self:_bootstrapUUIDThenPull(interactive)
return
end
@@ -1008,6 +1022,23 @@ function Bookhoard:getProgress(ensure_networking, interactive)
self.pull_timestamp = now
end
-- Establish the bookhoard UUID for the current document by pushing once, then
-- (once cached) perform the originally-requested pull. Used when a pull is
-- requested before any push has run on a newly downloaded book.
function Bookhoard:_bootstrapUUIDThenPull(interactive)
self:updateProgress(false, false)
UIManager:scheduleIn(2, function()
if self:getBookhoardUUID() then
self:_doGetProgress(interactive)
elseif interactive then
UIManager:show(InfoMessage:new{
text = _("Could not link this book. Check your network and try again."),
timeout = 3,
})
end
end)
end
function Bookhoard:_doGetProgress(interactive)
local book_uuid = self:getBookhoardUUID()
if not book_uuid then return end