From 7effd27819468efe194bdadde2b04ee2a47ca451 Mon Sep 17 00:00:00 2001 From: marcoelissa Date: Tue, 4 Oct 2022 14:15:52 +0700 Subject: [PATCH] minor fix conversation styles --- src/@context/Orbis.tsx | 4 +- src/@types/Orbis.d.ts | 41 ++++++ .../FloatingChat/Conversation.module.css | 55 ++++++-- .../Orbis/FloatingChat/Conversation.tsx | 41 +++++- .../FloatingChat/ConversationItem.module.css | 80 +++++++++++ .../Orbis/FloatingChat/ConversationItem.tsx | 85 ++++++++++++ .../@shared/Orbis/FloatingChat/Messages.tsx | 5 + .../Orbis/FloatingChat/index.module.css | 74 +--------- .../@shared/Orbis/FloatingChat/index.tsx | 127 ++++++++---------- src/components/@shared/Orbis/Post.tsx | 2 +- 10 files changed, 351 insertions(+), 163 deletions(-) create mode 100644 src/components/@shared/Orbis/FloatingChat/ConversationItem.module.css create mode 100644 src/components/@shared/Orbis/FloatingChat/ConversationItem.tsx create mode 100644 src/components/@shared/Orbis/FloatingChat/Messages.tsx diff --git a/src/@context/Orbis.tsx b/src/@context/Orbis.tsx index 1f9372209..aee563e5d 100644 --- a/src/@context/Orbis.tsx +++ b/src/@context/Orbis.tsx @@ -30,7 +30,7 @@ function OrbisProvider({ children }: { children: ReactNode }): ReactElement { } } - const checkConnection = async (provider: object): Promise => { + const checkConnection = async (): Promise => { 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]) diff --git a/src/@types/Orbis.d.ts b/src/@types/Orbis.d.ts index fbd061e2e..eff37afbd 100644 --- a/src/@types/Orbis.d.ts +++ b/src/@types/Orbis.d.ts @@ -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 + } +} diff --git a/src/components/@shared/Orbis/FloatingChat/Conversation.module.css b/src/components/@shared/Orbis/FloatingChat/Conversation.module.css index 3f3e23acf..d174f816f 100644 --- a/src/components/@shared/Orbis/FloatingChat/Conversation.module.css +++ b/src/components/@shared/Orbis/FloatingChat/Conversation.module.css @@ -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; + } +} diff --git a/src/components/@shared/Orbis/FloatingChat/Conversation.tsx b/src/components/@shared/Orbis/FloatingChat/Conversation.tsx index 8389be8d1..bf65292ae 100644 --- a/src/components/@shared/Orbis/FloatingChat/Conversation.tsx +++ b/src/components/@shared/Orbis/FloatingChat/Conversation.tsx @@ -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 ( + + {!loading ? decrypted : '---'} + + ) } export default function DmConversation({ @@ -36,6 +47,14 @@ export default function DmConversation({ }) { const { account } = useOrbis() + // const newCancelToken = useCancelToken() + + // async function getProfileData(address: string): Promise { + // 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({
{messages.map((message, index) => (
-
- {/* Avatar */} -
+ {account?.did !== message.creator_details.did && ( +
+ +
+ )}
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 ( +
onClick(conversation)} + > +
+ + {unreads > 0 && ( +
{unreads}
+ )} +
+
+
+

{name}

+ + +
+ {/*

{conversation.chat}

*/} +
+
+ ) +} diff --git a/src/components/@shared/Orbis/FloatingChat/Messages.tsx b/src/components/@shared/Orbis/FloatingChat/Messages.tsx new file mode 100644 index 000000000..f24410e55 --- /dev/null +++ b/src/components/@shared/Orbis/FloatingChat/Messages.tsx @@ -0,0 +1,5 @@ +import React from 'react' + +export default function Messages() { + return
Messages
+} diff --git a/src/components/@shared/Orbis/FloatingChat/index.module.css b/src/components/@shared/Orbis/FloatingChat/index.module.css index 358032356..1fcbb83bc 100644 --- a/src/components/@shared/Orbis/FloatingChat/index.module.css +++ b/src/components/@shared/Orbis/FloatingChat/index.module.css @@ -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; diff --git a/src/components/@shared/Orbis/FloatingChat/index.tsx b/src/components/@shared/Orbis/FloatingChat/index.tsx index 40f4e7ad0..56d802253 100644 --- a/src/components/@shared/Orbis/FloatingChat/index.tsx +++ b/src/components/@shared/Orbis/FloatingChat/index.tsx @@ -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() {
Direct Messages - {sumCount > 0 && {sumCount}} + {unreads.length > 0 && ( + {unreads.length} + )}
-
- {conversations.map((dm, index) => ( -
+ {conversations.map((conversation, index) => ( + openConversation(dm.stream_id)} - > -
- Avatar - {dm.count > '0' && ( -
{dm.count}
- )} -
-
-
-

{dm.name}

- {dm.date} -
-

{dm.chat}

-
-
+ conversation={conversation} + unreads={getConversationUnreads(conversation.stream_id)} + onClick={() => openConversation(conversation)} + /> ))}
{conversationId && ( -
+
- {conversationId} + {conversationTitle}
- +
)} diff --git a/src/components/@shared/Orbis/Post.tsx b/src/components/@shared/Orbis/Post.tsx index ed33c7046..afeb48061 100644 --- a/src/components/@shared/Orbis/Post.tsx +++ b/src/components/@shared/Orbis/Post.tsx @@ -124,7 +124,7 @@ export default function Post({
{showProfile && (