openUserPage(e)} className="group flex items-start gap-2">
diff --git a/src/components/user/large.tsx b/src/components/user/large.tsx
index c5264f97..d4180246 100644
--- a/src/components/user/large.tsx
+++ b/src/components/user/large.tsx
@@ -1,6 +1,6 @@
-import { DatabaseContext } from '@components/contexts/database';
import { ImageWithFallback } from '@components/imageWithFallback';
+import { createCacheProfile, getCacheProfile } from '@utils/storage';
import { truncate } from '@utils/truncate';
import { DotsHorizontalIcon } from '@radix-ui/react-icons';
@@ -8,14 +8,11 @@ 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;
+import { memo, useCallback, useEffect, useState } from 'react';
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) => {
@@ -26,34 +23,20 @@ export const UserLarge = memo(function UserLarge({ pubkey, time }: { pubkey: str
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]);
+ getCacheProfile(pubkey).then((res) => {
+ if (res) {
+ setProfile(JSON.parse(res.metadata));
+ } else {
+ fetchProfile(pubkey)
+ .then((res: any) => {
+ setProfile(JSON.parse(res.content));
+ createCacheProfile(pubkey, res.content);
+ })
+ .catch(console.error);
+ }
+ });
+ }, [fetchProfile, pubkey]);
return (
diff --git a/src/components/user/mention.tsx b/src/components/user/mention.tsx
index 3cfe132b..2a57cd3c 100644
--- a/src/components/user/mention.tsx
+++ b/src/components/user/mention.tsx
@@ -1,12 +1,10 @@
-import { DatabaseContext } from '@components/contexts/database';
-
+import { createCacheProfile, getCacheProfile } from '@utils/storage';
import { truncate } from '@utils/truncate';
import { fetch } from '@tauri-apps/api/http';
-import { memo, useCallback, useContext, useEffect, useState } from 'react';
+import { memo, useCallback, useEffect, useState } from 'react';
export const UserMention = memo(function UserMention({ pubkey }: { pubkey: string }) {
- const { db }: any = useContext(DatabaseContext);
const [profile, setProfile] = useState(null);
const fetchProfile = useCallback(async (id: string) => {
@@ -17,34 +15,20 @@ export const UserMention = memo(function UserMention({ pubkey }: { pubkey: strin
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) => {
- // insert to database
- await db.execute('INSERT OR IGNORE INTO cache_profiles (id, metadata) VALUES (?, ?);', [pubkey, event.content]);
- // update state
- setProfile(JSON.parse(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]);
+ getCacheProfile(pubkey).then((res) => {
+ if (res) {
+ setProfile(JSON.parse(res.metadata));
+ } else {
+ fetchProfile(pubkey)
+ .then((res: any) => {
+ setProfile(JSON.parse(res.content));
+ createCacheProfile(pubkey, res.content);
+ })
+ .catch(console.error);
+ }
+ });
+ }, [fetchProfile, pubkey]);
return
@{profile?.name || truncate(pubkey, 16, ' .... ')};
});
diff --git a/src/components/user/mini.tsx b/src/components/user/mini.tsx
index 63d4776d..07a4e508 100644
--- a/src/components/user/mini.tsx
+++ b/src/components/user/mini.tsx
@@ -1,14 +1,13 @@
-import { DatabaseContext } from '@components/contexts/database';
import { ImageWithFallback } from '@components/imageWithFallback';
+import { createCacheProfile, getCacheProfile } from '@utils/storage';
import { truncate } from '@utils/truncate';
import { fetch } from '@tauri-apps/api/http';
import Avatar from 'boring-avatars';
-import { memo, useCallback, useContext, useEffect, useState } from 'react';
+import { memo, useCallback, useEffect, useState } from 'react';
export const UserMini = memo(function UserMini({ pubkey }: { pubkey: string }) {
- const { db }: any = useContext(DatabaseContext);
const [profile, setProfile] = useState(null);
const fetchProfile = useCallback(async (id: string) => {
@@ -19,34 +18,20 @@ export const UserMini = memo(function UserMini({ pubkey }: { pubkey: string }) {
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]);
+ getCacheProfile(pubkey).then((res) => {
+ if (res) {
+ setProfile(JSON.parse(res.metadata));
+ } else {
+ fetchProfile(pubkey)
+ .then((res: any) => {
+ setProfile(JSON.parse(res.content));
+ createCacheProfile(pubkey, res.content);
+ })
+ .catch(console.error);
+ }
+ });
+ }, [fetchProfile, pubkey]);
return (
diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx
index e3308cab..cac8697f 100644
--- a/src/pages/_app.tsx
+++ b/src/pages/_app.tsx
@@ -1,4 +1,8 @@
-import { Provider } from 'jotai';
+import RelayProvider from '@components/relaysProvider';
+
+import { relaysAtom } from '@stores/relays';
+
+import { Provider, useAtom } from 'jotai';
import type { NextPage } from 'next';
import type { AppProps } from 'next/app';
import { ReactElement, ReactNode } from 'react';
@@ -17,5 +21,11 @@ type AppPropsWithLayout = AppProps & {
export default function MyApp({ Component, pageProps }: AppPropsWithLayout) {
// Use the layout defined at the page level, if available
const getLayout = Component.getLayout ?? ((page) => page);
- return
{getLayout()};
+ const [relays] = useAtom(relaysAtom);
+
+ return (
+
+ {getLayout()}
+
+ );
}
diff --git a/src/pages/index.tsx b/src/pages/index.tsx
index ede83f0b..a88903d7 100644
--- a/src/pages/index.tsx
+++ b/src/pages/index.tsx
@@ -1,6 +1,6 @@
import BaseLayout from '@layouts/base';
-import { getActiveAccount } from '@utils/storage';
+import { getAccounts } from '@utils/storage';
import LumeSymbol from '@assets/icons/Lume';
@@ -11,10 +11,10 @@ export default function Page() {
const router = useRouter();
useEffect(() => {
- getActiveAccount()
- .then((res: any[]) => {
+ getAccounts()
+ .then((res: any) => {
if (res.length > 0) {
- router.push('/newsfeed/following');
+ router.push('/newsfeed/circle');
} else {
router.push('/onboarding');
}
diff --git a/src/pages/newsfeed/[id].tsx b/src/pages/newsfeed/[id].tsx
index 469a1018..b6d7ce27 100644
--- a/src/pages/newsfeed/[id].tsx
+++ b/src/pages/newsfeed/[id].tsx
@@ -1,11 +1,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 { RelayContext } from '@components/relaysProvider';
+
+import { getNoteByID } from '@utils/storage';
import useLocalStorage from '@rehooks/local-storage';
import { useRouter } from 'next/router';
@@ -14,15 +15,13 @@ import {
ReactElement,
ReactFragment,
ReactPortal,
- useCallback,
useContext,
useEffect,
useState,
} from 'react';
export default function Page() {
- const { db }: any = useContext(DatabaseContext);
- const relayPool: any = useContext(RelayContext);
+ const pool: any = useContext(RelayContext);
const router = useRouter();
const id = router.query.id;
@@ -32,17 +31,15 @@ export default function Page() {
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}"`);
- setRootEvent(result[0]);
- }, [db, id]);
-
useEffect(() => {
let unsubscribe: () => void;
- fetchRoot()
- .then(() => {
- unsubscribe = relayPool.subscribe(
+ getNoteByID(id)
+ .then((res) => {
+ // update state
+ setRootEvent(res);
+ // get all comments
+ unsubscribe = pool.subscribe(
[
{
'#e': [id],
@@ -60,7 +57,7 @@ export default function Page() {
return () => {
unsubscribe();
};
- }, [fetchRoot, id, relayPool, relays]);
+ }, [id, pool, relays]);
return (
diff --git a/src/pages/onboarding/create/index.tsx b/src/pages/onboarding/create/index.tsx
index e31f934b..3dfbf87e 100644
--- a/src/pages/onboarding/create/index.tsx
+++ b/src/pages/onboarding/create/index.tsx
@@ -1,13 +1,17 @@
import BaseLayout from '@layouts/base';
-import { pool } from '@utils/pool';
-import { createAccount, getAllRelays } from '@utils/storage';
+import { RelayContext } from '@components/relaysProvider';
+
+import { relaysAtom } from '@stores/relays';
+
+import { createAccount } from '@utils/storage';
import { EyeClosedIcon, EyeOpenIcon } from '@radix-ui/react-icons';
+import { useAtom } from 'jotai';
import Image from 'next/image';
import { useRouter } from 'next/router';
import { generatePrivateKey, getEventHash, getPublicKey, nip19, signEvent } from 'nostr-tools';
-import { JSXElementConstructor, ReactElement, ReactFragment, ReactPortal, useMemo, useState } from 'react';
+import { JSXElementConstructor, ReactElement, ReactFragment, ReactPortal, useContext, useMemo, useState } from 'react';
import { Config, names, uniqueNamesGenerator } from 'unique-names-generator';
const config: Config = {
@@ -16,7 +20,9 @@ const config: Config = {
export default function Page() {
const router = useRouter();
+ const pool: any = useContext(RelayContext);
+ const [relays] = useAtom(relaysAtom);
const [type, setType] = useState('password');
const [loading, setLoading] = useState(false);
@@ -78,16 +84,11 @@ export default function Page() {
// insert to database then broadcast
createAccount(data)
.then(() => {
- getAllRelays()
- .then((res) => {
- // publish to relays
- pool(res).publish(event, res);
- router.push({
- pathname: '/onboarding/create/step-2',
- query: { id: pubKey, privkey: privKey },
- });
- })
- .catch(console.error);
+ pool.publish(event, relays);
+ router.push({
+ pathname: '/onboarding/create/step-2',
+ query: { id: pubKey, privkey: privKey },
+ });
})
.catch(console.error);
};
diff --git a/src/pages/onboarding/create/step-2.tsx b/src/pages/onboarding/create/step-2.tsx
index 5c902de5..c2db11e1 100644
--- a/src/pages/onboarding/create/step-2.tsx
+++ b/src/pages/onboarding/create/step-2.tsx
@@ -1,15 +1,27 @@
import BaseLayout from '@layouts/base';
+import { RelayContext } from '@components/relaysProvider';
import { UserBase } from '@components/user/base';
-import { pool } from '@utils/pool';
-import { createFollows, getAllRelays } from '@utils/storage';
+import { relaysAtom } from '@stores/relays';
+
+import { createFollows } from '@utils/storage';
import { CheckCircledIcon } from '@radix-ui/react-icons';
import { createClient } from '@supabase/supabase-js';
+import { useAtom } from 'jotai';
import { useRouter } from 'next/router';
import { getEventHash, signEvent } from 'nostr-tools';
-import { JSXElementConstructor, Key, ReactElement, ReactFragment, ReactPortal, useEffect, useState } from 'react';
+import {
+ JSXElementConstructor,
+ Key,
+ ReactElement,
+ ReactFragment,
+ ReactPortal,
+ useContext,
+ useEffect,
+ useState,
+} from 'react';
const supabase = createClient(
'https://niwaazauwnrwiwmnocnn.supabase.co',
@@ -52,9 +64,12 @@ const initialList = [
];
export default function Page() {
+ const pool: any = useContext(RelayContext);
+
const router = useRouter();
const { id, privkey }: any = router.query;
+ const [relays] = useAtom(relaysAtom);
const [loading, setLoading] = useState(false);
const [list, setList]: any = useState(initialList);
const [follows, setFollows] = useState([]);
@@ -93,13 +108,9 @@ export default function Page() {
createFollows(follows, id, 0)
.then((res) => {
if (res === 'ok') {
- getAllRelays()
- .then((res) => {
- // publish to relays
- pool(res).publish(event, res);
- router.push('/');
- })
- .catch(console.error);
+ // publish to relays
+ pool.publish(event, relays);
+ router.push('/');
}
})
.catch(console.error);
diff --git a/src/pages/onboarding/login/step-2.tsx b/src/pages/onboarding/login/step-2.tsx
index def0e08c..9cf8c857 100644
--- a/src/pages/onboarding/login/step-2.tsx
+++ b/src/pages/onboarding/login/step-2.tsx
@@ -1,69 +1,72 @@
import BaseLayout from '@layouts/base';
-import { pool } from '@utils/pool';
-import { createAccount, createFollows, getAllRelays } from '@utils/storage';
+import { RelayContext } from '@components/relaysProvider';
+
+import { relaysAtom } from '@stores/relays';
+
+import { createAccount, createFollows } from '@utils/storage';
+import { tagsToArray } from '@utils/tags';
import { truncate } from '@utils/truncate';
import destr from 'destr';
+import { useAtom } from 'jotai';
import Image from 'next/image';
import { useRouter } from 'next/router';
import { getPublicKey, nip19 } from 'nostr-tools';
-import { JSXElementConstructor, ReactElement, ReactFragment, ReactPortal, useEffect, useState } from 'react';
-
-const tags = (arr) => {
- const newarr = [];
- // push item to newarr
- arr.forEach((item) => {
- newarr.push(['p', item]);
- });
- return newarr;
-};
+import {
+ JSXElementConstructor,
+ ReactElement,
+ ReactFragment,
+ ReactPortal,
+ useContext,
+ useEffect,
+ useState,
+} from 'react';
export default function Page() {
+ const pool: any = useContext(RelayContext);
+
const router = useRouter();
const privkey: any = router.query.privkey;
const pubkey = getPublicKey(privkey);
+ const [relays] = useAtom(relaysAtom);
const [profile, setProfile] = useState(null);
useEffect(() => {
- getAllRelays()
- .then((res) => {
- pool(res).subscribe(
- [
- {
- authors: [pubkey],
- kinds: [0, 3],
- since: 0,
- },
- ],
- res,
- (event: any) => {
- if (event.kind === 0) {
- const data = {
- pubkey: pubkey,
- privkey: privkey,
- npub: nip19.npubEncode(pubkey),
- nsec: nip19.nsecEncode(privkey),
- metadata: event.content,
- };
- setProfile(destr(event.content));
- createAccount(data);
- } else {
- if (event.tags.length > 0) {
- createFollows(tags(event.tags), pubkey, 0);
- }
- }
- },
- undefined,
- undefined,
- {
- unsubscribeOnEose: true,
+ pool.subscribe(
+ [
+ {
+ authors: [pubkey],
+ kinds: [0, 3],
+ since: 0,
+ },
+ ],
+ relays,
+ (event: any) => {
+ if (event.kind === 0) {
+ const data = {
+ pubkey: pubkey,
+ privkey: privkey,
+ npub: nip19.npubEncode(pubkey),
+ nsec: nip19.nsecEncode(privkey),
+ metadata: event.content,
+ };
+ setProfile(destr(event.content));
+ createAccount(data);
+ } else {
+ if (event.tags.length > 0) {
+ createFollows(tagsToArray(event.tags), pubkey, 0);
}
- );
- })
- .catch(console.error);
- }, [privkey, pubkey]);
+ }
+ },
+ undefined,
+ undefined,
+ {
+ unsubscribeOnEose: true,
+ }
+ );
+ }, [pool, privkey, pubkey, relays]);
// submit then redirect to home
const submit = () => {
diff --git a/src/stores/account.tsx b/src/stores/account.tsx
new file mode 100644
index 00000000..5b4054fd
--- /dev/null
+++ b/src/stores/account.tsx
@@ -0,0 +1,9 @@
+import { isSSR } from '@utils/ssr';
+import { getActiveAccount } from '@utils/storage';
+
+import { atomWithCache } from 'jotai-cache';
+
+export const activeAccountAtom = atomWithCache(async () => {
+ const response = isSSR ? null : await getActiveAccount();
+ return response;
+});
diff --git a/src/stores/relays.tsx b/src/stores/relays.tsx
new file mode 100644
index 00000000..67d65fbe
--- /dev/null
+++ b/src/stores/relays.tsx
@@ -0,0 +1,9 @@
+import { isSSR } from '@utils/ssr';
+import { getAllRelays } from '@utils/storage';
+
+import { atomWithCache } from 'jotai-cache';
+
+export const relaysAtom = atomWithCache(async () => {
+ const response = isSSR ? null : await getAllRelays();
+ return response;
+});
diff --git a/src/stores/user.tsx b/src/stores/user.tsx
deleted file mode 100644
index b9cad4fb..00000000
--- a/src/stores/user.tsx
+++ /dev/null
@@ -1,3 +0,0 @@
-import { atom } from 'jotai';
-
-export const currentUser = atom({});
diff --git a/src/utils/pool.tsx b/src/utils/pool.tsx
deleted file mode 100644
index 6f167652..00000000
--- a/src/utils/pool.tsx
+++ /dev/null
@@ -1,6 +0,0 @@
-import { RelayPool } from 'nostr-relaypool';
-
-export function pool({ relays }: { relays: any }) {
- const createPool = new RelayPool(relays, { useEventCache: false, logSubscriptions: false });
- return createPool;
-}
diff --git a/src/utils/ssr.tsx b/src/utils/ssr.tsx
new file mode 100644
index 00000000..3f489e4f
--- /dev/null
+++ b/src/utils/ssr.tsx
@@ -0,0 +1 @@
+export const isSSR = typeof window === 'undefined';
diff --git a/src/utils/storage.tsx b/src/utils/storage.tsx
index 3afb9f1e..b99e24f3 100644
--- a/src/utils/storage.tsx
+++ b/src/utils/storage.tsx
@@ -25,7 +25,14 @@ export async function getAllRelays() {
// get active account
export async function getActiveAccount() {
const db = await connect();
- return await db.select(`SELECT * FROM accounts LIMIT 1;`);
+ const result = await db.select(`SELECT * FROM accounts LIMIT 1;`);
+ return result[0];
+}
+
+// get all accounts
+export async function getAccounts() {
+ const db = await connect();
+ return await db.select(`SELECT * FROM accounts`);
}
// get all follows by account id
@@ -71,3 +78,26 @@ export async function createCacheProfile(id, metadata) {
const db = await connect();
return await db.execute('INSERT OR IGNORE INTO cache_profiles (id, metadata) VALUES (?, ?);', [id, metadata]);
}
+
+// get cache profile
+export async function getCacheProfile(id) {
+ const db = await connect();
+ const result = await db.select(`SELECT metadata FROM cache_profiles WHERE id = "${id}"`);
+ return result[0];
+}
+
+// get note by id
+export async function getNoteByID(id) {
+ const db = await connect();
+ const result = await db.select(`SELECT * FROM cache_notes WHERE id = "${id}"`);
+ return result[0];
+}
+
+// create cache note
+export async function createCacheNote(data) {
+ const db = await connect();
+ return await db.execute(
+ 'INSERT OR IGNORE INTO cache_notes (id, pubkey, created_at, kind, content, tags, is_root) VALUES (?, ?, ?, ?, ?, ?, ?);',
+ [data.id, data.pubkey, data.created_at, data.kind, data.content, JSON.stringify(data.tags), 0]
+ );
+}
diff --git a/src/utils/tags.tsx b/src/utils/tags.tsx
new file mode 100644
index 00000000..a4d7b49e
--- /dev/null
+++ b/src/utils/tags.tsx
@@ -0,0 +1,8 @@
+export const tagsToArray = (arr) => {
+ const newarr = [];
+ // push item to newarr
+ arr.forEach((item) => {
+ newarr.push(item[1]);
+ });
+ return newarr;
+};
From e2fa8cbe03d9cbf755718800d6e7cfc6c4bb6181 Mon Sep 17 00:00:00 2001
From: Ren Amamiya <123083837+reyamir@users.noreply.github.com>
Date: Fri, 24 Mar 2023 11:08:36 +0700
Subject: [PATCH 52/71] fixed some bug
---
src/components/columns/navigator/messages/list.tsx | 4 ++--
src/components/note/connector.tsx | 2 +-
src/components/user/base.tsx | 4 +++-
3 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/src/components/columns/navigator/messages/list.tsx b/src/components/columns/navigator/messages/list.tsx
index 59de3e5c..9a202232 100644
--- a/src/components/columns/navigator/messages/list.tsx
+++ b/src/components/columns/navigator/messages/list.tsx
@@ -5,8 +5,8 @@ import { Key, memo } from 'react';
export const MessageList = memo(function MessageList({ data }: { data: any }) {
return (
<>
- {data.map((item: string, index: Key) => (
-
+ {data.map((item: { pubkey: string }, index: Key) => (
+
))}
>
);
diff --git a/src/components/note/connector.tsx b/src/components/note/connector.tsx
index d9167d60..d725f155 100644
--- a/src/components/note/connector.tsx
+++ b/src/components/note/connector.tsx
@@ -17,7 +17,7 @@ export const NoteConnector = memo(function NoteConnector() {
const [relays] = useAtom(relaysAtom);
const [activeAccount] = useAtom(activeAccountAtom);
- const [isOnline] = useState(navigator.onLine);
+ const [isOnline] = useState(true);
const now = useRef(new Date());
useEffect(() => {
diff --git a/src/components/user/base.tsx b/src/components/user/base.tsx
index 1ab3ca59..b55649bf 100644
--- a/src/components/user/base.tsx
+++ b/src/components/user/base.tsx
@@ -35,7 +35,9 @@ export const UserBase = memo(function UserBase({ pubkey }: { pubkey: string }) {
)}
- {profile?.display_name || profile?.name}
+
+ {profile?.display_name || profile?.name}
+
{truncate(pubkey, 16, ' .... ')}
From c1f06f8b287e422304d00144401c0529e130bf14 Mon Sep 17 00:00:00 2001
From: Ren Amamiya <123083837+reyamir@users.noreply.github.com>
Date: Fri, 24 Mar 2023 14:59:01 +0700
Subject: [PATCH 53/71] FUCK!!!
---
package.json | 2 +
pnpm-lock.yaml | 20 +++
src/components/columns/account/active.tsx | 6 +-
src/components/note/connector.tsx | 15 +-
src/components/note/content/index.tsx | 4 +-
src/components/note/content/metadata.tsx | 4 +-
src/components/note/counter/comments.tsx | 4 +-
src/components/note/counter/likes.tsx | 4 +-
src/components/note/form/basic.tsx | 4 +-
src/components/note/form/comment.tsx | 4 +-
src/components/note/index.tsx | 10 +-
src/components/note/mention.tsx | 4 +-
src/components/note/root.tsx | 8 +-
src/components/profile/followers.tsx | 14 +-
src/components/profile/follows.tsx | 14 +-
src/components/profile/metadata.tsx | 14 +-
src/components/profile/notes.tsx | 14 +-
src/pages/_app.tsx | 4 +-
src/pages/index.tsx | 2 +-
src/pages/newsfeed/[id].tsx | 6 +-
src/pages/newsfeed/circle.tsx | 37 +----
src/pages/newsfeed/following.tsx | 158 ++++++----------------
src/pages/onboarding/create/index.tsx | 4 +-
src/pages/onboarding/create/step-2.tsx | 4 +-
src/pages/onboarding/login/step-2.tsx | 6 +-
src/stores/note.tsx | 11 +-
src/utils/storage.tsx | 6 +
src/utils/tags.tsx | 8 --
src/utils/transform.tsx | 17 +++
29 files changed, 179 insertions(+), 229 deletions(-)
delete mode 100644 src/utils/tags.tsx
create mode 100644 src/utils/transform.tsx
diff --git a/package.json b/package.json
index f8e607ea..698f9b6b 100644
--- a/package.json
+++ b/package.json
@@ -19,6 +19,7 @@
"@radix-ui/react-popover": "^1.0.5",
"@radix-ui/react-tabs": "^1.0.3",
"@supabase/supabase-js": "^2.12.1",
+ "@tanstack/query-core": "^4.27.0",
"@tanstack/react-virtual": "3.0.0-beta.54",
"@tauri-apps/api": "^1.2.0",
"@uiw/react-markdown-preview": "^4.1.10",
@@ -29,6 +30,7 @@
"framer-motion": "^9.1.7",
"jotai": "^2.0.3",
"jotai-cache": "^0.3.0",
+ "jotai-tanstack-query": "^0.6.0",
"next": "^13.2.4",
"next-remove-imports": "^1.0.10",
"nostr-relaypool": "^0.5.18",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index f8fa932c..34e47510 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -9,6 +9,7 @@ specifiers:
'@radix-ui/react-tabs': ^1.0.3
'@supabase/supabase-js': ^2.12.1
'@tailwindcss/typography': ^0.5.9
+ '@tanstack/query-core': ^4.27.0
'@tanstack/react-virtual': 3.0.0-beta.54
'@tauri-apps/api': ^1.2.0
'@tauri-apps/cli': ^1.2.3
@@ -34,6 +35,7 @@ specifiers:
husky: ^8.0.3
jotai: ^2.0.3
jotai-cache: ^0.3.0
+ jotai-tanstack-query: ^0.6.0
lint-staged: ^13.2.0
next: ^13.2.4
next-remove-imports: ^1.0.10
@@ -63,6 +65,7 @@ dependencies:
'@radix-ui/react-popover': 1.0.5_zula6vjvt3wdocc4mwcxqa6nzi
'@radix-ui/react-tabs': 1.0.3_biqbaboplfbrettd7655fr4n2y
'@supabase/supabase-js': 2.12.1
+ '@tanstack/query-core': 4.27.0
'@tanstack/react-virtual': 3.0.0-beta.54_react@18.2.0
'@tauri-apps/api': 1.2.0
'@uiw/react-markdown-preview': 4.1.10_zula6vjvt3wdocc4mwcxqa6nzi
@@ -73,6 +76,7 @@ dependencies:
framer-motion: 9.1.7_biqbaboplfbrettd7655fr4n2y
jotai: 2.0.3_react@18.2.0
jotai-cache: 0.3.0_jotai@2.0.3
+ jotai-tanstack-query: 0.6.0_jqgumvl52k2nlr5n23qdneaa6y
next: 13.2.4_biqbaboplfbrettd7655fr4n2y
next-remove-imports: 1.0.10
nostr-relaypool: 0.5.18_ws@8.13.0
@@ -1286,6 +1290,11 @@ packages:
tailwindcss: 3.2.7_postcss@8.4.21
dev: true
+ /@tanstack/query-core/4.27.0:
+ resolution:
+ { integrity: sha512-sm+QncWaPmM73IPwFlmWSKPqjdTXZeFf/7aEmWh00z7yl2FjqophPt0dE1EHW9P1giMC5rMviv7OUbSDmWzXXA== }
+ dev: false
+
/@tanstack/react-virtual/3.0.0-beta.54_react@18.2.0:
resolution:
{ integrity: sha512-D1mDMf4UPbrtHRZZriCly5bXTBMhylslm4dhcHqTtDJ6brQcgGmk8YD9JdWBGWfGSWPKoh2x1H3e7eh+hgPXtQ== }
@@ -3829,6 +3838,17 @@ packages:
jotai: 2.0.3_react@18.2.0
dev: false
+ /jotai-tanstack-query/0.6.0_jqgumvl52k2nlr5n23qdneaa6y:
+ resolution:
+ { integrity: sha512-87oD6MnjrgfLWeCJXB/dQt4xyCmyFYZeG9jw4Y2lIprtwLKS5s/vCEjNP5fnYG2nuPBkopiRECTEqtIysvHSxg== }
+ peerDependencies:
+ '@tanstack/query-core': '*'
+ jotai: '>=1.11.0'
+ dependencies:
+ '@tanstack/query-core': 4.27.0
+ jotai: 2.0.3_react@18.2.0
+ dev: false
+
/jotai/2.0.3_react@18.2.0:
resolution:
{ integrity: sha512-MMjhSPAL3RoeZD9WbObufRT2quThEAEknHHridf2ma8Ml7ZVQmUiHk0ssdbR3F0h3kcwhYqSGJ59OjhPge7RRg== }
diff --git a/src/components/columns/account/active.tsx b/src/components/columns/account/active.tsx
index 7daa181b..dff9e4ea 100644
--- a/src/components/columns/account/active.tsx
+++ b/src/components/columns/account/active.tsx
@@ -3,18 +3,18 @@ import { RelayContext } from '@components/relaysProvider';
import { relaysAtom } from '@stores/relays';
import { createFollows } from '@utils/storage';
-import { tagsToArray } from '@utils/tags';
+import { tagsToArray } from '@utils/transform';
import * as DropdownMenu from '@radix-ui/react-dropdown-menu';
import { AvatarIcon, ExitIcon, GearIcon } from '@radix-ui/react-icons';
-import { useAtom } from 'jotai';
+import { useAtomValue } from 'jotai';
import Image from 'next/image';
import { useRouter } from 'next/router';
import { memo, useContext, useEffect } from 'react';
export const ActiveAccount = memo(function ActiveAccount({ user }: { user: any }) {
const pool: any = useContext(RelayContext);
- const [relays] = useAtom(relaysAtom);
+ const relays = useAtomValue(relaysAtom);
const router = useRouter();
const userData = JSON.parse(user.metadata);
diff --git a/src/components/note/connector.tsx b/src/components/note/connector.tsx
index d725f155..1edcb83f 100644
--- a/src/components/note/connector.tsx
+++ b/src/components/note/connector.tsx
@@ -6,29 +6,28 @@ import { relaysAtom } from '@stores/relays';
import { dateToUnix, hoursAgo } from '@utils/getDate';
import { createCacheNote, getAllFollowsByID } from '@utils/storage';
+import { pubkeyArray } from '@utils/transform';
-import { useAtom, useSetAtom } from 'jotai';
+import { useAtom, useAtomValue, useSetAtom } from 'jotai';
import { memo, useContext, useEffect, useRef, useState } from 'react';
export const NoteConnector = memo(function NoteConnector() {
const pool: any = useContext(RelayContext);
const setHasNewerNote = useSetAtom(hasNewerNoteAtom);
- const [relays] = useAtom(relaysAtom);
+ const relays = useAtomValue(relaysAtom);
const [activeAccount] = useAtom(activeAccountAtom);
const [isOnline] = useState(true);
const now = useRef(new Date());
useEffect(() => {
- let unsubscribe;
-
getAllFollowsByID(activeAccount.id).then((follows) => {
- unsubscribe = pool.subscribe(
+ pool.subscribe(
[
{
kinds: [1],
- authors: follows,
+ authors: pubkeyArray(follows),
since: dateToUnix(hoursAgo(12, now.current)),
},
],
@@ -43,10 +42,6 @@ export const NoteConnector = memo(function NoteConnector() {
}
);
});
-
- return () => {
- unsubscribe();
- };
}, [activeAccount.id, pool, relays, setHasNewerNote]);
return (
diff --git a/src/components/note/content/index.tsx b/src/components/note/content/index.tsx
index bc1b75a8..090c109e 100644
--- a/src/components/note/content/index.tsx
+++ b/src/components/note/content/index.tsx
@@ -8,7 +8,7 @@ import destr from 'destr';
import { memo, useMemo } from 'react';
import reactStringReplace from 'react-string-replace';
-export const Content = memo(function Content({ data }: { data: any }) {
+export const NoteContent = memo(function NoteContent({ data }: { data: any }) {
const content = useMemo(() => {
let parsedContent;
// get data tags
@@ -33,7 +33,7 @@ export const Content = memo(function Content({ data }: { data: any }) {
if (tags[match][0] === 'p') {
return
;
} else if (tags[match][0] === 'e') {
- return
;
+ return
;
}
});
}
diff --git a/src/components/note/content/metadata.tsx b/src/components/note/content/metadata.tsx
index 5a110239..f991dba5 100644
--- a/src/components/note/content/metadata.tsx
+++ b/src/components/note/content/metadata.tsx
@@ -4,7 +4,7 @@ import { RelayContext } from '@components/relaysProvider';
import { relaysAtom } from '@stores/relays';
-import { useAtom } from 'jotai';
+import { useAtomValue } from 'jotai';
import { useContext, useEffect, useState } from 'react';
export default function NoteMetadata({
@@ -19,7 +19,7 @@ export default function NoteMetadata({
eventContent: any;
}) {
const pool: any = useContext(RelayContext);
- const [relays] = useAtom(relaysAtom);
+ const relays = useAtomValue(relaysAtom);
const [likes, setLikes] = useState(0);
const [comments, setComments] = useState(0);
diff --git a/src/components/note/counter/comments.tsx b/src/components/note/counter/comments.tsx
index 1deeb615..819de01c 100644
--- a/src/components/note/counter/comments.tsx
+++ b/src/components/note/counter/comments.tsx
@@ -11,7 +11,7 @@ import CommentIcon from '@assets/icons/comment';
import * as Dialog from '@radix-ui/react-dialog';
import { SizeIcon } from '@radix-ui/react-icons';
-import { useAtom } from 'jotai';
+import { useAtom, useAtomValue } from 'jotai';
import { useRouter } from 'next/router';
import { getEventHash, signEvent } from 'nostr-tools';
import { memo, useContext, useState } from 'react';
@@ -32,7 +32,7 @@ export const CommentsCounter = memo(function CommentsCounter({
const router = useRouter();
const pool: any = useContext(RelayContext);
- const [relays] = useAtom(relaysAtom);
+ const relays = useAtomValue(relaysAtom);
const [activeAccount] = useAtom(activeAccountAtom);
const [open, setOpen] = useState(false);
diff --git a/src/components/note/counter/likes.tsx b/src/components/note/counter/likes.tsx
index 37ee6dc1..eb1ccccd 100644
--- a/src/components/note/counter/likes.tsx
+++ b/src/components/note/counter/likes.tsx
@@ -8,7 +8,7 @@ import { dateToUnix } from '@utils/getDate';
import LikeIcon from '@assets/icons/like';
import LikedIcon from '@assets/icons/liked';
-import { useAtom } from 'jotai';
+import { useAtom, useAtomValue } from 'jotai';
import { getEventHash, signEvent } from 'nostr-tools';
import { memo, useContext, useEffect, useState } from 'react';
@@ -23,7 +23,7 @@ export const LikesCounter = memo(function LikesCounter({
}) {
const pool: any = useContext(RelayContext);
- const [relays] = useAtom(relaysAtom);
+ const relays = useAtomValue(relaysAtom);
const [activeAccount] = useAtom(activeAccountAtom);
const [isReact, setIsReact] = useState(false);
diff --git a/src/components/note/form/basic.tsx b/src/components/note/form/basic.tsx
index d10d47aa..a44a49ae 100644
--- a/src/components/note/form/basic.tsx
+++ b/src/components/note/form/basic.tsx
@@ -8,7 +8,7 @@ import { dateToUnix } from '@utils/getDate';
import * as Dialog from '@radix-ui/react-dialog';
import { SizeIcon } from '@radix-ui/react-icons';
import * as commands from '@uiw/react-md-editor/lib/commands';
-import { useAtom } from 'jotai';
+import { useAtom, useAtomValue } from 'jotai';
import dynamic from 'next/dynamic';
import { getEventHash, signEvent } from 'nostr-tools';
import { useContext, useState } from 'react';
@@ -20,7 +20,7 @@ const MDEditor = dynamic(() => import('@uiw/react-md-editor').then((mod) => mod.
export default function FormBasic() {
const pool: any = useContext(RelayContext);
- const [relays] = useAtom(relaysAtom);
+ const relays = useAtomValue(relaysAtom);
const [activeAccount] = useAtom(activeAccountAtom);
const [open, setOpen] = useState(false);
diff --git a/src/components/note/form/comment.tsx b/src/components/note/form/comment.tsx
index 91a60c2b..5c54b4fd 100644
--- a/src/components/note/form/comment.tsx
+++ b/src/components/note/form/comment.tsx
@@ -6,14 +6,14 @@ import { relaysAtom } from '@stores/relays';
import { dateToUnix } from '@utils/getDate';
-import { useAtom } from 'jotai';
+import { useAtom, useAtomValue } from 'jotai';
import { getEventHash, signEvent } from 'nostr-tools';
import { useContext, useState } from 'react';
export default function FormComment({ eventID }: { eventID: any }) {
const pool: any = useContext(RelayContext);
- const [relays] = useAtom(relaysAtom);
+ const relays = useAtomValue(relaysAtom);
const [activeAccount] = useAtom(activeAccountAtom);
const [value, setValue] = useState('');
diff --git a/src/components/note/index.tsx b/src/components/note/index.tsx
index 9ebabe9c..25ef9983 100644
--- a/src/components/note/index.tsx
+++ b/src/components/note/index.tsx
@@ -1,16 +1,16 @@
-import { Content } from '@components/note/content';
+import { NoteContent } from '@components/note/content';
import { RootNote } from '@components/note/root';
import destr from 'destr';
import { useRouter } from 'next/router';
-import { memo, useMemo, useRef } from 'react';
+import { memo, useCallback, useRef } from 'react';
export const Note = memo(function Note({ event }: { event: any }) {
const router = useRouter();
const tags = destr(event.tags);
const rootEventID = useRef(null);
- const fetchRootEvent = useMemo(() => {
+ const fetchRootEvent = useCallback(() => {
if (tags.length > 0) {
if (tags[0][0] === 'e' || tags[0][2] === 'root') {
rootEventID.current = tags[0][1];
@@ -43,8 +43,8 @@ export const Note = memo(function Note({ event }: { event: any }) {
onClick={(e) => openThread(e)}
className="relative z-10 flex h-min min-h-min w-full select-text flex-col border-b border-zinc-800 py-5 px-3 hover:bg-black/20"
>
- <>{fetchRootEvent}>
-
+
{fetchRootEvent()}
+
);
});
diff --git a/src/components/note/mention.tsx b/src/components/note/mention.tsx
index 29df6b14..4ab3cf5e 100644
--- a/src/components/note/mention.tsx
+++ b/src/components/note/mention.tsx
@@ -5,13 +5,13 @@ import { relaysAtom } from '@stores/relays';
import { createCacheNote, getNoteByID } from '@utils/storage';
-import { useAtom } from 'jotai';
+import { useAtomValue } from 'jotai';
import { memo, useCallback, useContext, useEffect, useState } from 'react';
export const MentionNote = memo(function MentionNote({ id }: { id: string }) {
const pool: any = useContext(RelayContext);
- const [relays] = useAtom(relaysAtom);
+ const relays = useAtomValue(relaysAtom);
const [event, setEvent] = useState(null);
const fetchEvent = useCallback(() => {
diff --git a/src/components/note/root.tsx b/src/components/note/root.tsx
index ec4750f4..7244f00a 100644
--- a/src/components/note/root.tsx
+++ b/src/components/note/root.tsx
@@ -1,17 +1,17 @@
-import { Content } from '@components/note/content';
+import { NoteContent } from '@components/note/content';
import { RelayContext } from '@components/relaysProvider';
import { relaysAtom } from '@stores/relays';
import { createCacheNote, getNoteByID } from '@utils/storage';
-import { useAtom } from 'jotai';
+import { useAtomValue } from 'jotai';
import { memo, useCallback, useContext, useEffect, useState } from 'react';
export const RootNote = memo(function RootNote({ id }: { id: string }) {
const pool: any = useContext(RelayContext);
- const [relays] = useAtom(relaysAtom);
+ const relays = useAtomValue(relaysAtom);
const [event, setEvent] = useState(null);
const fetchEvent = useCallback(() => {
@@ -51,7 +51,7 @@ export const RootNote = memo(function RootNote({ id }: { id: string }) {
return (
);
} else {
diff --git a/src/components/profile/followers.tsx b/src/components/profile/followers.tsx
index febb62c7..31d3945a 100644
--- a/src/components/profile/followers.tsx
+++ b/src/components/profile/followers.tsx
@@ -1,20 +1,22 @@
-import { RelayContext } from '@components/contexts/relay';
+import { RelayContext } from '@components/relaysProvider';
+
+import { relaysAtom } from '@stores/relays';
-import useLocalStorage from '@rehooks/local-storage';
import destr from 'destr';
+import { useAtomValue } from 'jotai';
import { Author } from 'nostr-relaypool';
import { useContext, useEffect, useState } from 'react';
export default function ProfileFollowers({ id }: { id: string }) {
- const relayPool: any = useContext(RelayContext);
- const [relays]: any = useLocalStorage('relays');
+ const pool: any = useContext(RelayContext);
+ const relays: any = useAtomValue(relaysAtom);
const [followers, setFollowers] = useState(null);
useEffect(() => {
- const user = new Author(relayPool, relays, id);
+ const user = new Author(pool, relays, id);
user.followers((res) => setFollowers(destr(res.tags)), 0, 100);
- }, [id, relayPool, relays]);
+ }, [id, pool, relays]);
return (