diff --git a/src/components/note/atoms/user.tsx b/src/components/note/atoms/user.tsx index 6fe5e87b..2fe94ff3 100644 --- a/src/components/note/atoms/user.tsx +++ b/src/components/note/atoms/user.tsx @@ -14,7 +14,7 @@ import Database from 'tauri-plugin-sql-api'; const db = typeof window !== 'undefined' ? await Database.load('sqlite:lume.db') : null; export const User = memo(function User({ pubkey, time }: { pubkey: string; time: any }) { - const [profile, setProfile] = useState({ picture: null, name: null }); + const [profile, setProfile] = useState({ picture: null, name: null, username: null }); const { onEvent } = useNostrEvents({ filter: { diff --git a/src/components/note/atoms/userWithUsername.tsx b/src/components/note/atoms/userWithUsername.tsx new file mode 100644 index 00000000..30b87ff0 --- /dev/null +++ b/src/components/note/atoms/userWithUsername.tsx @@ -0,0 +1,97 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +import { ImageWithFallback } from '@components/imageWithFallback'; + +import { truncate } from '@utils/truncate'; + +import MoreIcon from '@assets/icons/More'; + +import Avatar from 'boring-avatars'; +import { useNostrEvents } from 'nostr-react'; +import { memo, useEffect, useState } from 'react'; +import Database from 'tauri-plugin-sql-api'; + +const db = typeof window !== 'undefined' ? await Database.load('sqlite:lume.db') : null; + +export const UserWithUsername = memo(function UserWithUsername({ pubkey }: { pubkey: string }) { + const [profile, setProfile] = useState({ picture: null, name: null, username: null }); + + const { onEvent } = useNostrEvents({ + filter: { + authors: [pubkey], + kinds: [0], + }, + }); + + onEvent(async (rawMetadata) => { + try { + const metadata: any = JSON.parse(rawMetadata.content); + if (profile.picture === null || profile.name === null) { + setProfile(metadata); + await db.execute( + `INSERT OR IGNORE INTO cache_profiles (pubkey, metadata) VALUES ("${pubkey}", '${JSON.stringify( + metadata + )}')` + ); + } else { + return; + } + } catch (err) { + console.error(err, rawMetadata); + } + }); + + useEffect(() => { + const initialProfile = async () => { + const result: any = await db.select( + `SELECT metadata FROM cache_profiles WHERE pubkey = "${pubkey}"` + ); + db.close; + return result; + }; + + initialProfile() + .then((res) => { + if (res[0] !== undefined) { + setProfile(JSON.parse(res[0].metadata)); + } + }) + .catch(console.error); + }, [pubkey]); + + return ( +
+
+ {profile.picture ? ( + + ) : ( + + )} +
+
+
+
+ + {profile.name ? profile.name : truncate(pubkey, 16, ' .... ')} + + + {profile.username ? profile.username : truncate(pubkey, 16, ' .... ')} + +
+
+ +
+
+
+
+ ); +}); diff --git a/src/components/note/modal/index.tsx b/src/components/note/modal/index.tsx new file mode 100644 index 00000000..31d3a05c --- /dev/null +++ b/src/components/note/modal/index.tsx @@ -0,0 +1,41 @@ +import { UserWithUsername } from '@components/note/atoms/userWithUsername'; +import Content from '@components/note/content'; +import NoteReply from '@components/note/modal/noteReply'; + +import { useNostrEvents } from 'nostr-react'; +import { memo } from 'react'; + +/* eslint-disable @typescript-eslint/no-explicit-any */ +const Modal = ({ event }: { event: any }) => { + const { events } = useNostrEvents({ + filter: { + '#e': [event.id], + since: event.created_at, + kinds: [1], + limit: 100, + }, + }); + + return ( +
+
+
+
+
+
+ + +
+
+ {events.map((item) => ( + + ))} +
+
+
+
+
+ ); +}; + +export default memo(Modal); diff --git a/src/components/note/modal/noteReply.tsx b/src/components/note/modal/noteReply.tsx new file mode 100644 index 00000000..9bf934c2 --- /dev/null +++ b/src/components/note/modal/noteReply.tsx @@ -0,0 +1,18 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +import { User } from '@components/note/atoms/user'; +import Content from '@components/note/content'; + +export default function NoteReply({ event }: { event: any }) { + return ( +
+
+ +
+
+ +
+
+
+
+ ); +} diff --git a/src/components/note/single.tsx b/src/components/note/single.tsx index c7227065..c5bad333 100644 --- a/src/components/note/single.tsx +++ b/src/components/note/single.tsx @@ -4,33 +4,41 @@ import Reply from '@components/note/atoms/reply'; import { User } from '@components/note/atoms/user'; import Content from '@components/note/content'; -import { useRouter } from 'next/router'; +import * as Dialog from '@radix-ui/react-dialog'; +import dynamic from 'next/dynamic'; import { memo } from 'react'; +const Modal = dynamic(() => import('@components/note/modal'), { + ssr: false, + loading: () => <>, +}); + // eslint-disable-next-line @typescript-eslint/no-explicit-any export const Single = memo(function Single({ event }: { event: any }) { - const router = useRouter(); - - const openThread = (id: string) => { - router.push(`/feed/${id}`); - }; - return ( -
openThread(event.id)} - className="flex h-min min-h-min w-full cursor-pointer select-text flex-col border-b border-zinc-800 py-4 px-6 hover:bg-zinc-800"> -
- -
-
- -
- - + + +
+
+ +
+
+ +
+ + +
+
-
-
+ + + + + + + + ); });