diff --git a/pkg/models/posts.go b/pkg/models/posts.go index 852f7fa..014122c 100644 --- a/pkg/models/posts.go +++ b/pkg/models/posts.go @@ -8,8 +8,8 @@ type Post struct { Alias string `json:"alias" gorm:"uniqueIndex"` Title string `json:"title"` Content string `json:"content"` - Tags []Tag `gorm:"many2many:post_tags"` - Categories []Category `gorm:"many2many:post_categories"` + Tags []Tag `json:"tags" gorm:"many2many:post_tags"` + Categories []Category `json:"categories" gorm:"many2many:post_categories"` LikedAccounts []PostLike `json:"liked_accounts"` DislikedAccounts []PostDislike `json:"disliked_accounts"` RepostTo *Post `json:"repost_to" gorm:"foreignKey:RepostID"` diff --git a/pkg/server/posts_api.go b/pkg/server/posts_api.go index adcd0d9..d1919fa 100644 --- a/pkg/server/posts_api.go +++ b/pkg/server/posts_api.go @@ -1,13 +1,14 @@ package server import ( + "strings" + "code.smartsheep.studio/hydrogen/interactive/pkg/database" "code.smartsheep.studio/hydrogen/interactive/pkg/models" "code.smartsheep.studio/hydrogen/interactive/pkg/services" "github.com/gofiber/fiber/v2" "github.com/google/uuid" "github.com/samber/lo" - "strings" ) func listPost(c *fiber.Ctx) error { @@ -37,7 +38,6 @@ func listPost(c *fiber.Ctx) error { "count": count, "data": posts, }) - } func createPost(c *fiber.Ctx) error { @@ -49,6 +49,8 @@ func createPost(c *fiber.Ctx) error { Content string `json:"content" validate:"required"` Tags []models.Tag `json:"tags"` Categories []models.Category `json:"categories"` + RepostTo uint `json:"repost_to"` + ReplyTo uint `json:"reply_to"` } if err := BindAndValidate(c, &data); err != nil { @@ -57,7 +59,32 @@ func createPost(c *fiber.Ctx) error { data.Alias = strings.ReplaceAll(uuid.NewString(), "-", "") } - post, err := services.NewPost(user, data.Alias, data.Title, data.Content, data.Categories, data.Tags) + var repostTo *uint = nil + var replyTo *uint = nil + var relatedCount int64 + if data.RepostTo > 0 { + if err := database.C.Where(&models.Post{ + BaseModel: models.BaseModel{ID: data.RepostTo}, + }).Model(&models.Post{}).Count(&relatedCount).Error; err != nil { + return fiber.NewError(fiber.StatusBadRequest, err.Error()) + } else if relatedCount <= 0 { + return fiber.NewError(fiber.StatusNotFound, "related post was not found") + } else { + repostTo = &data.RepostTo + } + } else if data.ReplyTo > 0 { + if err := database.C.Where(&models.Post{ + BaseModel: models.BaseModel{ID: data.ReplyTo}, + }).Model(&models.Post{}).Count(&relatedCount).Error; err != nil { + return fiber.NewError(fiber.StatusBadRequest, err.Error()) + } else if relatedCount <= 0 { + return fiber.NewError(fiber.StatusNotFound, "related post was not found") + } else { + replyTo = &data.ReplyTo + } + } + + post, err := services.NewPost(user, data.Alias, data.Title, data.Content, data.Categories, data.Tags, replyTo, repostTo) if err != nil { return fiber.NewError(fiber.StatusBadRequest, err.Error()) } diff --git a/pkg/services/posts.go b/pkg/services/posts.go index a4b4265..297b672 100644 --- a/pkg/services/posts.go +++ b/pkg/services/posts.go @@ -1,10 +1,11 @@ package services import ( - "code.smartsheep.studio/hydrogen/interactive/pkg/database" - "code.smartsheep.studio/hydrogen/interactive/pkg/models" "errors" "fmt" + + "code.smartsheep.studio/hydrogen/interactive/pkg/database" + "code.smartsheep.studio/hydrogen/interactive/pkg/models" "github.com/samber/lo" "github.com/spf13/viper" "gorm.io/gorm" @@ -16,6 +17,10 @@ func ListPost(tx *gorm.DB, take int, offset int) ([]*models.Post, error) { Limit(take). Offset(offset). Preload("Author"). + Preload("RepostTo"). + Preload("ReplyTo"). + Preload("RepostTo.Author"). + Preload("ReplyTo.Author"). Find(&posts).Error; err != nil { return posts, err } @@ -62,8 +67,9 @@ func NewPost( alias, title, content string, categories []models.Category, tags []models.Tag, + replyTo, repostTo *uint, ) (models.Post, error) { - return NewPostWithRealm(user, nil, alias, title, content, categories, tags) + return NewPostWithRealm(user, nil, alias, title, content, categories, tags, replyTo, repostTo) } func NewPostWithRealm( @@ -72,6 +78,7 @@ func NewPostWithRealm( alias, title, content string, categories []models.Category, tags []models.Tag, + replyTo, repostTo *uint, ) (models.Post, error) { var err error var post models.Post @@ -101,6 +108,8 @@ func NewPostWithRealm( Categories: categories, AuthorID: user.ID, RealmID: realmId, + RepostID: repostTo, + ReplyID: replyTo, } if err := database.C.Save(&post).Error; err != nil { diff --git a/pkg/view/src/components/PostItem.tsx b/pkg/view/src/components/PostItem.tsx index f8deff6..fef6fb9 100644 --- a/pkg/view/src/components/PostItem.tsx +++ b/pkg/view/src/components/PostItem.tsx @@ -1,7 +1,16 @@ import { createSignal, Show } from "solid-js"; import { getAtk, useUserinfo } from "../stores/userinfo.tsx"; -export default function PostItem(props: { post: any, onError: (message: string | null) => void, onReact: () => void }) { +export default function PostItem(props: { + post: any, + noAuthor?: boolean, + noControl?: boolean, + onRepost?: (post: any) => void, + onReply?: (post: any) => void, + onEdit?: (post: any) => void, + onError: (message: string | null) => void, + onReact: () => void +}) { const [reacting, setReacting] = createSignal(false); const userinfo = useUserinfo(); @@ -23,79 +32,111 @@ export default function PostItem(props: { post: any, onError: (message: string | return (
- - -
-
- - + + -
+

{props.post.title}

{props.post.content}
-
-
- -
-
- + +

+ + Reposted a post +

+
+
- -
- + + +

+ + Replied a post +

+
+
-
- -
-
- -
- -
- -
- - -
- +
+ +
+
+
+ +
+ +
+ +
+
+ +
+
+ +
+ +
+ +
+ + +
+
+
+
); } \ No newline at end of file diff --git a/pkg/view/src/components/PostList.tsx b/pkg/view/src/components/PostList.tsx index 43163b0..21ebfb2 100644 --- a/pkg/view/src/components/PostList.tsx +++ b/pkg/view/src/components/PostList.tsx @@ -5,13 +5,16 @@ import PostItem from "./PostItem.tsx"; export default function PostList(props: { info: { data: any[], count: number } | null, + onRepost?: (post: any) => void, + onReply?: (post: any) => void, + onEdit?: (post: any) => void, onUpdate: (pn: number) => Promise, onError: (message: string | null) => void }) { const [loading, setLoading] = createSignal(true); - const posts = createMemo(() => props.info?.data) - const postCount = createMemo(() => props.info?.count ?? 0) + const posts = createMemo(() => props.info?.data); + const postCount = createMemo(() => props.info?.count ?? 0); const [page, setPage] = createSignal(1); const pageCount = createMemo(() => Math.ceil(postCount() / 10)); @@ -35,7 +38,14 @@ export default function PostList(props: {
- {item => readPosts()} onError={props.onError} />} + {item => readPosts()} + onError={props.onError} + />}
diff --git a/pkg/view/src/components/PostPublish.tsx b/pkg/view/src/components/PostPublish.tsx index a69fb73..41375cf 100644 --- a/pkg/view/src/components/PostPublish.tsx +++ b/pkg/view/src/components/PostPublish.tsx @@ -6,6 +6,7 @@ import styles from "./PostPublish.module.css"; export default function PostPublish(props: { replying?: any, reposting?: any, + editing?: any, onError: (message: string | null) => void, onPost: () => void }) { @@ -30,7 +31,9 @@ export default function PostPublish(props: { body: JSON.stringify({ alias: data.alias ?? crypto.randomUUID().replace(/-/g, ""), title: data.title, - content: data.content + content: data.content, + repost_to: props.reposting?.id, + reply_to: props.replying?.id, }) }); if (res.status !== 200) { @@ -60,6 +63,26 @@ export default function PostPublish(props: {
+ + + + + + + + + +