-
-
-
-
diff --git a/src/components/note/root.tsx b/src/components/note/root.tsx
index 92d75818..1e942f07 100644
--- a/src/components/note/root.tsx
+++ b/src/components/note/root.tsx
@@ -44,9 +44,7 @@ export const RootNote = memo(function RootNote({ id }: { id: string }) {
insertDB(event);
},
undefined,
- (events, relayURL) => {
- console.log(events, relayURL);
- },
+ undefined,
{
unsubscribeOnEose: true,
}
diff --git a/src/components/user/extend.tsx b/src/components/user/extend.tsx
index 8f11c3f8..48a1ea70 100644
--- a/src/components/user/extend.tsx
+++ b/src/components/user/extend.tsx
@@ -1,6 +1,8 @@
import { DatabaseContext } from '@components/contexts/database';
import { ImageWithFallback } from '@components/imageWithFallback';
+import { truncate } from '@utils/truncate';
+
import { DotsHorizontalIcon } from '@radix-ui/react-icons';
import { fetch } from '@tauri-apps/api/http';
import Avatar from 'boring-avatars';
@@ -74,7 +76,9 @@ export const UserExtend = memo(function UserExtend({ pubkey, time }: { pubkey: s
- {profile?.name}
+
+ {profile?.display_name || profile?.name || truncate(pubkey, 16, ' .... ')}
+
·
{dayjs().to(dayjs.unix(time))}
diff --git a/src/components/user/large.tsx b/src/components/user/large.tsx
new file mode 100644
index 00000000..c5264f97
--- /dev/null
+++ b/src/components/user/large.tsx
@@ -0,0 +1,97 @@
+import { DatabaseContext } from '@components/contexts/database';
+import { ImageWithFallback } from '@components/imageWithFallback';
+
+import { truncate } from '@utils/truncate';
+
+import { DotsHorizontalIcon } from '@radix-ui/react-icons';
+import { fetch } from '@tauri-apps/api/http';
+import Avatar from 'boring-avatars';
+import dayjs from 'dayjs';
+import relativeTime from 'dayjs/plugin/relativeTime';
+import { memo, useCallback, useContext, useEffect, useState } from 'react';
+
+truncate;
+
+dayjs.extend(relativeTime);
+
+export const UserLarge = memo(function UserLarge({ pubkey, time }: { pubkey: string; time: any }) {
+ const { db }: any = useContext(DatabaseContext);
+ const [profile, setProfile] = useState(null);
+
+ const fetchProfile = useCallback(async (id: string) => {
+ const res = await fetch(`https://rbr.bio/${id}/metadata.json`, {
+ method: 'GET',
+ timeout: 30,
+ });
+ return res.data;
+ }, []);
+
+ const getCacheProfile = useCallback(async () => {
+ const result: any = await db.select(`SELECT metadata FROM cache_profiles WHERE id = "${pubkey}"`);
+ return result[0];
+ }, [db, pubkey]);
+
+ const insertCacheProfile = useCallback(
+ async (event) => {
+ // update state
+ setProfile(JSON.parse(event.content));
+ // insert to database
+ await db.execute('INSERT OR IGNORE INTO cache_profiles (id, metadata) VALUES (?, ?);', [pubkey, event.content]);
+ },
+ [db, pubkey]
+ );
+
+ useEffect(() => {
+ getCacheProfile()
+ .then((res) => {
+ if (res !== undefined) {
+ setProfile(JSON.parse(res.metadata));
+ } else {
+ fetchProfile(pubkey)
+ .then((res) => insertCacheProfile(res))
+ .catch(console.error);
+ }
+ })
+ .catch(console.error);
+ }, [fetchProfile, getCacheProfile, insertCacheProfile, pubkey]);
+
+ return (
+
+
+ {profile?.picture ? (
+
+ ) : (
+
+ )}
+
+
+
+
+
+ {profile?.display_name || profile?.name || truncate(pubkey, 16, ' .... ')}
+
+
+ {profile?.username || truncate(pubkey, 16, ' .... ')} · {dayjs().to(dayjs.unix(time))}
+
+
+
+
+
+
+
+
+
+
+ );
+});
diff --git a/src/components/user/mini.tsx b/src/components/user/mini.tsx
index 3289cac2..63d4776d 100644
--- a/src/components/user/mini.tsx
+++ b/src/components/user/mini.tsx
@@ -64,7 +64,9 @@ export const UserMini = memo(function UserMini({ pubkey }: { pubkey: string }) {
)}
-
{profile?.name || truncate(pubkey, 16, ' .... ')}
+
+ {profile?.display_name || profile?.name || truncate(pubkey, 16, ' .... ')}
+
);
diff --git a/src/pages/newsfeed/[id].tsx b/src/pages/newsfeed/[id].tsx
index 753282fd..469a1018 100644
--- a/src/pages/newsfeed/[id].tsx
+++ b/src/pages/newsfeed/[id].tsx
@@ -2,9 +2,12 @@ import BaseLayout from '@layouts/base';
import WithSidebarLayout from '@layouts/withSidebar';
import { DatabaseContext } from '@components/contexts/database';
+import { RelayContext } from '@components/contexts/relay';
import { Content } from '@components/note/content';
+import { ContentExtend } from '@components/note/content/extend';
import FormComment from '@components/note/form/comment';
+import useLocalStorage from '@rehooks/local-storage';
import { useRouter } from 'next/router';
import {
JSXElementConstructor,
@@ -18,26 +21,65 @@ import {
} from 'react';
export default function Page() {
- const router = useRouter();
const { db }: any = useContext(DatabaseContext);
+ const relayPool: any = useContext(RelayContext);
+ const router = useRouter();
const id = router.query.id;
- const [root, setRoot] = useState(null);
+
+ const [relays]: any = useLocalStorage('relays');
+
+ const [rootEvent, setRootEvent] = useState(null);
+ const [comments, setComments] = useState([]);
const fetchRoot = useCallback(async () => {
const result = await db.select(`SELECT * FROM cache_notes WHERE id = "${id}"`);
- setRoot(result[0]);
+ setRootEvent(result[0]);
}, [db, id]);
useEffect(() => {
- fetchRoot().catch(console.error);
- }, [fetchRoot]);
+ let unsubscribe: () => void;
+
+ fetchRoot()
+ .then(() => {
+ unsubscribe = relayPool.subscribe(
+ [
+ {
+ '#e': [id],
+ kinds: [1],
+ },
+ ],
+ relays,
+ (event: any) => {
+ setComments((comments) => [...comments, event]);
+ }
+ );
+ })
+ .catch(console.error);
+
+ return () => {
+ unsubscribe();
+ };
+ }, [fetchRoot, id, relayPool, relays]);
return (
-
{root && }
+
+ {rootEvent && }
+
-
+
+
+
+ {comments.length > 0 &&
+ comments.map((comment) => (
+
+
+
+ ))}
);