114 lines
2.5 KiB
JavaScript
Raw Normal View History

2021-08-03 12:31:26 +10:00
import './App.css';
import { Waku } from 'js-waku';
2021-08-03 12:31:26 +10:00
import * as React from 'react';
import protons from 'protons';
2021-08-03 12:31:26 +10:00
const ContentTopic = '/toy-chat/2/huilong/proto';
2021-08-03 12:31:26 +10:00
const proto = protons(`
message ChatMessage {
uint64 timestamp = 1;
string nick = 2;
bytes text = 3;
}
`);
2021-08-03 12:31:26 +10:00
function App() {
const [waku, setWaku] = React.useState(undefined);
const [wakuStatus, setWakuStatus] = React.useState('None');
const [messages, setMessages] = React.useState([]);
2021-08-03 12:31:26 +10:00
React.useEffect(() => {
if (wakuStatus !== 'None') return;
setWakuStatus('Starting');
Waku.create({ bootstrap: true }).then((waku) => {
2021-08-03 12:31:26 +10:00
setWaku(waku);
setWakuStatus('Connecting');
});
}, [waku, wakuStatus]);
React.useEffect(() => {
if (!waku) return;
2021-09-03 17:04:25 +10:00
// We do not handle disconnection/re-connection in this example
if (wakuStatus === 'Connected') return;
waku.waitForConnectedPeer().then(() => {
// We are now connected to a store node
setWakuStatus('Connected');
});
}, [waku, wakuStatus]);
React.useEffect(() => {
if (wakuStatus !== 'Connected') return;
const processMessages = (retrievedMessages) => {
const messages = retrievedMessages.map(decodeMessage).filter(Boolean);
setMessages((currentMessages) => {
return currentMessages.concat(messages.reverse());
});
};
2021-09-03 17:06:13 +10:00
waku.store
.queryHistory([ContentTopic], { callback: processMessages })
2021-09-03 17:06:13 +10:00
.catch((e) => {
console.log('Failed to retrieve messages', e);
});
}, [waku, wakuStatus]);
2021-08-03 12:31:26 +10:00
return (
<div className="App">
<header className="App-header">
<h2>{wakuStatus}</h2>
<h3>Messages</h3>
2021-08-03 12:31:26 +10:00
<ul>
<Messages messages={messages} />
2021-08-03 12:31:26 +10:00
</ul>
</header>
</div>
);
}
export default App;
function decodeMessage(wakuMessage) {
if (!wakuMessage.payload) return;
const { timestamp, nick, text } = proto.ChatMessage.decode(
wakuMessage.payload
);
2021-08-05 16:01:25 +10:00
if (!timestamp || !text || !nick) return;
const time = new Date();
time.setTime(timestamp);
const utf8Text = Buffer.from(text).toString('utf-8');
return { text: utf8Text, timestamp: time, nick };
}
function Messages(props) {
return props.messages.map(({ text, timestamp, nick }) => {
return (
<li>
({formatDate(timestamp)}) {nick}: {text}
</li>
);
});
}
2021-08-03 12:31:26 +10:00
function formatDate(timestamp) {
return timestamp.toLocaleString([], {
month: 'short',
day: 'numeric',
hour: 'numeric',
minute: '2-digit',
second: '2-digit',
hour12: false,
});
2021-08-03 12:31:26 +10:00
}