fix(ui): hide Comic/Manga editor section for non-comics media

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).
This commit is contained in:
John O'Keefe committed 2026-10-25 12:08:26 -04:00
1 parent ab2a5568ae
commit d41c3e4774
4 files changed
+249 -217

No files matched your search

+17
View File
@@ -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
+7
View File
@@ -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),