summaryrefslogtreecommitdiff
path: root/gui/src/components/modals/UserModal.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'gui/src/components/modals/UserModal.tsx')
-rw-r--r--gui/src/components/modals/UserModal.tsx121
1 files changed, 62 insertions, 59 deletions
diff --git a/gui/src/components/modals/UserModal.tsx b/gui/src/components/modals/UserModal.tsx
index aeffc95..4a7f812 100644
--- a/gui/src/components/modals/UserModal.tsx
+++ b/gui/src/components/modals/UserModal.tsx
@@ -6,13 +6,12 @@ import Icon from "@/components/Icon";
import useLocalState from "@/state/state";
import { useLocation } from "wouter";
import toast from "react-hot-toast";
-import { isValidPatp } from "urbit-ob";
-import { isValidNostrPubkey } from "@/logic/nostrill";
import { generateNprofile } from "@/logic/nostr";
-import { useState } from "react";
+import { useEffect, useState } from "react";
+import type { UserType } from "@/types/nostrill";
-export default function ({ userString }: { userString: string }) {
- const { setModal, api, pubkey, profiles, following, followers } =
+export default function ({ user }: { user: UserType }) {
+ const { setModal, api, lastFact, pubkey, profiles, following, followers } =
useLocalState((s) => ({
setModal: s.setModal,
api: s.api,
@@ -20,31 +19,15 @@ export default function ({ userString }: { userString: string }) {
profiles: s.profiles,
following: s.following,
followers: s.followers,
+ lastFact: s.lastFact,
}));
const [_, navigate] = useLocation();
- const [loading, setLoading] = useState(false);
+ const [isLoading, setLoading] = useState(false);
function close() {
setModal(null);
}
- const user = isValidPatp(userString)
- ? { urbit: userString }
- : isValidNostrPubkey(userString)
- ? { nostr: userString }
- : { error: "" };
-
- if ("error" in user) {
- return (
- <Modal close={close}>
- <div className="user-modal-error">
- <Icon name="comet" size={48} />
- <p>Invalid user identifier</p>
- </div>
- </Modal>
- );
- }
-
const itsMe =
"urbit" in user
? user.urbit === api?.airlock.our
@@ -52,6 +35,7 @@ export default function ({ userString }: { userString: string }) {
? user.nostr === pubkey
: false;
+ const userString = "urbit" in user ? user.urbit : user.nostr;
const profile = profiles.get(userString);
const isFollowing = following.has(userString);
const isFollower = followers.includes(userString);
@@ -60,6 +44,15 @@ export default function ({ userString }: { userString: string }) {
const userFeed = following.get(userString);
const postCount = userFeed ? Object.keys(userFeed.feed).length : 0;
+ // useEffect(() => {
+ // if (!lastFact) return;
+ // if (!("fols" in lastFact)) return;
+ // if (!("new" in lastFact.fols)) return;
+ // if (lastFact.fols.new.user === userString) setLoading(false);
+ // const name = profile?.name || userString;
+ // toast.success(`Followed ${name}`);
+ // }, [lastFact]);
+
async function copy(e: React.MouseEvent) {
e.stopPropagation();
await navigator.clipboard.writeText(userString);
@@ -93,7 +86,7 @@ export default function ({ userString }: { userString: string }) {
} catch (err) {
toast.error("Action failed");
} finally {
- setLoading(false);
+ // setLoading(false);
}
}
@@ -112,16 +105,6 @@ export default function ({ userString }: { userString: string }) {
? `${userString.slice(0, 10)}...${userString.slice(-8)}`
: userString;
- // Check if a string is a URL
- const isURL = (str: string): boolean => {
- try {
- new URL(str);
- return true;
- } catch {
- return str.startsWith("http://") || str.startsWith("https://");
- }
- };
-
// Get banner image from profile.other
const bannerImage = profile?.other?.banner || profile?.other?.Banner;
@@ -210,29 +193,15 @@ export default function ({ userString }: { userString: string }) {
{otherFields.length > 0 && (
<div className="user-modal-custom-fields">
<h4>Additional Info</h4>
- {otherFields.map(([key, value]) => (
- <div key={key} className="custom-field-item">
- <span className="field-key">{key}:</span>
- {isURL(value) ? (
- <a
- href={value}
- target="_blank"
- rel="noopener noreferrer"
- className="field-value field-link"
- onClick={(e) => e.stopPropagation()}
- >
- {value}
- <Icon
- name="nostr"
- size={12}
- className="external-link-icon"
- />
- </a>
- ) : (
- <span className="field-value">{value}</span>
- )}
- </div>
- ))}
+ {otherFields.map(([key, value]) => {
+ console.log({ key, value });
+ return (
+ <div key={key} className="custom-field-item">
+ <span className="field-key">{key}:</span>
+ <ProfValue value={value} />
+ </div>
+ );
+ })}
</div>
)}
@@ -242,10 +211,10 @@ export default function ({ userString }: { userString: string }) {
<button
className={`action-btn ${isFollowing ? "following" : "follow"}`}
onClick={handleFollow}
- disabled={loading}
+ disabled={isLoading}
>
<Icon name="pals" size={16} />
- {loading ? "..." : isFollowing ? "Following" : "Follow"}
+ {isLoading ? "..." : isFollowing ? "Following" : "Follow"}
</button>
)}
<>
@@ -275,3 +244,37 @@ export default function ({ userString }: { userString: string }) {
</Modal>
);
}
+
+// Check if a string is a URL
+const isURL = (str: string): boolean => {
+ if (!str) return false;
+ try {
+ new URL(str);
+ return true;
+ } catch {
+ return false;
+ }
+};
+
+export function ProfValue({ value }: { value: any }) {
+ if (typeof value === "string")
+ return isURL(value) ? (
+ <a
+ href={value}
+ target="_blank"
+ rel="noopener noreferrer"
+ className="field-value field-link"
+ onClick={(e) => e.stopPropagation()}
+ >
+ {value}
+ <Icon name="nostr" size={12} className="external-link-icon" />
+ </a>
+ ) : (
+ <span className="field-value">{value}</span>
+ );
+ else if (typeof value === "number")
+ return <span className="field-value">{value}</span>;
+ else if (typeof value === "object")
+ return <span className="field-value">{JSON.stringify(value)}</span>;
+ else return <span className="field-value">{JSON.stringify(value)}</span>;
+}