1
0
mirror of https://github.com/oceanprotocol/market.git synced 2024-12-02 05:57:29 +01:00

temporary push

This commit is contained in:
marcoelissa 2023-01-10 02:03:22 +07:00
parent 348c5d45fe
commit 9c364e34e6
5 changed files with 244 additions and 46 deletions

View File

@ -15,9 +15,13 @@ import { didToAddress } 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[]
}
type IOrbisProvider = {
orbis: IOrbis
account: IOrbisProfile
@ -26,6 +30,8 @@ type IOrbisProvider = {
conversationId: string
conversations: IOrbisConversation[]
notifications: Record<string, string[]>
activeConversationTitle: string
newConversation: INewConversation
connectOrbis: (options: {
address: string
lit?: boolean
@ -41,12 +47,15 @@ type IOrbisProvider = {
error?: unknown
result?: string
}>
setOpenConversations: (value: boolean) => void
setConversationId: (value: string) => void
createConversation: (value: string) => Promise<void>
setActiveConversationTitle: (title: string) => void
setNewConversation: (newConversation: INewConversation) => void
setOpenConversations: (open: boolean) => void
setConversationId: (conversationId: string) => void
getConversation: (userDid: string) => Promise<IOrbisConversation>
createConversation: (userDid: string) => Promise<void>
clearMessageNotifs: (conversationId: string) => void
getConversationTitle: (conversationId: string) => Promise<string>
getDid: (value: string) => Promise<string>
getDid: (address: string) => Promise<string>
}
const OrbisContext = createContext({} as IOrbisProvider)
@ -72,6 +81,9 @@ function OrbisProvider({ children }: { children: ReactNode }): ReactElement {
const [openConversations, setOpenConversations] = useState(false)
const [conversationId, setConversationId] = useState(null)
const [conversations, setConversations] = useState<IOrbisConversation[]>([])
const [activeConversationTitle, setActiveConversationTitle] = useState(null)
const [newConversation, setNewConversation] =
useState<INewConversation | null>(null)
// Function to reset states
const resetStates = () => {
@ -215,8 +227,14 @@ function OrbisProvider({ children }: { children: ReactNode }): ReactElement {
if (!error && data.length > 0) {
const _usersNotifications = { ...usersNotifications }
const _conversationIds = conversations.map((o) => o.stream_id)
// Only show new notifications from existing conversations
const _unreads = data.filter((o: IOrbisNotification) => {
return o.status === 'new'
return (
_conversationIds.includes(o.content.conversation_id) &&
o.status === 'new'
)
})
_unreads.forEach((o: IOrbisNotification) => {
const conversationId = o.content.conversation_id
@ -259,20 +277,26 @@ function OrbisProvider({ children }: { children: ReactNode }): ReactElement {
}
const getConversations = async (did: string = null) => {
if (!did) return []
const { data } = await orbis.getConversations({
did,
context: CONVERSATION_CONTEXT
})
// Only show conversations with exactly 2 unique participants and remove duplicates based on participants
// Only show conversations with unique recipients
const filteredConversations: IOrbisConversation[] = []
data.forEach((conversation: IOrbisConversation) => {
if (conversation.recipients.length === 2) {
if (conversation.recipients.length > 1) {
// Sort recipients by alphabetical order and stringify
const sortedRecipients = conversation.recipients.sort()
const stringifiedRecipients = sortedRecipients.join(',')
// Check if conversation already exists based on sorted and stringified recipients
const found = filteredConversations.find(
(o: IOrbisConversation) =>
o.recipients.length === 2 &&
o.recipients.includes(conversation.recipients[0]) &&
o.recipients.includes(conversation.recipients[1])
o.recipients.length > 1 &&
o.recipients.sort().join(',') === stringifiedRecipients
)
if (!found) {
@ -288,6 +312,32 @@ function OrbisProvider({ children }: { children: ReactNode }): ReactElement {
return filteredConversations
}
const getConversation = async (userDid: string) => {
if (!account || !userDid) return null
console.log('has account and target userDid')
const _conversations = await getConversations(account?.did)
if (!_conversations.length) return null
console.log('has conversations')
const filteredConversations = _conversations.filter(
(conversation: IOrbisConversation) => {
return (
conversation.recipients.length === 2 &&
conversation.recipients.includes(userDid)
)
}
)
if (!filteredConversations.length) return null
console.log('has filtered conversations')
return filteredConversations[0]
}
const createConversation = async (userDid: string) => {
let _account = account
if (!_account) {
@ -343,6 +393,53 @@ function OrbisProvider({ children }: { children: ReactNode }): ReactElement {
}
}
// const createConversationV2 = async (userDid: string) => {
// let _account = account
// if (!_account) {
// // Check connection and force connect
// _account = await checkOrbisConnection({
// address: accountId,
// autoConnect: true
// })
// }
// if (!hasLit) {
// const res = await connectLit()
// if (res.status !== 200) {
// alert('Error connecting to Lit.')
// return
// }
// }
// // Refetch to make sure we have the latest conversations
// const _conversations = await getConversations(_account?.did)
// const 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)
// }
// }
// }
const getConversationTitle = async (conversationId: string) => {
if (conversationId && conversations.length) {
// Get conversation based on conversationId
@ -395,6 +492,10 @@ function OrbisProvider({ children }: { children: ReactNode }): ReactElement {
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [account])
useEffect(() => {
console.log({ newConversation, activeConversationTitle })
}, [newConversation, activeConversationTitle])
return (
<OrbisContext.Provider
value={{
@ -405,12 +506,17 @@ function OrbisProvider({ children }: { children: ReactNode }): ReactElement {
conversationId,
conversations,
notifications,
activeConversationTitle,
newConversation,
connectOrbis,
disconnectOrbis,
checkOrbisConnection,
connectLit,
setActiveConversationTitle,
setNewConversation,
setOpenConversations,
setConversationId,
getConversation,
createConversation,
clearMessageNotifs,
getConversationTitle,

View File

@ -75,7 +75,7 @@ export default function DmConversation() {
async () => {
getMessages(true)
},
!isLoading && hasLit ? 15000 : false
isLoading || !hasLit || !messages.length ? false : 15000
)
const showTime = (streamId: string): boolean => {
@ -123,7 +123,12 @@ export default function DmConversation() {
useEffect(() => {
if (isMounted) {
if (conversationId && orbis && hasLit) {
if (
conversationId &&
!conversationId.startsWith('new-') &&
orbis &&
hasLit
) {
getMessages()
} else {
setMessages([])

View File

@ -46,6 +46,24 @@
transform: rotate(180deg);
}
.btnCopy {
border: none;
background-color: transparent;
padding: 0;
margin: 0;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
pointer-events: auto;
}
.btnCopy .copyIcon {
pointer-events: none;
width: 1rem;
fill: var(--color-secondary);
}
.toggleArrow {
display: flex;
align-items: center;

View File

@ -1,46 +1,81 @@
import React, { useState, useEffect } from 'react'
import React, { useEffect } from 'react'
import styles from './Header.module.css'
import { useWeb3 } from '@context/Web3'
import { useOrbis } from '@context/Orbis'
import { didToAddress } from '@utils/orbis'
import ChatBubble from '@images/chatbubble.svg'
import ArrowBack from '@images/arrow.svg'
import ChevronUp from '@images/chevronup.svg'
import Copy from '@images/copy.svg'
export default function Header() {
const { accountId } = useWeb3()
const {
conversations,
conversationId,
openConversations,
notifications,
activeConversationTitle,
newConversation,
setActiveConversationTitle,
setNewConversation,
getConversationTitle,
setOpenConversations,
setConversationId
} = useOrbis()
const [name, setName] = useState<string>(null)
const handleToggle = (
const handleClick = (
e: React.MouseEvent<HTMLDivElement | HTMLButtonElement>
) => {
e.preventDefault()
const target = e.target as HTMLElement
if (target.tagName === 'BUTTON') {
setConversationId(null)
console.log(target)
const { role } = target.dataset
if (role) {
if (role === 'back-button') {
setConversationId(null)
setNewConversation(null)
} 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)
alert('Address copied to clipboard')
}
} else {
setOpenConversations(!openConversations)
}
}
useEffect(() => {
if (conversationId) {
getConversationTitle(conversationId).then((name) => setName(name))
const setConversationTitle = async (conversationId: string) => {
if (conversationId.startsWith('new-')) {
setActiveConversationTitle(conversationId.replace('new-', ''))
} else {
setName(null)
const title = await getConversationTitle(conversationId)
setActiveConversationTitle(title)
}
}
useEffect(() => {
if (!conversationId) setActiveConversationTitle(null)
else setConversationTitle(conversationId)
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [conversationId, conversations])
}, [conversationId])
return (
<div className={styles.header} onClick={handleToggle}>
<div className={styles.header} onClick={handleClick}>
{!conversationId ? (
<>
<div>
@ -59,8 +94,9 @@ export default function Header() {
<button
type="button"
aria-label="button"
data-role="back-button"
className={styles.btnBack}
onClick={handleToggle}
onClick={handleClick}
>
<ArrowBack
role="img"
@ -69,7 +105,23 @@ export default function Header() {
/>
</button>
)}
<span>{name}</span>
{activeConversationTitle && (
<>
<span>{activeConversationTitle}</span>
<button
onClick={handleClick}
data-role="copy-address"
title="Copy Address"
className={styles.btnCopy}
>
<Copy
role="img"
aria-label="Copy Address"
className={styles.copyIcon}
/>
</button>
</>
)}
</>
)}
<div className={styles.toggleArrow}>

View File

@ -5,6 +5,7 @@ import Button from '@shared/atoms/Button'
import Stats from './Stats'
import Account from './Account'
import styles from './index.module.css'
import { accountTruncate } from '@utils/web3'
import { useWeb3 } from '@context/Web3'
import { useProfile } from '@context/Profile'
import { useOrbis } from '@context/Orbis'
@ -23,18 +24,24 @@ const LinkExternal = ({ url, text }: { url: string; text: string }) => {
}
const DmButton = ({ accountId }: { accountId: string }) => {
const { ownAccount } = useProfile()
const { profile, ownAccount } = useProfile()
const { accountId: ownAccountId, connect } = useWeb3()
const { checkOrbisConnection, createConversation, getDid } = useOrbis()
const {
checkOrbisConnection,
getConversation,
setNewConversation,
setConversationId,
setOpenConversations,
getDid
} = useOrbis()
const [userDid, setUserDid] = useState<string | undefined>()
const [isCreatingConversation, setIsCreatingConversation] = useState(false)
const handleActivation = async (e: React.MouseEvent) => {
e.preventDefault()
const handleActivation = async () => {
const resConnect = await connect()
if (resConnect) {
await checkOrbisConnection({
address: ownAccountId,
address: resConnect,
autoConnect: true,
lit: true
})
@ -59,11 +66,31 @@ const DmButton = ({ accountId }: { accountId: string }) => {
<Button
style="primary"
size="small"
disabled={!ownAccountId || isCreatingConversation}
disabled={isCreatingConversation}
onClick={async () => {
setIsCreatingConversation(true)
await createConversation(userDid)
setIsCreatingConversation(false)
if (!ownAccountId) {
handleActivation()
} else {
setIsCreatingConversation(true)
const conversation = await getConversation(userDid)
if (conversation) {
setConversationId(conversation.stream_id)
} else {
console.log('need to create new conversation')
const suffix =
profile && profile?.name
? profile?.name
: accountTruncate(accountId)
setConversationId(`new-${suffix}`)
setNewConversation({
name: suffix,
recipients: [userDid]
})
}
setOpenConversations(true)
setIsCreatingConversation(false)
}
}}
>
{isCreatingConversation ? 'Loading...' : 'Send Direct Message'}
@ -71,16 +98,6 @@ const DmButton = ({ accountId }: { accountId: string }) => {
</div>
)
}
if (!ownAccountId) {
return (
<div className={styles.dmButton}>
<Button style="primary" size="small" onClick={handleActivation}>
Connect Wallet
</Button>
</div>
)
}
}
export default function AccountHeader({