110 lines
2.7 KiB
JavaScript
Raw Normal View History

2021-07-28 10:18:13 +10:00
import './App.css';
import { Waku, WakuMessage } from 'js-waku';
2021-07-28 12:20:43 +10:00
import * as React from 'react';
2021-07-28 15:12:37 +10:00
import protons from 'protons';
2021-07-28 10:18:13 +10:00
const ContentTopic = `/min-react-js-chat/1/chat/proto`;
2021-07-28 13:21:03 +10:00
2021-07-28 15:12:37 +10:00
const proto = protons(`
message SimpleChatMessage {
2021-07-30 15:19:21 +10:00
uint64 timestamp = 1;
2021-07-28 15:12:37 +10:00
string text = 2;
}
`);
2021-07-28 10:18:13 +10:00
function App() {
2021-07-28 12:20:43 +10:00
const [waku, setWaku] = React.useState(undefined);
2021-07-30 15:19:21 +10:00
const [wakuStatus, setWakuStatus] = React.useState('None');
const [sendCounter, setSendCounter] = React.useState(0);
2021-07-30 15:29:38 +10:00
const [messages, setMessages] = React.useState([]);
2021-07-28 12:20:43 +10:00
React.useEffect(() => {
if (!!waku) return;
2021-07-30 15:19:21 +10:00
if (wakuStatus !== 'None') return;
2021-07-28 12:20:43 +10:00
2021-07-28 12:37:05 +10:00
setWakuStatus('Starting');
2021-07-28 12:20:43 +10:00
Waku.create({ bootstrap: true }).then((waku) => {
2021-07-28 12:20:43 +10:00
setWaku(waku);
2021-07-28 12:37:05 +10:00
setWakuStatus('Connecting');
waku.waitForConnectedPeer().then(() => {
2021-07-28 12:37:05 +10:00
setWakuStatus('Ready');
});
2021-07-28 12:20:43 +10:00
});
2021-07-28 12:37:05 +10:00
}, [waku, wakuStatus]);
2021-07-28 12:20:43 +10:00
2021-07-28 13:07:41 +10:00
// Need to keep the same reference around to add and delete from relay observer
const processIncomingMessage = React.useCallback((wakuMessage) => {
2021-07-28 15:12:37 +10:00
if (!wakuMessage.payload) return;
2021-07-30 15:19:21 +10:00
const { text, timestamp } = proto.SimpleChatMessage.decode(
2021-07-28 15:12:37 +10:00
wakuMessage.payload
);
2021-07-30 15:19:21 +10:00
const time = new Date();
time.setTime(timestamp);
const message = { text, timestamp: time };
setMessages((currMessages) => {
return [message].concat(currMessages);
2021-07-28 15:12:37 +10:00
});
2021-07-28 13:07:41 +10:00
}, []);
React.useEffect(() => {
if (!waku) return;
waku.relay.addObserver(processIncomingMessage, [ContentTopic]);
return function cleanUp() {
waku.relay.deleteObserver(processIncomingMessage, [ContentTopic]);
};
}, [waku, wakuStatus, processIncomingMessage]);
2021-07-28 12:45:41 +10:00
const sendMessageOnClick = () => {
if (wakuStatus !== 'Ready') return;
2021-08-02 12:14:30 +10:00
sendMessage(`Here is message #${sendCounter}`, new Date(), waku).then(() =>
2021-07-28 12:45:41 +10:00
console.log('Message sent')
);
2021-07-30 15:19:21 +10:00
setSendCounter(sendCounter + 1);
2021-07-28 12:45:41 +10:00
};
2021-07-28 10:18:13 +10:00
return (
<div className="App">
<header className="App-header">
2021-07-28 12:20:43 +10:00
<p>{wakuStatus}</p>
2021-07-28 12:45:41 +10:00
<button onClick={sendMessageOnClick} disabled={wakuStatus !== 'Ready'}>
Send Message
</button>
2021-07-28 13:21:03 +10:00
<ul>
2021-07-30 15:19:21 +10:00
{messages.map((msg) => {
2021-07-28 15:12:37 +10:00
return (
<li>
<p>
{msg.timestamp.toString()}: {msg.text}
</p>
</li>
);
2021-07-28 13:21:03 +10:00
})}
</ul>
2021-07-28 10:18:13 +10:00
</header>
</div>
);
}
export default App;
2021-07-28 12:37:05 +10:00
function sendMessage(message, timestamp, waku) {
2021-07-30 15:19:21 +10:00
const time = timestamp.getTime();
2021-07-28 15:12:37 +10:00
const payload = proto.SimpleChatMessage.encode({
2021-07-30 15:19:21 +10:00
timestamp: time,
2021-07-28 15:12:37 +10:00
text: message,
});
return WakuMessage.fromBytes(payload, ContentTopic).then((wakuMessage) =>
waku.relay.send(wakuMessage)
);
2021-07-28 12:45:41 +10:00
}