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 { Ship } from "@/types/urbit"; function PostData(props: { host: Ship; id: PostID; rter?: Ship; rtat?: number; rtid?: PostID; nest?: number; // nested quotes className?: string; }) { const { api } = useLocalState(); const { host, id, nest } = props; const [enest, setEnest] = useState(nest); useEffect(() => { setEnest(nest); }, [nest]); return function (Component: React.ElementType) { // const [showNested, setShowNested] = useState(nest <= 3); const handleShowNested = (e: React.MouseEvent) => { e.stopPropagation(); setEnest(enest! - 3); }; const [dead, setDead] = useState(false); const [denied, setDenied] = useState(false); const { isLoading, isError, data, refetch } = useQuery({ queryKey: ["trill-thread", host, id], queryFn: fetchNode, }); const queryClient = useQueryClient(); const dataRef = useRef(data); useEffect(() => { dataRef.current = data; }, [data]); async function fetchNode(): Promise { const res = await api!.scryPost(host, id, null, null); if ("fpost" 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; } } } 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 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(); } if (enest > 3) return (
); else return data ? ( dead ? (

{host} did not respond

) : denied ? (

{host} denied you access to this post

) : "no-node" in data || "bucun" in data ? (

Post not found

) : "bugen" in data ? (

Post not found, requesting...

) : "fpost" in data && data.fpost.contents === null ? (

Post deleted

) : ( ) ) : // no data isLoading || isError ? (
) : (

...

); }; } export default PostData;