diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index 196aa2ff..cd9fdb11 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -37,6 +37,11 @@ struct GetFollowData { account_id: i32, } +#[derive(Deserialize, Type)] +struct GetFollowPubkeyData { + pubkey: String, +} + #[derive(Deserialize, Type)] struct CreateFollowData { pubkey: String, @@ -105,6 +110,19 @@ async fn get_follows(db: DbState<'_>, data: GetFollowData) -> Result, + data: GetFollowPubkeyData, +) -> Result, ()> { + db.follow() + .find_first(vec![follow::pubkey::equals(data.pubkey)]) + .exec() + .await + .map_err(|_| ()) +} + #[tauri::command] #[specta::specta] async fn create_follow(db: DbState<'_>, data: CreateFollowData) -> Result { @@ -198,6 +216,7 @@ async fn main() { get_accounts, create_account, get_follows, + get_follow_by_pubkey, create_follow, create_note, get_notes, @@ -238,6 +257,7 @@ async fn main() { get_accounts, create_account, get_follows, + get_follow_by_pubkey, create_follow, create_note, get_notes, diff --git a/src/components/note/parent.tsx b/src/components/note/parent.tsx index 07399915..8614e3f9 100644 --- a/src/components/note/parent.tsx +++ b/src/components/note/parent.tsx @@ -45,7 +45,7 @@ export const NoteParent = memo(function NoteParent({ id }: { id: string }) { parent_id: parentID, parent_comment_id: '', created_at: event.created_at, - account_id: activeAccount.pubkey, + account_id: activeAccount.id, }).catch(console.error); }, undefined, diff --git a/src/components/note/repost.tsx b/src/components/note/repost.tsx index 80394934..1a8590ce 100644 --- a/src/components/note/repost.tsx +++ b/src/components/note/repost.tsx @@ -41,7 +41,7 @@ export const NoteRepost = memo(function NoteRepost({ id }: { id: string }) { parent_id: parentID, parent_comment_id: '', created_at: event.created_at, - account_id: activeAccount.pubkey, + account_id: activeAccount.id, }).catch(console.error); }, undefined, diff --git a/src/components/user/extend.tsx b/src/components/user/extend.tsx index d5026177..b04934b5 100644 --- a/src/components/user/extend.tsx +++ b/src/components/user/extend.tsx @@ -1,23 +1,20 @@ import { ImageWithFallback } from '@components/imageWithFallback'; -import { RelayContext } from '@components/relaysProvider'; import { DEFAULT_AVATAR } from '@stores/constants'; import { truncate } from '@utils/truncate'; import { DotsHorizontalIcon } from '@radix-ui/react-icons'; +import { fetch } from '@tauri-apps/api/http'; import dayjs from 'dayjs'; import relativeTime from 'dayjs/plugin/relativeTime'; import { useRouter } from 'next/router'; -import { Author } from 'nostr-relaypool'; -import { memo, useContext, useEffect, useState } from 'react'; +import { useCallback, useEffect, useState } from 'react'; dayjs.extend(relativeTime); -export const UserExtend = memo(function UserExtend({ pubkey, time }: { pubkey: string; time: any }) { +export const UserExtend = ({ pubkey, time }: { pubkey: string; time: number }) => { const router = useRouter(); - const [pool, relays]: any = useContext(RelayContext); - const [profile, setProfile] = useState(null); const openUserPage = (e) => { @@ -25,10 +22,36 @@ export const UserExtend = memo(function UserExtend({ pubkey, time }: { pubkey: s router.push(`/users/${pubkey}`); }; + const fetchMetadata = useCallback(async (pubkey: string) => { + const res = await fetch(`https://rbr.bio/${pubkey}/metadata.json`, { + method: 'GET', + timeout: 5, + }); + return res.data; + }, []); + + const getCachedMetadata = useCallback(async () => { + const { getFollowByPubkey } = await import('@utils/bindings'); + getFollowByPubkey({ pubkey: pubkey }) + .then((res) => { + if (res) { + const metadata = JSON.parse(res.metadata); + setProfile(metadata); + } else { + fetchMetadata(pubkey).then((res: any) => { + if (res.content) { + const metadata = JSON.parse(res.content); + setProfile(metadata); + } + }); + } + }) + .catch(console.error); + }, [fetchMetadata, pubkey]); + useEffect(() => { - const user = new Author(pool, relays, pubkey); - user.metaData((res) => setProfile(JSON.parse(res.content)), 0); - }, [pool, relays, pubkey]); + getCachedMetadata().catch(console.error); + }, [getCachedMetadata]); return (
@@ -61,4 +84,4 @@ export const UserExtend = memo(function UserExtend({ pubkey, time }: { pubkey: s
); -}); +}; diff --git a/src/components/user/follow.tsx b/src/components/user/follow.tsx index d3f8505b..8548f1b5 100644 --- a/src/components/user/follow.tsx +++ b/src/components/user/follow.tsx @@ -1,22 +1,29 @@ import { ImageWithFallback } from '@components/imageWithFallback'; -import { RelayContext } from '@components/relaysProvider'; import { DEFAULT_AVATAR } from '@stores/constants'; import { truncate } from '@utils/truncate'; -import { Author } from 'nostr-relaypool'; -import { memo, useContext, useEffect, useMemo, useState } from 'react'; - -export const UserFollow = memo(function UserFollow({ pubkey }: { pubkey: string }) { - const [pool, relays]: any = useContext(RelayContext); +import { useCallback, useEffect, useState } from 'react'; +export const UserFollow = ({ pubkey }: { pubkey: string }) => { const [profile, setProfile] = useState(null); - const user = useMemo(() => new Author(pool, relays, pubkey), [pubkey, pool, relays]); + + const getCachedMetadata = useCallback(async () => { + const { getFollowByPubkey } = await import('@utils/bindings'); + getFollowByPubkey({ pubkey: pubkey }) + .then((res) => { + if (res) { + const metadata = JSON.parse(res.metadata); + setProfile(metadata); + } + }) + .catch(console.error); + }, [pubkey]); useEffect(() => { - user.metaData((res) => setProfile(JSON.parse(res.content)), 0); - }, [user]); + getCachedMetadata().catch(console.error); + }, [getCachedMetadata]); return (
@@ -36,4 +43,4 @@ export const UserFollow = memo(function UserFollow({ pubkey }: { pubkey: string
); -}); +}; diff --git a/src/components/user/large.tsx b/src/components/user/large.tsx index 45e75ec8..11474890 100644 --- a/src/components/user/large.tsx +++ b/src/components/user/large.tsx @@ -1,5 +1,4 @@ import { ImageWithFallback } from '@components/imageWithFallback'; -import { RelayContext } from '@components/relaysProvider'; import { DEFAULT_AVATAR } from '@stores/constants'; @@ -8,19 +7,28 @@ import { truncate } from '@utils/truncate'; import { DotsHorizontalIcon } from '@radix-ui/react-icons'; import dayjs from 'dayjs'; import relativeTime from 'dayjs/plugin/relativeTime'; -import { Author } from 'nostr-relaypool'; -import { memo, useContext, useEffect, useState } from 'react'; +import { useCallback, useEffect, useState } from 'react'; dayjs.extend(relativeTime); -export const UserLarge = memo(function UserLarge({ pubkey, time }: { pubkey: string; time: any }) { - const [pool, relays]: any = useContext(RelayContext); +export const UserLarge = ({ pubkey, time }: { pubkey: string; time: number }) => { const [profile, setProfile] = useState(null); + const getCachedMetadata = useCallback(async () => { + const { getFollowByPubkey } = await import('@utils/bindings'); + getFollowByPubkey({ pubkey: pubkey }) + .then((res) => { + if (res) { + const metadata = JSON.parse(res.metadata); + setProfile(metadata); + } + }) + .catch(console.error); + }, [pubkey]); + useEffect(() => { - const user = new Author(pool, relays, pubkey); - user.metaData((res) => setProfile(JSON.parse(res.content)), 0); - }, [pool, relays, pubkey]); + getCachedMetadata().catch(console.error); + }, [getCachedMetadata]); return (
@@ -51,4 +59,4 @@ export const UserLarge = memo(function UserLarge({ pubkey, time }: { pubkey: str
); -}); +}; diff --git a/src/components/user/mention.tsx b/src/components/user/mention.tsx index e5d8da89..34fbb60b 100644 --- a/src/components/user/mention.tsx +++ b/src/components/user/mention.tsx @@ -1,18 +1,41 @@ -import { RelayContext } from '@components/relaysProvider'; - import { truncate } from '@utils/truncate'; -import { Author } from 'nostr-relaypool'; -import { memo, useContext, useEffect, useState } from 'react'; +import { fetch } from '@tauri-apps/api/http'; +import { memo, useCallback, useEffect, useState } from 'react'; export const UserMention = memo(function UserMention({ pubkey }: { pubkey: string }) { - const [pool, relays]: any = useContext(RelayContext); const [profile, setProfile] = useState(null); + const fetchMetadata = useCallback(async (pubkey: string) => { + const res = await fetch(`https://rbr.bio/${pubkey}/metadata.json`, { + method: 'GET', + timeout: 5, + }); + return res.data; + }, []); + + const getCachedMetadata = useCallback(async () => { + const { getFollowByPubkey } = await import('@utils/bindings'); + getFollowByPubkey({ pubkey: pubkey }) + .then((res) => { + if (res) { + const metadata = JSON.parse(res.metadata); + setProfile(metadata); + } else { + fetchMetadata(pubkey).then((res: any) => { + if (res.content) { + const metadata = JSON.parse(res.content); + setProfile(metadata); + } + }); + } + }) + .catch(console.error); + }, [fetchMetadata, pubkey]); + useEffect(() => { - const user = new Author(pool, relays, pubkey); - user.metaData((res) => setProfile(JSON.parse(res.content)), 0); - }, [pool, relays, pubkey]); + getCachedMetadata().catch(console.error); + }, [getCachedMetadata]); return @{profile?.name || truncate(pubkey, 16, ' .... ')}; }); diff --git a/src/components/user/mini.tsx b/src/components/user/mini.tsx index 2392ff62..a8ee798a 100644 --- a/src/components/user/mini.tsx +++ b/src/components/user/mini.tsx @@ -1,21 +1,29 @@ import { ImageWithFallback } from '@components/imageWithFallback'; -import { RelayContext } from '@components/relaysProvider'; import { DEFAULT_AVATAR } from '@stores/constants'; import { truncate } from '@utils/truncate'; -import { Author } from 'nostr-relaypool'; -import { useContext, useEffect, useState } from 'react'; +import { useCallback, useEffect, useState } from 'react'; export const UserMini = ({ pubkey }: { pubkey: string }) => { - const [pool, relays]: any = useContext(RelayContext); const [profile, setProfile] = useState(null); + const getCachedMetadata = useCallback(async () => { + const { getFollowByPubkey } = await import('@utils/bindings'); + getFollowByPubkey({ pubkey: pubkey }) + .then((res) => { + if (res) { + const metadata = JSON.parse(res.metadata); + setProfile(metadata); + } + }) + .catch(console.error); + }, [pubkey]); + useEffect(() => { - const user = new Author(pool, relays, pubkey); - user.metaData((res) => setProfile(JSON.parse(res.content)), 0); - }, [pool, relays, pubkey]); + getCachedMetadata().catch(console.error); + }, [getCachedMetadata]); if (profile) { return ( diff --git a/src/pages/newsfeed/following.tsx b/src/pages/newsfeed/following.tsx index 6231147d..cc36a953 100644 --- a/src/pages/newsfeed/following.tsx +++ b/src/pages/newsfeed/following.tsx @@ -42,7 +42,7 @@ export default function Page() { const computeItemKey = useCallback( (index: string | number) => { - return data[index].id; + return data[index].eventId; }, [data] ); diff --git a/src/utils/bindings.ts b/src/utils/bindings.ts index f755e763..708147a7 100644 --- a/src/utils/bindings.ts +++ b/src/utils/bindings.ts @@ -20,6 +20,10 @@ export function getFollows(data: GetFollowData) { return invoke('get_follows', { data }); } +export function getFollowByPubkey(data: GetFollowPubkeyData) { + return invoke('get_follow_by_pubkey', { data }); +} + export function createFollow(data: CreateFollowData) { return invoke('create_follow', { data }); } @@ -41,7 +45,6 @@ export function getNoteById(data: GetNoteByIdData) { } export type GetFollowData = { account_id: number }; -export type GetNoteByIdData = { event_id: string }; export type Note = { id: number; eventId: string; @@ -54,9 +57,12 @@ export type Note = { createdAt: number; accountId: number; }; -export type GetNoteData = { date: number; limit: number; offset: number }; -export type CreateFollowData = { pubkey: string; kind: number; metadata: string; account_id: number }; export type Account = { id: number; pubkey: string; privkey: string; active: boolean; metadata: string }; +export type GetLatestNoteData = { date: number }; +export type CreateFollowData = { pubkey: string; kind: number; metadata: string; account_id: number }; +export type GetFollowPubkeyData = { pubkey: string }; +export type CreateAccountData = { pubkey: string; privkey: string; metadata: string }; +export type Follow = { id: number; pubkey: string; kind: number; metadata: string; accountId: number }; export type CreateNoteData = { event_id: string; pubkey: string; @@ -68,6 +74,5 @@ export type CreateNoteData = { created_at: number; account_id: number; }; -export type GetLatestNoteData = { date: number }; -export type CreateAccountData = { pubkey: string; privkey: string; metadata: string }; -export type Follow = { id: number; pubkey: string; kind: number; metadata: string; accountId: number }; +export type GetNoteByIdData = { event_id: string }; +export type GetNoteData = { date: number; limit: number; offset: number };