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

minor fix conversation styles

This commit is contained in:
marcoelissa 2022-10-04 14:15:52 +07:00
parent 9bdaaa781e
commit 7effd27819
10 changed files with 351 additions and 163 deletions

View File

@ -30,7 +30,7 @@ function OrbisProvider({ children }: { children: ReactNode }): ReactElement {
}
}
const checkConnection = async (provider: object): Promise<void> => {
const checkConnection = async (): Promise<void> => {
const res = await orbis.isConnected()
if (res.status === 200) {
@ -67,7 +67,7 @@ function OrbisProvider({ children }: { children: ReactNode }): ReactElement {
// Check if wallet connected
useEffect(() => {
if (!account && orbis && web3Provider) {
checkConnection(web3Provider)
checkConnection()
}
}, [account, orbis, web3Provider])

41
src/@types/Orbis.d.ts vendored
View File

@ -63,8 +63,12 @@ declare interface OrbisPostCreatorDetailsInterface {
a_r: number
did: string
metadata: {
address: string
chain: string
ensName: string
}
nonces?: object
profile?: OrbisCreatorProfileInterface
}
declare interface OrbisPostMentionsInterface {
@ -143,3 +147,40 @@ declare interface OrbisPostInterface {
timestamp: number
type: string
}
declare interface OrbisConversationInterface {
content: {
recipients: string[]
}
context?: string | null
details: {
content: {
recipients: string[]
creator: string
}
}
last_message_timestamp: number
last_timestamp_read: number
recipients: string[]
recipients_details: OrbisPostCreatorDetailsInterface[]
stream_id: string
}
declare interface OrbisNotificationInterface {
content: {
conversation_id: string
encryptedMessage: {
accessControlConditions: string
encryptedString: string
encryptedSymmetricKey: string
}
}
family: string
post_details: object
status: string
type: string
user_notifying_details: {
did: string
profile: OrbisCreatorProfileInterface
}
}

View File

@ -2,15 +2,18 @@
padding: calc(var(--spacer) / 2);
height: calc(100% - (var(--spacer) * 3.5));
display: flex;
flex-direction: column-reverse;
flex-direction: column;
overflow-y: auto;
}
.conversationRecipient,
.conversationSend {
.conversationItem {
display: flex;
align-items: flex-end;
margin-bottom: calc(var(--spacer) / 2);
margin-bottom: calc(var(--spacer) / 4);
}
.conversationItem[data-type='right'] {
justify-content: end;
}
.conversationSend .chatBubbleItem {
@ -28,14 +31,14 @@
border-radius: 100%;
border: 1px solid var(--border-color);
flex-shrink: 0;
width: calc(var(--font-size-large) * 2);
height: calc(var(--font-size-large) * 2);
width: calc(var(--font-size-large) * 2) !important;
height: calc(var(--font-size-large) * 2) !important;
}
.colBubble {
display: flex;
flex-direction: column;
width: 100%;
max-width: 80%;
}
.chatBubbleItem {
@ -50,7 +53,7 @@
display: inline-block;
background-color: var(--color-primary);
padding: calc(var(--spacer) / 4) calc(var(--spacer) / 2.5);
font-size: var(--font-size-base);
font-size: var(--font-size-text);
border-radius: 1rem;
overflow: hidden;
text-overflow: ellipsis;
@ -65,22 +68,28 @@
}
.chatDefault {
border-bottom-left-radius: 0px;
background-color: var(--border-color);
border-bottom-left-radius: 0px;
}
.conversationRecipient[data-sender='away']
+ .conversationRecipient[data-sender='away']
.conversationItem[data-type='right']
+ .conversationItem[data-type='right']
.chatBubble {
border-bottom-left-radius: 0;
border-top-right-radius: 0;
}
/* .conversationRecipient .colBubble .chatBubbleItem .chatBubble {
.conversationItem[data-type='left']
+ .conversationItem[data-type='left']
.chatBubble {
border-top-left-radius: 0;
}
/* .conversationItem .colBubble .chatBubbleItem .chatBubble {
border-top-left-radius: 0;
border-bottom-left-radius: 0px;
} */
/* .conversationRecipient .colBubble .chatBubbleItem:first-of-type .chatBubble {
/* .conversationItem .colBubble .chatBubbleItem:first-of-type .chatBubble {
border-top-left-radius: 1rem;
border-bottom-left-radius: 0px;
}
@ -101,3 +110,21 @@
color: var(--color-secondary);
padding-top: calc(var(--spacer) / 8);
}
.decrypting {
-webkit-animation: pulse 2s ease-in-out 0s infinite forwards;
-moz-animation: pulse 2s ease-in-out 0s infinite forwards;
animation: pulse 2s ease-in-out 0s infinite forwards;
}
@keyframes pulse {
0% {
opacity: 1;
}
50% {
opacity: 0;
}
100% {
opacity: 1;
}
}

View File

@ -1,5 +1,9 @@
import React, { useEffect, useState } from 'react'
// import { useCancelToken } from '@hooks/useCancelToken'
import { useOrbis } from '@context/Orbis'
// import get3BoxProfile from '@utils/profile'
import { didToAddress } from '@utils/orbis'
import Blockies from '@shared/atoms/Blockies'
import styles from './Conversation.module.css'
function RenderDecryptedMessage({
@ -8,10 +12,12 @@ function RenderDecryptedMessage({
content: OrbisPostContentInterface
}) {
const { orbis } = useOrbis()
const [loading, setLoading] = useState(true)
const [decrypted, setDecrypted] = useState(null)
useEffect(() => {
const decryptMessage = async (content: OrbisPostContentInterface) => {
setLoading(true)
const res = await orbis.decryptMessage(content)
if (res) {
@ -19,6 +25,7 @@ function RenderDecryptedMessage({
}
setDecrypted(res.result)
setLoading(false)
}
if (content) {
console.log(content)
@ -26,7 +33,11 @@ function RenderDecryptedMessage({
}
}, [content])
return <>{decrypted}</>
return (
<span className={loading && styles.decrypting}>
{!loading ? decrypted : '---'}
</span>
)
}
export default function DmConversation({
@ -36,6 +47,14 @@ export default function DmConversation({
}) {
const { account } = useOrbis()
// const newCancelToken = useCancelToken()
// async function getProfileData(address: string): Promise<string> {
// const profile = await get3BoxProfile(address, newCancelToken())
// if (!profile) return null
// return profile?.image
// }
useEffect(() => {
console.log(messages)
// messages.forEach((message) => {
@ -47,15 +66,23 @@ export default function DmConversation({
<div className={styles.conversationBox}>
{messages.map((message, index) => (
<div
className={styles.conversationRecipient}
className={styles.conversationItem}
key={index}
data-sender={
account?.did === message.creator_details.did ? 'home' : 'away'
data-type={
account?.did === message.creator_details.did ? 'right' : 'left'
}
>
<div className={styles.colAvatar}>
{/* <img src={} alt="Avatar" className={styles.avatar}></img> */}
</div>
{account?.did !== message.creator_details.did && (
<div className={styles.colAvatar}>
<Blockies
accountId={didToAddress(message.creator_details.did)}
className={styles.avatar}
// image={getProfileData(
// didToAddress(message.creator_details.did)
// )}
/>
</div>
)}
<div className={styles.colBubble}>
<div className={styles.chatBubbleItem}>
<div

View File

@ -0,0 +1,80 @@
.conversationItem {
display: flex;
padding: calc(var(--spacer) / 2) var(--spacer);
border-bottom: 1px solid var(--border-color);
cursor: pointer;
}
.accountAvatarSet {
position: relative;
flex-shrink: 0;
}
.accountAvatarSet .notificationCount {
position: absolute;
bottom: -4px;
right: -4px;
}
.accountAvatar {
aspect-ratio: 1/1;
border-radius: 100%;
border: 1px solid var(--border-color);
flex-shrink: 0;
width: calc(var(--font-size-large) * 2.5);
height: calc(var(--font-size-large) * 2.5);
margin-left: 0;
}
.notificationCount {
background-color: var(--color-primary);
width: 20px;
height: 20px;
color: var(--brand-white);
border-radius: 100%;
display: flex;
justify-content: center;
align-items: center;
font-size: var(--font-size-mini);
font-weight: 600;
position: absolute;
bottom: -4px;
right: -4px;
}
.accountInfo {
-webkit-box-flex: 1;
flex: 1;
padding-left: calc(var(--spacer) / 2);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
min-width: 0;
}
.accountHeading {
display: flex;
justify-content: space-between;
}
.accountName {
margin-bottom: calc(var(--spacer) / 6);
font-size: var(--font-size-medium);
color: var(--color-primary);
}
.lastMessageDate {
font-size: var(--font-size-mini);
color: var(--font-color-text);
min-width: calc(var(--spacer) * 1.5);
text-align: right;
}
.accountChat {
font-size: var(--font-size-small);
color: var(--color-secondary);
margin-bottom: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}

View File

@ -0,0 +1,85 @@
import React, { useState, useEffect } from 'react'
import { useCancelToken } from '@hooks/useCancelToken'
import { useOrbis } from '@context/Orbis'
import { accountTruncate } from '@utils/web3'
import get3BoxProfile from '@utils/profile'
import { didToAddress } from '@utils/orbis'
import Blockies from '@shared/atoms/Blockies'
import Time from '@shared/atoms/Time'
import styles from './ConversationItem.module.css'
export default function ConversationItem({
conversation,
unreads,
onClick
}: {
conversation: OrbisConversationInterface
unreads: number
onClick: (param: OrbisConversationInterface | null) => void
}) {
const { account } = useOrbis()
const newCancelToken = useCancelToken()
const [name, setName] = useState(null)
const [address, setAddress] = useState(null)
const [image, setImage] = useState(null)
useEffect(() => {
const getProfile = async () => {
const details = conversation.recipients_details.find(
(o) => o.did !== account.did
)
const _address = didToAddress(details.did)
setAddress(_address)
if (details?.metadata?.ensName) {
setName(details?.metadata?.ensName)
} else if (details?.profile?.username) {
setName(details?.profile?.username)
} else {
setName(accountTruncate(_address))
}
const profile = await get3BoxProfile(_address, newCancelToken())
setImage(profile?.image)
}
if (conversation && account) {
getProfile()
}
}, [conversation, account, newCancelToken])
return (
<div
className={styles.conversationItem}
onClick={() => onClick(conversation)}
>
<div className={styles.accountAvatarSet}>
<Blockies
accountId={address}
className={styles.accountAvatar}
image={image}
/>
{unreads > 0 && (
<div className={styles.notificationCount}>{unreads}</div>
)}
</div>
<div className={styles.accountInfo}>
<div className={styles.accountHeading}>
<h3 className={styles.accountName}>{name}</h3>
<span className={styles.lastMessageDate}>
<Time
date={conversation.last_message_timestamp.toString()}
isUnix={true}
relative
/>
</span>
</div>
{/* <p className={styles.accountChat}>{conversation.chat}</p> */}
</div>
</div>
)
}

View File

@ -0,0 +1,5 @@
import React from 'react'
export default function Messages() {
return <div>Messages</div>
}

View File

@ -86,27 +86,13 @@
transform: scaleY(-1);
}
.dmList {
.conversations {
position: relative;
overflow: auto;
height: 100%;
}
.dmItem {
display: flex;
padding: calc(var(--spacer) / 2) var(--spacer);
border-bottom: 1px solid var(--border-color);
cursor: pointer;
}
.dmDate {
font-size: var(--font-size-mini);
color: var(--font-color-text);
min-width: calc(var(--spacer) * 1.5);
text-align: right;
}
.dmCount {
.notificationCount {
background-color: var(--color-primary);
width: 20px;
height: 20px;
@ -117,64 +103,10 @@
align-items: center;
font-size: var(--font-size-mini);
font-weight: 600;
}
.accountAvatarSet .dmCount {
position: absolute;
bottom: -4px;
right: -4px;
}
.header .dmCount {
margin-left: calc(var(--spacer) / 4);
}
.accountInfo {
-webkit-box-flex: 1;
flex: 1;
padding-left: calc(var(--spacer) / 2);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
min-width: 0;
}
.accountHeading {
display: flex;
justify-content: space-between;
}
.accountAvatarSet {
position: relative;
flex-shrink: 0;
}
.accountAvatar {
aspect-ratio: 1/1;
border-radius: 100%;
border: 1px solid var(--border-color);
flex-shrink: 0;
width: calc(var(--font-size-large) * 2.5);
height: calc(var(--font-size-large) * 2.5);
margin-left: 0;
}
.accountName {
margin-bottom: calc(var(--spacer) / 6);
font-size: var(--font-size-medium);
color: var(--color-primary);
}
.accountChat {
font-size: var(--font-size-small);
color: var(--color-secondary);
margin-bottom: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.conversationId {
.conversation {
position: absolute;
top: 0;
left: 0;

View File

@ -6,14 +6,17 @@ import styles from './index.module.css'
import Conversation from './Conversation'
import ChatToolbar from './ChatToolbar'
import { useOrbis } from '@context/Orbis'
import ConversationItem from './ConversationItem'
export default function FloatingChat() {
const { orbis, account } = useOrbis()
const [opened, setOpened] = useState(false)
const [conversationId, setConversationId] = useState(null)
const [conversations, setConversations] = useState([])
const [messages, setMessages] = useState([])
const { orbis, account } = useOrbis()
const [conversationTitle, setConversationTitle] = useState(null)
const [unreads, setUnreads] = useState([])
const getConversations = async () => {
const { data, error } = await orbis.getConversations({ did: account?.did })
@ -27,8 +30,34 @@ export default function FloatingChat() {
}
}
const getNotifications = async () => {
const { data, error } = await orbis.api.rpc('orbis_f_notifications', {
user_did: account?.did || 'none',
notif_type: 'messages'
})
if (error) {
console.log(error)
}
if (data.length > 0) {
const _unreads = data.filter((o: OrbisNotificationInterface) => {
return o.status === 'new'
})
setUnreads(_unreads)
}
}
const getConversationUnreads = (conversationId: string) => {
const _unreads = unreads.filter(
(o) => o.content.conversation_id === conversationId
)
return _unreads.length
}
useEffect(() => {
if (orbis && account) {
getNotifications()
getConversations()
}
}, [orbis, account])
@ -37,7 +66,8 @@ export default function FloatingChat() {
const { data, error } = await orbis.getMessages(id)
if (data) {
console.log(data)
data.reverse()
// const _messages = [...messages, ...data]
setMessages(data)
}
if (error) {
@ -45,44 +75,20 @@ export default function FloatingChat() {
}
}
const dummyData = [
{
name: '0xd30D…AFbD',
chat: 'Hello world!',
date: '15 Minutes Ago',
image: '/apple-touch-icon.png',
count: '3'
},
{
name: 'realdatawhale.eth',
chat: 'Getting some similar glitches with profile NFT. The current non-NFT photo works fine.',
date: '1 Day Ago',
image: '/apple-touch-icon.png',
count: '1'
},
{
name: 'hidetaka.eth',
chat: 'I already updated in the past.',
date: '1 Oct',
image: '/apple-touch-icon.png',
count: '0'
},
{
name: 'orbisclub.eth',
chat: 'Yeah that is weird, Did you update your profile within Orbis or with an app you built',
date: '1 Oct',
image: '/apple-touch-icon.png',
count: '0'
function openConversation(conversation: OrbisConversationInterface | null) {
if (!conversation) {
setConversationId(null)
setConversationTitle(null)
setMessages([])
} else {
setConversationId(conversation.stream_id)
getMessages(conversation.stream_id)
// Get conversation title
const recipient = conversation.recipients_details.find(
(o) => o.did !== account.did
)
setConversationTitle(recipient?.metadata?.ensName)
}
]
const sumCount = dummyData.reduce(function (prev, current) {
return prev + +current.count
}, 0)
function openConversation(id: string) {
setConversationId(id)
getMessages(id)
}
return (
@ -91,7 +97,9 @@ export default function FloatingChat() {
<div className={styles.header}>
<ChatBubble role="img" aria-label="Chat" className={styles.icon} />
<span>Direct Messages</span>
{sumCount > 0 && <span className={styles.dmCount}>{sumCount}</span>}
{unreads.length > 0 && (
<span className={styles.notificationCount}>{unreads.length}</span>
)}
<button
type="button"
className={styles.toggle}
@ -104,35 +112,18 @@ export default function FloatingChat() {
/>
</button>
</div>
<div className={styles.dmList}>
{conversations.map((dm, index) => (
<div
<div className={styles.conversations}>
{conversations.map((conversation, index) => (
<ConversationItem
key={index}
className={styles.dmItem}
onClick={() => openConversation(dm.stream_id)}
>
<div className={styles.accountAvatarSet}>
<img
src={dm.image}
alt="Avatar"
className={styles.accountAvatar}
></img>
{dm.count > '0' && (
<div className={styles.dmCount}>{dm.count}</div>
)}
</div>
<div className={styles.accountInfo}>
<div className={styles.accountHeading}>
<h3 className={styles.accountName}>{dm.name}</h3>
<span className={styles.dmDate}>{dm.date}</span>
</div>
<p className={styles.accountChat}>{dm.chat}</p>
</div>
</div>
conversation={conversation}
unreads={getConversationUnreads(conversation.stream_id)}
onClick={() => openConversation(conversation)}
/>
))}
</div>
{conversationId && (
<div className={styles.conversationId}>
<div className={styles.conversation}>
<div className={styles.header}>
<button
type="button"
@ -146,7 +137,7 @@ export default function FloatingChat() {
className={styles.back}
/>
</button>
<span>{conversationId}</span>
<span>{conversationTitle}</span>
<button
type="button"
className={styles.toggle}
@ -159,7 +150,7 @@ export default function FloatingChat() {
/>
</button>
</div>
<Conversation messages={messages} orbis={orbis} />
<Conversation messages={messages} />
<ChatToolbar />
</div>
)}

View File

@ -124,7 +124,7 @@ export default function Post({
<Blockies
accountId={address}
className={styles.blockies}
image={profile?.image}
image={profile?.image || post?.creator_details?.profile?.pfp}
/>
<div className={styles.content}>
{showProfile && (