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) {
+ }
Technical ")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 135, "Technical ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -1395,7 +1401,7 @@ func MetadataEditorModal(book handlers.MediaDetail) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 135, " ")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 136, " ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -1403,72 +1409,72 @@ func MetadataEditorModal(book handlers.MediaDetail) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 136, " ")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 142, "\" readonly class=\"input opacity-60 font-mono text-xs\">
")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -1476,7 +1482,7 @@ func MetadataEditorModal(book handlers.MediaDetail) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 142, "Rescan ")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 143, "Rescan ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -1484,7 +1490,7 @@ func MetadataEditorModal(book handlers.MediaDetail) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 143, "Reset to Scanned Cancel ")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 144, "Reset to Scanned Cancel ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@@ -1492,7 +1498,7 @@ func MetadataEditorModal(book handlers.MediaDetail) templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
- templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 144, "Save
")
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 145, "Save")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}