From d16f59d6eb21a9b5627a6671c783204608a1e7e9 Mon Sep 17 00:00:00 2001 From: marcoelissa Date: Wed, 14 Dec 2022 23:24:55 +0700 Subject: [PATCH] update flow on address changed --- src/@context/Orbis.tsx | 151 ++++++++++++------ src/@types/Orbis.d.ts | 129 +++++++++------ .../@shared/Orbis/Comment/Postbox.tsx | 6 +- .../@shared/Orbis/DirectMessages/index.tsx | 12 +- src/components/Header/Wallet/Details.tsx | 5 +- src/components/Profile/Header/index.tsx | 6 +- 6 files changed, 206 insertions(+), 103 deletions(-) diff --git a/src/@context/Orbis.tsx b/src/@context/Orbis.tsx index 1e94dc1a4..bc9c4f060 100644 --- a/src/@context/Orbis.tsx +++ b/src/@context/Orbis.tsx @@ -12,6 +12,8 @@ import { Orbis } from '@orbisclub/orbis-sdk' import { useWeb3 } from './Web3' import { accountTruncate } from '@utils/web3' import { didToAddress } from '@utils/orbis' +import usePrevious from '@hooks/usePrevious' +import useLocalStorage from '@hooks/useLocalStorage' import DirectMessages from '@shared/Orbis/DirectMessages' @@ -24,9 +26,13 @@ type IOrbisProvider = { conversations: IOrbisConversation[] conversationTitle: string unreadMessages: IOrbisNotification[] - connectOrbis: (lit?: boolean) => Promise - disconnectOrbis: () => void + connectOrbis: (options: { + address: string + lit?: boolean + }) => Promise + disconnectOrbis: (address: string) => void checkOrbisConnection: (options: { + address: string autoConnect?: boolean lit?: boolean }) => Promise @@ -49,6 +55,11 @@ const CONVERSATION_CONTEXT = 'ocean_market' // Can be changed to whatever function OrbisProvider({ children }: { children: ReactNode }): ReactElement { const { web3Provider, accountId } = useWeb3() + const prevAccountId = usePrevious(accountId) + const [ceramicSessions, setCeramicSessions] = useLocalStorage( + 'ocean-ceramic-sessions', + [] + ) const [account, setAccount] = useState(null) const [hasLit, setHasLit] = useState(false) const [openConversations, setOpenConversations] = useState(false) @@ -56,38 +67,21 @@ function OrbisProvider({ children }: { children: ReactNode }): ReactElement { const [conversations, setConversations] = useState([]) const [unreadMessages, setUnreadMessages] = useState([]) - const conversationTitle = useMemo(() => { - let title = null - if (conversationId && conversations.length) { - const conversation = conversations.find( - (o) => o.stream_id === conversationId - ) - if (conversation) { - const details = conversation.recipients_details.find( - (o: IOrbisProfile) => o.did !== account.did - ) - const did = conversation.recipients.find( - (o: string) => o !== account.did - ) - - const address = didToAddress(did) - - if (details) { - title = - details?.metadata?.ensName || - details?.profile?.username || - accountTruncate(address) - } else { - title = accountTruncate(address) - } - } - } - - return title - }, [conversationId, account, conversations]) + // Function to reset states + const resetStates = () => { + setConversationId(null) + setConversations([]) + setUnreadMessages([]) + } // Connecting to Orbis - const connectOrbis = async (lit = false) => { + const connectOrbis = async ({ + address, + lit = false + }: { + address: string + lit?: boolean + }) => { const res = await orbis.connect_v2({ provider: web3Provider, chain: 'ethereum', @@ -98,16 +92,26 @@ function OrbisProvider({ children }: { children: ReactNode }): ReactElement { const { data } = await orbis.getProfile(res.did) setAccount(data) setHasLit(res.details.hasLit) + const sessionString = orbis.session.serialize() + setCeramicSessions({ + ...ceramicSessions, + [address.toLowerCase()]: sessionString + }) return data } else { - await connectOrbis() + await connectOrbis({ address }) } } - const disconnectOrbis = () => { + const disconnectOrbis = (address: string) => { const res = orbis.logout() if (res.status === 200) { setAccount(null) + resetStates() + const _ceramicSessions = { ...ceramicSessions } + console.log(_ceramicSessions[address.toLowerCase()]) + delete _ceramicSessions[address.toLowerCase()] + setCeramicSessions({ ..._ceramicSessions }) } } @@ -118,24 +122,31 @@ function OrbisProvider({ children }: { children: ReactNode }): ReactElement { } const checkOrbisConnection = async ({ + address, autoConnect, lit }: { + address: string autoConnect?: boolean lit?: boolean }) => { - const res = await orbis.isConnected() - console.log(res) - if (res.status === 200) { + const sessionString = ceramicSessions[address.toLowerCase()] || null + const res = await orbis.isConnected(sessionString) + if ( + res.status === 200 && + didToAddress(res.did) === accountId.toLowerCase() + ) { setHasLit(res.details.hasLit) const { data } = await orbis.getProfile(res.did) setAccount(data) return data } else if (autoConnect) { - const data = await connectOrbis(lit) + const data = await connectOrbis({ address, lit }) return data + } else { + resetStates() + return null } - return null } const getDid = async (address: string) => { @@ -150,13 +161,16 @@ function OrbisProvider({ children }: { children: ReactNode }): ReactElement { let _did: string = null if (data && data.length > 0) { - console.log(data) - // Try to get mainnet did - const mainnetDid = data.find((o: any) => { - const did = o.did.split(':') - return did[3] === '1' - }) + const mainnetDid = data.find( + (o: { + did: string + details: Pick + }) => { + const did = o.did.split(':') + return did[3] === '1' + } + ) _did = mainnetDid?.did || data[0].did } else { @@ -197,7 +211,10 @@ function OrbisProvider({ children }: { children: ReactNode }): ReactElement { let _account = account if (!_account) { // Check connection and force connect - _account = await checkOrbisConnection({ autoConnect: true }) + _account = await checkOrbisConnection({ + address: accountId, + autoConnect: true + }) } if (!hasLit) { @@ -243,8 +260,6 @@ function OrbisProvider({ children }: { children: ReactNode }): ReactElement { notif_type: 'messages' }) - console.log({ did, data, error }) - if (error) { setUnreadMessages([]) } else if (data.length > 0) { @@ -261,6 +276,36 @@ function OrbisProvider({ children }: { children: ReactNode }): ReactElement { } } + const conversationTitle = useMemo(() => { + let title = null + if (conversationId && conversations.length) { + const conversation = conversations.find( + (o) => o.stream_id === conversationId + ) + if (conversation) { + const details = conversation.recipients_details.find( + (o: IOrbisProfile) => o.did !== account.did + ) + const did = conversation.recipients.find( + (o: string) => o !== account.did + ) + + const address = didToAddress(did) + + if (details) { + title = + details?.metadata?.ensName || + details?.profile?.username || + accountTruncate(address) + } else { + title = accountTruncate(address) + } + } + } + + return title + }, [conversationId, account, conversations]) + useInterval(async () => { await getMessageNotifs() }, NOTIFICATION_REFRESH_INTERVAL) @@ -268,13 +313,19 @@ function OrbisProvider({ children }: { children: ReactNode }): ReactElement { useEffect(() => { if (accountId && web3Provider) { // Check if wallet connected - checkOrbisConnection({}) + checkOrbisConnection({ address: accountId }) } // eslint-disable-next-line react-hooks/exhaustive-deps }, [accountId, web3Provider]) useEffect(() => { - if (account) getConversations(account?.did) + if (accountId !== prevAccountId) resetStates() + }, [accountId, prevAccountId]) + + useEffect(() => { + if (account) { + getConversations(account?.did) + } // eslint-disable-next-line react-hooks/exhaustive-deps }, [account]) diff --git a/src/@types/Orbis.d.ts b/src/@types/Orbis.d.ts index 2a859a2b1..f41786c0c 100644 --- a/src/@types/Orbis.d.ts +++ b/src/@types/Orbis.d.ts @@ -1,8 +1,8 @@ declare module '@orbisclub/orbis-sdk' declare interface IOrbisConstructor { - ceramic?: any - node?: any + ceramic?: unknown + node?: string store?: string PINATA_GATEWAY?: string PINATA_API_KEY?: string @@ -11,17 +11,18 @@ declare interface IOrbisConstructor { } declare interface IOrbis { - api: any - connect: (provider: any, lit?: boolean) => Promise + api: SupabaseClient + session: DIDSession + connect: (provider: unknown, lit?: boolean) => Promise connect_v2: (opts?: { - provider?: any + provider?: unknown chain?: string lit?: boolean - oauth?: any + oauth?: unknown }) => Promise - connectLit: (provider: any) => Promise<{ + connectLit: (provider: unknown) => Promise<{ status?: number - error?: any + error?: unknown result?: string }> connectWithSeed: (seed: Uint8Array) => Promise @@ -59,34 +60,34 @@ declare interface IOrbis { result: string }> createTileDocument: ( - content: any, + content: unknown, tags: string[], schema: string, family: string ) => Promise<{ status: number doc?: string - error?: any + error?: unknown result: string }> decryptMessage: (content: { conversation_id: string encryptedMessage: IOrbisEncryptedBody - }) => Promise - decryptPost: (content: IOrbisPostContent) => Promise + }) => Promise<{ result: string }> + decryptPost: (content: IOrbisPostContent) => Promise<{ result: string }> deletePost: (stream_id: string) => Promise<{ status: number result: string }> deterministicDocument: ( - content: any, + content: unknown, tags: string[], schema?: string, family?: string ) => Promise<{ status: number doc?: string - error?: any + error?: unknown result: string }> editPost: ( @@ -99,24 +100,47 @@ declare interface IOrbis { }> getChannel: (channel_id: string) => Promise<{ data: IOrbisChannel - error: any + error: unknown status: number }> getConversation: (conversation_id: string) => Promise<{ status: number - data: any - error: any + data: IOrbisConversation | null + error: unknown + }> + getConversations: (opts: { did: string; context?: string }) => Promise<{ + data: IOrbisConversation[] + error: unknown + status: number + }> + getCredentials: (did: string) => Promise<{ + data: { + stream_id: string + family: string + content: unknown + issuer: string + creator: string + subject_id: string + type: string + }[] + error: unknown + status: number }> - getConversations: (opts: { did: string; context?: string }) => Promise getDids: (address: string) => Promise<{ - data: any - error: any + data: { + did: string + details: Pick + count_followers: number + count_following: number + pfp: string + }[] + error: unknown status: number }> getGroup: (group_id: string) => Promise<{ data: IOrbisGroup - error: any - status: any + error: unknown + status: number }> getGroupMembers: (group_id: string) => Promise<{ data: { @@ -132,12 +156,12 @@ declare interface IOrbis { stream_id: string timestamp: number }[] - error: any + error: unknown status: number }> getGroups: () => Promise<{ data: IOrbisGroup[] - error: any + error: unknown status: number }> getIsFollowing: ( @@ -145,7 +169,7 @@ declare interface IOrbis { did_followed: string ) => Promise<{ data: boolean - error: any + error: unknown status: number }> getIsGroupMember: ( @@ -153,7 +177,7 @@ declare interface IOrbis { did: string ) => Promise<{ data: boolean - error: any + error: unknown status: number }> getMessages: ( @@ -161,7 +185,7 @@ declare interface IOrbis { page: number ) => Promise<{ data: IOrbisMessage[] - error: any + error: unknown status: number }> getNotifications: ( @@ -174,10 +198,14 @@ declare interface IOrbis { algorithm?: string }, page: number - ) => Promise + ) => Promise<{ + data: IOrbisNotification[] + error: unknown + status: number + }> getPost: (post_id: string) => Promise<{ data: IOrbisPost - error: any + error: unknown status: number }> getPosts: ( @@ -192,7 +220,7 @@ declare interface IOrbis { page: number ) => Promise<{ data: IOrbisPost[] - error: any + error: unknown status: number }> getReaction: ( @@ -200,22 +228,22 @@ declare interface IOrbis { did: string ) => Promise<{ data: { type: string } - error: any + error: unknown status: number }> getProfile: (did: string) => Promise<{ data: IOrbisProfile - error: any + error: unknown status: number }> getProfileFollowers: (did: string) => Promise<{ data: IOrbisProfile['details'][] - error: any + error: unknown status: number }> getProfileFollowing: (did: string) => Promise<{ data: IOrbisProfile['details'][] - error: any + error: unknown status: number }> getProfileGroups: (did: string) => Promise<{ @@ -231,19 +259,19 @@ declare interface IOrbis { group_id: string stream_id: string }[] - error: any + error: unknown status: number }> getProfilesByUsername: (username: string) => Promise<{ data: IOrbisProfile[] - error: any + error: unknown status: number }> isConnected: (sessionString?: string) => Promise logout: () => { status: number result: string - error: any + error: unknown } react: ( post_id: string, @@ -272,7 +300,7 @@ declare interface IOrbis { ) => Promise<{ status: number doc?: string - error?: any + error?: unknown result: string }> setNotificationsReadTime: ( @@ -282,7 +310,7 @@ declare interface IOrbis { ) => Promise<{ status: number doc?: string - error?: any + error?: unknown result: string }> updateChannel: ( @@ -322,27 +350,31 @@ declare interface IOrbis { }> updateTileDocument: ( stream_id: string, - content: any, + content: unknown, tags: string[], schema: string, family?: string ) => Promise<{ status: number doc?: string - error?: any + error?: unknown result: string }> uploadMedia: (file: File) => Promise<{ status: number - error?: any - result: any + error?: unknown + result: { url: string; gateway: string } | string }> } interface IOrbisConnectReturns { status: number did: string - details: any + details: { + did: string + profile: IOrbisProfile['details']['profile'] + hasLit: boolean + } result: string } @@ -412,7 +444,7 @@ declare interface IOrbisProfile { chain?: string ensName?: string } - nonces?: any + nonces?: number profile?: { cover?: string data?: object @@ -426,7 +458,12 @@ declare interface IOrbisProfile { } username?: string } - twitter_details?: any + twitter_details?: { + credential_id: string + issuer: string + timestamp: number + username: string + } } did: string last_activity_timestamp: number diff --git a/src/components/@shared/Orbis/Comment/Postbox.tsx b/src/components/@shared/Orbis/Comment/Postbox.tsx index 8c7a0fbf4..1d827493c 100644 --- a/src/components/@shared/Orbis/Comment/Postbox.tsx +++ b/src/components/@shared/Orbis/Comment/Postbox.tsx @@ -131,7 +131,7 @@ export default function Postbox({ e.preventDefault() const resConnect = await connect() if (resConnect) { - await checkOrbisConnection({ autoConnect: true }) + await checkOrbisConnection({ address: accountId, autoConnect: true }) } } @@ -153,7 +153,9 @@ export default function Postbox({
diff --git a/src/components/@shared/Orbis/DirectMessages/index.tsx b/src/components/@shared/Orbis/DirectMessages/index.tsx index c22c861c7..856402562 100644 --- a/src/components/@shared/Orbis/DirectMessages/index.tsx +++ b/src/components/@shared/Orbis/DirectMessages/index.tsx @@ -17,7 +17,11 @@ const BodyContent = () => { e.preventDefault() const resConnect = await connect() if (resConnect) { - await checkOrbisConnection({ autoConnect: true, lit: true }) + await checkOrbisConnection({ + address: accountId, + autoConnect: true, + lit: true + }) } } @@ -56,7 +60,11 @@ const BodyContent = () => {