From d41c3e47748e19bb48aaa5cf47629e79fdf71050 Mon Sep 17 00:00:00 2001 From: John O'Keefe Date: Sun, 25 Oct 2026 12:05:14 -0400 Subject: [PATCH] fix(ui): hide Comic/Manga editor section for non-comics media MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The metadata editor's Comic/Manga section (Manga Type, Reading Direction, Age Rating, Story Arc, Imprint, Scan Info, Metadata Notes, B&W) rendered for every item — an audiobook showed a manga dropdown, which is nonsense. MediaDetail now carries LibraryTypeName (resolved via GetLibraryType in the /media/:uuid handler) and a ShowComicMetadata() gate: comics and manga libraries always show the section; other media only when the scanner recorded comic-style values (fixed-layout manga-style EPUBs get those scanner defaults deliberately — when present they stay editable). --- internal/handlers/media_detail.go | 17 ++ internal/router/frontend.go | 7 + templates/book_detail_modals.templ | 22 +- templates/book_detail_modals_templ.go | 420 +++++++++++++------------- 4 files changed, 249 insertions(+), 217 deletions(-) diff --git a/internal/handlers/media_detail.go b/internal/handlers/media_detail.go index 0378bc12..492764be 100644 --- a/internal/handlers/media_detail.go +++ b/internal/handlers/media_detail.go @@ -12,6 +12,11 @@ import ( type MediaDetail struct { database.MediaItems // Embedded - ALL book fields available + // Display type of the owning library ("audiobooks", "comics", "ebooks", + // "manga"); "" when it could not be resolved. Drives media-type-aware + // UI gating (e.g. hiding the Comic/Manga editor section). + LibraryTypeName string + // Audio editorial/tech surfaces (A2a): duration parsed out of the // audio_metadata JSONB the scanner wrote (display-only). audioDurationSeconds float64 @@ -44,6 +49,18 @@ type MediaDetail struct { DeletedAnnotations []DeletedAnnotationResponse `json:"deleted_annotations"` } +// ShowComicMetadata reports whether the Comic/Manga section belongs on +// this item's edit modal: comics and manga libraries always; other media +// only when the scanner actually recorded comic-style values (fixed-layout +// manga-style EPUBs get scanner defaults). +func (md *MediaDetail) ShowComicMetadata() bool { + if md.LibraryTypeName == "comics" || md.LibraryTypeName == "manga" { + return true + } + return (md.MangaType.Valid && md.MangaType.String != "") || + (md.ReadingDirection.Valid && md.ReadingDirection.String != "") +} + // BookStatsData is the per-book reading-stats card payload. type BookStatsData struct { TotalMinutes int diff --git a/internal/router/frontend.go b/internal/router/frontend.go index 711027f5..4d7008da 100644 --- a/internal/router/frontend.go +++ b/internal/router/frontend.go @@ -1712,6 +1712,12 @@ func registerFrontendRoutes(cfg *Config) { } // Assemble response (no field duplication!) + libraryTypeName := "" + if lib, lerr := cfg.Queries.GetLibrary(c.Request().Context(), mediaItem.LibraryID); lerr == nil { + if lt, terr := cfg.Queries.GetLibraryType(c.Request().Context(), lib.LibraryTypeID); terr == nil { + libraryTypeName = lt.Name + } + } detail := handlers.MediaDetail{ MediaItems: mediaItem, // Embedded - ALL fields available FileLocation: fileLocation, @@ -1720,6 +1726,7 @@ func registerFrontendRoutes(cfg *Config) { Collections: collections, ReadingProgress: progress, BookStats: bookStats, + LibraryTypeName: libraryTypeName, ActiveConflict: activeConflict, NotesCount: len(notes), HighlightsCount: len(highlights), diff --git a/templates/book_detail_modals.templ b/templates/book_detail_modals.templ index 011d7f0d..2dc19281 100644 --- a/templates/book_detail_modals.templ +++ b/templates/book_detail_modals.templ @@ -543,16 +543,17 @@ templ MetadataEditorModal(book handlers.MediaDetail) { } -
- + if book.ShowComicMetadata() { +
+
@@ -601,6 +602,7 @@ templ MetadataEditorModal(book handlers.MediaDetail) {
+ }
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 134, " class=\"rounded\">
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 145, "Save") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err }