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-22 00:39:05 +00:00
|
|
|
export default function App() {
|
2021-04-23 04:40:28 +00:00
|
|
|
let [stateMessages, setMessages] = useState<ChatMessage[]>([]);
|
|
|
|
let [stateWaku, setWaku] = useState<Waku | undefined>(undefined);
|
2021-04-23 04:43:39 +00:00
|
|
|
let [nick, setNick] = useState<string>('web-chat');
|
2021-04-19 01:34:13 +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,
|
2021-04-22 07:03:33 +00:00
|
|
|
emitSelf: true,
|
|
|
|
},
|
|
|
|
},
|
2021-04-22 06:50:37 +00:00
|
|
|
});
|
2021-04-19 00:36:37 +00:00
|
|
|
|
2021-04-23 04:40:28 +00:00
|
|
|
setWaku(waku);
|
2021-04-21 05:51:52 +00:00
|
|
|
|
2021-04-22 05:43:21 +00:00
|
|
|
// FIXME: Connect to a go-waku instance by default, temporary hack until
|
|
|
|
// we have a go-waku instance in the fleet
|
2021-04-22 00:39:05 +00:00
|
|
|
waku.libp2p.peerStore.addressBook.add(
|
2021-04-22 07:03:33 +00:00
|
|
|
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
|
|
|
|
2021-04-22 01:09:10 +00:00
|
|
|
const handleNewMessages = (event: { data: Uint8Array }) => {
|
|
|
|
const wakuMsg = WakuMessage.decode(event.data);
|
|
|
|
if (wakuMsg.payload) {
|
|
|
|
const chatMsg = ChatMessage.decode(wakuMsg.payload);
|
2021-04-23 04:40:28 +00:00
|
|
|
const messages = stateMessages.slice();
|
2021-04-22 01:09:10 +00:00
|
|
|
messages.push(chatMsg);
|
|
|
|
console.log('setState on ', messages);
|
2021-04-23 04:40:28 +00:00
|
|
|
setMessages(messages);
|
2021-04-22 01:09:10 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2021-04-23 04:40:28 +00:00
|
|
|
if (!stateWaku) {
|
2021-04-21 06:11:07 +00:00
|
|
|
initWaku()
|
|
|
|
.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);
|
2021-04-22 01:09:10 +00:00
|
|
|
|
|
|
|
// 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-22 01:09:10 +00:00
|
|
|
};
|
2021-04-21 06:11:07 +00:00
|
|
|
}
|
2021-04-22 00:39:05 +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()!;
|
2021-04-23 04:40:28 +00:00
|
|
|
if (!stateWaku) {
|
2021-04-22 06:50:37 +00:00
|
|
|
commandResponses.push('Waku is not yet initialized');
|
|
|
|
} else {
|
|
|
|
switch (cmd) {
|
|
|
|
case '/help':
|
2021-04-23 04:43:39 +00:00
|
|
|
commandResponses.push('/nick <nickname>: set a new nickname');
|
2021-04-23 04:56:18 +00:00
|
|
|
commandResponses.push('/info: some information about the node');
|
2021-04-22 07:03:33 +00:00
|
|
|
commandResponses.push(
|
|
|
|
'/connect <Multiaddr>: connect to the given peer'
|
|
|
|
);
|
2021-04-22 06:50:37 +00:00
|
|
|
commandResponses.push('/help: Display this help');
|
|
|
|
break;
|
2021-04-23 04:43:39 +00:00
|
|
|
case '/nick':
|
|
|
|
const arg = args.shift();
|
|
|
|
if (!arg) {
|
|
|
|
commandResponses.push('No nick provided');
|
|
|
|
} else {
|
|
|
|
setNick(arg);
|
|
|
|
commandResponses.push(`New nick: ${arg}`);
|
|
|
|
}
|
|
|
|
break;
|
2021-04-23 04:56:18 +00:00
|
|
|
case '/info':
|
|
|
|
if (!stateWaku) {
|
|
|
|
commandResponses.push(`Waku node is starting`);
|
|
|
|
} else {
|
|
|
|
commandResponses.push(
|
|
|
|
`PeerId: ${stateWaku.libp2p.peerId.toB58String()}`
|
|
|
|
);
|
|
|
|
}
|
|
|
|
break;
|
2021-04-22 06:50:37 +00:00
|
|
|
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 {
|
2021-04-23 04:40:28 +00:00
|
|
|
stateWaku.libp2p.peerStore.addressBook.add(
|
2021-04-22 06:50:37 +00:00
|
|
|
PeerId.createFromB58String(peerId),
|
2021-04-22 07:03:33 +00:00
|
|
|
[peerMultiaddr]
|
|
|
|
);
|
2021-04-22 06:50:37 +00:00
|
|
|
}
|
|
|
|
} catch (e) {
|
2021-04-23 05:21:51 +00:00
|
|
|
commandResponses.push('Invalid multiaddr: ' + e);
|
2021-04-22 06:50:37 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case '/peers':
|
2021-04-23 04:40:28 +00:00
|
|
|
stateWaku.libp2p.peerStore.peers.forEach((peer, peerId) => {
|
2021-04-22 07:03:33 +00:00
|
|
|
commandResponses.push(peerId + ':');
|
|
|
|
let addresses = ' addresses: [';
|
|
|
|
peer.addresses.forEach(({ multiaddr }) => {
|
|
|
|
addresses += ' ' + multiaddr.toString() + ',';
|
|
|
|
});
|
|
|
|
addresses = addresses.replace(/,$/, '');
|
|
|
|
addresses += ']';
|
2021-04-22 06:50:37 +00:00
|
|
|
commandResponses.push(addresses);
|
2021-04-23 05:21:51 +00:00
|
|
|
let protocols = ' protocols: [';
|
|
|
|
protocols += peer.protocols;
|
|
|
|
protocols += ']';
|
|
|
|
commandResponses.push(protocols);
|
2021-04-22 07:03:33 +00:00
|
|
|
});
|
2021-04-22 06:50:37 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
commandResponses.push('Unknown Command');
|
|
|
|
}
|
|
|
|
}
|
2021-04-23 04:40:28 +00:00
|
|
|
const messages = stateMessages.slice();
|
|
|
|
commandResponses.forEach((res) => {
|
|
|
|
messages.push(new ChatMessage(new Date(), cmd, res));
|
2021-04-22 06:50:37 +00:00
|
|
|
});
|
2021-04-23 04:40:28 +00:00
|
|
|
setMessages(messages);
|
2021-04-22 06:50:37 +00:00
|
|
|
};
|
2021-04-22 06:12:28 +00:00
|
|
|
|
2021-04-21 06:11:07 +00:00
|
|
|
return (
|
2021-04-26 07:33:12 +00:00
|
|
|
<div className="chat-app">
|
|
|
|
<WakuContext.Provider value={{ waku: stateWaku }}>
|
|
|
|
<Room
|
|
|
|
nick={nick}
|
|
|
|
lines={stateMessages}
|
|
|
|
commandHandler={commandHandler}
|
|
|
|
/>
|
|
|
|
</WakuContext.Provider>
|
2021-04-21 06:11:07 +00:00
|
|
|
</div>
|
|
|
|
);
|
2021-04-14 04:44:12 +00:00
|
|
|
}
|