Use messenger for messages (#16)

This commit is contained in:
Szymon Szlachtowicz 2021-09-28 15:17:08 +02:00 committed by GitHub
parent c5258f8068
commit 9275f9cb0f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 123 additions and 19 deletions

View File

@ -1,10 +1,10 @@
import React, { useCallback, useState } from "react"; import React from "react";
import styled from "styled-components"; import styled from "styled-components";
import { ChannelData } from "../../helpers/channelsMock"; import { ChannelData } from "../../helpers/channelsMock";
import { useMessenger } from "../../hooks/useMessenger";
import { Theme } from "../../styles/themes"; import { Theme } from "../../styles/themes";
import { Channel } from "../Channels"; import { Channel } from "../Channels";
import { ChatMessage } from "../models/ChatMessage";
import { ChatInput } from "./ChatInput"; import { ChatInput } from "./ChatInput";
import { ChatMessages } from "./ChatMessages"; import { ChatMessages } from "./ChatMessages";
@ -15,17 +15,7 @@ interface ChatBodyProps {
} }
export function ChatBody({ theme, channel }: ChatBodyProps) { export function ChatBody({ theme, channel }: ChatBodyProps) {
const [messages, setMessages] = useState<ChatMessage[]>([]); const { messages, sendMessage } = useMessenger(channel.name);
const addMessage = useCallback(
(message: string) => {
setMessages((prevMessages) => [
...prevMessages,
{ sender: "User1", date: new Date(), content: message },
]);
},
[messages]
);
return ( return (
<ChatBodyWrapper theme={theme}> <ChatBodyWrapper theme={theme}>
@ -38,7 +28,7 @@ export function ChatBody({ theme, channel }: ChatBodyProps) {
/> />
</ChannelWrapper> </ChannelWrapper>
<ChatMessages messages={messages} theme={theme} /> <ChatMessages messages={messages} theme={theme} />
<ChatInput theme={theme} addMessage={addMessage} /> <ChatInput theme={theme} addMessage={sendMessage} />
</ChatBodyWrapper> </ChatBodyWrapper>
); );
} }

View File

@ -1,8 +1,8 @@
import React, { useEffect, useRef } from "react"; import React, { useEffect, useRef } from "react";
import styled from "styled-components"; import styled from "styled-components";
import { ChatMessage } from "../../models/ChatMessage";
import { Theme } from "../../styles/themes"; import { Theme } from "../../styles/themes";
import { ChatMessage } from "../models/ChatMessage";
type ChatMessagesProps = { type ChatMessagesProps = {
messages: ChatMessage[]; messages: ChatMessage[];
@ -19,14 +19,16 @@ export function ChatMessages({ messages, theme }: ChatMessagesProps) {
return ( return (
<MessagesWrapper ref={ref}> <MessagesWrapper ref={ref}>
{messages.map((message) => ( {messages.map((message, idx) => (
<MessageWrapper key={message.date.toDateString()}> <MessageWrapper key={idx}>
<Icon /> <Icon />
<ContentWrapper> <ContentWrapper>
<MessageHeaderWrapper> <MessageHeaderWrapper>
<UserNameWrapper theme={theme}>{message.sender}</UserNameWrapper> <UserNameWrapper theme={theme}>
{message.sender.slice(0, 10)}
</UserNameWrapper>
<TimeWrapper theme={theme}> <TimeWrapper theme={theme}>
{message.date.toLocaleTimeString()} {message.date.toLocaleString()}
</TimeWrapper> </TimeWrapper>
</MessageHeaderWrapper> </MessageHeaderWrapper>
<MessageText theme={theme}>{message.content}</MessageText> <MessageText theme={theme}>{message.content}</MessageText>

View File

@ -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<Messenger | undefined>(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 };
}

View File

@ -0,0 +1,4 @@
import { Identity } from "./identity";
import { Messenger } from "./messenger";
export { Messenger, Identity };