feat(reader): comic treatment for fixed-layout items in comics/manga libraries

PDFs shelved in comics or manga libraries (scanned manga, official manga
PDFs with text layers) now get comic reader treatment: bookmarks only —
no text-selection highlights, no annotations, no in-book search. Items
in ebooks libraries are completely unaffected, and EPUBs keep their
existing behavior everywhere.

- handlers: new exported ShouldTreatAsComic(libraryType, formatGroup) —
  true for fixed_layout/comic_archive in manga/comics libraries; the
  reader JSON API also exposes it as treat_as_comic
- router: the SSR reader page fetches the library type and passes
  TreatAsComic through ReaderMetadata into the init config
- reader: when treatAsComic is set, the PDF textLayer selection listener
  (mouse and touch paths) never attaches so no highlight popover can
  open; pointer mode is forced to pan (Smart/Text segment hidden);
  search button and toggleSearch are disabled; previously-created PDF
  highlights stop rendering
- bookmarks are unchanged (already page-index based for fixed layout),
  and device sync / OPDS / format classification are untouched since
  format_group stays fixed_layout
This commit is contained in:
2026-09-17 14:36:58 -04:00
parent b3a429d7e1
commit 80e5d5b0d1
6 changed files with 158 additions and 108 deletions
+21
View File
@@ -102,6 +102,7 @@ func (h *ReaderHandler) ShowReader(c *echo.Context) error {
// Determine if panel detection should be enabled
enablePanelDetection := shouldEnablePanelDetection(libraryWithType.TypeName, mediaItem.FormatGroup)
treatAsComic := ShouldTreatAsComic(libraryWithType.TypeName, mediaItem.FormatGroup)
// Get reading progress
var progress database.ReadingProgress
@@ -133,6 +134,7 @@ func (h *ReaderHandler) ShowReader(c *echo.Context) error {
"progress": progress,
"bookmarks": bookmarks,
"enable_panel_detection": enablePanelDetection,
"treat_as_comic": treatAsComic,
"format_group": mediaItem.FormatGroup,
"manga_type": mediaItem.MangaType,
"reading_direction": mediaItem.ReadingDirection,
@@ -639,6 +641,25 @@ func (h *ReaderHandler) ParseEbook(c *echo.Context) error {
})
}
// ShouldTreatAsComic reports whether a fixed-layout item that lives in a
// comics or manga library should get comic reader treatment: bookmarks
// only — no text-selection highlights, no annotations, no in-book search.
// Comic archives already behave this way; this flag extends it to fixed-
// layout PDFs shelved in comic libraries (scanned or official manga PDFs).
func ShouldTreatAsComic(libraryType string, formatGroup string) bool {
comicLibraries := map[string]bool{
"manga": true,
"comics": true,
}
fixedFormats := map[string]bool{
"fixed_layout": true,
"comic_archive": true,
}
return comicLibraries[libraryType] && fixedFormats[formatGroup]
}
// shouldEnablePanelDetection determines if panel detection should be enabled
// based on library type and format group
func shouldEnablePanelDetection(libraryType string, formatGroup string) bool {