From 4b016c908dda2019f3bf89e5a3d2eae535e5fbd2 Mon Sep 17 00:00:00 2001
From: polwex <polwex@sortug.com>
Date: Thu, 18 Sep 2025 00:24:39 +0700
Subject: oioi

---
 front/src/pages/User.tsx | 85 +++++++++++++++++++++++++++++++++++-------------
 1 file changed, 63 insertions(+), 22 deletions(-)

(limited to 'front/src/pages/User.tsx')

diff --git a/front/src/pages/User.tsx b/front/src/pages/User.tsx
index e209bb3..d8b66e1 100644
--- a/front/src/pages/User.tsx
+++ b/front/src/pages/User.tsx
@@ -1,25 +1,59 @@
 // import spinner from "@/assets/icons/spinner.svg";
 import Composer from "@/components/composer/Composer";
 import PostList from "@/components/feed/PostList";
-import ProfileEditor from "@/components/ProfileEditor";
+import Profile from "@/components/profile/Profile";
 import useLocalState, { useStore } from "@/state/state";
-import type { Ship } from "@/types/urbit";
-import "@/styles/ProfileEditor.css";
 import Icon from "@/components/Icon";
 import toast from "react-hot-toast";
 import { 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 UserFeed({ p }: { p: Ship }) {
-  const { api } = useLocalState((s) => ({
+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 <ErrorPage msg={"Invalid user"} />;
+  else
+    return <UserFeed user={user} userString={userString} isMe={isOwnProfile} />;
+}
+
+function UserFeed({
+  user,
+  userString,
+  isMe,
+}: {
+  user: UserType;
+  userString: string;
+  isMe: boolean;
+}) {
+  const { api, addProfile } = useLocalState((s) => ({
+    api: s.api,
+    addProfile: s.addProfile,
   }));
   // auto updating on SSE doesn't work if we do shallow
   const { following } = useStore();
-  const feed = following.get(p);
+  const feed = following.get(userString);
   const refetch = () => feed;
-  const isOwnProfile = p === api?.airlock.our;
-  const isFollowing = following.has(p);
+  const isFollowing = following.has(userString);
 
   const [isFollowLoading, setIsFollowLoading] = useState(false);
   const [isAccessLoading, setIsAccessLoading] = useState(false);
@@ -31,14 +65,16 @@ function UserFeed({ p }: { p: Ship }) {
     setIsFollowLoading(true);
     try {
       if (isFollowing) {
-        await api.unfollow(p);
-        toast.success(`Unfollowed ${p}`);
+        await api.unfollow(user);
+        toast.success(`Unfollowed ${userString}`);
       } else {
-        await api.follow(p);
-        toast.success(`Now following ${p}`);
+        await api.follow(user);
+        toast.success(`Now following ${userString}`);
       }
     } catch (error) {
-      toast.error(`Failed to ${isFollowing ? "unfollow" : "follow"} ${p}`);
+      toast.error(
+        `Failed to ${isFollowing ? "unfollow" : "follow"} ${userString}`,
+      );
       console.error("Follow error:", error);
     } finally {
       setIsFollowLoading(false);
@@ -47,15 +83,20 @@ function UserFeed({ p }: { p: Ship }) {
 
   const handleRequestAccess = async () => {
     if (!api) return;
+    if (!("urbit" in user)) return;
 
     setIsAccessLoading(true);
     try {
-      const res = await api.peekFeed(p);
-      toast.success(`Access request sent to ${p}`);
+      const res = await api.peekFeed(user.urbit);
+      toast.success(`Access request sent to ${user.urbit}`);
       if ("error" in res) toast.error(res.error);
-      else setFC(res.ok);
+      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 ${p}`);
+      toast.error(`Failed to request access from ${user.urbit}`);
       console.error("Access request error:", error);
     } finally {
       setIsAccessLoading(false);
@@ -64,14 +105,14 @@ function UserFeed({ p }: { p: Ship }) {
 
   return (
     <div id="user-page">
-      <ProfileEditor ship={p} />
+      <Profile user={user} userString={userString} isMe={isMe} />
 
-      {!isOwnProfile && (
+      {!isMe && (
         <div className="user-actions">
           <button
             onClick={handleFollow}
             disabled={isFollowLoading}
-            className={`action-btn ${isFollowing ? "following" : "follow"}`}
+            className={`action-btn ${isFollowing ? "" : "follow"}`}
           >
             {isFollowLoading ? (
               <>
@@ -118,7 +159,7 @@ function UserFeed({ p }: { p: Ship }) {
         </div>
       ) : null}
 
-      {!isOwnProfile && !feed && !fc && (
+      {!isMe && !feed && !fc && (
         <div id="other-user-feed">
           <div className="empty-feed-message">
             <Icon name="messages" size={48} color="textMuted" />
@@ -135,4 +176,4 @@ function UserFeed({ p }: { p: Ship }) {
   );
 }
 
-export default UserFeed;
+export default UserLoader;
-- 
cgit v1.2.3

