js-waku/web-chat/src/App.tsx

114 lines
3.2 KiB
TypeScript
Raw Normal View History

2021-04-21 05:51:52 +00:00
import { multiaddr } from 'multiaddr';
import PeerId from 'peer-id';
2021-04-21 06:11:07 +00:00
import React, { useEffect, useState } from 'react';
2021-04-14 04:44:12 +00:00
import './App.css';
2021-04-21 05:51:52 +00:00
import { ChatMessage } from 'waku-chat/chat_message';
import { WakuMessage } from 'waku/waku_message';
import { RelayDefaultTopic } from 'waku/waku_relay';
import handleCommand from './command';
2021-04-16 01:32:00 +00:00
import Room from './Room';
2021-04-21 05:51:52 +00:00
import Waku from 'waku/waku';
2021-04-19 01:34:13 +00:00
import { WakuContext } from './WakuContext';
import { generate } from 'server-name-generator';
2021-04-14 04:44:12 +00:00
2021-04-21 05:51:52 +00:00
export const ChatContentTopic = 'dingpu';
export default function App() {
2021-04-23 04:40:28 +00:00
let [stateMessages, setMessages] = useState<ChatMessage[]>([]);
let [stateWaku, setWaku] = useState<Waku | undefined>(undefined);
let [nick, setNick] = useState<string>(generate());
2021-04-19 01:34:13 +00:00
2021-04-21 06:11:07 +00:00
useEffect(() => {
const handleNewMessages = (event: { data: Uint8Array }) => {
const chatMsg = decodeWakuMessage(event.data);
if (chatMsg) {
copyAndReplace([chatMsg], stateMessages, setMessages);
}
};
2021-04-23 04:40:28 +00:00
if (!stateWaku) {
2021-04-27 01:05:35 +00:00
initWaku(setWaku)
2021-04-21 06:11:07 +00:00
.then(() => console.log('Waku init done'))
.catch((e) => console.log('Waku init failed ', e));
2021-04-22 00:58:56 +00:00
} else {
2021-04-23 04:40:28 +00:00
stateWaku.libp2p.pubsub.on(RelayDefaultTopic, handleNewMessages);
// To clean up listener when component unmounts
return () => {
2021-04-23 04:40:28 +00:00
stateWaku?.libp2p.pubsub.removeListener(
2021-04-22 07:03:33 +00:00
RelayDefaultTopic,
handleNewMessages
);
};
2021-04-21 06:11:07 +00:00
}
2021-04-27 01:05:35 +00:00
}, [stateWaku, stateMessages]);
2021-04-21 05:51:52 +00:00
2021-04-21 06:11:07 +00:00
return (
2021-04-27 04:39:34 +00:00
<div
className="chat-app"
style={{ height: '100vh', width: '100vw', overflow: 'hidden' }}
>
<WakuContext.Provider value={{ waku: stateWaku }}>
<Room
nick={nick}
lines={stateMessages}
commandHandler={(input: string) => {
const { command, response } = handleCommand(
input,
stateWaku,
setNick
);
const commandMessages = response.map((msg) => {
return new ChatMessage(new Date(), command, msg);
});
copyAndReplace(commandMessages, stateMessages, setMessages);
}}
/>
</WakuContext.Provider>
2021-04-21 06:11:07 +00:00
</div>
);
2021-04-14 04:44:12 +00:00
}
2021-04-27 01:05:35 +00:00
async function initWaku(setter: (waku: Waku) => void) {
try {
const waku = await Waku.create({
config: {
pubsub: {
enabled: true,
emitSelf: true,
},
},
});
setter(waku);
// FIXME: Connect to a go-waku instance by default, temporary hack until
// we have a go-waku instance in the fleet
waku.libp2p.peerStore.addressBook.add(
PeerId.createFromB58String(
'16Uiu2HAmVVi6Q4j7MAKVibquW8aA27UNrA4Q8Wkz9EetGViu8ZF1'
),
[multiaddr('/ip4/134.209.113.86/tcp/9001/ws')]
);
} catch (e) {
console.log('Issue starting waku ', e);
}
}
function decodeWakuMessage(data: Uint8Array): null | ChatMessage {
const wakuMsg = WakuMessage.decode(data);
if (!wakuMsg.payload) {
return null;
}
return ChatMessage.decode(wakuMsg.payload);
}
function copyAndReplace<T>(
newValues: Array<T>,
currentValues: Array<T>,
setter: (val: Array<T>) => void
) {
const copy = currentValues.slice();
setter(copy.concat(newValues));
}