fix(sync): treat page index as sole locator for fixed-layout pull path

The push path (koreader→server) was already updated to omit epubcfi
for paging documents, and SaveProgress derives percentage from
page/total_pages for fixed formats. However, the pull path
(server→koreader) still returned any stored epubcfi and attempted
CFI→XPointer conversion, and SaveProgress preserved stale CFI values
written by the web reader (which generates fake CFIs via
CFI.fake.fromIndex for every comic/PDF page).

These fake CFI strings lingered in the database and koreader's pull
path picked them up over progress.page, causing tonumber("epubcfi(...)")
→ nil → GotoPage(nil) → crash when the user confirmed the sync prompt.

Changes:
- GetMetadata (koreader.go): for fixed_layout/comic_archive formats,
  skip returning epubcfi and skip the CFI→CRE XPointer conversion.
  Reflowable documents are byte-for-byte unchanged.
- SaveProgress (progress.go): for fixed formats, explicitly clear
  epubcfi and character_offset on every save so stale values from
  prior web-reader sessions are cleaned up over time.
This commit is contained in:
2026-06-07 00:26:53 -04:00
parent d11a623f9f
commit 762181c123
2 changed files with 18 additions and 7 deletions
+5 -2
View File
@@ -404,8 +404,11 @@ func (s *ProgressService) SaveProgress(ctx context.Context, req SaveProgressRequ
isFixed := formatGroup == FormatGroupFixedLayout || formatGroup == FormatGroupComicArchive
if isFixed {
// Fixed-layout & comic formats: the page index is the canonical locator.
// Derive percentage from page; CFI/character-offset are meaningless for
// image-based content, so they are intentionally left untouched here.
// CFI/character-offset are meaningless for image-based content, so clear
// any stale value that may have been stored by the web reader (which
// generates fake CFIs for comics).
params.Epubcfi = pgtype.Text{}
params.CharacterOffset = pgtype.Int8{}
if params.CurrentPage.Valid && params.TotalPages.Valid && params.TotalPages.Int32 > 0 {
pct := PageToPercentage(int(params.CurrentPage.Int32), int(params.TotalPages.Int32))
params.Percentage = pgtype.Float8{Float64: pct, Valid: true}