diff --git a/pkg/server/posts_api.go b/pkg/server/posts_api.go
index 2bb1157..1dee6d9 100644
--- a/pkg/server/posts_api.go
+++ b/pkg/server/posts_api.go
@@ -53,7 +53,6 @@ func getPost(c *fiber.Ctx) error {
func listPost(c *fiber.Ctx) error {
take := c.QueryInt("take", 0)
offset := c.QueryInt("offset", 0)
- authorId := c.Query("authorId")
tx := database.C.
Where("realm_id IS NULL").
@@ -61,13 +60,21 @@ func listPost(c *fiber.Ctx) error {
Order("created_at desc")
var author models.Account
- if len(authorId) > 0 {
- if err := database.C.Where(&models.Account{Name: authorId}).First(&author).Error; err != nil {
+ if len(c.Query("authorId")) > 0 {
+ if err := database.C.Where(&models.Account{Name: c.Query("authorId")}).First(&author).Error; err != nil {
return fiber.NewError(fiber.StatusNotFound, err.Error())
}
tx = tx.Where(&models.Post{AuthorID: author.ID})
}
+ if len(c.Query("category")) > 0 {
+ tx = services.FilterPostWithCategory(tx, c.Query("category"))
+ }
+
+ if len(c.Query("tag")) > 0 {
+ tx = services.FilterPostWithTag(tx, c.Query("tag"))
+ }
+
var count int64
if err := tx.
Model(&models.Post{}).
diff --git a/pkg/services/posts.go b/pkg/services/posts.go
index dd40cf1..a7ee191 100644
--- a/pkg/services/posts.go
+++ b/pkg/services/posts.go
@@ -30,6 +30,20 @@ func PreloadRelatedPost(tx *gorm.DB) *gorm.DB {
Preload("ReplyTo.Tags")
}
+func FilterPostWithCategory(tx *gorm.DB, alias string) *gorm.DB {
+ prefix := viper.GetString("database.prefix")
+ return tx.Joins(fmt.Sprintf("JOIN %spost_categories ON %sposts.id = %spost_categories.post_id", prefix, prefix, prefix)).
+ Joins(fmt.Sprintf("JOIN %scategories ON %scategories.id = %spost_categories.category_id", prefix, prefix, prefix)).
+ Where(fmt.Sprintf("%scategories.alias = ?", prefix), alias)
+}
+
+func FilterPostWithTag(tx *gorm.DB, alias string) *gorm.DB {
+ prefix := viper.GetString("database.prefix")
+ return tx.Joins(fmt.Sprintf("JOIN %spost_tags ON %sposts.id = %spost_tags.post_id", prefix, prefix, prefix)).
+ Joins(fmt.Sprintf("JOIN %stags ON %stags.id = %spost_tags.tag_id", prefix, prefix, prefix)).
+ Where(fmt.Sprintf("%stags.alias = ?", prefix), alias)
+}
+
func GetPost(tx *gorm.DB) (*models.Post, error) {
var post *models.Post
if err := PreloadRelatedPost(tx).
diff --git a/pkg/view/src/components/PostItem.tsx b/pkg/view/src/components/PostItem.tsx
index 2fdd92c..b59e351 100644
--- a/pkg/view/src/components/PostItem.tsx
+++ b/pkg/view/src/components/PostItem.tsx
@@ -13,6 +13,7 @@ export default function PostItem(props: {
onReply?: (post: any) => void,
onEdit?: (post: any) => void,
onDelete?: (post: any) => void,
+ onSearch?: (filter: any) => void,
onError: (message: string | null) => void,
onReact: () => void
}) {
@@ -72,16 +73,22 @@ export default function PostItem(props: {
-
+
diff --git a/pkg/view/src/components/PostList.tsx b/pkg/view/src/components/PostList.tsx
index ca7b91a..c30a841 100644
--- a/pkg/view/src/components/PostList.tsx
+++ b/pkg/view/src/components/PostList.tsx
@@ -10,7 +10,7 @@ export default function PostList(props: {
onRepost?: (post: any) => void,
onReply?: (post: any) => void,
onEdit?: (post: any) => void,
- onUpdate: (pn: number) => Promise
,
+ onUpdate: (pn: number, filter?: any) => Promise,
onError: (message: string | null) => void
}) {
const [loading, setLoading] = createSignal(true);
@@ -21,9 +21,9 @@ export default function PostList(props: {
const [page, setPage] = createSignal(1);
const pageCount = createMemo(() => Math.ceil(postCount() / 10));
- async function readPosts() {
+ async function readPosts(filter?: any) {
setLoading(true);
- await props.onUpdate(page());
+ await props.onUpdate(page(), filter);
setLoading(false);
}
diff --git a/pkg/view/src/index.tsx b/pkg/view/src/index.tsx
index a40d463..e0e9a04 100644
--- a/pkg/view/src/index.tsx
+++ b/pkg/view/src/index.tsx
@@ -26,6 +26,7 @@ render(() => (
+ import("./pages/search.tsx"))} />
import("./pages/realms"))} />
import("./pages/realms/realm.tsx"))} />
import("./pages/account.tsx"))} />
diff --git a/pkg/view/src/pages/search.tsx b/pkg/view/src/pages/search.tsx
new file mode 100644
index 0000000..3407191
--- /dev/null
+++ b/pkg/view/src/pages/search.tsx
@@ -0,0 +1,123 @@
+import { useNavigate, useSearchParams } from "@solidjs/router";
+import { createSignal, Show } from "solid-js";
+import { createStore } from "solid-js/store";
+import PostPublish from "../components/PostPublish.tsx";
+import PostList from "../components/PostList.tsx";
+import { closeModel, openModel } from "../scripts/modals.ts";
+
+export default function SearchPage() {
+ const [searchParams] = useSearchParams();
+
+ const [error, setError] = createSignal(null);
+
+ const [page, setPage] = createSignal(0);
+ const [info, setInfo] = createSignal(null);
+
+ const navigate = useNavigate();
+
+ async function readPosts(pn?: number) {
+ if (pn) setPage(pn);
+ const res = await fetch("/api/posts?" + new URLSearchParams({
+ take: (10).toString(),
+ offset: ((page() - 1) * 10).toString(),
+ ...searchParams
+ }));
+ if (res.status !== 200) {
+ setError(await res.text());
+ } else {
+ setError(null);
+ setInfo(await res.json());
+ }
+ }
+
+ function setMeta(data: any, field: string, open = true) {
+ const meta: { [id: string]: any } = {
+ reposting: null,
+ replying: null,
+ editing: null
+ };
+ meta[field] = data;
+ setPublishMeta(meta);
+
+ if (open) openModel("#post-publish");
+ else closeModel("#post-publish");
+ }
+
+ const [publishMeta, setPublishMeta] = createStore({
+ replying: null,
+ reposting: null,
+ editing: null
+ });
+
+ function getDescribe() {
+ let builder = [];
+ if (searchParams["category"]) {
+ builder.push("category is #" + searchParams["category"]);
+ } else if (searchParams["tag"]) {
+ builder.push("tag is #" + searchParams["tag"]);
+ }
+
+ return builder.join(" and ");
+ }
+
+ function back() {
+ if (window.history.length > 0) {
+ window.history.back();
+ } else {
+ navigate("/");
+ }
+ }
+
+ return (
+ <>
+
+
+
+
+
+
+ You will only see posts with {getDescribe()}
+
+
+
+
+ setMeta(item, "reposting")}
+ onReply={(item) => setMeta(item, "replying")}
+ onEdit={(item) => setMeta(item, "editing")}
+ />
+ >
+ );
+}
\ No newline at end of file