104 lines
2.7 KiB
TypeScript
Raw Normal View History

import { WakuMessage } from 'js-waku';
import { ChatContentTopic } from './App';
import ChatList from './ChatList';
2021-04-19 13:33:23 +10:00
import MessageInput from './MessageInput';
import { useWaku } from './WakuContext';
import { TitleBar } from '@livechat/ui-kit';
import { Message } from './Message';
import { ChatMessage } from './chat_message';
import { useEffect, useState } from 'react';
import PeerId from 'peer-id';
2021-04-14 15:13:55 +10:00
interface Props {
messages: Message[];
2021-04-22 16:12:28 +10:00
commandHandler: (cmd: string) => void;
2021-04-23 14:43:39 +10:00
nick: string;
2021-04-14 15:13:55 +10:00
}
2021-04-22 17:03:33 +10:00
export default function Room(props: Props) {
const { waku } = useWaku();
2021-04-19 12:55:33 +10:00
const [peers, setPeers] = useState<PeerId[]>([]);
const [storePeers, setStorePeers] = useState(0);
const [relayPeers, setRelayPeers] = useState(0);
useEffect(() => {
// Add a peer to the list every time a connection happen to ensure the stats update correctly
if (!waku) return;
const addPeer = (event: { peerId: PeerId }) => {
setPeers((peers) => {
return [...peers, event.peerId];
});
};
waku.libp2p.peerStore.on('change:protocols', addPeer);
return () => {
waku.libp2p.connectionManager.removeListener('change:protocols', addPeer);
};
}, [waku]);
useEffect(() => {
if (!waku) return;
setRelayPeers(waku.relay.getPeers().size);
(async () => {
let counter = 0;
// eslint-disable-next-line @typescript-eslint/no-unused-vars
for await (const _peer of waku.store.peers) {
counter++;
}
setStorePeers(counter);
})();
}, [waku, peers]);
2021-07-15 14:37:30 +10:00
2021-04-22 17:03:33 +10:00
return (
<div
className="chat-container"
2021-04-28 10:46:44 +10:00
style={{ height: '98vh', display: 'flex', flexDirection: 'column' }}
>
2021-07-15 14:37:30 +10:00
<TitleBar
2022-01-06 17:39:08 +11:00
leftIcons={[`Peers: ${relayPeers} relay ${storePeers} store.`]}
2021-07-15 14:37:30 +10:00
title="Waku v2 chat app"
/>
<ChatList messages={props.messages} />
<MessageInput
sendMessage={
waku
? async (messageToSend) => {
return handleMessage(
messageToSend,
props.nick,
props.commandHandler,
waku.relay.send.bind(waku.relay)
);
}
: undefined
}
/>
</div>
2021-04-22 17:03:33 +10:00
);
2021-04-19 14:57:38 +10:00
}
2021-04-14 15:13:55 +10:00
2021-04-27 13:36:25 +10:00
async function handleMessage(
message: string,
nick: string,
commandHandler: (cmd: string) => void,
messageSender: (msg: WakuMessage) => Promise<void>
) {
if (message.startsWith('/')) {
commandHandler(message);
} else {
const timestamp = new Date();
const chatMessage = ChatMessage.fromUtf8String(timestamp, nick, message);
const wakuMsg = await WakuMessage.fromBytes(
chatMessage.encode(),
ChatContentTopic,
{ timestamp }
);
2021-04-27 13:36:25 +10:00
return messageSender(wakuMsg);
}
}