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

151 lines
4.5 KiB
TypeScript
Raw Normal View History

2021-04-19 04:54:39 +00:00
import { Paper } from '@material-ui/core';
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';
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';
2021-04-14 04:44:12 +00:00
2021-04-21 05:51:52 +00:00
export const ChatContentTopic = 'dingpu';
2021-04-14 05:23:00 +00:00
interface State {
2021-04-22 00:58:56 +00:00
messages: ChatMessage[],
2021-04-21 05:51:52 +00:00
waku?: Waku
2021-04-14 05:23:00 +00:00
}
export default function App() {
2021-04-21 06:11:07 +00:00
let [state, setState] = useState<State>({ messages: [] });
2021-04-19 01:34:13 +00:00
2021-04-14 05:23:00 +00:00
2021-04-21 06:11:07 +00:00
useEffect(() => {
async function initWaku() {
try {
2021-04-22 06:50:37 +00:00
const waku = await Waku.create({
config: {
pubsub: {
enabled: true,
emitSelf: true
}
}
});
2021-04-19 00:36:37 +00:00
2021-04-22 00:58:56 +00:00
setState(({ messages }) => {
return { waku, messages };
2021-04-21 06:11:07 +00:00
});
2021-04-21 05:51:52 +00:00
// 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')]);
2021-04-21 06:11:07 +00:00
} catch (e) {
console.log('Issue starting waku ', e);
}
}
2021-04-19 01:34:13 +00:00
const handleNewMessages = (event: { data: Uint8Array }) => {
const wakuMsg = WakuMessage.decode(event.data);
if (wakuMsg.payload) {
const chatMsg = ChatMessage.decode(wakuMsg.payload);
const messages = state.messages.slice();
messages.push(chatMsg);
console.log('setState on ', messages);
setState({ messages, waku: state.waku });
}
};
2021-04-21 06:11:07 +00:00
if (!state.waku) {
initWaku()
.then(() => console.log('Waku init done'))
.catch((e) => console.log('Waku init failed ', e));
2021-04-22 00:58:56 +00:00
} else {
state.waku.libp2p.pubsub.on(RelayDefaultTopic, handleNewMessages);
// To clean up listener when component unmounts
return () => {
state.waku?.libp2p.pubsub.removeListener(RelayDefaultTopic, handleNewMessages);
};
2021-04-21 06:11:07 +00:00
}
});
2021-04-21 05:51:52 +00:00
2021-04-22 06:50:37 +00:00
const commandHandler = (input: string) => {
let commandResponses: string[] = [];
const args = input.split(' ');
const cmd = args.shift()!;
const waku = state.waku;
if (!waku) {
commandResponses.push('Waku is not yet initialized');
} else {
switch (cmd) {
case '/help':
commandResponses.push('/connect <Multiaddr>: connect to the given peer');
commandResponses.push('/help: Display this help');
break;
case '/connect':
const peer = args.shift();
if (!peer) {
commandResponses.push('No peer provided');
} else {
try {
const peerMultiaddr = multiaddr(peer);
const peerId = peerMultiaddr.getPeerId();
if (!peerId) {
commandResponses.push('Peer Id needed to dial');
} else {
waku.libp2p.peerStore.addressBook.add(
PeerId.createFromB58String(peerId),
[peerMultiaddr]);
}
} catch (e) {
commandResponses.push('Invalid multaddr: ' + e);
}
}
break;
case '/peers':
waku.libp2p.peerStore.peers.forEach((peer, peerId) => {
commandResponses.push(peerId + ":")
let addresses = " addresses: ["
peer.addresses.forEach(({multiaddr}) => {
addresses += " " + multiaddr.toString() + ",";
})
addresses = addresses.replace(/,$/,"");
addresses += "]";
commandResponses.push(addresses);
let protos = " protos: [";
protos += peer.protocols;
protos+= "]"
commandResponses.push(protos)
})
break;
default:
commandResponses.push('Unknown Command');
}
2021-04-22 06:12:28 +00:00
2021-04-22 06:50:37 +00:00
}
setState(({ waku, messages }) => {
commandResponses.forEach((res) => {
messages.push(new ChatMessage(new Date(), cmd, res));
});
return { waku, messages };
});
};
2021-04-22 06:12:28 +00:00
2021-04-21 06:11:07 +00:00
return (
<div className='App'>
<div className='chat-room'>
<WakuContext.Provider value={{ waku: state.waku }}>
<Paper>
2021-04-22 06:50:37 +00:00
<Room lines={state.messages} commandHandler={commandHandler} />
2021-04-21 06:11:07 +00:00
</Paper>
</WakuContext.Provider>
2021-04-14 05:13:55 +00:00
</div>
2021-04-21 06:11:07 +00:00
</div>
);
2021-04-14 04:44:12 +00:00
}