2023-02-23 11:45:31 +01:00
|
|
|
import type {
|
|
|
|
|
IDecodedMessage as WakuMessage,
|
|
|
|
|
LightNode,
|
|
|
|
|
} from "@waku/interfaces";
|
2022-06-17 10:48:15 +10:00
|
|
|
import ChatList from "./ChatList";
|
|
|
|
|
import MessageInput from "./MessageInput";
|
2023-02-23 14:27:00 +01:00
|
|
|
import { useWaku, useContentPair } from "@waku/react";
|
2022-06-17 10:48:15 +10:00
|
|
|
import { TitleBar } from "@livechat/ui-kit";
|
|
|
|
|
import { Message } from "./Message";
|
|
|
|
|
import { ChatMessage } from "./chat_message";
|
|
|
|
|
import { useEffect, useState } from "react";
|
2023-02-01 12:38:24 +05:30
|
|
|
import { Encoder } from "@waku/core/lib/message/version_0";
|
2022-06-17 10:48:15 +10:00
|
|
|
|
|
|
|
|
interface Props {
|
|
|
|
|
messages: Message[];
|
|
|
|
|
commandHandler: (cmd: string) => void;
|
|
|
|
|
nick: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export default function Room(props: Props) {
|
2023-02-23 11:45:31 +01:00
|
|
|
const { node } = useWaku<LightNode>();
|
2023-02-23 14:27:00 +01:00
|
|
|
const { encoder } = useContentPair();
|
2022-06-17 10:48:15 +10:00
|
|
|
|
|
|
|
|
const [storePeers, setStorePeers] = useState(0);
|
2022-09-02 14:08:44 +10:00
|
|
|
const [filterPeers, setFilterPeers] = useState(0);
|
|
|
|
|
const [lightPushPeers, setLightPushPeers] = useState(0);
|
2022-06-17 10:48:15 +10:00
|
|
|
|
2023-01-30 20:41:25 +05:30
|
|
|
const [bootstrapPeers, setBootstrapPeers] = useState(new Set<string>());
|
|
|
|
|
const [peerExchangePeers, setPeerExchangePeers] = useState(new Set<string>());
|
|
|
|
|
|
2022-06-17 10:48:15 +10:00
|
|
|
useEffect(() => {
|
2023-02-23 11:45:31 +01:00
|
|
|
if (!node) return;
|
2022-06-17 10:48:15 +10:00
|
|
|
|
|
|
|
|
// Update store peer when new peer connected & identified
|
2023-02-23 11:45:31 +01:00
|
|
|
node.libp2p.peerStore.addEventListener("change:protocols", async (evt) => {
|
2023-01-30 20:41:25 +05:30
|
|
|
const { peerId } = evt.detail;
|
2023-02-23 11:45:31 +01:00
|
|
|
const tags = (await node.libp2p.peerStore.getTags(peerId)).map(
|
2023-01-30 20:41:25 +05:30
|
|
|
(t) => t.name
|
|
|
|
|
);
|
|
|
|
|
if (tags.includes("peer-exchange")) {
|
|
|
|
|
setPeerExchangePeers((peers) => new Set(peers).add(peerId.toString()));
|
|
|
|
|
} else {
|
|
|
|
|
setBootstrapPeers((peers) => new Set(peers).add(peerId.toString()));
|
|
|
|
|
}
|
|
|
|
|
|
2023-02-23 11:45:31 +01:00
|
|
|
const storePeers = await node.store.peers();
|
2022-09-02 14:08:44 +10:00
|
|
|
setStorePeers(storePeers.length);
|
|
|
|
|
|
2023-02-23 11:45:31 +01:00
|
|
|
const filterPeers = await node.filter.peers();
|
2022-09-02 14:08:44 +10:00
|
|
|
setFilterPeers(filterPeers.length);
|
|
|
|
|
|
2023-02-23 11:45:31 +01:00
|
|
|
const lightPushPeers = await node.lightPush.peers();
|
2022-09-02 14:08:44 +10:00
|
|
|
setLightPushPeers(lightPushPeers.length);
|
2022-06-17 10:48:15 +10:00
|
|
|
});
|
2023-02-23 11:45:31 +01:00
|
|
|
}, [node]);
|
2022-06-17 10:48:15 +10:00
|
|
|
|
2023-01-30 20:41:25 +05:30
|
|
|
useEffect(() => {
|
|
|
|
|
console.log("Bootstrap Peers:");
|
|
|
|
|
console.table(bootstrapPeers);
|
|
|
|
|
|
|
|
|
|
console.log("Peer Exchange Peers:");
|
|
|
|
|
console.table(peerExchangePeers);
|
|
|
|
|
}, [bootstrapPeers, peerExchangePeers]);
|
|
|
|
|
|
2022-06-17 10:48:15 +10:00
|
|
|
return (
|
|
|
|
|
<div
|
|
|
|
|
className="chat-container"
|
|
|
|
|
style={{ height: "98vh", display: "flex", flexDirection: "column" }}
|
|
|
|
|
>
|
|
|
|
|
<TitleBar
|
2022-09-02 14:08:44 +10:00
|
|
|
leftIcons={[
|
|
|
|
|
`Peers: ${lightPushPeers} light push, ${filterPeers} filter, ${storePeers} store.`,
|
|
|
|
|
]}
|
2023-01-30 20:41:25 +05:30
|
|
|
rightIcons={[
|
|
|
|
|
`Bootstrap (DNS Discovery): ${bootstrapPeers.size}, Peer exchange: ${peerExchangePeers.size}. `,
|
|
|
|
|
"View console for more details.",
|
|
|
|
|
]}
|
2022-06-17 10:48:15 +10:00
|
|
|
title="Waku v2 chat app"
|
|
|
|
|
/>
|
|
|
|
|
<ChatList messages={props.messages} />
|
|
|
|
|
<MessageInput
|
|
|
|
|
sendMessage={
|
2023-02-23 11:45:31 +01:00
|
|
|
node
|
2022-06-17 10:48:15 +10:00
|
|
|
? async (messageToSend) => {
|
|
|
|
|
return handleMessage(
|
|
|
|
|
messageToSend,
|
|
|
|
|
props.nick,
|
|
|
|
|
props.commandHandler,
|
2022-09-21 16:36:41 +10:00
|
|
|
async (msg) => {
|
2023-02-23 14:27:00 +01:00
|
|
|
await node.lightPush.push(encoder as Encoder, msg);
|
2022-09-21 16:36:41 +10:00
|
|
|
}
|
2022-06-17 10:48:15 +10:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
: undefined
|
|
|
|
|
}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function handleMessage(
|
|
|
|
|
message: string,
|
|
|
|
|
nick: string,
|
|
|
|
|
commandHandler: (cmd: string) => void,
|
2022-10-28 11:48:19 +11:00
|
|
|
sender: (wakuMsg: Partial<WakuMessage>) => Promise<void>
|
2022-06-17 10:48:15 +10:00
|
|
|
) {
|
|
|
|
|
if (message.startsWith("/")) {
|
|
|
|
|
commandHandler(message);
|
|
|
|
|
} else {
|
|
|
|
|
const timestamp = new Date();
|
|
|
|
|
const chatMessage = ChatMessage.fromUtf8String(timestamp, nick, message);
|
2022-09-21 16:36:41 +10:00
|
|
|
const payload = chatMessage.encode();
|
|
|
|
|
|
|
|
|
|
await sender({ payload, timestamp });
|
2022-06-17 10:48:15 +10:00
|
|
|
}
|
|
|
|
|
}
|