From b1cecbbc07abf70f2ba6cfd2b73658c91b5d61e0 Mon Sep 17 00:00:00 2001
From: Ren Amamiya <123083837+reyamir@users.noreply.github.com>
Date: Tue, 20 Jun 2023 13:48:08 +0700
Subject: [PATCH] add user page
---
src/app/space/components/blocks/profile.tsx | 107 -----------
src/app/trending/components/profile.tsx | 2 +-
src/app/user/_default.page.tsx | 1 +
src/app/user/layout.tsx | 14 ++
src/app/user/pages/index.page.tsx | 192 ++++++++++++++++++++
src/shared/accounts/active.tsx | 6 +-
src/shared/user.tsx | 6 +-
7 files changed, 216 insertions(+), 112 deletions(-)
delete mode 100644 src/app/space/components/blocks/profile.tsx
create mode 100644 src/app/user/_default.page.tsx
create mode 100644 src/app/user/layout.tsx
create mode 100644 src/app/user/pages/index.page.tsx
diff --git a/src/app/space/components/blocks/profile.tsx b/src/app/space/components/blocks/profile.tsx
deleted file mode 100644
index 4ec091ad..00000000
--- a/src/app/space/components/blocks/profile.tsx
+++ /dev/null
@@ -1,107 +0,0 @@
-import { ArrowLeftIcon } from "@shared/icons";
-import { Image } from "@shared/image";
-import { useActiveAccount } from "@stores/accounts";
-import { DEFAULT_AVATAR } from "@stores/constants";
-import { useProfile } from "@utils/hooks/useProfile";
-import { compactNumber } from "@utils/number";
-import { shortenKey } from "@utils/shortenKey";
-import useSWR from "swr";
-
-const fetcher = (url: string) => fetch(url).then((r) => r.json());
-
-export function ProfileBlock({ params }: { params: any }) {
- const removeBlock = useActiveAccount((state: any) => state.removeBlock);
-
- const close = () => {
- removeBlock(params.id, true);
- };
-
- const { user } = useProfile(params.pubkey);
- const { data: userStats } = useSWR(
- user ? `https://api.nostr.band/v0/stats/profile/${params.pubkey}` : null,
- fetcher,
- );
-
- return (
-
- {error &&
Failed to fetch
}
+ {error &&
Failed to fetch user stats
}
{!userStats ? (
Loading...
) : (
diff --git a/src/app/user/_default.page.tsx b/src/app/user/_default.page.tsx
new file mode 100644
index 00000000..e4596971
--- /dev/null
+++ b/src/app/user/_default.page.tsx
@@ -0,0 +1 @@
+export { LayoutUser as Layout } from "./layout";
diff --git a/src/app/user/layout.tsx b/src/app/user/layout.tsx
new file mode 100644
index 00000000..90a31e26
--- /dev/null
+++ b/src/app/user/layout.tsx
@@ -0,0 +1,14 @@
+import { MultiAccounts } from "@shared/multiAccounts";
+import { Navigation } from "@shared/navigation";
+
+export function LayoutUser({ children }: { children: React.ReactNode }) {
+ return (
+
+ );
+}
diff --git a/src/app/user/pages/index.page.tsx b/src/app/user/pages/index.page.tsx
new file mode 100644
index 00000000..5138d834
--- /dev/null
+++ b/src/app/user/pages/index.page.tsx
@@ -0,0 +1,192 @@
+import { NDKEvent, NDKPrivateKeySigner } from "@nostr-dev-kit/ndk";
+import { Image } from "@shared/image";
+import { RelayContext } from "@shared/relayProvider";
+import { useActiveAccount } from "@stores/accounts";
+import { DEFAULT_AVATAR } from "@stores/constants";
+import { dateToUnix } from "@utils/date";
+import { usePageContext } from "@utils/hooks/usePageContext";
+import { useProfile } from "@utils/hooks/useProfile";
+import { compactNumber } from "@utils/number";
+import { shortenKey } from "@utils/shortenKey";
+import { useContext } from "react";
+import useSWR from "swr";
+
+const fetcher = (url: string) => fetch(url).then((r) => r.json());
+
+export function Page() {
+ const ndk = useContext(RelayContext);
+ const pageContext = usePageContext();
+ const searchParams: any = pageContext.urlParsed.search;
+ const pubkey = searchParams.pubkey;
+
+ const { user } = useProfile(pubkey);
+ const { data: userStats, error } = useSWR(
+ `https://api.nostr.band/v0/stats/profile/${pubkey}`,
+ fetcher,
+ );
+
+ const account = useActiveAccount((state: any) => state.account);
+ const follows = account ? JSON.parse(account.follows) : [];
+
+ const follow = (pubkey: string) => {
+ try {
+ const followsAsSet = new Set(follows);
+ followsAsSet.add(pubkey);
+
+ const signer = new NDKPrivateKeySigner(account.privkey);
+ ndk.signer = signer;
+
+ const tags = [];
+ followsAsSet.forEach((item) => {
+ tags.push(["p", item]);
+ });
+
+ const event = new NDKEvent(ndk);
+ event.content = "";
+ event.created_at = dateToUnix();
+ event.pubkey = pubkey;
+ event.kind = 3;
+ event.tags = tags;
+ // publish event
+ event.publish();
+ } catch (error) {
+ console.log(error);
+ }
+ };
+
+ const unfollow = (pubkey: string) => {
+ try {
+ const followsAsSet = new Set(follows);
+ followsAsSet.delete(pubkey);
+
+ const signer = new NDKPrivateKeySigner(account.privkey);
+ ndk.signer = signer;
+
+ const tags = [];
+ followsAsSet.forEach((item) => {
+ tags.push(["p", item]);
+ });
+
+ const event = new NDKEvent(ndk);
+ event.content = "";
+ event.created_at = dateToUnix();
+ event.pubkey = pubkey;
+ event.kind = 3;
+ event.tags = tags;
+ // publish event
+ event.publish();
+ } catch (error) {
+ console.log(error);
+ }
+ };
+
+ return (
+
+
+
+
+
+
+
+
+
+
+ {user?.displayName || user?.name || "No name"}
+
+
+ {user?.nip05 || shortenKey(pubkey)}
+
+
+ {user?.about}
+
+
+
+
+ {error &&
Failed to fetch user stats
}
+ {!userStats ? (
+
Loading...
+ ) : (
+
+
+
+ {userStats.stats[pubkey].followers_pubkey_count ?? 0}
+
+
+ Followers
+
+
+
+
+ {userStats.stats[pubkey].pub_following_pubkey_count ?? 0}
+
+
+ Following
+
+
+
+
+ {userStats.stats[pubkey].zaps_received
+ ? compactNumber.format(
+ userStats.stats[pubkey].zaps_received.msats / 1000,
+ )
+ : 0}
+
+
+ Zaps received
+
+
+
+
+ {userStats.stats[pubkey].zaps_sent
+ ? compactNumber.format(
+ userStats.stats[pubkey].zaps_sent.msats / 1000,
+ )
+ : 0}
+
+
+ Zaps sent
+
+
+
+ )}
+
+ {follows.includes(pubkey) ? (
+
+ ) : (
+
+ )}
+
+ Message
+
+
+
+
+
+ );
+}
diff --git a/src/shared/accounts/active.tsx b/src/shared/accounts/active.tsx
index afe3aa2d..5f3c5cae 100644
--- a/src/shared/accounts/active.tsx
+++ b/src/shared/accounts/active.tsx
@@ -24,7 +24,7 @@ export function ActiveAccount({ data }: { data: any }) {
// subscribe to channel
const sub = ndk.subscribe(
{
- kinds: [4, 42],
+ kinds: [1, 4, 42],
"#p": [data.pubkey],
since: since,
},
@@ -35,6 +35,10 @@ export function ActiveAccount({ data }: { data: any }) {
sub.addListener("event", (event) => {
switch (event.kind) {
+ case 1:
+ // send native notifiation
+ sendNativeNotification("Someone mention you");
+ break;
case 4:
// save
saveChat(data.pubkey, event);
diff --git a/src/shared/user.tsx b/src/shared/user.tsx
index 9b6c45d1..42db1997 100644
--- a/src/shared/user.tsx
+++ b/src/shared/user.tsx
@@ -66,7 +66,7 @@ export function User({
leaveTo="opacity-0 translate-y-1"
>
-