summaryrefslogtreecommitdiff
path: root/front/src/components/post
diff options
context:
space:
mode:
Diffstat (limited to 'front/src/components/post')
-rw-r--r--front/src/components/post/Body.tsx2
-rw-r--r--front/src/components/post/Footer.tsx62
-rw-r--r--front/src/components/post/Loader.tsx124
-rw-r--r--front/src/components/post/Reactions.tsx4
4 files changed, 95 insertions, 97 deletions
diff --git a/front/src/components/post/Body.tsx b/front/src/components/post/Body.tsx
index e8b659c..b4f1bb2 100644
--- a/front/src/components/post/Body.tsx
+++ b/front/src/components/post/Body.tsx
@@ -161,7 +161,7 @@ function Heading({ string, num }: { string: string; num: number }) {
}
function Ref({ r, nest }: { r: Reference; nest: number }) {
- if (r.ref.type === "nostril") {
+ if (r.ref.type === "trill") {
const comp = PostData({
host: r.ref.ship,
id: r.ref.path.slice(1),
diff --git a/front/src/components/post/Footer.tsx b/front/src/components/post/Footer.tsx
index d16f4fc..5b79da0 100644
--- a/front/src/components/post/Footer.tsx
+++ b/front/src/components/post/Footer.tsx
@@ -13,33 +13,33 @@ function Footer({ poast, refetch }: PostProps) {
const [_showMenu, setShowMenu] = useState(false);
const [location, navigate] = useLocation();
const [reposting, _setReposting] = useState(false);
- const { api, setComposerData, setModal, addNotification } = useLocalState((s) => ({
- api: s.api,
- setComposerData: s.setComposerData,
- setModal: s.setModal,
- addNotification: s.addNotification,
- }));
+ const { api, setComposerData, setModal, addNotification } = useLocalState(
+ (s) => ({
+ api: s.api,
+ setComposerData: s.setComposerData,
+ setModal: s.setModal,
+ addNotification: s.addNotification,
+ }),
+ );
const our = api!.airlock.our!;
function doReply(e: React.MouseEvent) {
+ console.log("do reply");
e.stopPropagation();
+ e.preventDefault();
setComposerData({ type: "reply", post: { trill: poast } });
- // Only add notification if replying to someone else's post
- if (poast.author !== our) {
- addNotification({
- type: "reply",
- from: our,
- message: `You replied to ${poast.author}'s post`,
- postId: poast.id,
- });
- }
+ // Scroll to top where composer is located
+ window.scrollTo({ top: 0, behavior: "smooth" });
+ // Focus will be handled by the composer component
}
function doQuote(e: React.MouseEvent) {
e.stopPropagation();
+ e.preventDefault();
setComposerData({
type: "quote",
post: { trill: poast },
});
- navigate("/composer");
+ // Scroll to top where composer is located
+ window.scrollTo({ top: 0, behavior: "smooth" });
}
const childrenCount = poast.children
? poast.children.length
@@ -49,6 +49,7 @@ function Footer({ poast, refetch }: PostProps) {
const myRP = poast.engagement.shared.find((r) => r.pid.ship === our);
async function cancelRP(e: React.MouseEvent) {
e.stopPropagation();
+ e.preventDefault();
const r = await api!.deletePost(our);
if (r) toast.success("Repost deleted");
refetch();
@@ -57,6 +58,7 @@ function Footer({ poast, refetch }: PostProps) {
async function sendRP(e: React.MouseEvent) {
// TODO update backend because contents are only markdown now
e.stopPropagation();
+ e.preventDefault();
// const c = [
// {
// ref: {
@@ -85,6 +87,7 @@ function Footer({ poast, refetch }: PostProps) {
}
function doReact(e: React.MouseEvent) {
e.stopPropagation();
+ e.preventDefault();
const modal = <TrillReactModal poast={poast} />;
setModal(modal);
}
@@ -138,13 +141,17 @@ function Footer({ poast, refetch }: PostProps) {
<span role="link" onMouseUp={showReplyCount} className="reply-count">
{displayCount(childrenCount)}
</span>
- <Icon name="reply" size={20} onClick={doReply} />
+ <div className="icon-wrapper" role="link" onMouseUp={doReply}>
+ <Icon name="reply" size={20} />
+ </div>
</div>
<div className="icon">
<span role="link" onMouseUp={showQuoteCount} className="quote-count">
{displayCount(poast.engagement.quoted.length)}
</span>
- <Icon name="quote" size={20} onClick={doQuote} />
+ <div className="icon-wrapper" role="link" onMouseUp={doQuote}>
+ <Icon name="quote" size={20} />
+ </div>
</div>
<div className="icon">
<span
@@ -157,15 +164,18 @@ function Footer({ poast, refetch }: PostProps) {
{reposting ? (
<p>...</p>
) : myRP ? (
- <Icon
- name="repost"
- size={20}
- className="my-rp"
- onClick={cancelRP}
- title="cancel repost"
- />
+ <div className="icon-wrapper" role="link" onMouseUp={cancelRP}>
+ <Icon
+ name="repost"
+ size={20}
+ className="my-rp"
+ title="cancel repost"
+ />
+ </div>
) : (
- <Icon name="repost" size={20} onClick={sendRP} title="repost" />
+ <div className="icon-wrapper" role="link" onMouseUp={sendRP}>
+ <Icon name="repost" size={20} title="repost" />
+ </div>
)}
</div>
<div className="icon" role="link" onMouseUp={doReact}>
diff --git a/front/src/components/post/Loader.tsx b/front/src/components/post/Loader.tsx
index a23bea1..e45e01a 100644
--- a/front/src/components/post/Loader.tsx
+++ b/front/src/components/post/Loader.tsx
@@ -2,23 +2,30 @@ import { useQuery, useQueryClient } from "@tanstack/react-query";
import spinner from "@/assets/triangles.svg";
import { useEffect, useRef, useState } from "react";
import useLocalState from "@/state/state";
-import type { PostID } from "@/types/trill";
+import type { FullNode, PostID } from "@/types/trill";
import type { Ship } from "@/types/urbit";
+import type { AsyncRes } from "@/types/ui";
+import { toFlat } from "@/logic/trill/helpers";
-function PostData(props: {
+type Props = {
host: Ship;
id: PostID;
+ nest?: number; // nested quotes
rter?: Ship;
rtat?: number;
rtid?: PostID;
- nest?: number; // nested quotes
className?: string;
-}) {
- const { api } = useLocalState((s) => ({ api: s.api }));
+};
+function PostData(props: Props) {
+ const { api } = useLocalState((s) => ({
+ api: s.api,
+ }));
+
const { host, id, nest } = props;
- const [enest, setEnest] = useState(nest);
+
+ const [enest, setEnest] = useState(nest || 0);
useEffect(() => {
- setEnest(nest);
+ if (nest) setEnest(nest);
}, [nest]);
return function (Component: React.ElementType) {
@@ -39,61 +46,52 @@ function PostData(props: {
dataRef.current = data;
}, [data]);
- async function fetchNode(): Promise<any> {
- const res = await api!.scryPost(host, id, null, null);
- if ("fpost" in res) return res;
+ async function fetchNode(): AsyncRes<FullNode> {
+ let error = "";
+ const res = await api!.scryThread(host, id);
+ console.log("scry res", res);
+ if ("error" in res) error = res.error;
+ if ("ok" in res) return res;
else {
- const existing = queryClient.getQueryData(["trill-thread", host, id]);
- const existingData = existing || data;
- if ("bugen" in res) {
- // we peek for the actual node
- peekTheNode();
- // if we have a cache we don't invalidate it
- if (existingData && "fpost" in existingData) return existingData;
- // if we don't have a cache then we show the loading screen
- else return res;
- }
- if ("no-node" in res) {
- if (existingData && "fpost" in existingData) return existingData;
- else return res;
- }
+ const res2 = await api!.peekThread(host, id);
+ return res2;
}
}
- function peekTheNode() {
- let timer;
- peekNode({ ship: host, id });
- timer = setTimeout(() => {
- const gotPost = dataRef.current && "fpost" in dataRef.current;
- setDead(!gotPost);
- // clearTimeout(timer);
- }, 10_000);
+ async function peekTheNode() {
+ // let timer;
+ // peekNode({ ship: host, id });
+ // timer = setTimeout(() => {
+ // const gotPost = dataRef.current && "fpost" in dataRef.current;
+ // setDead(!gotPost);
+ // // clearTimeout(timer);
+ // }, 10_000);
}
- useEffect(() => {
- const path = `${host}/${id}`;
- if (path in peekedPosts) {
- queryClient.setQueryData(["trill-thread", host, id], {
- fpost: peekedPosts[path],
- });
- } else if (path in deniedPosts) {
- setDenied(true);
- }
- }, [peekedPosts]);
- useEffect(() => {
- const path = `${host}/${id}`;
- if (path in deniedPosts) setDenied(true);
- }, [deniedPosts]);
+ // useEffect(() => {
+ // const path = `${host}/${id}`;
+ // if (path in peekedPosts) {
+ // queryClient.setQueryData(["trill-thread", host, id], {
+ // fpost: peekedPosts[path],
+ // });
+ // } else if (path in deniedPosts) {
+ // setDenied(true);
+ // }
+ // }, [peekedPosts]);
+ // useEffect(() => {
+ // const path = `${host}/${id}`;
+ // if (path in deniedPosts) setDenied(true);
+ // }, [deniedPosts]);
- useEffect(() => {
- const l = lastThread;
- if (l && l.thread == id) {
- queryClient.setQueryData(["trill-thread", host, id], { fpost: l });
- }
- }, [lastThread]);
+ // useEffect(() => {
+ // const l = lastThread;
+ // if (l && l.thread == id) {
+ // queryClient.setQueryData(["trill-thread", host, id], { fpost: l });
+ // }
+ // }, [lastThread]);
function retryPeek(e: React.MouseEvent) {
- e.stopPropagation();
- setDead(false);
- peekTheNode();
+ // e.stopPropagation();
+ // setDead(false);
+ // peekTheNode();
}
if (enest > 3)
return (
@@ -122,24 +120,14 @@ function PostData(props: {
{host} denied you access to this post
</p>
</div>
- ) : "no-node" in data || "bucun" in data ? (
+ ) : "error" in data ? (
<div className={props.className}>
<p className="x-center not-found">Post not found</p>
- </div>
- ) : "bugen" in data ? (
- <div className={props.className}>
- <div className="x-center not-found">
- <p className="x-center">Post not found, requesting...</p>
- <img src={spinner} className="x-center s-100" alt="" />
- </div>
- </div>
- ) : "fpost" in data && data.fpost.contents === null ? (
- <div className={props.className}>
- <p className="x-center not-found">Post deleted</p>
+ <p className="x-center not-found">{data.error}</p>
</div>
) : (
<Component
- data={data.fpost}
+ data={toFlat(data.ok)}
refetch={refetch}
{...props}
nest={enest}
diff --git a/front/src/components/post/Reactions.tsx b/front/src/components/post/Reactions.tsx
index ee40d26..ae75d8c 100644
--- a/front/src/components/post/Reactions.tsx
+++ b/front/src/components/post/Reactions.tsx
@@ -20,7 +20,7 @@ import Modal from "../modals/Modal";
import useLocalState from "@/state/state";
export function ReactModal({ send }: { send: (s: string) => Promise<number> }) {
- const { setModal } = useLocalState();
+ const { setModal } = useLocalState((s) => ({ setModal: s.setModal }));
async function sendReact(e: React.MouseEvent, s: string) {
e.stopPropagation();
const res = await send(s);
@@ -115,7 +115,7 @@ export function TrillReactModal({ poast }: { poast: Poast }) {
addNotification: s.addNotification,
}));
const our = api!.airlock.our!;
-
+
async function sendReact(s: string) {
const result = await api!.addReact(poast.host, poast.id, s);
// Only add notification if reacting to someone else's post