112 lines
3.1 KiB
JavaScript
Raw Normal View History

import { Waku, WakuMessage } from "js-waku";
import * as React from "react";
2022-04-01 16:07:53 +11:00
import protobuf from "protobufjs";
2022-01-07 17:12:36 +11:00
const ContentTopic = `/relay-reactjs-chat/1/chat/proto`;
2022-04-01 16:07:53 +11:00
const SimpleChatMessage = new protobuf.Type("SimpleChatMessage")
.add(new protobuf.Field("timestamp", 1, "uint64"))
.add(new protobuf.Field("text", 2, "string"));
function App() {
const [waku, setWaku] = React.useState(undefined);
const [wakuStatus, setWakuStatus] = React.useState("None");
2022-01-07 17:12:36 +11:00
// Using a counter just for the messages to be different
const [sendCounter, setSendCounter] = React.useState(0);
2022-01-07 17:15:34 +11:00
const [messages, setMessages] = React.useState([]);
React.useEffect(() => {
if (!!waku) return;
if (wakuStatus !== "None") return;
setWakuStatus("Starting");
2022-01-24 18:19:11 +11:00
Waku.create({ bootstrap: { default: true } }).then((waku) => {
setWaku(waku);
setWakuStatus("Connecting");
waku.waitForRemotePeer().then(() => {
setWakuStatus("Ready");
2022-01-07 17:06:39 +11:00
});
});
}, [waku, wakuStatus]);
2022-01-07 17:14:14 +11:00
const processIncomingMessage = React.useCallback((wakuMessage) => {
if (!wakuMessage.payload) return;
2022-04-01 16:07:53 +11:00
const { text, timestamp } = SimpleChatMessage.decode(wakuMessage.payload);
2022-01-07 17:15:34 +11:00
2022-01-07 17:14:14 +11:00
const time = new Date();
time.setTime(timestamp);
2022-01-07 17:15:34 +11:00
const message = { text, timestamp: time };
2022-01-07 17:14:14 +11:00
2022-01-07 17:15:34 +11:00
setMessages((messages) => {
return [message].concat(messages);
});
2022-01-07 17:14:14 +11:00
}, []);
React.useEffect(() => {
if (!waku) return;
// Pass the content topic to only process messages related to your dApp
waku.relay.addObserver(processIncomingMessage, [ContentTopic]);
// `cleanUp` is called when the component is unmounted, see ReactJS doc.
return function cleanUp() {
waku.relay.deleteObserver(processIncomingMessage, [ContentTopic]);
};
}, [waku, wakuStatus, processIncomingMessage]);
2022-01-07 17:12:36 +11:00
const sendMessageOnClick = () => {
// Check Waku is started and connected first.
if (wakuStatus !== "Ready") return;
2022-01-07 17:12:36 +11:00
sendMessage(`Here is message #${sendCounter}`, waku, new Date()).then(() =>
console.log("Message sent")
2022-01-07 17:12:36 +11:00
);
// For demonstration purposes.
setSendCounter(sendCounter + 1);
};
return (
2022-01-07 17:12:36 +11:00
<div className="App">
<header className="App-header">
<p>{wakuStatus}</p>
<button onClick={sendMessageOnClick} disabled={wakuStatus !== "Ready"}>
2022-01-07 17:12:36 +11:00
Send Message
</button>
2022-01-07 17:15:34 +11:00
<ul>
{messages.map((msg) => {
return (
<li key={msg.timestamp.valueOf()}>
2022-01-07 17:15:34 +11:00
<p>
{msg.timestamp.toString()}: {msg.text}
</p>
</li>
);
})}
</ul>
</header>
</div>
);
}
2022-01-07 17:12:36 +11:00
function sendMessage(message, waku, timestamp) {
const time = timestamp.getTime();
// Encode to protobuf
2022-04-01 16:07:53 +11:00
const protoMsg = SimpleChatMessage.create({
2022-01-07 17:12:36 +11:00
timestamp: time,
2022-01-24 18:19:11 +11:00
text: message,
2022-01-07 17:12:36 +11:00
});
2022-04-01 16:07:53 +11:00
const payload = SimpleChatMessage.encode(protoMsg).finish();
2022-01-07 17:12:36 +11:00
// Wrap in a Waku Message
return WakuMessage.fromBytes(payload, ContentTopic).then((wakuMessage) =>
// Send over Waku Relay
waku.relay.send(wakuMessage)
);
}
export default App;