KOReader sync: a position with fewer than 6 path parts keeps the previous BookScrollId
Version
Kavita v0.9.1.4 (docker jvmilazz0/kavita:latest). Same code is on develop.
What happens
KoreaderHelper.UpdateProgressDto bails out early when the incoming position splits into fewer than 6 parts:
var path = koreaderPosition.Split('/');
if (path.Length < 6)
{
if (path.Length >= 3) progress.PageNum = GetPageNumber(path);
return; // BookScrollId is left as it was
}A position whose element is a direct child of <body> and that carries a .N offset instead of /text().N has exactly 5 parts:
/body/DocFragment[28]/body/p[99].0 -> ["", "body", "DocFragment[28]", "body", "p[99].0"]
/body/DocFragment[27]/body/p[43] -> 5 parts as wellKavita then updates PageNum (the chapter) but keeps whatever BookScrollId was stored earlier, so the reader is sent to a stale paragraph, or to the chapter heading, or to DocFragment[N].0 if the previous scroll id was empty.
From the Debug log:
Saving KOReader progress for User (3): /body/DocFragment[28]/body/p[99].0 - F787...
Converted KOReader progress from /body/DocFragment[28]/body/p[99].0 to Page 27 with ScrollId: //body/p[27].//body/p[27] is a leftover from an earlier push of /body/DocFragment[25]/body/p[27]/text().709.
KOReader itself usually sends /text().N, which makes 6 parts and works. Other KOReader-sync clients (justRead on iOS sends .../p[43], and progress bridges send .../p[99].0) hit the 5-part case on every push for epubs whose paragraphs sit directly under <body>.
Expected
/body/DocFragment[28]/body/p[99].0 should store PageNum = 27, BookScrollId = //body/p[99].
Suggested fix
Strip the trailing .N / /text()... before counting, and take lastTag from the last element rather than path[5], so that a 5-part path is handled the same as a 6-part one. Two smaller things noticed in the same area, happy to split them out:
KoreaderBookDtoBuilder.WithTimestampdoesnew DateTimeOffset(lastModifiedUtc)on aDateTimewhose Kind is Unspecified, so the returnedtimestampis shifted by the server's UTC offset (5 hours in the future here). KOReader compares this against its own last page turn to decide forward vs backward sync.percentageisPageNum / file.Pages, i.e. chapter granularity, so a book at 99.9% reports 80/81 = 98.8%.
Source: Kareadita/Kavita