")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var2 string
templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(metadata.Title)
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/reader.templ`, Line: 30, Col: 26}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `reader.templ`, Line: 30, Col: 26}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))
if templ_7745c5c3_Err != nil {
@@ -67,7 +67,7 @@ func Reader(user User, metadata ReaderMetadata) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- var templ_7745c5c3_Var3 = []any{"theme-" + user.Theme + " h-screen overflow-hidden"}
+ var templ_7745c5c3_Var3 = []any{"theme-" + user.Theme + " h-screen overflow-hidden overscroll-none"}
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var3...)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
@@ -79,7 +79,7 @@ func Reader(user User, metadata ReaderMetadata) templ.Component {
var templ_7745c5c3_Var4 string
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.ResolveAttributeValue(readerInitExpr(metadata))
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/reader.templ`, Line: 40, Col: 36}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `reader.templ`, Line: 40, Col: 36}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var4)
if templ_7745c5c3_Err != nil {
@@ -92,7 +92,7 @@ func Reader(user User, metadata ReaderMetadata) templ.Component {
var templ_7745c5c3_Var5 string
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.ResolveAttributeValue(templ.CSSClasses(templ_7745c5c3_Var3).String())
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/reader.templ`, Line: 1, Col: 0}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `reader.templ`, Line: 1, Col: 0}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var5)
if templ_7745c5c3_Err != nil {
@@ -122,7 +122,7 @@ func Reader(user User, metadata ReaderMetadata) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -174,7 +174,7 @@ func ReaderChrome(metadata ReaderMetadata) templ.Component {
var templ_7745c5c3_Var7 templ.SafeURL
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinURLErrs("/media/" + metadata.MediaItemID)
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/reader.templ`, Line: 292, Col: 63}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `reader.templ`, Line: 298, Col: 63}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
if templ_7745c5c3_Err != nil {
@@ -187,7 +187,7 @@ func ReaderChrome(metadata ReaderMetadata) templ.Component {
var templ_7745c5c3_Var8 string
templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(metadata.Title)
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/reader.templ`, Line: 295, Col: 95}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `reader.templ`, Line: 301, Col: 95}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
if templ_7745c5c3_Err != nil {
@@ -229,7 +229,7 @@ func drawerHeader(title string) templ.Component {
var templ_7745c5c3_Var10 string
templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(title)
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/reader.templ`, Line: 555, Col: 35}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `reader.templ`, Line: 561, Col: 35}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10))
if templ_7745c5c3_Err != nil {
diff --git a/web/src/reader/reader.ts b/web/src/reader/reader.ts
index a5797ed..a934fcd 100644
--- a/web/src/reader/reader.ts
+++ b/web/src/reader/reader.ts
@@ -730,6 +730,20 @@ document.addEventListener("alpine:init", () => {
this.scheduleSelectionPopover(doc, index);
});
}
+ // Clicks in the book dismiss the popover in ANY mode and for ANY
+ // content doc (EPUB sections and fixed-layout pages alike): iframe
+ // events never bubble to the host document (so the host
+ // outside-click dismiss never sees them). Clicking a painted
+ // highlight still works: this hides, then foliate's
+ // show-annotation re-opens it in edit mode.
+ doc.addEventListener(
+ "pointerdown",
+ () => {
+ if (this.selectionPopover.open)
+ this.hideSelectionPopover();
+ },
+ { passive: true },
+ );
// Text selection → highlight popover (reflowable EPUB only;
// fixed-layout highlight overlays are a later milestone).
if (!this.isFixedLayout) {
@@ -759,21 +773,6 @@ document.addEventListener("alpine:init", () => {
(e: PointerEvent) => setTimeout(() => checkSelection(e), 0),
{ passive: true },
);
- // Clicks in the book dismiss the popover in ANY mode: iframe
- // events never bubble to the host document (so the host
- // outside-click dismiss never sees them), and the collapsed
- // check above only covers create mode — edit mode had no
- // outside-click path at all, leaving Esc as the only way out.
- // Clicking a painted highlight still works: this hides, then
- // foliate's show-annotation re-opens it in edit mode.
- doc.addEventListener(
- "pointerdown",
- () => {
- if (this.selectionPopover.open)
- this.hideSelectionPopover();
- },
- { passive: true },
- );
doc.addEventListener(
"keyup",
(ev: KeyboardEvent) => {
@@ -1627,6 +1626,9 @@ document.addEventListener("alpine:init", () => {
const p = this.selectionPopover;
const token = getToken();
if (!token || !this.mediaItemId || (!p.cfi && p.pdfPage < 0)) return;
+ // The note editor writes into p.note live; "Highlight with note"
+ // creates the highlight AND its note in one POST.
+ const note = p.note.trim();
const pdfAnchor =
p.pdfPage >= 0
? JSON.stringify({ v: 1, page: p.pdfPage, rects: p.pdfRects })
@@ -1647,7 +1649,7 @@ document.addEventListener("alpine:init", () => {
epubcfi_start: p.pdfPage >= 0 ? pdfAnchor : p.cfi,
epubcfi_end: p.pdfPage >= 0 ? pdfAnchor : p.cfiEnd,
color,
- note_text: "",
+ note_text: note,
percentage_start: this.lastRelocateDetail?.fraction ?? 0,
}),
},
@@ -1676,7 +1678,7 @@ document.addEventListener("alpine:init", () => {
? ""
: this.toRangeCfi(p.cfi, p.cfiEnd, p.text) || p.cfi,
color,
- note: "",
+ note,
id: row.id,
});
// Clear the DOM selection: the gesture is consumed, and it is
@@ -1692,7 +1694,7 @@ document.addEventListener("alpine:init", () => {
/* ignore highlight errors */
}
},
- async saveHighlightChanges() {
+ async saveHighlightChanges(keepNoteOpen = false) {
const p = this.selectionPopover;
const token = getToken();
if (!token || !this.mediaItemId || !p.id) return;
@@ -1756,7 +1758,9 @@ document.addEventListener("alpine:init", () => {
id: p.id,
});
}
- p.noteOpen = false;
+ // Color tweaks made while the note editor is open keep the
+ // editor open — only the explicit save/close paths collapse it.
+ if (!keepNoteOpen) p.noteOpen = false;
} catch (_e) {
/* ignore highlight errors */
}