From 420a543f8af3075502b0a7530a0fa06af264eb8b Mon Sep 17 00:00:00 2001 From: polwex Date: Tue, 18 Nov 2025 16:59:24 +0700 Subject: refactoring gui too, improvements to Nostr user logic --- gui/src/pages/Error.tsx | 60 +++++++++++++ gui/src/pages/Feed.tsx | 15 ++-- gui/src/pages/Thread.tsx | 2 +- gui/src/pages/User.tsx | 219 +++++++++++------------------------------------ 4 files changed, 116 insertions(+), 180 deletions(-) create mode 100644 gui/src/pages/Error.tsx (limited to 'gui/src/pages') diff --git a/gui/src/pages/Error.tsx b/gui/src/pages/Error.tsx new file mode 100644 index 0000000..c29e6a6 --- /dev/null +++ b/gui/src/pages/Error.tsx @@ -0,0 +1,60 @@ +import "@/styles/ErrorPage.css"; +import Icon from "@/components/Icon"; +import { Link } from "wouter"; +export function P404() { + return ( +
+
+
+ +
+

404

+

Page Not Found

+

+ The page you're looking for doesn't exist or has been moved. +

+
+ + + + + + +
+
+
+ ); +} + +export function ErrorPage({ msg }: { msg: string }) { + return ( +
+ +

{msg}

+
+
+
+ +
+

Oops!

+

Something went wrong

+

{msg}

+
+ + + +
+
+
+
+ ); +} diff --git a/gui/src/pages/Feed.tsx b/gui/src/pages/Feed.tsx index 02f7b1a..bb001d4 100644 --- a/gui/src/pages/Feed.tsx +++ b/gui/src/pages/Feed.tsx @@ -1,35 +1,30 @@ -// import spinner from "@/assets/icons/spinner.svg"; import "@/styles/trill.css"; import "@/styles/feed.css"; -import UserLoader from "./User"; import PostList from "@/components/feed/PostList"; import useLocalState from "@/state/state"; import { useParams } from "wouter"; import spinner from "@/assets/triangles.svg"; import { useState } from "react"; import Composer from "@/components/composer/Composer"; -import { ErrorPage } from "@/Router"; +import { ErrorPage } from "@/pages/Error"; import NostrFeed from "@/components/nostr/Feed"; type FeedType = "global" | "following" | "nostr"; function Loader() { - // const { api } = useLocalState(); const params = useParams(); console.log({ params }); - // const [loc, navigate] = useLocation(); - // console.log({ loc }); - // const our = api!.airlock.ship; + if (!params.taip) return ; if (params.taip === "global") return ; + if (params.taip === "following") return ; if (params.taip === "nostr") return ; // else if (param === FeedType.Rumors) return ; // else if (param === FeedType.Home) return ; - else if (params.taip) return ; else return ; } function FeedPage({ t }: { t: FeedType }) { const [active, setActive] = useState(t); return ( -
+ <>
) : null}
-
+ ); } // {active === "global" ? ( diff --git a/gui/src/pages/Thread.tsx b/gui/src/pages/Thread.tsx index dec8946..fc215f2 100644 --- a/gui/src/pages/Thread.tsx +++ b/gui/src/pages/Thread.tsx @@ -3,7 +3,7 @@ import { useQuery } from "@tanstack/react-query"; import useLocalState from "@/state/state"; import Icon from "@/components/Icon"; import spinner from "@/assets/triangles.svg"; -import { ErrorPage } from "@/Router"; +import { ErrorPage } from "@/pages/Error"; import "@/styles/trill.css"; import "@/styles/feed.css"; import Post from "@/components/post/Post"; diff --git a/gui/src/pages/User.tsx b/gui/src/pages/User.tsx index b73cd96..1611037 100644 --- a/gui/src/pages/User.tsx +++ b/gui/src/pages/User.tsx @@ -9,204 +9,85 @@ import { useEffect, useState } from "react"; import type { FC } from "@/types/trill"; import type { UserType } from "@/types/nostrill"; import { isValidPatp } from "urbit-ob"; -import { isValidNostrPubkey } from "@/logic/nostrill"; -import { ErrorPage } from "@/Router"; - -function UserLoader({ userString }: { userString: string }) { - const { api, pubkey } = useLocalState((s) => ({ - api: s.api, - pubkey: s.pubkey, - })); - // auto updating on SSE doesn't work if we do shallow - - const user = isValidPatp(userString) - ? { urbit: userString } - : isValidNostrPubkey(userString) - ? { nostr: userString } - : { error: "" }; - - const isOwnProfile = - "urbit" in user - ? user.urbit === api?.airlock.our - : "nostr" in user - ? pubkey === user.nostr - : false; - if ("error" in user) return ; - else - return ; +import { ErrorPage } from "@/pages/Error"; +import { useParams } from "wouter"; +import { isValidNostrKey } from "@/logic/nostr"; +import TrillFeed from "@/components/trill/User"; +import NostrFeed from "@/components/nostr/User"; + +function UserLoader() { + const params = useParams(); + console.log({ params }); + const userString = params.user; + if (!userString) return ; + else if (isValidPatp(userString)) + return ; + else if (isValidNostrKey(userString)) + return ; + else return ; } function UserFeed({ user, userString, - isMe, }: { user: UserType; userString: string; - isMe: boolean; }) { - const { api, addProfile, addNotification, lastFact } = useLocalState((s) => ({ + const { api, pubkey } = useLocalState((s) => ({ api: s.api, addProfile: s.addProfile, addNotification: s.addNotification, lastFact: s.lastFact, + pubkey: s.pubkey, })); + const isMe = + "urbit" in user + ? user.urbit === api?.airlock.our + : "nostr" in user + ? pubkey === user.nostr + : false; // auto updating on SSE doesn't work if we do shallow const { following } = useStore(); const feed = following.get(userString); const hasFeed = !feed ? false : Object.entries(feed).length > 0; const refetch = () => feed; - const isFollowing = following.has(userString); const [isFollowLoading, setIsFollowLoading] = useState(false); const [isAccessLoading, setIsAccessLoading] = useState(false); - const [fc, setFC] = useState(); - - useEffect(() => { - console.log("fact", lastFact); - console.log(isFollowLoading); - if (!isFollowLoading) return; - const follow = lastFact?.fols; - if (!follow) return; - if ("new" in follow) { - if (userString !== follow.new.user) return; - toast.success(`Now following ${userString}`); - setIsFollowLoading(false); - addNotification({ - type: "follow", - from: userString, - message: `You are now following ${userString}`, - }); - } else if ("quit" in follow) { - toast.success(`Unfollowed ${userString}`); - setIsFollowLoading(false); - addNotification({ - type: "unfollow", - from: userString, - message: `You unfollowed ${userString}`, - }); - } - }, [lastFact, userString, isFollowLoading]); - - const handleFollow = async () => { - if (!api) return; - - setIsFollowLoading(true); - try { - if (isFollowing) { - await api.unfollow(user); - } else { - await api.follow(user); - toast.success(`Follow request sent to ${userString}`); - } - } catch (error) { - toast.error( - `Failed to ${isFollowing ? "unfollow" : "follow"} ${userString}`, - ); - setIsFollowLoading(false); - console.error("Follow error:", error); - } - }; - - const handleRequestAccess = async () => { - if (!api) return; - if (!("urbit" in user)) return; - - setIsAccessLoading(true); - try { - const res = await api.peekFeed(user.urbit); - toast.success(`Access request sent to ${user.urbit}`); - addNotification({ - type: "access_request", - from: userString, - message: `Access request sent to ${userString}`, - }); - if ("error" in res) toast.error(res.error); - else { - console.log("peeked", res.ok.feed); - setFC(res.ok.feed); - if (res.ok.profile) addProfile(userString, res.ok.profile); - } - } catch (error) { - toast.error(`Failed to request access from ${user.urbit}`); - console.error("Access request error:", error); - } finally { - setIsAccessLoading(false); - } - }; - console.log({ user, userString, feed, fc }); return (
- - {!isMe && ( -
- - - -
- )} - - {feed && hasFeed ? ( -
- - -
- ) : fc ? ( -
- - -
+ {isMe ? ( + + ) : "urbit" in user ? ( + + ) : "nostr" in user ? ( + ) : null} - - {!isMe && !feed && !fc && ( -
-
- -

No Posts Available

-

- This user's posts are not publicly visible. - {!isFollowing && " Try following them"} or request temporary - access to see their content. -

-
-
- )}
); } export default UserLoader; + +function MyFeed() { + return <>; +} -- cgit v1.2.3