mirror of
https://github.com/oceanprotocol/market.git
synced 2024-12-02 05:57:29 +01:00
update direct message component
This commit is contained in:
parent
20d587a249
commit
1f6c9a06a6
@ -27,7 +27,7 @@ type IOrbisProvider = {
|
||||
unreadMessages: IOrbisNotification[]
|
||||
connectOrbis: (lit?: boolean) => Promise<IOrbisProfile | null>
|
||||
disconnectOrbis: () => void
|
||||
checkConnection: (options: {
|
||||
checkOrbisConnection: (options: {
|
||||
autoConnect?: boolean
|
||||
lit?: boolean
|
||||
}) => Promise<IOrbisProfile>
|
||||
@ -38,10 +38,7 @@ type IOrbisProvider = {
|
||||
}>
|
||||
setOpenConversations: (value: boolean) => void
|
||||
setConversationId: (value: string) => void
|
||||
setConversations: (value: IOrbisConversation[]) => void
|
||||
getConversations: (did: string) => Promise<void>
|
||||
createConversation: (value: string) => Promise<void>
|
||||
checkConversation: (value: string) => Promise<IOrbisConversation[]>
|
||||
getDid: (value: string) => Promise<string>
|
||||
}
|
||||
|
||||
@ -67,17 +64,23 @@ function OrbisProvider({ children }: { children: ReactNode }): ReactElement {
|
||||
(o) => o.stream_id === conversationId
|
||||
)
|
||||
if (conversation) {
|
||||
const recipient = conversation.recipients_details.find(
|
||||
const details = conversation.recipients_details.find(
|
||||
(o: IOrbisProfile) => o.did !== account.did
|
||||
)
|
||||
const did = conversation.recipients.find(
|
||||
(o: string) => o !== account.did
|
||||
)
|
||||
|
||||
const address =
|
||||
recipient?.metadata?.address || didToAddress(recipient?.did)
|
||||
const address = didToAddress(did)
|
||||
|
||||
title =
|
||||
recipient?.metadata?.ensName ||
|
||||
recipient?.profile?.username ||
|
||||
accountTruncate(address)
|
||||
if (details) {
|
||||
title =
|
||||
details?.metadata?.ensName ||
|
||||
details?.profile?.username ||
|
||||
accountTruncate(address)
|
||||
} else {
|
||||
title = accountTruncate(address)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -95,6 +98,7 @@ function OrbisProvider({ children }: { children: ReactNode }): ReactElement {
|
||||
if (res.status === 200) {
|
||||
const { data } = await orbis.getProfile(res.did)
|
||||
setAccount(data)
|
||||
setHasLit(res.details.hasLit)
|
||||
return data
|
||||
} else {
|
||||
await sleep(2000)
|
||||
@ -115,7 +119,7 @@ function OrbisProvider({ children }: { children: ReactNode }): ReactElement {
|
||||
return res
|
||||
}
|
||||
|
||||
const checkConnection = async ({
|
||||
const checkOrbisConnection = async ({
|
||||
autoConnect,
|
||||
lit
|
||||
}: {
|
||||
@ -141,25 +145,32 @@ function OrbisProvider({ children }: { children: ReactNode }): ReactElement {
|
||||
context: CONVERSATION_CONTEXT
|
||||
})
|
||||
|
||||
setConversations(data || [])
|
||||
return data || []
|
||||
}
|
||||
// Only show conversations with exactly 2 unique participants and remove duplicates based on participants
|
||||
const filteredConversations: IOrbisConversation[] = []
|
||||
data.forEach((conversation: IOrbisConversation) => {
|
||||
if (conversation.recipients.length === 2) {
|
||||
const found = filteredConversations.find(
|
||||
(o: IOrbisConversation) =>
|
||||
o.recipients.length === 2 &&
|
||||
o.recipients.includes(conversation.recipients[0]) &&
|
||||
o.recipients.includes(conversation.recipients[1])
|
||||
)
|
||||
|
||||
const checkConversation = async (userDid: string) => {
|
||||
const filtered: IOrbisConversation[] = conversations.filter(
|
||||
(conversation: IOrbisConversation) => {
|
||||
return conversation.recipients.includes(userDid)
|
||||
if (!found) {
|
||||
filteredConversations.push(conversation)
|
||||
}
|
||||
}
|
||||
)
|
||||
})
|
||||
|
||||
return filtered
|
||||
setConversations(filteredConversations)
|
||||
return filteredConversations
|
||||
}
|
||||
|
||||
const createConversation = async (userDid: string) => {
|
||||
let _account = account
|
||||
if (!_account) {
|
||||
// Check connection and force connect
|
||||
_account = await checkConnection({ autoConnect: true })
|
||||
_account = await checkOrbisConnection({ autoConnect: true })
|
||||
}
|
||||
|
||||
if (!hasLit) {
|
||||
@ -222,6 +233,8 @@ function OrbisProvider({ children }: { children: ReactNode }): ReactElement {
|
||||
|
||||
if (data && data.length > 0) {
|
||||
_did = data[0].did
|
||||
} else {
|
||||
_did = `did:pkh:eip155:0:${address.toLowerCase()}`
|
||||
}
|
||||
|
||||
return _did
|
||||
@ -234,7 +247,7 @@ function OrbisProvider({ children }: { children: ReactNode }): ReactElement {
|
||||
useEffect(() => {
|
||||
if (accountId && web3Provider) {
|
||||
// Check if wallet connected
|
||||
checkConnection({})
|
||||
checkOrbisConnection({})
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [accountId, web3Provider])
|
||||
@ -257,19 +270,16 @@ function OrbisProvider({ children }: { children: ReactNode }): ReactElement {
|
||||
unreadMessages,
|
||||
connectOrbis,
|
||||
disconnectOrbis,
|
||||
checkConnection,
|
||||
checkOrbisConnection,
|
||||
connectLit,
|
||||
setOpenConversations,
|
||||
setConversationId,
|
||||
setConversations,
|
||||
getConversations,
|
||||
createConversation,
|
||||
checkConversation,
|
||||
getDid
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
{account && <DirectMessages />}
|
||||
<DirectMessages />
|
||||
</OrbisContext.Provider>
|
||||
)
|
||||
}
|
||||
|
@ -1,10 +1,15 @@
|
||||
.conversation {
|
||||
position: relative;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.loading {
|
||||
position: absolute;
|
||||
top: calc(var(--spacer) / 3);
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
padding: calc(var(--spacer) / 4);
|
||||
text-align: center;
|
||||
color: var(--color-secondary);
|
||||
|
@ -121,10 +121,10 @@ export default function DmConversation() {
|
||||
|
||||
useEffect(() => {
|
||||
const el = messagesWrapper.current
|
||||
messagesWrapper.current.addEventListener('scroll', onScrollMessages)
|
||||
el?.addEventListener('scroll', onScrollMessages)
|
||||
|
||||
return () => {
|
||||
el.removeEventListener('scroll', onScrollMessages)
|
||||
el?.removeEventListener('scroll', onScrollMessages)
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [messages])
|
||||
|
@ -1,40 +1,50 @@
|
||||
.header {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: flex-start;
|
||||
gap: calc(0.5 * var(--spacer));
|
||||
align-items: center;
|
||||
padding: calc(0.35 * var(--spacer)) var(--spacer);
|
||||
padding: calc(0.35 * var(--spacer)) calc(0.5 * var(--spacer));
|
||||
border-bottom: 1px solid var(--border-color);
|
||||
box-shadow: var(--box-shadow);
|
||||
font-size: var(--font-size-h5);
|
||||
font-weight: var(--font-weight-bold);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.icon {
|
||||
margin-left: 0;
|
||||
width: 1.5rem;
|
||||
margin-right: calc(0.5 * var(--spacer));
|
||||
fill: var(--font-color-text);
|
||||
}
|
||||
|
||||
.back {
|
||||
margin-left: 0;
|
||||
width: 1rem;
|
||||
margin-right: calc(0.5 * var(--spacer));
|
||||
fill: var(--font-color-text);
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
.btnBack {
|
||||
border: none;
|
||||
background-color: transparent;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
cursor: pointer;
|
||||
width: 2rem;
|
||||
height: 2rem;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.toggle {
|
||||
cursor: pointer;
|
||||
.btnBack:hover {
|
||||
background-color: var(--background-highlight);
|
||||
}
|
||||
|
||||
.btnBack .backIcon {
|
||||
pointer-events: none;
|
||||
width: 1rem;
|
||||
fill: var(--font-color-text);
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
.toggleArrow {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-left: auto;
|
||||
background: transparent;
|
||||
border: none;
|
||||
@ -43,7 +53,9 @@
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
.toggle .icon {
|
||||
.toggleArrow .icon {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
fill: transparent;
|
||||
}
|
||||
|
||||
|
@ -11,40 +11,54 @@ export default function Header() {
|
||||
conversationId,
|
||||
openConversations,
|
||||
conversationTitle,
|
||||
unreadMessages,
|
||||
setOpenConversations,
|
||||
setConversationId
|
||||
} = useOrbis()
|
||||
|
||||
const handleToggle = (e: any) => {
|
||||
e.preventDefault()
|
||||
if (e.target.type === 'button') {
|
||||
setConversationId(null)
|
||||
} else {
|
||||
setOpenConversations(!openConversations)
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={styles.header}>
|
||||
<div className={styles.header} onClick={handleToggle}>
|
||||
{!conversationId ? (
|
||||
<>
|
||||
<ChatBubble role="img" aria-label="Chat" className={styles.icon} />
|
||||
<div>
|
||||
<ChatBubble role="img" aria-label="Chat" className={styles.icon} />
|
||||
</div>
|
||||
<span>Direct Messages</span>
|
||||
{/* {unreadMessages.length > 0 && (
|
||||
{unreadMessages.length > 0 && (
|
||||
<span className={styles.notificationCount}>
|
||||
{unreadMessages.length}
|
||||
</span>
|
||||
)} */}
|
||||
)}
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<button
|
||||
type="button"
|
||||
aria-label="button"
|
||||
className={styles.btnBack}
|
||||
onClick={() => setConversationId(null)}
|
||||
>
|
||||
<ArrowBack role="img" aria-label="arrow" className={styles.back} />
|
||||
</button>
|
||||
{openConversations && (
|
||||
<button
|
||||
type="button"
|
||||
aria-label="button"
|
||||
className={styles.btnBack}
|
||||
onClick={handleToggle}
|
||||
>
|
||||
<ArrowBack
|
||||
role="img"
|
||||
aria-label="arrow"
|
||||
className={styles.backIcon}
|
||||
/>
|
||||
</button>
|
||||
)}
|
||||
<span>{conversationTitle}</span>
|
||||
</>
|
||||
)}
|
||||
<button
|
||||
type="button"
|
||||
className={styles.toggle}
|
||||
onClick={() => setOpenConversations(!openConversations)}
|
||||
>
|
||||
<div className={styles.toggleArrow}>
|
||||
<ChevronUp
|
||||
role="img"
|
||||
aria-label="Toggle"
|
||||
@ -52,7 +66,7 @@ export default function Header() {
|
||||
openConversations ? styles.isFlipped : ''
|
||||
}`}
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
.conversation {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: calc(var(--spacer) / 2) var(--spacer);
|
||||
padding: calc(0.5 * var(--spacer)) calc(0.5 * var(--spacer));
|
||||
border-bottom: 1px solid var(--border-color);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
@ -28,14 +28,19 @@ export default function ConversationItem({
|
||||
const details = conversation.recipients_details.find(
|
||||
(o) => o.did !== account.did
|
||||
)
|
||||
const did = conversation.recipients.find((o) => o !== account.did)
|
||||
|
||||
const _address = didToAddress(details?.did)
|
||||
const _address = didToAddress(did)
|
||||
setAddress(_address)
|
||||
|
||||
if (details?.metadata?.ensName) {
|
||||
setName(details?.metadata?.ensName)
|
||||
} else if (details?.profile?.username) {
|
||||
setName(details?.profile?.username)
|
||||
if (details) {
|
||||
if (details?.metadata?.ensName) {
|
||||
setName(details?.metadata?.ensName)
|
||||
} else if (details?.profile?.username) {
|
||||
setName(details?.profile?.username)
|
||||
} else {
|
||||
setName(accountTruncate(_address))
|
||||
}
|
||||
} else {
|
||||
setName(accountTruncate(_address))
|
||||
}
|
||||
|
@ -11,7 +11,7 @@
|
||||
left: 0;
|
||||
transition: transform 300ms ease 0s;
|
||||
pointer-events: none;
|
||||
z-index: 20;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.floating {
|
||||
@ -40,6 +40,21 @@
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.walletWrapper {
|
||||
margin: auto;
|
||||
max-width: 320px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.walletWrapper p {
|
||||
color: var(--color-secondary);
|
||||
font-size: var(--font-size-small);
|
||||
}
|
||||
|
||||
.walletWrapper button {
|
||||
margin: var(--spacer) auto 0;
|
||||
}
|
||||
|
||||
.isClosed {
|
||||
transform: translateY(90%);
|
||||
}
|
||||
|
@ -2,11 +2,79 @@ import React from 'react'
|
||||
import styles from './index.module.css'
|
||||
import Conversation from './Conversation'
|
||||
import { useOrbis } from '@context/Orbis'
|
||||
import { useWeb3 } from '@context/Web3'
|
||||
import Header from './Header'
|
||||
import List from './List'
|
||||
import walletStyles from '../../../Header/Wallet/Account.module.css'
|
||||
// import loadable from '@loadable/component'
|
||||
// const Wallet = loadable(() => import('../../../Header/Wallet'))
|
||||
|
||||
const BodyContent = () => {
|
||||
const { account, conversationId, checkOrbisConnection } = useOrbis()
|
||||
const { accountId, connect } = useWeb3()
|
||||
|
||||
const handleActivation = async (e: React.MouseEvent) => {
|
||||
e.preventDefault()
|
||||
const resConnect = await connect()
|
||||
if (resConnect) {
|
||||
await checkOrbisConnection({ autoConnect: true, lit: true })
|
||||
}
|
||||
}
|
||||
|
||||
if (!accountId) {
|
||||
return (
|
||||
<div className={styles.walletWrapper}>
|
||||
<div>
|
||||
<h5>Connect your wallet to start messaging</h5>
|
||||
<p>You will be ask to sign:</p>
|
||||
<p>
|
||||
Sign 1: Create your decentralized Identity (DID) to share a message
|
||||
and own it
|
||||
</p>
|
||||
<p>Sign 2: Create your encrypted key to enable private messages</p>
|
||||
<button
|
||||
className={`${walletStyles.button} ${walletStyles.initial}`}
|
||||
onClick={(e) => handleActivation(e)}
|
||||
>
|
||||
Connect <span>Wallet</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
if (!account) {
|
||||
return (
|
||||
<div className={styles.walletWrapper}>
|
||||
<div>
|
||||
<h5>Sign your wallet to start messaging</h5>
|
||||
<p>
|
||||
Sign 1: Create your decentralized Identity (DID) to share a message
|
||||
and own it
|
||||
</p>
|
||||
<p>Sign 2: Create your encrypted key to enable private messages</p>
|
||||
<button
|
||||
className={`${walletStyles.button} ${walletStyles.initial}`}
|
||||
onClick={() =>
|
||||
checkOrbisConnection({ autoConnect: true, lit: true })
|
||||
}
|
||||
>
|
||||
Sign <span>Wallet</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
if (conversationId) {
|
||||
return <Conversation />
|
||||
}
|
||||
|
||||
return <List />
|
||||
}
|
||||
|
||||
export default function DirectMessages() {
|
||||
const { openConversations, conversationId } = useOrbis()
|
||||
const { openConversations } = useOrbis()
|
||||
|
||||
return (
|
||||
<div
|
||||
@ -17,7 +85,7 @@ export default function DirectMessages() {
|
||||
<Header />
|
||||
</div>
|
||||
<div className={styles.bodyWrapper}>
|
||||
{conversationId ? <Conversation /> : <List />}
|
||||
<BodyContent />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -19,7 +19,7 @@ export default function Details(): ReactElement {
|
||||
networkId,
|
||||
balance
|
||||
} = useWeb3()
|
||||
const { disconnectOrbis } = useOrbis()
|
||||
const { checkOrbisConnection, disconnectOrbis } = useOrbis()
|
||||
const { locale } = useUserPreferences()
|
||||
|
||||
const [mainCurrency, setMainCurrency] = useState<string>()
|
||||
@ -85,6 +85,7 @@ export default function Details(): ReactElement {
|
||||
onClick={async () => {
|
||||
await web3Modal?.clearCachedProvider()
|
||||
connect()
|
||||
checkOrbisConnection({})
|
||||
}}
|
||||
>
|
||||
Switch Wallet
|
||||
|
@ -22,25 +22,23 @@ const LinkExternal = ({ url, text }: { url: string; text: string }) => {
|
||||
)
|
||||
}
|
||||
|
||||
export default function AccountHeader({
|
||||
accountId
|
||||
}: {
|
||||
accountId: string
|
||||
}): ReactElement {
|
||||
const { profile, ownAccount } = useProfile()
|
||||
const { accountId: ownAccountId } = useWeb3()
|
||||
const { createConversation, getDid } = useOrbis()
|
||||
const [isShowMore, setIsShowMore] = useState(false)
|
||||
const DmButton = ({ accountId }: { accountId: string }) => {
|
||||
const { ownAccount } = useProfile()
|
||||
const { accountId: ownAccountId, connect } = useWeb3()
|
||||
const { checkOrbisConnection, createConversation, getDid } = useOrbis()
|
||||
const [userDid, setUserDid] = useState<string | undefined>()
|
||||
|
||||
const toogleShowMore = () => {
|
||||
setIsShowMore(!isShowMore)
|
||||
const handleActivation = async (e: React.MouseEvent) => {
|
||||
e.preventDefault()
|
||||
const resConnect = await connect()
|
||||
if (resConnect) {
|
||||
await checkOrbisConnection({ autoConnect: true, lit: true })
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
const getUserDid = async () => {
|
||||
const did = await getDid(accountId)
|
||||
console.log(did)
|
||||
setUserDid(did)
|
||||
}
|
||||
|
||||
@ -50,6 +48,44 @@ export default function AccountHeader({
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [accountId])
|
||||
|
||||
if (!ownAccount && userDid) {
|
||||
return (
|
||||
<div className={styles.dmButton}>
|
||||
<Button
|
||||
style="primary"
|
||||
size="small"
|
||||
disabled={!ownAccountId}
|
||||
onClick={() => createConversation(userDid)}
|
||||
>
|
||||
Send Direct Message
|
||||
</Button>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
if (!ownAccountId) {
|
||||
return (
|
||||
<div className={styles.dmButton}>
|
||||
<Button style="primary" size="small" onClick={handleActivation}>
|
||||
Connect Wallet
|
||||
</Button>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default function AccountHeader({
|
||||
accountId
|
||||
}: {
|
||||
accountId: string
|
||||
}): ReactElement {
|
||||
const { profile } = useProfile()
|
||||
const [isShowMore, setIsShowMore] = useState(false)
|
||||
|
||||
const toogleShowMore = () => {
|
||||
setIsShowMore(!isShowMore)
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={styles.grid}>
|
||||
<div>
|
||||
@ -58,19 +94,7 @@ export default function AccountHeader({
|
||||
</div>
|
||||
|
||||
<div>
|
||||
{!ownAccount && userDid && (
|
||||
<div className={styles.dmButton}>
|
||||
<Button
|
||||
style="primary"
|
||||
size="small"
|
||||
disabled={!ownAccountId}
|
||||
onClick={() => createConversation(userDid)}
|
||||
>
|
||||
Send Direct Message
|
||||
</Button>
|
||||
{!ownAccountId && <span>Please connect your wallet</span>}
|
||||
</div>
|
||||
)}
|
||||
<DmButton accountId={accountId} />
|
||||
<Markdown text={profile?.description} className={styles.description} />
|
||||
{isDescriptionTextClamped() ? (
|
||||
<span className={styles.more} onClick={toogleShowMore}>
|
||||
|
Loading…
Reference in New Issue
Block a user