From a4d8a3b37f57099f29b0d017ddd4746702875cd7 Mon Sep 17 00:00:00 2001 From: LittleSheep Date: Thu, 25 Jul 2024 22:58:47 +0800 Subject: [PATCH] :sparkles: User can pin multiple posts --- pkg/internal/models/accounts.go | 3 --- pkg/internal/models/posts.go | 2 ++ pkg/internal/server/api/index.go | 1 + pkg/internal/server/api/posts_api.go | 12 ++++++------ pkg/internal/server/api/users_api.go | 25 +++++++++++++++++++++++-- pkg/internal/services/posts.go | 13 +++++++++++++ 6 files changed, 45 insertions(+), 11 deletions(-) diff --git a/pkg/internal/models/accounts.go b/pkg/internal/models/accounts.go index 489b198..be54d5a 100644 --- a/pkg/internal/models/accounts.go +++ b/pkg/internal/models/accounts.go @@ -17,9 +17,6 @@ type Account struct { Reactions []Reaction `json:"reactions"` ExternalID uint `json:"external_id"` - PinnedPost *Post `json:"pinned_post"` - PinnedPostID *uint `json:"pinned_post_id"` - TotalUpvote int `json:"total_upvote"` TotalDownvote int `json:"total_downvote"` } diff --git a/pkg/internal/models/posts.go b/pkg/internal/models/posts.go index e506429..0b2ccad 100644 --- a/pkg/internal/models/posts.go +++ b/pkg/internal/models/posts.go @@ -28,6 +28,8 @@ type Post struct { RepostTo *Post `json:"repost_to" gorm:"foreignKey:RepostID"` Realm *Realm `json:"realm"` + PinnedAt *time.Time `json:"pinned_at"` + IsDraft bool `json:"is_draft"` PublishedAt *time.Time `json:"published_at"` PublishedUntil *time.Time `json:"published_until"` diff --git a/pkg/internal/server/api/index.go b/pkg/internal/server/api/index.go index 9e41d80..f2eeccd 100644 --- a/pkg/internal/server/api/index.go +++ b/pkg/internal/server/api/index.go @@ -9,6 +9,7 @@ func MapAPIs(app *fiber.App, baseURL string) { { api.Get("/users/me", getUserinfo) api.Get("/users/:account", getOthersInfo) + api.Get("/users/:account/pin", listOthersPinnedPost) recommendations := api.Group("/recommendations").Name("Recommendations API") { diff --git a/pkg/internal/server/api/posts_api.go b/pkg/internal/server/api/posts_api.go index 14befad..0da3146 100644 --- a/pkg/internal/server/api/posts_api.go +++ b/pkg/internal/server/api/posts_api.go @@ -173,11 +173,11 @@ func pinPost(c *fiber.Ctx) error { return fiber.NewError(fiber.StatusBadRequest, fmt.Sprintf("unable to find post in your posts to pin: %v", err)) } - user.PinnedPostID = &res.ID - - if err := database.C.Save(&user).Error; err != nil { - return fiber.NewError(fiber.StatusInternalServerError, fmt.Sprintf("failed to save changes: %v", err)) + if status, err := services.PinPost(res); err != nil { + return fiber.NewError(fiber.StatusInternalServerError, err.Error()) + } else if status { + return c.SendStatus(fiber.StatusOK) + } else { + return c.SendStatus(fiber.StatusNoContent) } - - return c.SendStatus(fiber.StatusOK) } diff --git a/pkg/internal/server/api/users_api.go b/pkg/internal/server/api/users_api.go index 23d92d7..0ecb173 100644 --- a/pkg/internal/server/api/users_api.go +++ b/pkg/internal/server/api/users_api.go @@ -4,6 +4,7 @@ import ( "git.solsynth.dev/hydrogen/interactive/pkg/internal/database" "git.solsynth.dev/hydrogen/interactive/pkg/internal/gap" "git.solsynth.dev/hydrogen/interactive/pkg/internal/models" + "git.solsynth.dev/hydrogen/interactive/pkg/internal/services" "github.com/gofiber/fiber/v2" ) @@ -16,7 +17,6 @@ func getUserinfo(c *fiber.Ctx) error { var data models.Account if err := database.C. Where(&models.Account{BaseModel: models.BaseModel{ID: user.ID}}). - Preload("PinnedPost"). First(&data).Error; err != nil { return fiber.NewError(fiber.StatusInternalServerError, err.Error()) } @@ -30,10 +30,31 @@ func getOthersInfo(c *fiber.Ctx) error { var data models.Account if err := database.C. Where(&models.Account{Name: account}). - Preload("PinnedPost"). First(&data).Error; err != nil { return fiber.NewError(fiber.StatusInternalServerError, err.Error()) } return c.JSON(data) } + +func listOthersPinnedPost(c *fiber.Ctx) error { + account := c.Params("account") + + var user models.Account + if err := database.C. + Where(&models.Account{Name: account}). + First(&user).Error; err != nil { + return fiber.NewError(fiber.StatusInternalServerError, err.Error()) + } + + tx := services.FilterPostDraft(database.C) + tx = tx.Where("author_id = ?", user.ID) + tx = tx.Where("pinned_at IS NOT NULL") + + items, err := services.ListPost(tx, 100, 0, "published_at DESC") + if err != nil { + return fiber.NewError(fiber.StatusBadRequest, err.Error()) + } + + return c.JSON(items) +} diff --git a/pkg/internal/services/posts.go b/pkg/internal/services/posts.go index 6618b66..857e679 100644 --- a/pkg/internal/services/posts.go +++ b/pkg/internal/services/posts.go @@ -310,3 +310,16 @@ func ReactPost(user models.Account, reaction models.Reaction) (bool, models.Reac return false, reaction, err } } + +func PinPost(post models.Post) (bool, error) { + if post.PinnedAt != nil { + post.PinnedAt = nil + } else { + post.PinnedAt = lo.ToPtr(time.Now()) + } + + if err := database.C.Save(&post).Error; err != nil { + return post.PinnedAt != nil, err + } + return post.PinnedAt != nil, nil +}