summaryrefslogtreecommitdiff
path: root/gui/src
diff options
context:
space:
mode:
authorpolwex <polwex@sortug.com>2025-11-12 07:11:07 +0700
committerpolwex <polwex@sortug.com>2025-11-12 07:11:07 +0700
commit284ce9ce7d9f81e54e91f917329d48926487fbf4 (patch)
tree7a156986323fd799e1457c8b7663806e32b2af7d /gui/src
parent7305d67ff7f9e78b73326ef0e1f68a9613d34205 (diff)
fixes to engagement handling
Diffstat (limited to 'gui/src')
-rw-r--r--gui/src/components/feed/PostList.tsx2
-rw-r--r--gui/src/components/post/Footer.tsx3
-rw-r--r--gui/src/components/post/Quote.tsx3
-rw-r--r--gui/src/logic/trill/helpers.ts24
-rw-r--r--gui/src/pages/Feed.tsx17
-rw-r--r--gui/src/pages/Thread.tsx52
-rw-r--r--gui/src/state/state.ts6
7 files changed, 96 insertions, 11 deletions
diff --git a/gui/src/components/feed/PostList.tsx b/gui/src/components/feed/PostList.tsx
index b09a0e9..0d01bd2 100644
--- a/gui/src/components/feed/PostList.tsx
+++ b/gui/src/components/feed/PostList.tsx
@@ -20,6 +20,8 @@ function TrillFeed({ data, refetch }: { data: FC; refetch: Function }) {
return (
<>
{Object.keys(data.feed)
+ // omit replies
+ .filter((i) => !data.feed[i].parent)
.sort()
.reverse()
.slice(0, 50)
diff --git a/gui/src/components/post/Footer.tsx b/gui/src/components/post/Footer.tsx
index 5b79da0..a87c1f8 100644
--- a/gui/src/components/post/Footer.tsx
+++ b/gui/src/components/post/Footer.tsx
@@ -41,6 +41,7 @@ function Footer({ poast, refetch }: PostProps) {
// Scroll to top where composer is located
window.scrollTo({ top: 0, behavior: "smooth" });
}
+ console.log({ poast });
const childrenCount = poast.children
? poast.children.length
? poast.children.length
@@ -52,7 +53,7 @@ function Footer({ poast, refetch }: PostProps) {
e.preventDefault();
const r = await api!.deletePost(our);
if (r) toast.success("Repost deleted");
- refetch();
+ // refetch();
if (location.includes(poast.id)) navigate("/");
}
async function sendRP(e: React.MouseEvent) {
diff --git a/gui/src/components/post/Quote.tsx b/gui/src/components/post/Quote.tsx
index 28149f0..98720ea 100644
--- a/gui/src/components/post/Quote.tsx
+++ b/gui/src/components/post/Quote.tsx
@@ -49,12 +49,11 @@ function Quote({
return (
<div onMouseUp={gotoQuote} className="quote-in-post">
<header className="btw">
- (
<div className="quote-author flex">
<Sigil patp={data.author} size={20} />
{data.author}
</div>
- )<span>{date_diff(data.time, "short")}</span>
+ <span>{date_diff(data.time, "short")}</span>
</header>
<Body poast={data} nest={nest} refetch={refetch!} />
</div>
diff --git a/gui/src/logic/trill/helpers.ts b/gui/src/logic/trill/helpers.ts
index 6b5a138..8bd1b0c 100644
--- a/gui/src/logic/trill/helpers.ts
+++ b/gui/src/logic/trill/helpers.ts
@@ -8,3 +8,27 @@ export function toFlat(n: FullNode): Poast {
: Object.keys(n.children).map((c) => n.children[c].id),
};
}
+
+type res = { threadChildren: FullNode[]; replies: FullNode[] };
+const bunt: res = { threadChildren: [], replies: [] };
+export function extractThread(node: FullNode): res {
+ if (!node.children) return bunt;
+ const r = Object.keys(node.children)
+ .sort()
+ .reduce((acc, index) => {
+ const n = node.children[index];
+ // if (typeof n.post === "string") return acc;
+ const nn = n as FullNode;
+ return n.author !== node.author
+ ? { ...acc, replies: [...acc.replies, nn] }
+ : {
+ ...acc,
+ threadChildren: [
+ ...acc.threadChildren,
+ nn,
+ ...extractThread(nn).threadChildren,
+ ],
+ };
+ }, bunt);
+ return r;
+}
diff --git a/gui/src/pages/Feed.tsx b/gui/src/pages/Feed.tsx
index 66acc66..ac596dd 100644
--- a/gui/src/pages/Feed.tsx
+++ b/gui/src/pages/Feed.tsx
@@ -57,7 +57,7 @@ function FeedPage({ t }: { t: FeedType }) {
{active === "global" ? (
<Global />
) : active === "following" ? (
- <Global />
+ <Following />
) : active === "nostr" ? (
<Nostr />
) : null}
@@ -87,6 +87,21 @@ function Global() {
// else return <Inner data={data} refetch={refetch} />;
return <p>Error</p>;
}
+function Following() {
+ const following = useLocalState((s) => s.following2);
+ console.log({ following });
+
+ // console.log(data, "scry feed data");
+ // if (isPending) return <img className="x-center" src={spinner} />;
+ // else if ("bucun" in data) return <p>Error</p>;
+ // else return <Inner data={data} refetch={refetch} />;
+
+ return (
+ <div>
+ <PostList data={following} refetch={() => {}} />
+ </div>
+ );
+}
function Nostr() {
const { nostrFeed, api } = useLocalState((s) => ({
nostrFeed: s.nostrFeed,
diff --git a/gui/src/pages/Thread.tsx b/gui/src/pages/Thread.tsx
index 8296f07..dec8946 100644
--- a/gui/src/pages/Thread.tsx
+++ b/gui/src/pages/Thread.tsx
@@ -1,15 +1,15 @@
import { useParams } from "wouter";
import { useQuery } from "@tanstack/react-query";
import useLocalState from "@/state/state";
-import PostList from "@/components/feed/PostList";
-import Composer from "@/components/composer/Composer";
import Icon from "@/components/Icon";
import spinner from "@/assets/triangles.svg";
import { ErrorPage } from "@/Router";
import "@/styles/trill.css";
import "@/styles/feed.css";
import Post from "@/components/post/Post";
-import { toFlat } from "@/logic/trill/helpers";
+import { extractThread, toFlat } from "@/logic/trill/helpers";
+import type { FullNode } from "@/types/trill";
+import Composer from "@/components/composer/Composer";
export default function Thread() {
const params = useParams<{ host: string; id: string }>();
@@ -19,7 +19,7 @@ export default function Thread() {
async function fetchThread() {
return await api!.scryThread(host, id);
}
- const { isPending, data, error, refetch } = useQuery({
+ const { isPending, data, error } = useQuery({
queryKey: ["thread", params.host, params.id],
queryFn: fetchThread,
enabled: !!api && !!params.host && !!params.id,
@@ -66,7 +66,8 @@ export default function Thread() {
</main>
);
}
-
+ console.log({ data });
+ // TODO make Composer a modal when in Thread mode
return (
<main>
<div className="thread-header">
@@ -90,13 +91,52 @@ export default function Thread() {
<div id="feed-proper">
<Composer />
- <div className="thread-content">
+ <div id="thread-head">
<Post poast={toFlat(data.ok)} />
</div>
+ <div id="thread-children">
+ <ChildTree node={data.ok} />
+ </div>
</div>
</main>
);
}
+
+function ChildTree({ node }: { node: FullNode }) {
+ const { threadChildren, replies } = extractThread(node);
+ return (
+ <>
+ <div id="tail">
+ {threadChildren.map((n) => {
+ return <Post key={n.id} poast={toFlat(n)} />;
+ })}
+ </div>
+ <div id="replies">
+ {replies.map((n) => (
+ <ReplyThread key={n.id} node={n} />
+ ))}
+ </div>
+ </>
+ );
+}
+
+function ReplyThread({ node }: { node: FullNode }) {
+ // const { threadChildren, replies } = extractThread(node);
+ const { replies } = extractThread(node);
+ return (
+ <div className="trill-reply-thread">
+ <div className="head">
+ <Post poast={toFlat(node)} />
+ </div>
+ <div className="tail">
+ {replies.map((r) => (
+ <Post key={r.id} poast={toFlat(r)} />
+ ))}
+ </div>
+ </div>
+ );
+}
+
// function OwnData(props: Props) {
// const { api } = useLocalState((s) => ({
// api: s.api,
diff --git a/gui/src/state/state.ts b/gui/src/state/state.ts
index f329145..9bd5e0e 100644
--- a/gui/src/state/state.ts
+++ b/gui/src/state/state.ts
@@ -26,6 +26,7 @@ export type LocalState = {
profiles: Map<string, UserProfile>; // pubkey key
addProfile: (key: string, u: UserProfile) => void;
following: Map<string, FC>;
+ following2: FC;
followers: string[];
// Notifications
notifications: Notification[];
@@ -50,7 +51,8 @@ export const useStore = creator((set, get) => ({
await api.subscribeStore((data) => {
console.log("store sub", data);
if ("state" in data) {
- const { feed, nostr, following, relays, profiles, pubkey } = data.state;
+ const { feed, nostr, following, following2, relays, profiles, pubkey } =
+ data.state;
const flwing = new Map(Object.entries(following as Record<string, FC>));
flwing.set(api!.airlock.our!, feed);
set({
@@ -58,6 +60,7 @@ export const useStore = creator((set, get) => ({
nostrFeed: nostr,
profiles: new Map(Object.entries(profiles)),
following: flwing,
+ following2,
pubkey,
});
} else if ("fact" in data) {
@@ -103,6 +106,7 @@ export const useStore = creator((set, get) => ({
nostrFeed: [],
following: new Map(),
followers: [],
+ following2: { feed: {}, start: "", end: "" },
UISettings: {},
modal: null,
setModal: (modal) => set({ modal }),