summaryrefslogtreecommitdiff
path: root/gui/src/pages/User.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'gui/src/pages/User.tsx')
-rw-r--r--gui/src/pages/User.tsx219
1 files changed, 50 insertions, 169 deletions
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 <ErrorPage msg={"Invalid user"} />;
- else
- return <UserFeed user={user} userString={userString} isMe={isOwnProfile} />;
+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 <ErrorPage msg="no such user" />;
+ else if (isValidPatp(userString))
+ return <UserFeed user={{ urbit: userString }} userString={userString} />;
+ else if (isValidNostrKey(userString))
+ return <UserFeed user={{ nostr: userString }} userString={userString} />;
+ else return <ErrorPage msg="no such user" />;
}
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<FC>();
-
- 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 (
<div id="user-page">
<Profile user={user} userString={userString} isMe={isMe} />
-
- {!isMe && (
- <div className="user-actions">
- <button
- onClick={handleFollow}
- disabled={isFollowLoading}
- className={`action-btn ${isFollowing ? "" : "follow"}`}
- >
- {isFollowLoading ? (
- <>
- <Icon name="settings" size={16} />
- {isFollowing ? "Unfollowing..." : "Following..."}
- </>
- ) : (
- <>
- <Icon name={isFollowing ? "bell" : "pals"} size={16} />
- {isFollowing ? "Unfollow" : "Follow"}
- </>
- )}
- </button>
-
- <button
- onClick={handleRequestAccess}
- disabled={isAccessLoading}
- className="action-btn access"
- >
- {isAccessLoading ? (
- <>
- <Icon name="settings" size={16} />
- Requesting...
- </>
- ) : (
- <>
- <Icon name="key" size={16} />
- Request Access
- </>
- )}
- </button>
- </div>
- )}
-
- {feed && hasFeed ? (
- <div id="feed-proper">
- <Composer />
- <PostList data={feed} refetch={refetch} />
- </div>
- ) : fc ? (
- <div id="feed-proper">
- <Composer />
- <PostList data={fc} refetch={refetch} />
- </div>
+ {isMe ? (
+ <MyFeed />
+ ) : "urbit" in user ? (
+ <TrillFeed
+ user={user}
+ userString={userString}
+ feed={feed}
+ isFollowLoading={isFollowLoading}
+ setIsFollowLoading={setIsFollowLoading}
+ isAccessLoading={isAccessLoading}
+ setIsAccessLoading={setIsAccessLoading}
+ />
+ ) : "nostr" in user ? (
+ <NostrFeed
+ user={user}
+ userString={userString}
+ feed={feed}
+ isFollowLoading={isFollowLoading}
+ setIsFollowLoading={setIsFollowLoading}
+ isAccessLoading={isAccessLoading}
+ setIsAccessLoading={setIsAccessLoading}
+ />
) : null}
-
- {!isMe && !feed && !fc && (
- <div id="other-user-feed">
- <div className="empty-feed-message">
- <Icon name="messages" size={48} color="textMuted" />
- <h3>No Posts Available</h3>
- <p>
- This user's posts are not publicly visible.
- {!isFollowing && " Try following them"} or request temporary
- access to see their content.
- </p>
- </div>
- </div>
- )}
</div>
);
}
export default UserLoader;
+
+function MyFeed() {
+ return <></>;
+}