✨ User can pin multiple posts
This commit is contained in:
		@@ -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"`
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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"`
 | 
			
		||||
 
 | 
			
		||||
@@ -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")
 | 
			
		||||
		{
 | 
			
		||||
 
 | 
			
		||||
@@ -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)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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)
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user