diff --git a/src/@context/Orbis.tsx b/src/@context/Orbis.tsx index 0e0664e87..6a8d28de6 100644 --- a/src/@context/Orbis.tsx +++ b/src/@context/Orbis.tsx @@ -11,14 +11,13 @@ import { useInterval } from '@hooks/useInterval' import { Orbis } from '@orbisclub/orbis-sdk' import { useWeb3 } from './Web3' import { accountTruncate } from '@utils/web3' -import { didToAddress } from '@utils/orbis' +import { didToAddress, sleep } from '@utils/orbis' import { getEnsName } from '@utils/ens' import usePrevious from '@hooks/usePrevious' import useLocalStorage from '@hooks/useLocalStorage' import DirectMessages from '@shared/Orbis/DirectMessages' interface INewConversation { - name: string | null recipients: string[] } @@ -51,8 +50,8 @@ type IOrbisProvider = { setNewConversation: (newConversation: INewConversation) => void setOpenConversations: (open: boolean) => void setConversationId: (conversationId: string) => void - getConversation: (userDid: string) => Promise - createConversation: (userDid: string) => Promise + getConversationByDid: (userDid: string) => Promise + createConversation: (recipients: string[]) => Promise clearMessageNotifs: (conversationId: string) => void getConversationTitle: (conversationId: string) => Promise getDid: (address: string) => Promise @@ -62,7 +61,8 @@ const OrbisContext = createContext({} as IOrbisProvider) const orbis: IOrbis = new Orbis() const NOTIFICATION_REFRESH_INTERVAL = 5000 -const CONVERSATION_CONTEXT = 'ocean_market' // Can be changed to whatever +const CONVERSATION_CONTEXT = + process.env.NEXT_PUBLIC_ORBIS_CONTEXT || 'ocean_market' // Can be changed to whatever function OrbisProvider({ children }: { children: ReactNode }): ReactElement { const { web3Provider, accountId } = useWeb3() @@ -312,16 +312,23 @@ function OrbisProvider({ children }: { children: ReactNode }): ReactElement { return filteredConversations } - const getConversation = async (userDid: string) => { - if (!account || !userDid) return null + const getConversation = async (conversationId: string) => { + if (!conversationId) return null + const { data, error } = await orbis.getConversation(conversationId) + if (error || !data) { + await sleep(2000) + await getConversation(conversationId) + } else { + return data + } + } - console.log('has account and target userDid') + const getConversationByDid = async (userDid: string) => { + if (!account || !userDid) return null const _conversations = await getConversations(account?.did) if (!_conversations.length) return null - console.log('has conversations') - const filteredConversations = _conversations.filter( (conversation: IOrbisConversation) => { return ( @@ -333,67 +340,28 @@ function OrbisProvider({ children }: { children: ReactNode }): ReactElement { if (!filteredConversations.length) return null - console.log('has filtered conversations') - return filteredConversations[0] } - const createConversation = async (userDid: string) => { - let _account = account - if (!_account) { - // Check connection and force connect - _account = await checkOrbisConnection({ - address: accountId, - autoConnect: true - }) - } + const createConversation = async (recipients: string[]) => { + if (!recipients.length) return null - if (!hasLit) { - const res = await connectLit() - if (res.status !== 200) { - alert('Error connecting to Lit.') - return - } - } + const res = await orbis.createConversation({ + recipients, + context: CONVERSATION_CONTEXT + }) - let existingConversation = conversations.find( - (conversation: IOrbisConversation) => { - return conversation.recipients.includes(userDid) - } - ) - - // Refetch to make sure we have the latest conversations - if (!existingConversation) { - const _conversations = await getConversations(_account?.did) - existingConversation = _conversations.find( - (conversation: IOrbisConversation) => { - return conversation.recipients.includes(userDid) - } - ) - } - - if (existingConversation) { - setConversationId(existingConversation.stream_id) - setOpenConversations(true) - } else { - const res = await orbis.createConversation({ - recipients: [userDid], - context: CONVERSATION_CONTEXT - }) - if (res.status === 200) { - setTimeout(async () => { - const { data, error } = await orbis.getConversation(res.doc) - if (!error && data) { - setConversations([data, ...conversations]) - } - setConversationId(res.doc) - setOpenConversations(true) - }, 2000) + if (res.status === 200) { + await sleep(2000) + const _newConversation = await getConversation(res.doc) + if (_newConversation) { + setConversations([_newConversation, ...conversations]) + return _newConversation } } } - // const createConversationV2 = async (userDid: string) => { + // const createConversation = async (userDid: string) => { // let _account = account // if (!_account) { // // Check connection and force connect @@ -411,14 +379,22 @@ function OrbisProvider({ children }: { children: ReactNode }): ReactElement { // } // } - // // Refetch to make sure we have the latest conversations - // const _conversations = await getConversations(_account?.did) - // const existingConversation = _conversations.find( + // let existingConversation = conversations.find( // (conversation: IOrbisConversation) => { // return conversation.recipients.includes(userDid) // } // ) + // // Refetch to make sure we have the latest conversations + // if (!existingConversation) { + // const _conversations = await getConversations(_account?.did) + // existingConversation = _conversations.find( + // (conversation: IOrbisConversation) => { + // return conversation.recipients.includes(userDid) + // } + // ) + // } + // if (existingConversation) { // setConversationId(existingConversation.stream_id) // setOpenConversations(true) @@ -492,10 +468,6 @@ function OrbisProvider({ children }: { children: ReactNode }): ReactElement { // eslint-disable-next-line react-hooks/exhaustive-deps }, [account]) - useEffect(() => { - console.log({ newConversation, activeConversationTitle }) - }, [newConversation, activeConversationTitle]) - return ( + new Promise((resolve) => setTimeout(resolve, ms)) diff --git a/src/components/@shared/Orbis/Comment/Post.module.css b/src/components/@shared/Orbis/Comment/Post.module.css index 97359316d..0e47cad3d 100644 --- a/src/components/@shared/Orbis/Comment/Post.module.css +++ b/src/components/@shared/Orbis/Comment/Post.module.css @@ -45,6 +45,10 @@ font-size: var(--font-size-mini); } +.btnOptions { + cursor: pointer; +} + .blockies { aspect-ratio: 1/1; flex-shrink: 0; diff --git a/src/components/@shared/Orbis/Comment/Post.tsx b/src/components/@shared/Orbis/Comment/Post.tsx index 8915934f1..083719d97 100644 --- a/src/components/@shared/Orbis/Comment/Post.tsx +++ b/src/components/@shared/Orbis/Comment/Post.tsx @@ -142,8 +142,8 @@ export default function Post({
- - {accountTruncate(address)} + + {accountTruncate(address)}
@@ -168,6 +168,7 @@ export default function Post({ context={postClone?.context} editPost={postClone} callback={callbackEdit} + cancelEdit={() => setIsEditing(false)} /> )} {hideOverflow && ( @@ -219,15 +220,12 @@ export default function Post({
} + trigger="click" zIndex={21} placement={'top'} + className={styles.btnOptions} > - +
)} diff --git a/src/components/@shared/Orbis/Comment/Postbox.module.css b/src/components/@shared/Orbis/Comment/Postbox.module.css index 08c5b1289..b0a20eefd 100644 --- a/src/components/@shared/Orbis/Comment/Postbox.module.css +++ b/src/components/@shared/Orbis/Comment/Postbox.module.css @@ -38,6 +38,27 @@ text-align: right; } +.postbox .editActions { + display: flex; + gap: calc(var(--spacer) / 4); +} + +.postbox .editActions button { + background: transparent; + border: 0; + padding: 0; + cursor: pointer; + outline: none; +} + +.postbox .cancelEdit { + color: var(--color-secondary); +} + +.postbox .saveEdit { + color: var(--color-primary); +} + .connectWallet { width: 100%; display: flex; diff --git a/src/components/@shared/Orbis/Comment/Postbox.tsx b/src/components/@shared/Orbis/Comment/Postbox.tsx index 1d827493c..b149e2bf1 100644 --- a/src/components/@shared/Orbis/Comment/Postbox.tsx +++ b/src/components/@shared/Orbis/Comment/Postbox.tsx @@ -1,4 +1,4 @@ -import React, { useRef, useState, KeyboardEvent } from 'react' +import React, { useRef, useState, useEffect, KeyboardEvent } from 'react' import styles from './Postbox.module.css' import walletStyles from '../../../Header/Wallet/Account.module.css' import { EmojiClickData } from 'emoji-picker-react' @@ -16,6 +16,7 @@ export default function Postbox({ editPost = null, enterToSend = false, cancelReplyTo, + cancelEdit, callback }: { context: string @@ -24,6 +25,7 @@ export default function Postbox({ editPost?: IOrbisPost enterToSend?: boolean cancelReplyTo?: () => void + cancelEdit?: () => void callback: (value: IOrbisPost | IOrbisPost['content']) => void }) { const { orbis, account, checkOrbisConnection } = useOrbis() @@ -135,6 +137,12 @@ export default function Postbox({ } } + useEffect(() => { + if (editPost) { + postBoxArea.current.innerText = editPost.content.body + } + }, [editPost]) + if (!accountId) { return (
@@ -194,17 +202,33 @@ export default function Postbox({ />
-
- -
+ {editPost ? ( +
+ + · + +
+ ) : ( +
+ +
+ )}
) } diff --git a/src/components/@shared/Orbis/DirectMessages/Conversation.tsx b/src/components/@shared/Orbis/DirectMessages/Conversation.tsx index 31c79778a..c7bc283b3 100644 --- a/src/components/@shared/Orbis/DirectMessages/Conversation.tsx +++ b/src/components/@shared/Orbis/DirectMessages/Conversation.tsx @@ -1,6 +1,5 @@ import React, { useState, useEffect, useRef } from 'react' import { useOrbis } from '@context/Orbis' -import { useIsMounted } from '@hooks/useIsMounted' import { useInterval } from '@hooks/useInterval' import { throttle } from '@utils/throttle' import Time from '@shared/atoms/Time' @@ -18,9 +17,9 @@ export default function DmConversation() { connectLit, clearMessageNotifs } = useOrbis() - const isMounted = useIsMounted() const messagesWrapper = useRef(null) + const [isInitialized, setIsInitialized] = useState(false) const [isLoading, setIsLoading] = useState(false) const [messages, setMessages] = useState([]) const [currentPage, setCurrentPage] = useState(0) @@ -36,12 +35,16 @@ export default function DmConversation() { }, 300) } - const getMessages = async (polling = false) => { + const getMessages: (options?: { + polling?: boolean + reset?: boolean + }) => Promise = async ({ polling = false, reset = false }) => { if (isLoading || !hasLit) return if (!polling) setIsLoading(true) - const _page = polling ? 0 : currentPage + const _page = polling || reset ? 0 : currentPage + let _messages = reset ? [] : [...messages] const { data, error } = await orbis.getMessages(conversationId, _page) if (error) { @@ -52,30 +55,34 @@ export default function DmConversation() { data.reverse() if (!polling) { setHasMore(data.length >= 50) - const _messages = [...data, ...messages] + _messages = [...data, ..._messages] setMessages(_messages) if (currentPage === 0) { clearMessageNotifs(conversationId) scrollToBottom() } - setCurrentPage((prev) => prev + 1) + setCurrentPage(_page + 1) } else { const unique = data.filter( - (a) => !messages.some((b) => a.stream_id === b.stream_id) + (a) => !_messages.some((b) => a.stream_id === b.stream_id) ) - setNewMessages(unique.length) - setMessages([...messages, ...unique]) + setMessages([..._messages, ...unique]) + const el = messagesWrapper.current + if (el && el.scrollHeight > el.offsetHeight) { + setNewMessages((prev) => prev + unique.length) + } } } + setIsInitialized(true) setIsLoading(false) } useInterval( async () => { - getMessages(true) + getMessages({ polling: true }) }, - isLoading || !hasLit || !messages.length ? false : 15000 + !isLoading && hasLit && isInitialized ? 5000 : false ) const showTime = (streamId: string): boolean => { @@ -122,20 +129,18 @@ export default function DmConversation() { }, 1000) useEffect(() => { - if (isMounted) { - if ( - conversationId && - !conversationId.startsWith('new-') && - orbis && - hasLit - ) { - getMessages() - } else { - setMessages([]) - } + setIsInitialized(false) + setMessages([]) + if ( + conversationId && + !conversationId.startsWith('new-') && + orbis && + hasLit + ) { + getMessages({ reset: true }) } // eslint-disable-next-line react-hooks/exhaustive-deps - }, [conversationId, orbis, hasLit, isMounted]) + }, [conversationId, orbis, hasLit]) useEffect(() => { const el = messagesWrapper.current @@ -210,7 +215,7 @@ export default function DmConversation() { )} - + )} diff --git a/src/components/@shared/Orbis/DirectMessages/Header.tsx b/src/components/@shared/Orbis/DirectMessages/Header.tsx index 929a212ae..d1ac26b69 100644 --- a/src/components/@shared/Orbis/DirectMessages/Header.tsx +++ b/src/components/@shared/Orbis/DirectMessages/Header.tsx @@ -29,7 +29,6 @@ export default function Header() { ) => { e.preventDefault() const target = e.target as HTMLElement - console.log(target) const { role } = target.dataset if (role) { if (role === 'back-button') { @@ -38,17 +37,14 @@ export default function Header() { } else { let _address = '' if (newConversation) { - console.log(newConversation.recipients) _address = didToAddress(newConversation.recipients[0]) } else { - console.log(accountId) const conversation = conversations.find( (c) => c.stream_id === conversationId ) const recipients = conversation.recipients.filter( (r) => didToAddress(r) !== accountId.toLowerCase() ) - console.log(recipients) _address = didToAddress(recipients[0]) } navigator.clipboard.writeText(_address) @@ -96,7 +92,6 @@ export default function Header() { aria-label="button" data-role="back-button" className={styles.btnBack} - onClick={handleClick} > {activeConversationTitle}