diff --git a/internal/handlers/collections.go b/internal/handlers/collections.go index ddad262..389bae6 100644 --- a/internal/handlers/collections.go +++ b/internal/handlers/collections.go @@ -138,6 +138,7 @@ func (h *CollectionHandler) CreateCollection(c *echo.Context) error { func (h *CollectionHandler) GetCollections(c *echo.Context) error { includeAuto := c.QueryParam("include_auto") == "true" sortBy := c.QueryParam("sort_by") + libraryID := c.QueryParam("library_id") collections, err := h.GetCollectionsData(c) if err != nil { @@ -152,6 +153,7 @@ func (h *CollectionHandler) GetCollections(c *echo.Context) error { Icon string `json:"icon"` AutoAssignRules json.RawMessage `json:"auto_assign_rules"` CreatedAt string `json:"created_at"` + BookCount int `json:"book_count"` } response := make([]CollectionResponse, 0, len(collections)) @@ -159,6 +161,26 @@ func (h *CollectionHandler) GetCollections(c *echo.Context) error { if !includeAuto && len(col.AutoAssignRules) > 0 { continue } + + bookCount := 0 + if libraryID != "" { + libUUID, libErr := uuid.Parse(libraryID) + if libErr == nil { + items, countErr := h.db.GetCollectionItemsForDashboard(c.Request().Context(), database.GetCollectionItemsForDashboardParams{ + CollectionID: pgtype.UUID{Bytes: col.ID.Bytes, Valid: true}, + LibraryID: pgtype.UUID{Bytes: libUUID, Valid: true}, + Limit: 10000, + }) + if countErr == nil { + for _, item := range items { + if !item.Excluded.Valid || !item.Excluded.Bool { + bookCount++ + } + } + } + } + } + response = append(response, CollectionResponse{ ID: col.ID.Bytes, Name: col.Name, @@ -167,6 +189,7 @@ func (h *CollectionHandler) GetCollections(c *echo.Context) error { Icon: textToString(col.Icon), AutoAssignRules: col.AutoAssignRules, CreatedAt: col.CreatedAt.Time.String(), + BookCount: bookCount, }) } @@ -197,19 +220,83 @@ func (h *CollectionHandler) GetCollection(c *echo.Context) error { return c.JSON(http.StatusNotFound, map[string]string{"error": "collection not found"}) } - books, err := h.GetCollectionBooksData(c, collectionID) - if err != nil { - return c.JSON(http.StatusInternalServerError, map[string]string{"error": err.Error()}) - } + libraryID := c.QueryParam("library_id") + var bookList []BookInfo - bookList := make([]BookInfo, 0, len(books)) - for _, book := range books { - bookList = append(bookList, BookInfo{ - MediaItemID: uuid.UUID(book.MediaItemID.Bytes).String(), - Title: book.Title, - Author: textToString(book.Author), - CoverImagePath: utils.ResolveMediaURL(book.LibraryID, book.CoverImagePath), - }) + if libraryID != "" && collection.QueryType.Valid && collection.QueryType.String != "" { + libUUID, libErr := uuid.Parse(libraryID) + if libErr != nil { + return c.JSON(http.StatusBadRequest, map[string]string{"error": "invalid library_id"}) + } + user := c.Get("user").(database.Users) + userUUID := uuid.UUID(user.ID.Bytes) + dashboardSvc := services.NewDashboardService(h.db) + sections, secErr := dashboardSvc.GetDashboardSections(c.Request().Context(), userUUID, libUUID, 1000, []string{}, []string{}) + if secErr != nil { + return c.JSON(http.StatusInternalServerError, map[string]string{"error": secErr.Error()}) + } + for _, section := range sections { + if section.CollectionID == collectionID { + bookCards := make([]BookInfo, len(section.Items)) + for i, item := range section.Items { + itemUUID, _ := uuid.FromBytes(item.ID.Bytes[0:16]) + bookCards[i] = BookInfo{ + MediaItemID: itemUUID.String(), + Title: item.Title, + Author: textToString(item.Author), + CoverImagePath: utils.ResolveMediaURL(item.LibraryID, item.CoverImagePath), + } + } + bookList = bookCards + break + } + } + } else if libraryID != "" { + libUUID, libErr := uuid.Parse(libraryID) + if libErr != nil { + return c.JSON(http.StatusBadRequest, map[string]string{"error": "invalid library_id"}) + } + collItems, collErr := h.db.GetCollectionItemsForDashboard(c.Request().Context(), + database.GetCollectionItemsForDashboardParams{ + CollectionID: pgtype.UUID{Bytes: collectionID, Valid: true}, + LibraryID: pgtype.UUID{Bytes: libUUID, Valid: true}, + Limit: 10000, + }) + if collErr != nil { + bookList = []BookInfo{} + } else { + var validItems []database.GetCollectionItemsForDashboardRow + for _, item := range collItems { + if !item.Excluded.Valid || !item.Excluded.Bool { + validItems = append(validItems, item) + } + } + bookCards := make([]BookInfo, len(validItems)) + for i, item := range validItems { + itemUUID, _ := uuid.FromBytes(item.ID.Bytes[0:16]) + bookCards[i] = BookInfo{ + MediaItemID: itemUUID.String(), + Title: item.Title, + Author: textToString(item.Author), + CoverImagePath: utils.ResolveMediaURL(item.LibraryID, item.CoverImagePath), + } + } + bookList = bookCards + } + } else { + books, booksErr := h.GetCollectionBooksData(c, collectionID) + if booksErr != nil { + return c.JSON(http.StatusInternalServerError, map[string]string{"error": booksErr.Error()}) + } + bookList = make([]BookInfo, 0, len(books)) + for _, book := range books { + bookList = append(bookList, BookInfo{ + MediaItemID: uuid.UUID(book.MediaItemID.Bytes).String(), + Title: book.Title, + Author: textToString(book.Author), + CoverImagePath: utils.ResolveMediaURL(book.LibraryID, book.CoverImagePath), + }) + } } var viewSettings map[string]interface{}