feat(reader): send context_text with progress for reflowable EPUBs
The web reader now captures ~100 chars of visible text from the foliate relocate event's range and includes it as context_text in the progress PUT body for reflowable formats. This enables the server's reverseByTextSearch fallback in ConvertStandardToCRE, which is critical for single-file EPUBs (e.g. 1984) where foliate emits coarse or fake-section CFIs that CREngine cannot directly resolve. Previously only the KOReader plugin sent context_text; the web reader's omission left the fallback unusable, causing percentage-based position estimation that was off by ~1 page. Changes: - Add contextText state property (line 387) - Extract visible text from e.detail.range in relocate handler, normalize whitespace, and slice to 100 chars (lines 508-512) - Include context_text in saveProgress PUT body for reflowable EPUBs only, alongside epubcfi (line 575) The server-side chain was already wired: media.go accepts it, progress.go stores it, and koreader.go passes it to the CFI converter. No Go changes needed.
This commit is contained in:
@@ -384,6 +384,7 @@ document.addEventListener("alpine:init", () => {
|
|||||||
mediaItemId: "" as string,
|
mediaItemId: "" as string,
|
||||||
saveTimeout: null as ReturnType<typeof setTimeout> | null,
|
saveTimeout: null as ReturnType<typeof setTimeout> | null,
|
||||||
initTime: 0 as number,
|
initTime: 0 as number,
|
||||||
|
contextText: "" as string,
|
||||||
readingTheme: "light" as string,
|
readingTheme: "light" as string,
|
||||||
readingMode: "light" as string,
|
readingMode: "light" as string,
|
||||||
readingFont: "literata" as string,
|
readingFont: "literata" as string,
|
||||||
@@ -504,6 +505,11 @@ document.addEventListener("alpine:init", () => {
|
|||||||
slider.value = fraction;
|
slider.value = fraction;
|
||||||
slider.title = progressStr;
|
slider.title = progressStr;
|
||||||
}
|
}
|
||||||
|
const range = e.detail.range as Range | undefined;
|
||||||
|
if (range) {
|
||||||
|
const text = range.toString().replace(/\s+/g, " ").trim();
|
||||||
|
this.contextText = text ? text.slice(0, 100) : "";
|
||||||
|
}
|
||||||
this.debouncedSaveProgress(fraction, location, cfi);
|
this.debouncedSaveProgress(fraction, location, cfi);
|
||||||
});
|
});
|
||||||
const slider = document.getElementById(
|
const slider = document.getElementById(
|
||||||
@@ -566,6 +572,7 @@ document.addEventListener("alpine:init", () => {
|
|||||||
};
|
};
|
||||||
if (!this.isFixedLayout) {
|
if (!this.isFixedLayout) {
|
||||||
body.epubcfi = cfi || "";
|
body.epubcfi = cfi || "";
|
||||||
|
body.context_text = this.contextText || "";
|
||||||
}
|
}
|
||||||
|
|
||||||
const tocItem = this.lastRelocateDetail?.tocItem;
|
const tocItem = this.lastRelocateDetail?.tocItem;
|
||||||
|
|||||||
Reference in New Issue
Block a user