wallet-connect-web-examples/wallets/react-wallet-v2-chat/src/pages/chat.tsx
2022-10-28 11:09:05 +02:00

122 lines
3.2 KiB
TypeScript

import { Fragment, useEffect, useRef, useState } from 'react'
import { styled } from '@nextui-org/react'
import { useRouter } from 'next/router'
import { useSnapshot } from 'valtio'
import ChatboxInput from '@/components/ChatboxInput'
import ChatMessage from '@/components/ChatMessage'
import PageHeader from '@/components/PageHeader'
import { demoAddressResolver } from '@/config/chatConstants'
import SettingsStore from '@/store/SettingsStore'
import { chatClient } from '@/utils/WalletConnectUtil'
const ChatContainer = styled('div', {
display: 'flex',
flexDirection: 'column',
flexGrow: 1,
height: '84%',
maxWidth: '100%'
} as any)
const MessagesContainer = styled('div', {
display: 'flex',
flexGrow: 1,
flexDirection: 'column',
overflowY: 'scroll',
padding: '10px'
} as any)
/**
* Component
*/
export default function ChatPage() {
const [topic, setTopic] = useState('')
const [messages, setMessages] = useState<
{
message: string
authorAccount: string
}[]
>([])
const { eip155Address } = useSnapshot(SettingsStore.state)
const { query } = useRouter()
const lastMessageRef = useRef<null | HTMLDivElement>(null)
const fullEip155Address = `eip155:1:${eip155Address}`
async function onOutgoingMessage(outgoingMessage: string) {
await chatClient.message({
topic,
payload: {
message: outgoingMessage,
authorAccount: fullEip155Address,
timestamp: Date.now()
}
})
if (chatClient.getMessages({ topic }).length) {
setMessages(chatClient.getMessages({ topic }))
}
}
function isOutgoingMessage(authorAccount: string) {
return authorAccount === fullEip155Address
}
function getChatTitle() {
if (typeof query.peerAccount !== 'string') return ''
return demoAddressResolver[query.peerAccount] ?? query.peerAccount
}
useEffect(() => {
if (query?.topic) {
setTopic(query.topic as string)
}
}, [query])
useEffect(() => {
// Set existing messages on load.
if (topic) {
try {
const messages = chatClient.getMessages({ topic })
console.log('getMessages for topic: ', topic, messages)
setMessages(messages)
} catch (error) {}
}
}, [topic])
useEffect(() => {
lastMessageRef.current?.scrollIntoView({ behavior: 'smooth' })
}, [messages])
useEffect(() => {
if (topic) {
// Update local messages state on new message.
chatClient.once('chat_message', eventArgs => {
console.log('new chat message:', eventArgs)
setMessages(chatClient.getMessages({ topic }))
})
}
}, [messages, topic])
return (
<Fragment>
<PageHeader title={getChatTitle()} backButtonHref="/chats" withBackButton />
<ChatContainer>
<MessagesContainer>
{messages.map(({ message, authorAccount }, i) => (
<ChatMessage
key={i}
message={message}
messageType={isOutgoingMessage(authorAccount) ? 'outgoing' : 'incoming'}
/>
))}
<div ref={lastMessageRef}></div>
</MessagesContainer>
<ChatboxInput handleSend={onOutgoingMessage} />
</ChatContainer>
</Fragment>
)
}