refactor(cards): SSR collection detail ladder through the builder

All five branch shapes of GET /collections/:id now build cards via the
cards.go adapters: smart (BookCardsFromMediaItems), system-query (same
— gains format_group/badge it previously dropped), scoped
(BookCardsFromCollectionDashRows with the Excluded filter kept), and
the all-libraries branch whose rows distinguish ID vs MediaItemID
(BookCardsFromCollectionItemRows). LibraryTypeMap hoisted to once per
page; both []BookInfo{} error seeds die with the adapters' non-nil
empties.
This commit is contained in:
John O'Keefe committed 2026-10-17 14:06:39 -04:00
1 parent bdad40e211
commit a13b268adc
1 file changed
+8 -48
+8 -48
View File
@@ -709,6 +709,8 @@ func registerFrontendRoutes(cfg *Config) {
visibleIDs = nil
}
libTypes := handlers.LibraryTypeMap(c.Request().Context(), cfg.Queries)
if isSmart {
// Smart (dynamic) collection: membership is evaluated live —
// visible libraries, live items only, any enabled rule matches.
@@ -720,17 +722,7 @@ func registerFrontendRoutes(cfg *Config) {
if evalErr != nil {
return renderErrorPage(c, "Error loading books", "books_load_error")
}
bookCards := make([]handlers.BookInfo, 0, len(matches))
for _, item := range matches {
itemUUID, _ := uuid.FromBytes(item.ID.Bytes[0:16])
bookCards = append(bookCards, handlers.BookInfo{
MediaItemID: itemUUID.String(),
Title: item.Title,
Author: getText(item.Author),
CoverImagePath: utils.ResolveMediaURL(item.LibraryID, item.CoverImagePath),
})
}
books = bookCards
books = handlers.BookCardsFromMediaItems(matches, libTypes)
} else if collection.IsSystemCollection.Bool && collection.QueryType.Valid && collection.QueryType.String != "" && collection.QueryType.String != "filter" {
dashboardSvc := services.NewDashboardService(cfg.Queries)
sections, secErr := dashboardSvc.GetDashboardSections(c.Request().Context(), userUUID, libRes.LibUUID, 1000, []string{}, []string{})
@@ -740,17 +732,7 @@ func registerFrontendRoutes(cfg *Config) {
for _, section := range sections {
if section.CollectionID.String() == collectionID {
bookCards := make([]handlers.BookInfo, len(section.Items))
for i, item := range section.Items {
itemUUID, _ := uuid.FromBytes(item.ID.Bytes[0:16])
bookCards[i] = handlers.BookInfo{
MediaItemID: itemUUID.String(),
Title: item.Title,
Author: getText(item.Author),
CoverImagePath: utils.ResolveMediaURL(item.LibraryID, item.CoverImagePath),
}
}
books = bookCards
books = handlers.BookCardsFromMediaItems(section.Items, libTypes)
break
}
}
@@ -768,7 +750,7 @@ func registerFrontendRoutes(cfg *Config) {
Limit: pgtype.Int4{Int32: 1000, Valid: true},
})
if collErr != nil {
books = []handlers.BookInfo{}
books = handlers.BookCardsFromCollectionDashRows(nil, libTypes)
} else {
var validItems []database.GetCollectionItemsForDashboardRow
for _, item := range collItems {
@@ -776,36 +758,14 @@ func registerFrontendRoutes(cfg *Config) {
validItems = append(validItems, item)
}
}
bookCards := make([]handlers.BookInfo, len(validItems))
for i, item := range validItems {
itemUUID, _ := uuid.FromBytes(item.ID.Bytes[0:16])
bookCards[i] = handlers.BookInfo{
MediaItemID: itemUUID.String(),
Title: item.Title,
Author: getText(item.Author),
CoverImagePath: utils.ResolveMediaURL(item.LibraryID, item.CoverImagePath),
}
}
books = bookCards
books = handlers.BookCardsFromCollectionDashRows(validItems, libTypes)
}
} else {
collItems, collErr := cfg.Queries.GetCollectionItems(c.Request().Context(), pgtype.UUID{Bytes: collUUID, Valid: true})
if collErr != nil {
books = []handlers.BookInfo{}
collItems = nil
}
bookCards := make([]handlers.BookInfo, len(collItems))
for i, item := range collItems {
itemUUID, _ := uuid.FromBytes(item.MediaItemID.Bytes[0:16])
bookCards[i] = handlers.BookInfo{
MediaItemID: itemUUID.String(),
Title: item.Title,
Author: getText(item.Author),
CoverImagePath: utils.ResolveMediaURL(item.LibraryID, item.CoverImagePath),
}
}
books = bookCards
books = handlers.BookCardsFromCollectionItemRows(collItems, libTypes)
}
}
// Build collection data