diff --git a/packages/react-chat/src/components/Chat/ChatBody.tsx b/packages/react-chat/src/components/Chat/ChatBody.tsx index 7efb9855..6aa6b758 100644 --- a/packages/react-chat/src/components/Chat/ChatBody.tsx +++ b/packages/react-chat/src/components/Chat/ChatBody.tsx @@ -1,10 +1,10 @@ -import React, { useCallback, useState } from "react"; +import React from "react"; import styled from "styled-components"; import { ChannelData } from "../../helpers/channelsMock"; +import { useMessenger } from "../../hooks/useMessenger"; import { Theme } from "../../styles/themes"; import { Channel } from "../Channels"; -import { ChatMessage } from "../models/ChatMessage"; import { ChatInput } from "./ChatInput"; import { ChatMessages } from "./ChatMessages"; @@ -15,17 +15,7 @@ interface ChatBodyProps { } export function ChatBody({ theme, channel }: ChatBodyProps) { - const [messages, setMessages] = useState([]); - - const addMessage = useCallback( - (message: string) => { - setMessages((prevMessages) => [ - ...prevMessages, - { sender: "User1", date: new Date(), content: message }, - ]); - }, - [messages] - ); + const { messages, sendMessage } = useMessenger(channel.name); return ( @@ -38,7 +28,7 @@ export function ChatBody({ theme, channel }: ChatBodyProps) { /> - + ); } diff --git a/packages/react-chat/src/components/Chat/ChatMessages.tsx b/packages/react-chat/src/components/Chat/ChatMessages.tsx index c03601a9..3b63a4dd 100644 --- a/packages/react-chat/src/components/Chat/ChatMessages.tsx +++ b/packages/react-chat/src/components/Chat/ChatMessages.tsx @@ -1,8 +1,8 @@ import React, { useEffect, useRef } from "react"; import styled from "styled-components"; +import { ChatMessage } from "../../models/ChatMessage"; import { Theme } from "../../styles/themes"; -import { ChatMessage } from "../models/ChatMessage"; type ChatMessagesProps = { messages: ChatMessage[]; @@ -19,14 +19,16 @@ export function ChatMessages({ messages, theme }: ChatMessagesProps) { return ( - {messages.map((message) => ( - + {messages.map((message, idx) => ( + - {message.sender} + + {message.sender.slice(0, 10)} + - {message.date.toLocaleTimeString()} + {message.date.toLocaleString()} {message.content} diff --git a/packages/react-chat/src/hooks/useMessenger.ts b/packages/react-chat/src/hooks/useMessenger.ts new file mode 100644 index 00000000..5d71ad26 --- /dev/null +++ b/packages/react-chat/src/hooks/useMessenger.ts @@ -0,0 +1,108 @@ +import { StoreCodec } from "js-waku"; +import { useCallback, useEffect, useState } from "react"; +import { Identity, Messenger } from "status-communities/dist/cjs"; + +import { ChatMessage } from "../models/ChatMessage"; + +export function useMessenger(chatId: string) { + const [messenger, setMessenger] = useState(undefined); + const [messages, setMessages] = useState<{ [chatId: string]: ChatMessage[] }>( + {} + ); + + const addNewMessage = useCallback( + (sender: Uint8Array, content: string, date: Date) => { + let signer = "0x"; + sender.forEach((e) => { + signer = signer + e.toString(16); + }); + setMessages((prevMessages) => { + const newMessage = { + sender: signer, + content: content, + date: date, + }; + return { + ...prevMessages, + [chatId]: [...prevMessages[chatId], newMessage], + }; + }); + }, + [chatId] + ); + + useEffect(() => { + const createMessenger = async () => { + const identity = Identity.generate(); + const messenger = await Messenger.create(identity); + await new Promise((resolve) => { + messenger.waku?.libp2p.peerStore.on( + "change:protocols", + ({ protocols }) => { + if (protocols.includes(StoreCodec)) { + resolve(""); + } + } + ); + }); + await messenger.joinChat(chatId); + setMessages((prevMessages) => { + return { ...prevMessages, [chatId]: [] }; + }); + const chat = messenger.chatsById.get(chatId); + const contentTopic = chat?.contentTopic; + + if (contentTopic) { + const messages = await messenger.waku.store.queryHistory( + [contentTopic], + { decryptionKeys: [chat?.symKey] } + ); + console.log(messages); + } + messenger.addObserver((message) => { + addNewMessage( + message.signer ?? new Uint8Array(), + message.chatMessage?.text ?? "", + new Date(message.chatMessage?.proto.timestamp ?? 0) + ); + }, chatId); + setMessenger(messenger); + }; + createMessenger(); + }, []); + + useEffect(() => { + const joinNewChat = async () => { + try { + await messenger?.joinChat(chatId); + setMessages((prevMessages) => { + return { ...prevMessages, [chatId]: [] }; + }); + messenger?.addObserver((message) => { + addNewMessage( + message.signer ?? new Uint8Array(), + message.chatMessage?.text ?? "", + new Date(message.chatMessage?.proto.timestamp ?? 0) + ); + }, chatId); + } catch { + return; + } + }; + joinNewChat(); + }, [chatId]); + + const sendMessage = useCallback( + async (messageText: string) => { + await messenger?.sendMessage(messageText, chatId); + addNewMessage( + messenger?.identity.publicKey ?? new Uint8Array(), + messageText, + new Date() + ); + }, + [chatId, messenger] + ); + + return { messenger, messages: messages?.[chatId] ?? [], sendMessage }; +} diff --git a/packages/react-chat/src/components/models/ChatMessage.ts b/packages/react-chat/src/models/ChatMessage.ts similarity index 100% rename from packages/react-chat/src/components/models/ChatMessage.ts rename to packages/react-chat/src/models/ChatMessage.ts diff --git a/packages/status-communities/src/index.ts b/packages/status-communities/src/index.ts new file mode 100644 index 00000000..9607dd41 --- /dev/null +++ b/packages/status-communities/src/index.ts @@ -0,0 +1,4 @@ +import { Identity } from "./identity"; +import { Messenger } from "./messenger"; + +export { Messenger, Identity };