diff --git a/pkg/models/categories.go b/pkg/models/categories.go
index 20c232c..d3568fb 100644
--- a/pkg/models/categories.go
+++ b/pkg/models/categories.go
@@ -3,7 +3,7 @@ package models
type Tag struct {
BaseModel
- Alias string `json:"alias" gorm:"uniqueIndex"`
+ Alias string `json:"alias" gorm:"uniqueIndex" validate:"lowercase,alphanum,min=4,max=24"`
Name string `json:"name"`
Description string `json:"description"`
Posts []Post `json:"posts" gorm:"many2many:post_tags"`
@@ -12,7 +12,7 @@ type Tag struct {
type Category struct {
BaseModel
- Alias string `json:"alias" gorm:"uniqueIndex"`
+ Alias string `json:"alias" gorm:"uniqueIndex" validate:"lowercase,alphanum,min=4,max=24"`
Name string `json:"name"`
Description string `json:"description"`
Posts []Post `json:"categories" gorm:"many2many:post_categories"`
diff --git a/pkg/services/posts.go b/pkg/services/posts.go
index 4b7fe95..1fb9f81 100644
--- a/pkg/services/posts.go
+++ b/pkg/services/posts.go
@@ -19,12 +19,18 @@ func ListPost(tx *gorm.DB, take int, offset int) ([]*models.Post, error) {
Offset(offset).
Preload("Author").
Preload("Attachments").
+ Preload("Categories").
+ Preload("Tags").
Preload("RepostTo").
Preload("ReplyTo").
Preload("RepostTo.Author").
Preload("ReplyTo.Author").
Preload("RepostTo.Attachments").
Preload("ReplyTo.Attachments").
+ Preload("RepostTo.Categories").
+ Preload("ReplyTo.Categories").
+ Preload("RepostTo.Tags").
+ Preload("ReplyTo.Tags").
Find(&posts).Error; err != nil {
return posts, err
}
diff --git a/pkg/view/src/components/PostItem.tsx b/pkg/view/src/components/PostItem.tsx
index 4099a0d..3c8decd 100644
--- a/pkg/view/src/components/PostItem.tsx
+++ b/pkg/view/src/components/PostItem.tsx
@@ -1,4 +1,4 @@
-import { createSignal, Show } from "solid-js";
+import { createSignal, For, Show } from "solid-js";
import { getAtk, useUserinfo } from "../stores/userinfo.tsx";
import PostAttachments from "./PostAttachments.tsx";
@@ -59,6 +59,19 @@ export default function PostItem(props: {
{props.post.title}
{props.post.content}
+
+
diff --git a/pkg/view/src/components/PostPublish.module.css b/pkg/view/src/components/PostPublish.module.css
index 2b28c49..1c05ece 100644
--- a/pkg/view/src/components/PostPublish.module.css
+++ b/pkg/view/src/components/PostPublish.module.css
@@ -1,4 +1,8 @@
.publishInput {
outline-style: none !important;
outline-width: 0 !important;
+}
+
+.description {
+ color: var(--fallback-bc, oklch(var(--bc)/.8));
}
\ No newline at end of file
diff --git a/pkg/view/src/components/PostPublish.tsx b/pkg/view/src/components/PostPublish.tsx
index 287131b..72f6652 100644
--- a/pkg/view/src/components/PostPublish.tsx
+++ b/pkg/view/src/components/PostPublish.tsx
@@ -18,8 +18,14 @@ export default function PostPublish(props: {
const [uploading, setUploading] = createSignal(false);
const [attachments, setAttachments] = createSignal([]);
+ const [categories, setCategories] = createSignal<{ alias: string, name: string }[]>([]);
+ const [tags, setTags] = createSignal<{ alias: string, name: string }[]>([]);
- createEffect(() => setAttachments(props.editing?.attachments ?? []), [props.editing]);
+ createEffect(() => {
+ setAttachments(props.editing?.attachments ?? []);
+ setCategories(props.editing?.categories ?? []);
+ setTags(props.editing?.tags ?? []);
+ }, [props.editing]);
async function doPost(evt: SubmitEvent) {
evt.preventDefault();
@@ -40,6 +46,8 @@ export default function PostPublish(props: {
title: data.title,
content: data.content,
attachments: attachments(),
+ categories: categories(),
+ tags: tags(),
published_at: data.published_at ? new Date(data.published_at as string) : new Date(),
repost_to: props.reposting?.id,
reply_to: props.replying?.id
@@ -75,6 +83,8 @@ export default function PostPublish(props: {
title: data.title,
content: data.content,
attachments: attachments(),
+ categories: categories(),
+ tags: tags(),
published_at: data.published_at ? new Date(data.published_at as string) : new Date()
})
});
@@ -91,7 +101,8 @@ export default function PostPublish(props: {
async function uploadAttachments(evt: SubmitEvent) {
evt.preventDefault();
- const data = new FormData(evt.target as HTMLFormElement);
+ const form = evt.target as HTMLFormElement;
+ const data = new FormData(form);
if (!data.get("attachment")) return;
setUploading(true);
@@ -106,12 +117,47 @@ export default function PostPublish(props: {
const data = await res.json();
setAttachments(attachments().concat([data.info]));
props.onError(null);
+ form.reset();
}
setUploading(false);
}
+ function addCategory(evt: SubmitEvent) {
+ evt.preventDefault();
+
+ const form = evt.target as HTMLFormElement;
+ const data = Object.fromEntries(new FormData(form));
+ if (!data.alias) data.alias = crypto.randomUUID().replace(/-/g, "");
+ if (!data.name) return;
+
+ setCategories(categories().concat([data as any]));
+ form.reset();
+ }
+
+ function removeCategory(target: any) {
+ setCategories(categories().filter(item => item.alias !== target.alias))
+ }
+
+ function addTag(evt: SubmitEvent) {
+ evt.preventDefault();
+
+ const form = evt.target as HTMLFormElement;
+ const data = Object.fromEntries(new FormData(evt.target as HTMLFormElement));
+ if (!data.alias) data.alias = crypto.randomUUID().replace(/-/g, "");
+ if (!data.name) return;
+
+ setTags(tags().concat([data as any]));
+ form.reset();
+ }
+
+ function removeTag(target: any) {
+ setTags(tags().filter(item => item.alias !== target.alias))
+ }
+
function resetForm() {
setAttachments([]);
+ setCategories([]);
+ setTags([]);
props.onReset();
}
@@ -174,13 +220,16 @@ export default function PostPublish(props: {
placeholder="What's happend?!" />
-
+
+
+
+
>
);
}
\ No newline at end of file