weiro/handlers/posts.go

204 lines
4.2 KiB
Go
Raw Normal View History

package handlers
import (
"fmt"
"strconv"
"github.com/gofiber/fiber/v3"
"lmika.dev/lmika/weiro/models"
"lmika.dev/lmika/weiro/providers/db"
"lmika.dev/lmika/weiro/services/categories"
"lmika.dev/lmika/weiro/services/posts"
)
type PostsHandler struct {
PostService *posts.Service
CategoryService *categories.Service
}
func (ph PostsHandler) Index(c fiber.Ctx) error {
2026-02-23 10:18:34 +00:00
var req struct {
Filter string `query:"filter"`
Page int `query:"page"`
2026-02-23 10:18:34 +00:00
}
if err := c.Bind().Query(&req); err != nil {
return fiber.ErrBadRequest
}
const perPage = 25
if req.Page < 1 {
req.Page = 1
}
result, err := ph.PostService.ListPosts(c.Context(), req.Filter == "deleted", db.PagingParams{
Offset: int64((req.Page - 1) * perPage),
Limit: perPage,
})
if err != nil {
return err
}
totalPages := int(result.TotalCount+int64(perPage)-1) / perPage
if totalPages < 1 {
totalPages = 1
}
pageInfo := models.PageInfo{
CurrentPage: req.Page,
TotalPages: totalPages,
PostsPerPage: perPage,
}
2026-02-23 10:18:34 +00:00
return accepts(c, json(func() any {
return result.Posts
2026-02-23 10:18:34 +00:00
}), html(func(c fiber.Ctx) error {
return c.Render("posts/index", fiber.Map{
"req": req,
"posts": result.Posts,
"pageInfo": pageInfo,
2026-02-23 10:18:34 +00:00
})
}))
}
func (ph PostsHandler) New(c fiber.Ctx) error {
p := models.Post{
GUID: models.NewNanoID(),
State: models.StateDraft,
}
cats, err := ph.CategoryService.ListCategories(c.Context())
if err != nil {
return err
}
return c.Render("posts/edit", fiber.Map{
"post": p,
"categories": cats,
"selectedCategories": map[int64]bool{},
2026-03-25 10:09:57 +00:00
"bodyClass": "large-editor",
})
}
func (ph PostsHandler) Edit(c fiber.Ctx) error {
postIDStr := c.Params("postID")
if postIDStr == "" {
return fiber.ErrBadRequest
}
postID, err := strconv.ParseInt(postIDStr, 10, 64)
if err != nil {
return fiber.ErrBadRequest
}
post, err := ph.PostService.GetPost(c.Context(), postID)
if err != nil {
return err
}
cats, err := ph.CategoryService.ListCategories(c.Context())
if err != nil {
return err
}
postCats, err := ph.PostService.GetPostCategories(c.Context(), postID)
if err != nil {
return err
}
selectedCategories := make(map[int64]bool)
for _, pc := range postCats {
selectedCategories[pc.ID] = true
}
2026-02-23 10:18:34 +00:00
return accepts(c, json(func() any {
return post
}), html(func(c fiber.Ctx) error {
return c.Render("posts/edit", fiber.Map{
"post": post,
"categories": cats,
"selectedCategories": selectedCategories,
2026-03-25 10:09:57 +00:00
"bodyClass": "large-editor",
2026-02-23 10:18:34 +00:00
})
}))
}
func (ph PostsHandler) Update(c fiber.Ctx) error {
var req posts.CreatePostParams
if err := c.Bind().Body(&req); err != nil {
return err
}
post, err := ph.PostService.UpdatePost(c.Context(), req)
if err != nil {
return err
}
2026-02-23 10:18:34 +00:00
return accepts(c, json(func() any {
// TODO: should be created if brand new
return post
}), html(func(c fiber.Ctx) error {
return c.Redirect().To(fmt.Sprintf("/sites/%v/posts", post.SiteID))
}))
}
func (ph PostsHandler) Patch(c fiber.Ctx) error {
postIDStr := c.Params("postID")
if postIDStr == "" {
return fiber.ErrBadRequest
}
postID, err := strconv.ParseInt(postIDStr, 10, 64)
if err != nil {
return fiber.ErrBadRequest
}
var req struct {
Action string `json:"action"`
}
if err := c.Bind().Body(&req); err != nil {
return err
}
switch req.Action {
case "restore":
if err := ph.PostService.RestorePost(c.Context(), postID); err != nil {
return err
}
default:
return fiber.ErrBadRequest
}
return accepts(c, json(func() any {
return struct{}{}
}), html(func(c fiber.Ctx) error {
2026-03-18 11:19:26 +00:00
return c.Redirect().To(fmt.Sprintf("/sites/%v/posts", models.MustGetSite(c.Context()).ID))
2026-02-23 10:18:34 +00:00
}))
}
func (ph PostsHandler) Delete(c fiber.Ctx) error {
postIDStr := c.Params("postID")
if postIDStr == "" {
return fiber.ErrBadRequest
}
postID, err := strconv.ParseInt(postIDStr, 10, 64)
if err != nil {
return fiber.ErrBadRequest
}
var req struct {
Hard bool `query:"hard"`
}
if err := c.Bind().Query(&req); err != nil {
return err
}
if err := ph.PostService.DeletePost(c.Context(), postID, req.Hard); err != nil {
return err
}
return accepts(c, json(func() any {
return fiber.Map{}
}), html(func(c fiber.Ctx) error {
return c.Redirect().To("/")
}))
}