The pull path (_doGetProgress + syncToProgress) still used the
reflowable-oriented nav_target selection that prefers xpointer/cfi
over page. For has_pages documents, if the server returned an epubcfi
(e.g., a fake CFI from the web reader's comic renderer), nav_target
became a CFI string, tonumber() returned nil, and GotoPage(nil)
crashed koreader when the user confirmed the sync prompt. After the
crash the old position was retained because GotoPage never completed.
This makes the pull path symmetric with the push path (ef129fd, which
omits epubcfi for paging documents):
- _doGetProgress: for has_pages, select nav_target from progress.page
and show the actual page number in the sync prompt instead of
computing it from server_percentage × total_pages (which could
display the wrong page due to rounding differences between foliate
and koreader page math).
- syncToProgress: add a nil guard so a missing page number skips
gracefully instead of crashing.
collectBookData put getLastProgress() directly into the epubcfi field
for every document. For paging documents (has_pages == true: PDF, CBZ,
CBR, CB7, CBT, DjVu) that value is the current page as a *number*, so
the payload carried "epubcfi": 5 (a JSON number). The server types
KOReaderBookProgress.Epubcfi as *string, and the strict JSON binder
rejected it with a 400 ("cannot unmarshal number into ... epububcfi of
type string"), which the plugin surfaced as the misleading
"Failed to push progress. Check your network connection." Reflowable
EPUBs were unaffected because CREngine returns an xpointer string.
Only set epubcfi for rolling (reflowable) documents. Paging documents
carry their position in the numeric page/total_pages fields, which the
server already treats as the canonical locator for fixed-layout/comic
formats. The pull path already falls back to progress.page, so restore
keeps working.
Lua's json.encode produces {} for empty tables instead of [].
Use json.util.InitArray to mark tables as arrays so they encode
correctly as [] for authors, bookmarks, highlights, notes, and books.
- Append ?token= auth param to OPDS catalog URL
- Replace any existing stale Bookhoard entry (with or without token)
- Hot-update OPDS plugin's in-memory servers table so catalog
appears immediately without restarting KOReader
Writes directly to KOReader's opds.lua settings so the user
doesn't have to type the long URL. Also updates the manual
menu item to auto-configure instead of showing the URL.
Instead of showing a long auth URL that's impractical to type on
e-ink, tell users to open their Bookhoard web UI and approve from
Device Management. Uses persistent InfoMessage (no timeout) so
the message stays visible while they switch devices.