diff --git a/src/components/appHeader.tsx b/src/components/appHeader.tsx index d3b2ba8b..b7af353f 100644 --- a/src/components/appHeader.tsx +++ b/src/components/appHeader.tsx @@ -45,8 +45,9 @@ export default function AppHeader({ collector }: { collector: boolean }) {
-
-
{collector && }
+
+ {collector && } +
); diff --git a/src/components/channels/channelProfile.tsx b/src/components/channels/channelProfile.tsx index 6a8b88d9..a124255c 100644 --- a/src/components/channels/channelProfile.tsx +++ b/src/components/channels/channelProfile.tsx @@ -1,12 +1,12 @@ import { DEFAULT_AVATAR } from '@stores/constants'; -import { useChannelMetadata } from '@utils/hooks/useChannelMetadata'; +import { useChannelProfile } from '@utils/hooks/useChannelProfile'; import { Copy } from 'iconoir-react'; import { nip19 } from 'nostr-tools'; export const ChannelProfile = ({ id, pubkey }: { id: string; pubkey: string }) => { - const metadata = useChannelMetadata(id, pubkey); + const metadata = useChannelProfile(id, pubkey); const noteID = id ? nip19.noteEncode(id) : null; const copyNoteID = async () => { diff --git a/src/components/chats/chatListItem.tsx b/src/components/chats/chatListItem.tsx index 893dcca9..634d63ff 100644 --- a/src/components/chats/chatListItem.tsx +++ b/src/components/chats/chatListItem.tsx @@ -1,13 +1,13 @@ import { DEFAULT_AVATAR } from '@stores/constants'; import { usePageContext } from '@utils/hooks/usePageContext'; -import { useProfileMetadata } from '@utils/hooks/useProfileMetadata'; +import { useProfile } from '@utils/hooks/useProfile'; import { shortenKey } from '@utils/shortenKey'; import { twMerge } from 'tailwind-merge'; export const ChatListItem = ({ pubkey }: { pubkey: string }) => { - const profile = useProfileMetadata(pubkey); + const profile = useProfile(pubkey); const pageContext = usePageContext(); const searchParams: any = pageContext.urlParsed.search; diff --git a/src/components/chats/messageUser.tsx b/src/components/chats/messageUser.tsx index 1061b1c6..75b9d3d6 100644 --- a/src/components/chats/messageUser.tsx +++ b/src/components/chats/messageUser.tsx @@ -1,6 +1,6 @@ import { DEFAULT_AVATAR } from '@stores/constants'; -import { useProfileMetadata } from '@utils/hooks/useProfileMetadata'; +import { useProfile } from '@utils/hooks/useProfile'; import { shortenKey } from '@utils/shortenKey'; import dayjs from 'dayjs'; @@ -9,7 +9,7 @@ import relativeTime from 'dayjs/plugin/relativeTime'; dayjs.extend(relativeTime); export const MessageUser = ({ pubkey, time }: { pubkey: string; time: number }) => { - const profile = useProfileMetadata(pubkey); + const profile = useProfile(pubkey); return (
diff --git a/src/components/multiAccounts/index.tsx b/src/components/multiAccounts/index.tsx index fcc932a6..2aa60992 100644 --- a/src/components/multiAccounts/index.tsx +++ b/src/components/multiAccounts/index.tsx @@ -7,7 +7,7 @@ import { APP_VERSION } from '@stores/constants'; import LumeSymbol from '@assets/icons/Lume'; import { Plus } from 'iconoir-react'; -import { useCallback, useContext } from 'react'; +import { useContext } from 'react'; let accounts: any = []; @@ -19,17 +19,6 @@ if (typeof window !== 'undefined') { export default function MultiAccounts() { const activeAccount: any = useContext(AccountContext); - const renderAccount = useCallback( - (account: { pubkey: string }) => { - if (account.pubkey === activeAccount.pubkey) { - return ; - } else { - return ; - } - }, - [activeAccount.pubkey] - ); - return (
@@ -39,7 +28,13 @@ export default function MultiAccounts() { > - {accounts.map((account: { pubkey: string }) => renderAccount(account))} + {accounts.map((account: { pubkey: string }) => { + if (account.pubkey === activeAccount.pubkey) { + return ; + } else { + return ; + } + })}
- - Lume - + Lume v{APP_VERSION}
diff --git a/src/components/note/metadata.tsx b/src/components/note/metadata.tsx index 6e03d657..91543752 100644 --- a/src/components/note/metadata.tsx +++ b/src/components/note/metadata.tsx @@ -1,83 +1,5 @@ -import { AccountContext } from '@components/accountProvider'; -import { NoteComment } from '@components/note/meta/comment'; -import { NoteReaction } from '@components/note/meta/reaction'; -import { RelayContext } from '@components/relaysProvider'; +import { memo } from 'react'; -import { READONLY_RELAYS } from '@stores/constants'; - -import { memo, useContext, useEffect, useState } from 'react'; - -export const NoteMetadata = memo(function NoteMetadata({ - eventID, - eventPubkey, - eventContent, - eventTime, -}: { - eventID: string; - eventPubkey: string; - eventTime: any; - eventContent: any; -}) { - const pool: any = useContext(RelayContext); - const activeAccount: any = useContext(AccountContext); - - const [liked, setLiked] = useState(false); - const [likeCount, setLikeCount] = useState(0); - const [comments, setComments] = useState(0); - - useEffect(() => { - const unsubscribe = pool.subscribe( - [ - { - '#e': [eventID], - since: parseInt(eventTime), - kinds: [1, 7], - }, - ], - READONLY_RELAYS, - (event: any) => { - switch (event.kind) { - case 1: - // update state - setComments((comments) => (comments += 1)); - // save comment to database - // createCacheCommentNote(event, eventID); - break; - case 7: - if (event.pubkey === activeAccount.pubkey) { - setLiked(true); - } - if (event.content === '🤙' || event.content === '+') { - setLikeCount((likes) => (likes += 1)); - } - break; - default: - break; - } - }, - 100, - undefined, - { - unsubscribeOnEose: true, - logAllEvents: false, - } - ); - - return () => { - unsubscribe(); - }; - }, [eventID, eventTime, pool, activeAccount.pubkey]); - - return ( -
- - -
- ); +export const NoteMetadata = memo(function NoteMetadata() { + return
; }); diff --git a/src/components/note/preview/image.tsx b/src/components/note/preview/image.tsx index 69cae3ea..feb4eccd 100644 --- a/src/components/note/preview/image.tsx +++ b/src/components/note/preview/image.tsx @@ -1,7 +1,14 @@ export const ImagePreview = ({ url, size }: { url: string; size: string }) => { return (
- {url} + {url}
); }; diff --git a/src/components/user/base.tsx b/src/components/user/base.tsx index d39e3467..eb286069 100644 --- a/src/components/user/base.tsx +++ b/src/components/user/base.tsx @@ -1,12 +1,12 @@ import { DEFAULT_AVATAR } from '@stores/constants'; -import { useProfileMetadata } from '@utils/hooks/useProfileMetadata'; +import { useProfile } from '@utils/hooks/useProfile'; import { shortenKey } from '@utils/shortenKey'; import { memo } from 'react'; export const UserBase = memo(function UserBase({ pubkey }: { pubkey: string }) { - const profile = useProfileMetadata(pubkey); + const profile = useProfile(pubkey); return (
diff --git a/src/components/user/extend.tsx b/src/components/user/extend.tsx index d676a050..79c0eb1b 100644 --- a/src/components/user/extend.tsx +++ b/src/components/user/extend.tsx @@ -1,6 +1,6 @@ import { DEFAULT_AVATAR } from '@stores/constants'; -import { useProfileMetadata } from '@utils/hooks/useProfileMetadata'; +import { useProfile } from '@utils/hooks/useProfile'; import { shortenKey } from '@utils/shortenKey'; import dayjs from 'dayjs'; @@ -9,7 +9,7 @@ import relativeTime from 'dayjs/plugin/relativeTime'; dayjs.extend(relativeTime); export const UserExtend = ({ pubkey, time }: { pubkey: string; time: number }) => { - const profile = useProfileMetadata(pubkey); + const profile = useProfile(pubkey); return (
diff --git a/src/components/user/follow.tsx b/src/components/user/follow.tsx index 106481e9..7fdd1487 100644 --- a/src/components/user/follow.tsx +++ b/src/components/user/follow.tsx @@ -1,10 +1,10 @@ import { DEFAULT_AVATAR } from '@stores/constants'; -import { useProfileMetadata } from '@utils/hooks/useProfileMetadata'; +import { useProfile } from '@utils/hooks/useProfile'; import { shortenKey } from '@utils/shortenKey'; export const UserFollow = ({ pubkey }: { pubkey: string }) => { - const profile = useProfileMetadata(pubkey); + const profile = useProfile(pubkey); return (
diff --git a/src/components/user/large.tsx b/src/components/user/large.tsx index 77c320aa..614cbc26 100644 --- a/src/components/user/large.tsx +++ b/src/components/user/large.tsx @@ -1,6 +1,6 @@ import { DEFAULT_AVATAR } from '@stores/constants'; -import { useProfileMetadata } from '@utils/hooks/useProfileMetadata'; +import { useProfile } from '@utils/hooks/useProfile'; import { shortenKey } from '@utils/shortenKey'; import dayjs from 'dayjs'; @@ -10,7 +10,7 @@ import { MoreHoriz } from 'iconoir-react'; dayjs.extend(relativeTime); export const UserLarge = ({ pubkey, time }: { pubkey: string; time: number }) => { - const profile = useProfileMetadata(pubkey); + const profile = useProfile(pubkey); return (
diff --git a/src/components/user/mention.tsx b/src/components/user/mention.tsx index b90a1ac7..92f7a7f8 100644 --- a/src/components/user/mention.tsx +++ b/src/components/user/mention.tsx @@ -1,8 +1,8 @@ -import { useProfileMetadata } from '@utils/hooks/useProfileMetadata'; +import { useProfile } from '@utils/hooks/useProfile'; import { shortenKey } from '@utils/shortenKey'; export const UserMention = ({ pubkey }: { pubkey: string }) => { - const profile = useProfileMetadata(pubkey); + const profile = useProfile(pubkey); return ( @{profile?.name || profile?.username || shortenKey(pubkey)} ); diff --git a/src/components/user/mini.tsx b/src/components/user/mini.tsx index ead6ce69..d559351c 100644 --- a/src/components/user/mini.tsx +++ b/src/components/user/mini.tsx @@ -1,10 +1,10 @@ import { DEFAULT_AVATAR } from '@stores/constants'; -import { useProfileMetadata } from '@utils/hooks/useProfileMetadata'; +import { useProfile } from '@utils/hooks/useProfile'; import { shortenKey } from '@utils/shortenKey'; export const UserMini = ({ pubkey }: { pubkey: string }) => { - const profile = useProfileMetadata(pubkey); + const profile = useProfile(pubkey); return (
diff --git a/src/components/user/muted.tsx b/src/components/user/muted.tsx index 6a7abab7..6331592a 100644 --- a/src/components/user/muted.tsx +++ b/src/components/user/muted.tsx @@ -1,12 +1,12 @@ import { DEFAULT_AVATAR } from '@stores/constants'; -import { useProfileMetadata } from '@utils/hooks/useProfileMetadata'; +import { useProfile } from '@utils/hooks/useProfile'; import { shortenKey } from '@utils/shortenKey'; import { useState } from 'react'; export const UserMuted = ({ data }: { data: any }) => { - const profile = useProfileMetadata(data.content); + const profile = useProfile(data.content); const [status, setStatus] = useState(data.status); const unmute = async () => { diff --git a/src/components/user/quoteRepost.tsx b/src/components/user/quoteRepost.tsx index 44b5a903..ebf5e6e2 100644 --- a/src/components/user/quoteRepost.tsx +++ b/src/components/user/quoteRepost.tsx @@ -1,6 +1,6 @@ import { DEFAULT_AVATAR } from '@stores/constants'; -import { useProfileMetadata } from '@utils/hooks/useProfileMetadata'; +import { useProfile } from '@utils/hooks/useProfile'; import { shortenKey } from '@utils/shortenKey'; import dayjs from 'dayjs'; @@ -9,7 +9,7 @@ import relativeTime from 'dayjs/plugin/relativeTime'; dayjs.extend(relativeTime); export const UserQuoteRepost = ({ pubkey, time }: { pubkey: string; time: number }) => { - const profile = useProfileMetadata(pubkey); + const profile = useProfile(pubkey); return (
diff --git a/src/pages/newsfeed/following/index.page.tsx b/src/pages/newsfeed/following/index.page.tsx index 0cb23c59..0f6fa0f4 100644 --- a/src/pages/newsfeed/following/index.page.tsx +++ b/src/pages/newsfeed/following/index.page.tsx @@ -76,7 +76,7 @@ export function Page() { ) : status === 'error' ? (
{error.message}
) : ( -
+
- - + + + + + ); const container = document.getElementById('app'); diff --git a/src/renderer/_default.page.server.tsx b/src/renderer/_default.page.server.tsx index a5e69201..ad6487de 100644 --- a/src/renderer/_default.page.server.tsx +++ b/src/renderer/_default.page.server.tsx @@ -1,6 +1,7 @@ import { Shell } from '@renderer/shell'; import { PageContextServer } from '@renderer/types'; +import { StrictMode } from 'react'; import ReactDOMServer from 'react-dom/server'; import { dangerouslySkipEscape, escapeInject } from 'vite-plugin-ssr/server'; @@ -18,9 +19,11 @@ export function render(pageContext: PageContextServer) { if (!Page) throw new Error('My render() hook expects pageContext.Page to be defined'); pageHtml = ReactDOMServer.renderToString( - - - + + + + + ); } diff --git a/src/renderer/shell.tsx b/src/renderer/shell.tsx index 6bf2c8a9..1446d5d7 100644 --- a/src/renderer/shell.tsx +++ b/src/renderer/shell.tsx @@ -6,20 +6,17 @@ import { PageContextProvider } from '@utils/hooks/usePageContext'; import { PageContext } from '@renderer/types'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; -import { StrictMode } from 'react'; const queryClient = new QueryClient(); export function Shell({ children, pageContext }: { children: React.ReactNode; pageContext: PageContext }) { return ( - - - - - {children} - - - - + + + + {children} + + + ); } diff --git a/src/utils/hooks/useChannelProfile.tsx b/src/utils/hooks/useChannelProfile.tsx new file mode 100644 index 00000000..53d74ff5 --- /dev/null +++ b/src/utils/hooks/useChannelProfile.tsx @@ -0,0 +1,56 @@ +import { RelayContext } from '@components/relaysProvider'; + +import { READONLY_RELAYS } from '@stores/constants'; + +import { useContext } from 'react'; +import useSWRSubscription from 'swr/subscription'; + +export const useChannelProfile = (id: string, channelPubkey: string) => { + const pool: any = useContext(RelayContext); + + const { data } = useSWRSubscription( + id + ? [ + { + kinds: [41], + '#e': [id], + }, + { + ids: [id], + kinds: [40], + }, + ] + : null, + (key, { next }) => { + const unsubscribe = pool.subscribe( + key, + READONLY_RELAYS, + (event: { kind: number; pubkey: string; content: string }) => { + switch (event.kind) { + case 40: + next(null, JSON.parse(event.content)); + break; + case 41: + if (event.pubkey === channelPubkey) { + next(null, JSON.parse(event.content)); + } + default: + break; + } + }, + undefined, + undefined, + { + unsubscribeOnEose: true, + logAllEvents: false, + } + ); + + return () => { + unsubscribe(); + }; + } + ); + + return data; +}; diff --git a/src/utils/hooks/useProfile.tsx b/src/utils/hooks/useProfile.tsx new file mode 100644 index 00000000..519795c1 --- /dev/null +++ b/src/utils/hooks/useProfile.tsx @@ -0,0 +1,14 @@ +import useSWR from 'swr'; + +const fetcher = (url: string) => fetch(url).then((r: any) => r.json()); + +export const useProfile = (pubkey: string) => { + const { data, error } = useSWR(`https://rbr.bio/${pubkey}/metadata.json`, fetcher); + if (error) { + return error; + } + if (data) { + return JSON.parse(data.content); + } + return null; +}; diff --git a/src/utils/hooks/useProfileMetadata.tsx b/src/utils/hooks/useProfileMetadata.tsx deleted file mode 100644 index 4ca80f84..00000000 --- a/src/utils/hooks/useProfileMetadata.tsx +++ /dev/null @@ -1,54 +0,0 @@ -import { createPleb, getPleb } from '@utils/storage'; - -import { fetch } from '@tauri-apps/api/http'; -import { useCallback, useEffect, useState } from 'react'; - -export const fetchProfileMetadata = async (pubkey: string) => { - const result = await fetch(`https://rbr.bio/${pubkey}/metadata.json`, { - method: 'GET', - timeout: 5, - }); - return await result.data; -}; - -export const useProfileMetadata = (pubkey: string) => { - const [profile, setProfile] = useState(null); - - const getProfileFromDB = useCallback(async (pubkey: string) => { - return await getPleb(pubkey); - }, []); - - const insertPlebToDB = useCallback(async (pubkey: string, metadata: string) => { - return createPleb(pubkey, metadata); - }, []); - - useEffect(() => { - let ignore = false; - - if (!ignore) { - getProfileFromDB(pubkey) - .then((res: any) => { - if (res) { - // update state - setProfile(JSON.parse(res.metadata)); - } else { - fetchProfileMetadata(pubkey).then((res: any) => { - if (res) { - // update state - setProfile(JSON.parse(res.content)); - // insert to db - insertPlebToDB(pubkey, res.content); - } - }); - } - }) - .catch(console.error); - } - - return () => { - ignore = true; - }; - }, [getProfileFromDB, insertPlebToDB, pubkey]); - - return profile; -};