From a71502d19eca316d148a55d81c4158dbeb705dc6 Mon Sep 17 00:00:00 2001 From: Ren Amamiya <123083837+reyamir@users.noreply.github.com> Date: Fri, 28 Apr 2023 09:52:12 +0700 Subject: [PATCH] fix the mess I started --- src/app/channel/layout.tsx | 2 +- src/app/channel/pages/index.page.tsx | 24 +++--- src/app/chat/layout.tsx | 2 +- src/app/newsfeed/components/contentParser.tsx | 56 +++++++++++++ .../newsfeed/components/form.tsx} | 46 ++++++----- .../newsfeed/components}/note/base.tsx | 18 ++-- src/app/newsfeed/components/note/comment.tsx | 24 ++++++ .../components}/note/meta/comment.tsx | 0 .../components}/note/meta/reaction.tsx | 0 .../newsfeed/components}/note/metadata.tsx | 0 .../newsfeed/components}/note/parent.tsx | 23 ++---- .../newsfeed/components}/note/placeholder.tsx | 0 .../components}/note/preview/image.tsx | 0 .../components}/note/preview/video.tsx | 0 .../components}/note/preview/youtube.tsx | 0 .../newsfeed/components}/note/quote.tsx | 13 ++- .../newsfeed/components}/note/quoteRepost.tsx | 6 +- .../newsfeed/components}/note/rootNote.tsx | 23 ++---- .../newsfeed/components/user/default.tsx} | 2 +- .../newsfeed/components}/user/mention.tsx | 2 +- .../newsfeed/components/user/repost.tsx} | 2 +- src/app/newsfeed/layout.tsx | 2 +- .../newsfeed/pages/following/index.page.tsx | 10 +-- src/auth/pages/create/step-3/index.page.tsx | 3 +- src/auth/pages/import/step-2/index.page.tsx | 3 +- src/shared/appHeader.tsx | 5 +- src/shared/eventCollector.tsx | 49 +++++------ src/shared/layouts/channel.tsx | 31 ------- src/shared/layouts/newsfeed.tsx | 29 ------- src/shared/layouts/onboarding.tsx | 17 ---- src/shared/navigation.tsx | 4 +- src/shared/note/comment.tsx | 82 ------------------- src/shared/note/extend.tsx | 82 ------------------- src/utils/hooks/useActiveAccount.tsx | 15 ++++ src/utils/transform.tsx | 2 +- 35 files changed, 197 insertions(+), 380 deletions(-) create mode 100644 src/app/newsfeed/components/contentParser.tsx rename src/{shared/form/base.tsx => app/newsfeed/components/form.tsx} (74%) rename src/{shared => app/newsfeed/components}/note/base.tsx (73%) create mode 100644 src/app/newsfeed/components/note/comment.tsx rename src/{shared => app/newsfeed/components}/note/meta/comment.tsx (100%) rename src/{shared => app/newsfeed/components}/note/meta/reaction.tsx (100%) rename src/{shared => app/newsfeed/components}/note/metadata.tsx (100%) rename src/{shared => app/newsfeed/components}/note/parent.tsx (79%) rename src/{shared => app/newsfeed/components}/note/placeholder.tsx (100%) rename src/{shared => app/newsfeed/components}/note/preview/image.tsx (100%) rename src/{shared => app/newsfeed/components}/note/preview/video.tsx (100%) rename src/{shared => app/newsfeed/components}/note/preview/youtube.tsx (100%) rename src/{shared => app/newsfeed/components}/note/quote.tsx (78%) rename src/{shared => app/newsfeed/components}/note/quoteRepost.tsx (73%) rename src/{shared => app/newsfeed/components}/note/rootNote.tsx (71%) rename src/{shared/user/extend.tsx => app/newsfeed/components/user/default.tsx} (93%) rename src/{shared => app/newsfeed/components}/user/mention.tsx (80%) rename src/{shared/user/quoteRepost.tsx => app/newsfeed/components/user/repost.tsx} (93%) delete mode 100644 src/shared/layouts/channel.tsx delete mode 100644 src/shared/layouts/newsfeed.tsx delete mode 100644 src/shared/layouts/onboarding.tsx delete mode 100644 src/shared/note/comment.tsx delete mode 100644 src/shared/note/extend.tsx create mode 100644 src/utils/hooks/useActiveAccount.tsx diff --git a/src/app/channel/layout.tsx b/src/app/channel/layout.tsx index 6dfdf837..25e53586 100644 --- a/src/app/channel/layout.tsx +++ b/src/app/channel/layout.tsx @@ -4,7 +4,7 @@ import Navigation from '@lume/shared/navigation'; export function LayoutChannel({ children }: { children: React.ReactNode }) { return ( -
+
import('@lume/shared/channels/messages')); let mutedList: any = []; +let activeAccount: any = {}; let activeMutedList: any = []; let activeHidedList: any = []; if (typeof window !== 'undefined') { const { getBlacklist, getActiveBlacklist, getActiveAccount } = await import('@lume/utils/storage'); - const activeAccount = await getActiveAccount(); + activeAccount = await getActiveAccount(); activeHidedList = await getActiveBlacklist(activeAccount.id, 43); activeMutedList = await getActiveBlacklist(activeAccount.id, 44); mutedList = await getBlacklist(activeAccount.id, 44); @@ -33,12 +33,9 @@ export function Page() { const pageContext = usePageContext(); const searchParams: any = pageContext.urlParsed.search; - const id = searchParams.id; + const channelID = searchParams.id; const channelPubkey = searchParams.pubkey; - const pool: any = useContext(RelayContext); - const activeAccount: any = useContext(AccountContext); - const setChannelMessages = useSetAtom(channelMessagesAtom); const resetChannelMessages = useResetAtom(channelMessagesAtom); const resetChannelReply = useResetAtom(channelReplyAtom); @@ -47,16 +44,17 @@ export function Page() { const hided = arrayObjToPureArr(activeHidedList); const muted = arrayObjToPureArr(activeMutedList); - useSWRSubscription(id, () => { + useSWRSubscription(channelID, () => { // reset channel reply resetChannelReply(); // reset channel messages resetChannelMessages(); // subscribe for new messages + const pool = new RelayPool(FULL_RELAYS); const unsubscribe = pool.subscribe( [ { - '#e': [id], + '#e': [channelID], kinds: [42], since: dateToUnix(hoursAgo(48, now.current)), }, @@ -82,11 +80,11 @@ export function Page() {
- +
- {activeAccount.pubkey === channelPubkey && } + {activeAccount.pubkey === channelPubkey && }
@@ -94,7 +92,7 @@ export function Page() {
- +
diff --git a/src/app/chat/layout.tsx b/src/app/chat/layout.tsx index a2d156ea..daef39c6 100644 --- a/src/app/chat/layout.tsx +++ b/src/app/chat/layout.tsx @@ -4,7 +4,7 @@ import Navigation from '@lume/shared/navigation'; export function LayoutChat({ children }: { children: React.ReactNode }) { return ( -
+
{ + let parsedContent = noteContent.trim(); + + // get data tags + const tags = destr(noteTags); + // handle urls + parsedContent = reactStringReplace(parsedContent, /(https?:\/\/\S+)/g, (match, i) => { + if (match.match(/\.(jpg|jpeg|gif|png|webp)$/i)) { + // image url + return ; + } else if (match.match(/(http:|https:)?(\/\/)?(www\.)?(youtube.com|youtu.be)\/(watch|embed)?(\?v=|\/)?(\S+)?/)) { + // youtube + return ; + } else if (match.match(/\.(mp4|webm)$/i)) { + // video + return ; + } else { + return ( + + {match} + + ); + } + }); + // handle #-hashtags + parsedContent = reactStringReplace(parsedContent, /#(\w+)/g, (match, i) => ( + + #{match} + + )); + // handle mentions + if (tags && tags.length > 0) { + parsedContent = reactStringReplace(parsedContent, /\#\[(\d+)\]/gm, (match, i) => { + if (tags[match][0] === 'p') { + // @-mentions + return ; + } else if (tags[match][0] === 'e') { + // note-quotes + return ; + } else { + return; + } + }); + } + + return parsedContent; +}; diff --git a/src/shared/form/base.tsx b/src/app/newsfeed/components/form.tsx similarity index 74% rename from src/shared/form/base.tsx rename to src/app/newsfeed/components/form.tsx index 8ba23e94..5f7f50aa 100644 --- a/src/shared/form/base.tsx +++ b/src/app/newsfeed/components/form.tsx @@ -1,39 +1,41 @@ -import { AccountContext } from '@lume/shared/accountProvider'; import { ImagePicker } from '@lume/shared/form/imagePicker'; -import { RelayContext } from '@lume/shared/relaysProvider'; import { WRITEONLY_RELAYS } from '@lume/stores/constants'; import { noteContentAtom } from '@lume/stores/note'; import { dateToUnix } from '@lume/utils/getDate'; +import { useActiveAccount } from '@lume/utils/hooks/useActiveAccount'; import { useAtom } from 'jotai'; import { useResetAtom } from 'jotai/utils'; +import { RelayPool } from 'nostr-relaypool'; import { getEventHash, signEvent } from 'nostr-tools'; -import { useContext } from 'react'; - -export default function FormBase() { - const pool: any = useContext(RelayContext); - const activeAccount: any = useContext(AccountContext); +export default function NoteForm() { + const { account, isLoading, isError } = useActiveAccount(); const [value, setValue] = useAtom(noteContentAtom); const resetValue = useResetAtom(noteContentAtom); const submitEvent = () => { - const event: any = { - content: value, - created_at: dateToUnix(), - kind: 1, - pubkey: activeAccount.pubkey, - tags: [], - }; - event.id = getEventHash(event); - event.sig = signEvent(event, activeAccount.privkey); + if (!isLoading && !isError && account) { + const pool = new RelayPool(WRITEONLY_RELAYS); + const event: any = { + content: value, + created_at: dateToUnix(), + kind: 1, + pubkey: account.pubkey, + tags: [], + }; + event.id = getEventHash(event); + event.sig = signEvent(event, account.privkey); - // publish note - pool.publish(event, WRITEONLY_RELAYS); - // reset form - resetValue(); - // send notification - // sendNotification('Note has been published successfully'); + // publish note + pool.publish(event, WRITEONLY_RELAYS); + // reset form + resetValue(); + // send notification + // sendNotification('Note has been published successfully'); + } else { + console.log('Cannot publish note'); + } }; return ( diff --git a/src/shared/note/base.tsx b/src/app/newsfeed/components/note/base.tsx similarity index 73% rename from src/shared/note/base.tsx rename to src/app/newsfeed/components/note/base.tsx index c587c36f..186a46d2 100644 --- a/src/shared/note/base.tsx +++ b/src/app/newsfeed/components/note/base.tsx @@ -1,7 +1,6 @@ -import { NoteMetadata } from '@lume/shared/note/metadata'; -import { NoteParent } from '@lume/shared/note/parent'; -import { UserExtend } from '@lume/shared/user/extend'; -import { contentParser } from '@lume/utils/parser'; +import { contentParser } from '@lume/app/newsfeed/components/contentParser'; +import { NoteParent } from '@lume/app/newsfeed/components/note/parent'; +import { NoteDefaultUser } from '@lume/app/newsfeed/components/user/default'; import { memo } from 'react'; import { navigate } from 'vite-plugin-ssr/client/router'; @@ -40,19 +39,12 @@ export const NoteBase = memo(function NoteBase({ event }: { event: any }) { {parentNote()}
openUserPage(e)}> - +
{content}
-
e.stopPropagation()} className="mt-5 pl-[52px]"> - -
+
e.stopPropagation()} className="mt-5 pl-[52px]">
); diff --git a/src/app/newsfeed/components/note/comment.tsx b/src/app/newsfeed/components/note/comment.tsx new file mode 100644 index 00000000..3f1fa1a3 --- /dev/null +++ b/src/app/newsfeed/components/note/comment.tsx @@ -0,0 +1,24 @@ +import { contentParser } from '@lume/app/newsfeed/components/contentParser'; +import { NoteDefaultUser } from '@lume/app/newsfeed/components/user/default'; + +import { memo } from 'react'; + +export const NoteComment = memo(function NoteComment({ event }: { event: any }) { + const content = contentParser(event.content, event.tags); + + return ( +
+
+ +
+
+
+ {content} +
+
+
+
e.stopPropagation()} className="mt-5 pl-[52px]">
+
+
+ ); +}); diff --git a/src/shared/note/meta/comment.tsx b/src/app/newsfeed/components/note/meta/comment.tsx similarity index 100% rename from src/shared/note/meta/comment.tsx rename to src/app/newsfeed/components/note/meta/comment.tsx diff --git a/src/shared/note/meta/reaction.tsx b/src/app/newsfeed/components/note/meta/reaction.tsx similarity index 100% rename from src/shared/note/meta/reaction.tsx rename to src/app/newsfeed/components/note/meta/reaction.tsx diff --git a/src/shared/note/metadata.tsx b/src/app/newsfeed/components/note/metadata.tsx similarity index 100% rename from src/shared/note/metadata.tsx rename to src/app/newsfeed/components/note/metadata.tsx diff --git a/src/shared/note/parent.tsx b/src/app/newsfeed/components/note/parent.tsx similarity index 79% rename from src/shared/note/parent.tsx rename to src/app/newsfeed/components/note/parent.tsx index ac364166..ce196437 100644 --- a/src/shared/note/parent.tsx +++ b/src/app/newsfeed/components/note/parent.tsx @@ -1,15 +1,12 @@ -import { NoteMetadata } from '@lume/shared/note/metadata'; -import { RelayContext } from '@lume/shared/relaysProvider'; -import { UserExtend } from '@lume/shared/user/extend'; +import { contentParser } from '@lume/app/newsfeed/components/contentParser'; +import { NoteDefaultUser } from '@lume/app/newsfeed/components/user/default'; import { READONLY_RELAYS } from '@lume/stores/constants'; -import { contentParser } from '@lume/utils/parser'; -import { memo, useContext } from 'react'; +import { RelayPool } from 'nostr-relaypool'; +import { memo } from 'react'; import useSWRSubscription from 'swr/subscription'; export const NoteParent = memo(function NoteParent({ id }: { id: string }) { - const pool: any = useContext(RelayContext); - const { data, error } = useSWRSubscription( id ? [ @@ -20,6 +17,7 @@ export const NoteParent = memo(function NoteParent({ id }: { id: string }) { ] : null, (key, { next }) => { + const pool = new RelayPool(READONLY_RELAYS); const unsubscribe = pool.subscribe( key, READONLY_RELAYS, @@ -70,20 +68,13 @@ export const NoteParent = memo(function NoteParent({ id }: { id: string }) { <>
- +
{contentParser(data.content, data.tags)}
-
e.stopPropagation()} className="mt-5 pl-[52px]"> - -
+
e.stopPropagation()} className="mt-5 pl-[52px]">
)} diff --git a/src/shared/note/placeholder.tsx b/src/app/newsfeed/components/note/placeholder.tsx similarity index 100% rename from src/shared/note/placeholder.tsx rename to src/app/newsfeed/components/note/placeholder.tsx diff --git a/src/shared/note/preview/image.tsx b/src/app/newsfeed/components/note/preview/image.tsx similarity index 100% rename from src/shared/note/preview/image.tsx rename to src/app/newsfeed/components/note/preview/image.tsx diff --git a/src/shared/note/preview/video.tsx b/src/app/newsfeed/components/note/preview/video.tsx similarity index 100% rename from src/shared/note/preview/video.tsx rename to src/app/newsfeed/components/note/preview/video.tsx diff --git a/src/shared/note/preview/youtube.tsx b/src/app/newsfeed/components/note/preview/youtube.tsx similarity index 100% rename from src/shared/note/preview/youtube.tsx rename to src/app/newsfeed/components/note/preview/youtube.tsx diff --git a/src/shared/note/quote.tsx b/src/app/newsfeed/components/note/quote.tsx similarity index 78% rename from src/shared/note/quote.tsx rename to src/app/newsfeed/components/note/quote.tsx index f57af52e..587d1fd2 100644 --- a/src/shared/note/quote.tsx +++ b/src/app/newsfeed/components/note/quote.tsx @@ -1,14 +1,12 @@ -import { RelayContext } from '@lume/shared/relaysProvider'; -import { UserExtend } from '@lume/shared/user/extend'; +import { contentParser } from '@lume/app/newsfeed/components/contentParser'; +import { NoteDefaultUser } from '@lume/app/newsfeed/components/user/default'; import { READONLY_RELAYS } from '@lume/stores/constants'; -import { contentParser } from '@lume/utils/parser'; -import { memo, useContext } from 'react'; +import { RelayPool } from 'nostr-relaypool'; +import { memo } from 'react'; import useSWRSubscription from 'swr/subscription'; export const NoteQuote = memo(function NoteQuote({ id }: { id: string }) { - const pool: any = useContext(RelayContext); - const { data, error } = useSWRSubscription( id ? [ @@ -19,6 +17,7 @@ export const NoteQuote = memo(function NoteQuote({ id }: { id: string }) { ] : null, (key, { next }) => { + const pool = new RelayPool(READONLY_RELAYS); const unsubscribe = pool.subscribe( key, READONLY_RELAYS, @@ -45,7 +44,7 @@ export const NoteQuote = memo(function NoteQuote({ id }: { id: string }) {
) : (
- +
{contentParser(data.content, data.tags)} diff --git a/src/shared/note/quoteRepost.tsx b/src/app/newsfeed/components/note/quoteRepost.tsx similarity index 73% rename from src/shared/note/quoteRepost.tsx rename to src/app/newsfeed/components/note/quoteRepost.tsx index 1e8dcb93..cbc81590 100644 --- a/src/shared/note/quoteRepost.tsx +++ b/src/app/newsfeed/components/note/quoteRepost.tsx @@ -1,5 +1,5 @@ -import { RootNote } from '@lume/shared/note/rootNote'; -import { UserQuoteRepost } from '@lume/shared/user/quoteRepost'; +import { RootNote } from '@lume/app/newsfeed/components/note/rootNote'; +import { NoteRepostUser } from '@lume/app/newsfeed/components/user/repost'; import { getQuoteID } from '@lume/utils/transform'; import { memo } from 'react'; @@ -11,7 +11,7 @@ export const NoteQuoteRepost = memo(function NoteQuoteRepost({ event }: { event:
- +
diff --git a/src/shared/note/rootNote.tsx b/src/app/newsfeed/components/note/rootNote.tsx similarity index 71% rename from src/shared/note/rootNote.tsx rename to src/app/newsfeed/components/note/rootNote.tsx index 433ab0ec..87eb2d3f 100644 --- a/src/shared/note/rootNote.tsx +++ b/src/app/newsfeed/components/note/rootNote.tsx @@ -1,16 +1,13 @@ -import { NoteMetadata } from '@lume/shared/note/metadata'; -import { RelayContext } from '@lume/shared/relaysProvider'; -import { UserExtend } from '@lume/shared/user/extend'; +import { contentParser } from '@lume/app/newsfeed/components/contentParser'; +import { NoteDefaultUser } from '@lume/app/newsfeed/components/user/default'; import { READONLY_RELAYS } from '@lume/stores/constants'; -import { contentParser } from '@lume/utils/parser'; -import { memo, useContext } from 'react'; +import { RelayPool } from 'nostr-relaypool'; +import { memo } from 'react'; import useSWRSubscription from 'swr/subscription'; import { navigate } from 'vite-plugin-ssr/client/router'; export const RootNote = memo(function RootNote({ id }: { id: string }) { - const pool: any = useContext(RelayContext); - const openThread = (e) => { const selection = window.getSelection(); if (selection.toString().length === 0) { @@ -30,6 +27,7 @@ export const RootNote = memo(function RootNote({ id }: { id: string }) { ] : null, (key, { next }) => { + const pool = new RelayPool(READONLY_RELAYS); const unsubscribe = pool.subscribe( key, READONLY_RELAYS, @@ -56,20 +54,13 @@ export const RootNote = memo(function RootNote({ id }: { id: string }) {
) : (
openThread(e)} className="relative z-10 flex flex-col"> - +
{contentParser(data.content, data.tags)}
-
e.stopPropagation()} className="mt-5 pl-[52px]"> - -
+
e.stopPropagation()} className="mt-5 pl-[52px]">
)} diff --git a/src/shared/user/extend.tsx b/src/app/newsfeed/components/user/default.tsx similarity index 93% rename from src/shared/user/extend.tsx rename to src/app/newsfeed/components/user/default.tsx index e48afb38..eb45e475 100644 --- a/src/shared/user/extend.tsx +++ b/src/app/newsfeed/components/user/default.tsx @@ -7,7 +7,7 @@ import relativeTime from 'dayjs/plugin/relativeTime'; dayjs.extend(relativeTime); -export const UserExtend = ({ pubkey, time }: { pubkey: string; time: number }) => { +export const NoteDefaultUser = ({ pubkey, time }: { pubkey: string; time: number }) => { const profile = useProfile(pubkey); return ( diff --git a/src/shared/user/mention.tsx b/src/app/newsfeed/components/user/mention.tsx similarity index 80% rename from src/shared/user/mention.tsx rename to src/app/newsfeed/components/user/mention.tsx index ffeca2cd..a835d4a5 100644 --- a/src/shared/user/mention.tsx +++ b/src/app/newsfeed/components/user/mention.tsx @@ -1,7 +1,7 @@ import { useProfile } from '@lume/utils/hooks/useProfile'; import { shortenKey } from '@lume/utils/shortenKey'; -export const UserMention = ({ pubkey }: { pubkey: string }) => { +export const NoteMentionUser = ({ pubkey }: { pubkey: string }) => { const profile = useProfile(pubkey); return ( @{profile?.name || profile?.username || shortenKey(pubkey)} diff --git a/src/shared/user/quoteRepost.tsx b/src/app/newsfeed/components/user/repost.tsx similarity index 93% rename from src/shared/user/quoteRepost.tsx rename to src/app/newsfeed/components/user/repost.tsx index 248f9aa7..b2a7d4ab 100644 --- a/src/shared/user/quoteRepost.tsx +++ b/src/app/newsfeed/components/user/repost.tsx @@ -7,7 +7,7 @@ import relativeTime from 'dayjs/plugin/relativeTime'; dayjs.extend(relativeTime); -export const UserQuoteRepost = ({ pubkey, time }: { pubkey: string; time: number }) => { +export const NoteRepostUser = ({ pubkey, time }: { pubkey: string; time: number }) => { const profile = useProfile(pubkey); return ( diff --git a/src/app/newsfeed/layout.tsx b/src/app/newsfeed/layout.tsx index 614a5d3d..64fe2983 100644 --- a/src/app/newsfeed/layout.tsx +++ b/src/app/newsfeed/layout.tsx @@ -4,7 +4,7 @@ import Navigation from '@lume/shared/navigation'; export function LayoutNewsfeed({ children }: { children: React.ReactNode }) { return ( -
+
{error.message}
) : (
- +
{ setLoading(true); + const followsIncludeSelf = follows.concat([onboarding.pubkey]); // insert to database - createAccount(onboarding.pubkey, onboarding.privkey, onboarding.metadata, arrayToNIP02(follows), 1) + createAccount(onboarding.pubkey, onboarding.privkey, onboarding.metadata, arrayToNIP02(followsIncludeSelf), 1) .then((res) => { if (res) { for (const tag of follows) { diff --git a/src/auth/pages/import/step-2/index.page.tsx b/src/auth/pages/import/step-2/index.page.tsx index 9d02e5c4..78d9a33f 100644 --- a/src/auth/pages/import/step-2/index.page.tsx +++ b/src/auth/pages/import/step-2/index.page.tsx @@ -53,8 +53,9 @@ export function Page() { // show loading indicator setLoading(true); + const follows = onboarding.follows.concat([['p', pubkey]]); // insert to database - createAccount(pubkey, onboarding.privkey, onboarding.metadata, onboarding.follows, 1) + createAccount(pubkey, onboarding.privkey, onboarding.metadata, follows, 1) .then((res) => { if (res) { for (const tag of onboarding.follows) { diff --git a/src/shared/appHeader.tsx b/src/shared/appHeader.tsx index f432dcd0..a5ebbac7 100644 --- a/src/shared/appHeader.tsx +++ b/src/shared/appHeader.tsx @@ -45,9 +45,8 @@ export default function AppHeader({ collector }: { collector: boolean }) {
-
- {collector && } -
+
+ {collector && }
); diff --git a/src/shared/eventCollector.tsx b/src/shared/eventCollector.tsx index 9bcaf593..15dd5c5f 100644 --- a/src/shared/eventCollector.tsx +++ b/src/shared/eventCollector.tsx @@ -1,24 +1,26 @@ -import { AccountContext } from '@lume/shared/accountProvider'; import { NetworkStatusIndicator } from '@lume/shared/networkStatusIndicator'; -import { RelayContext } from '@lume/shared/relaysProvider'; import { READONLY_RELAYS } from '@lume/stores/constants'; import { hasNewerNoteAtom } from '@lume/stores/note'; import { dateToUnix } from '@lume/utils/getDate'; +import { useActiveAccount } from '@lume/utils/hooks/useActiveAccount'; import { createChat, createNote, updateAccount } from '@lume/utils/storage'; import { getParentID, nip02ToArray } from '@lume/utils/transform'; import { useSetAtom } from 'jotai'; -import { useCallback, useContext, useEffect, useRef } from 'react'; +import { RelayPool } from 'nostr-relaypool'; +import { useRef } from 'react'; +import useSWRSubscription from 'swr/subscription'; export default function EventCollector() { - const pool: any = useContext(RelayContext); - const activeAccount: any = useContext(AccountContext); - const setHasNewerNote = useSetAtom(hasNewerNoteAtom); const now = useRef(new Date()); - const subscribe = useCallback(async () => { - const follows = activeAccount.follows ? JSON.parse(activeAccount.follows) : []; + const { account, isLoading, isError } = useActiveAccount(); + + useSWRSubscription(!isLoading && !isError ? account : null, () => { + const follows = nip02ToArray(JSON.parse(account.follows)); + + const pool = new RelayPool(READONLY_RELAYS); const unsubscribe = pool.subscribe( [ { @@ -28,16 +30,16 @@ export default function EventCollector() { }, { kinds: [0, 3], - authors: [activeAccount.pubkey], + authors: [account.pubkey], }, { kinds: [4], - '#p': [activeAccount.pubkey], + '#p': [account.pubkey], since: dateToUnix(now.current), }, ], READONLY_RELAYS, - (event: { kind: number; tags: string[]; id: string; pubkey: string; content: string; created_at: number }) => { + (event: any) => { switch (event.kind) { // metadata case 0: @@ -48,7 +50,7 @@ export default function EventCollector() { const parentID = getParentID(event.tags, event.id); createNote( event.id, - activeAccount.id, + account.id, event.pubkey, event.kind, event.tags, @@ -61,21 +63,20 @@ export default function EventCollector() { break; // contacts case 3: - const arr = nip02ToArray(event.tags); // update account's folllows with NIP-02 tag list - updateAccount('follows', arr, event.pubkey); + updateAccount('follows', event.tags, event.pubkey); break; // chat case 4: - if (event.pubkey !== activeAccount.pubkey) { - createChat(activeAccount.id, event.pubkey, event.created_at); + if (event.pubkey !== account.pubkey) { + createChat(account.id, event.pubkey, event.created_at); } break; // repost case 6: createNote( event.id, - activeAccount.id, + account.id, event.pubkey, event.kind, event.tags, @@ -93,19 +94,7 @@ export default function EventCollector() { return () => { unsubscribe(); }; - }, [activeAccount.id, activeAccount.pubkey, activeAccount.follows, pool, setHasNewerNote]); - - useEffect(() => { - let ignore = false; - - if (!ignore) { - subscribe(); - } - - return () => { - ignore = true; - }; - }, [subscribe]); + }); return ; } diff --git a/src/shared/layouts/channel.tsx b/src/shared/layouts/channel.tsx deleted file mode 100644 index 5c863012..00000000 --- a/src/shared/layouts/channel.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import AppHeader from '@lume/shared/appHeader'; -import MultiAccounts from '@lume/shared/multiAccounts'; -import Navigation from '@lume/shared/navigation'; - -export default function ChannelLayout({ children }: { children: React.ReactNode }) { - return ( -
-
-
- -
-
-
- -
-
-
- -
-
-
{children}
-
-
-
-
-
- ); -} diff --git a/src/shared/layouts/newsfeed.tsx b/src/shared/layouts/newsfeed.tsx deleted file mode 100644 index 045339d8..00000000 --- a/src/shared/layouts/newsfeed.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import AppHeader from '@lume/shared/appHeader'; -import MultiAccounts from '@lume/shared/multiAccounts'; -import Navigation from '@lume/shared/navigation'; - -export default function NewsfeedLayout({ children }: { children: React.ReactNode }) { - return ( -
-
-
- -
-
-
- -
-
-
- -
-
{children}
-
-
-
-
- ); -} diff --git a/src/shared/layouts/onboarding.tsx b/src/shared/layouts/onboarding.tsx deleted file mode 100644 index f8e4558f..00000000 --- a/src/shared/layouts/onboarding.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import AppHeader from '@lume/shared/appHeader'; - -export default function OnboardingLayout({ children }: { children: React.ReactNode }) { - return ( -
-
-
- -
-
{children}
-
-
- ); -} diff --git a/src/shared/navigation.tsx b/src/shared/navigation.tsx index 78a9f0c2..b7de444e 100644 --- a/src/shared/navigation.tsx +++ b/src/shared/navigation.tsx @@ -24,7 +24,7 @@ export default function Navigation() { @@ -32,7 +32,7 @@ export default function Navigation() { Following diff --git a/src/shared/note/comment.tsx b/src/shared/note/comment.tsx deleted file mode 100644 index dd266cf8..00000000 --- a/src/shared/note/comment.tsx +++ /dev/null @@ -1,82 +0,0 @@ -import { NoteMetadata } from '@lume/shared/note/metadata'; -import { ImagePreview } from '@lume/shared/note/preview/image'; -import { VideoPreview } from '@lume/shared/note/preview/video'; -import { NoteQuote } from '@lume/shared/note/quote'; -import { UserExtend } from '@lume/shared/user/extend'; -import { UserMention } from '@lume/shared/user/mention'; - -import destr from 'destr'; -import { memo, useMemo } from 'react'; -import reactStringReplace from 'react-string-replace'; - -export const NoteComment = memo(function NoteComment({ event }: { event: any }) { - const content = useMemo(() => { - let parsedContent = event.content; - // get data tags - const tags = destr(event.tags); - // handle urls - parsedContent = reactStringReplace(parsedContent, /(https?:\/\/\S+)/g, (match, i) => { - if (match.match(/\.(jpg|jpeg|gif|png|webp)$/i)) { - // image url - return ; - } else if (match.match(/(www\.)?(youtube\.com\/watch\?v=|youtu\.be\/)([a-zA-Z0-9_-]{11})/i)) { - // youtube - return ; - } else if (match.match(/\.(mp4|webm)$/i)) { - // video - return ; - } else { - return ( - - {match} - - ); - } - }); - // handle #-hashtags - parsedContent = reactStringReplace(parsedContent, /#(\w+)/g, (match, i) => ( - - #{match} - - )); - // handle mentions - if (tags.length > 0) { - parsedContent = reactStringReplace(parsedContent, /\#\[(\d+)\]/gm, (match, i) => { - if (tags[match][0] === 'p') { - // @-mentions - return ; - } else if (tags[match][0] === 'e') { - // note-quotes - return ; - } else { - return; - } - }); - } - - return parsedContent; - }, [event.content, event.tags]); - - return ( -
-
- -
-
-
- {content} -
-
-
-
e.stopPropagation()} className="mt-5 pl-[52px]"> - -
-
-
- ); -}); diff --git a/src/shared/note/extend.tsx b/src/shared/note/extend.tsx deleted file mode 100644 index 3137c65f..00000000 --- a/src/shared/note/extend.tsx +++ /dev/null @@ -1,82 +0,0 @@ -import { NoteMetadata } from '@lume/shared/note/metadata'; -import { ImagePreview } from '@lume/shared/note/preview/image'; -import { VideoPreview } from '@lume/shared/note/preview/video'; -import { NoteQuote } from '@lume/shared/note/quote'; -import { UserLarge } from '@lume/shared/user/large'; -import { UserMention } from '@lume/shared/user/mention'; - -import destr from 'destr'; -import { memo, useMemo } from 'react'; -import reactStringReplace from 'react-string-replace'; - -export const NoteExtend = memo(function NoteExtend({ event }: { event: any }) { - const content = useMemo(() => { - let parsedContent = event.content; - // get data tags - const tags = destr(event.tags); - // handle urls - parsedContent = reactStringReplace(parsedContent, /(https?:\/\/\S+)/g, (match, i) => { - if (match.match(/\.(jpg|jpeg|gif|png|webp)$/i)) { - // image url - return ; - } else if (match.match(/(www\.)?(youtube\.com\/watch\?v=|youtu\.be\/)([a-zA-Z0-9_-]{11})/i)) { - // youtube - return ; - } else if (match.match(/\.(mp4|webm)$/i)) { - // video - return ; - } else { - return ( - - {match} - - ); - } - }); - // handle #-hashtags - parsedContent = reactStringReplace(parsedContent, /#(\w+)/g, (match, i) => ( - - #{match} - - )); - // handle mentions - if (tags.length > 0) { - parsedContent = reactStringReplace(parsedContent, /\#\[(\d+)\]/gm, (match, i) => { - if (tags[match][0] === 'p') { - // @-mentions - return ; - } else if (tags[match][0] === 'e') { - // note-quotes - return ; - } else { - return; - } - }); - } - - return parsedContent; - }, [event.content, event.tags]); - - return ( -
-
- -
-
-
- {content} -
-
-
-
- -
-
-
- ); -}); diff --git a/src/utils/hooks/useActiveAccount.tsx b/src/utils/hooks/useActiveAccount.tsx new file mode 100644 index 00000000..2a7baee3 --- /dev/null +++ b/src/utils/hooks/useActiveAccount.tsx @@ -0,0 +1,15 @@ +import { getActiveAccount } from '@lume/utils/storage'; + +import useSWR from 'swr'; + +const fetcher = () => getActiveAccount(); + +export const useActiveAccount = () => { + const { data, error, isLoading } = useSWR('activeAcount', fetcher); + + return { + account: data, + isLoading, + isError: error, + }; +}; diff --git a/src/utils/transform.tsx b/src/utils/transform.tsx index aca05ac9..850f9e5d 100644 --- a/src/utils/transform.tsx +++ b/src/utils/transform.tsx @@ -1,7 +1,7 @@ import destr from 'destr'; // convert NIP-02 to array of pubkey -export const nip02ToArray = (tags: string[]) => { +export const nip02ToArray = (tags: any) => { const arr = []; tags.forEach((item) => { arr.push(item[1]);