add @waku/react, use hook from there

This commit is contained in:
Sasha 2023-02-23 01:00:37 +01:00
parent 1c71f18b54
commit a3a2f9ded0
No known key found for this signature in database
7 changed files with 2142 additions and 22312 deletions

File diff suppressed because it is too large Load Diff

View File

@ -7,11 +7,12 @@
"@libp2p/bootstrap": "^5.0.0", "@libp2p/bootstrap": "^5.0.0",
"@livechat/ui-kit": "^0.5.0-24", "@livechat/ui-kit": "^0.5.0-24",
"@multiformats/multiaddr": "11.0.7", "@multiformats/multiaddr": "11.0.7",
"@waku/react": "file:../../../waku-ui",
"@waku/byte-utils": "^0.0.2", "@waku/byte-utils": "^0.0.2",
"@waku/core": "^0.0.10", "@waku/core": "^0.0.10",
"@waku/create": "^0.0.4", "@waku/create": "^0.0.4",
"@waku/dns-discovery": "0.0.5", "@waku/dns-discovery": "0.0.5",
"@waku/interfaces": "^0.0.5", "@waku/interfaces": "^0.0.7",
"@waku/peer-exchange": "^0.0.3", "@waku/peer-exchange": "^0.0.3",
"process": "^0.11.10", "process": "^0.11.10",
"protons-runtime": "^3.1.0", "protons-runtime": "^3.1.0",

View File

@ -8,14 +8,13 @@ import { WakuContext } from "./WakuContext";
import { ThemeProvider } from "@livechat/ui-kit"; import { ThemeProvider } from "@livechat/ui-kit";
import { generate } from "server-name-generator"; import { generate } from "server-name-generator";
import { Message } from "./Message"; import { Message } from "./Message";
import { wakuDnsDiscovery } from "@waku/dns-discovery";
import { wakuPeerExchangeDiscovery } from "@waku/peer-exchange";
import { waitForRemotePeer } from "@waku/core"; import { waitForRemotePeer } from "@waku/core";
import { Protocols, WakuLight } from "@waku/interfaces"; import { Protocols, LightNode } from "@waku/interfaces";
import { createLightNode } from "@waku/create";
import { DecodedMessage, Decoder } from "@waku/core/lib/message/version_0"; import { DecodedMessage, Decoder } from "@waku/core/lib/message/version_0";
import { PageDirection } from "@waku/interfaces"; import { PageDirection } from "@waku/interfaces";
import { useWaku } from "@waku/react";
const themes = { const themes = {
AuthorName: { AuthorName: {
css: { css: {
@ -48,65 +47,6 @@ const themes = {
export const ChatContentTopic = "/toy-chat/2/huilong/proto"; export const ChatContentTopic = "/toy-chat/2/huilong/proto";
const ChatDecoder = new Decoder(ChatContentTopic); const ChatDecoder = new Decoder(ChatContentTopic);
async function retrieveStoreMessages(
waku: WakuLight,
setArchivedMessages: (value: Message[]) => void
): Promise<void> {
const startTime = new Date();
// Only retrieve a week of history
startTime.setTime(Date.now() - 1000 * 60 * 60 * 24 * 7);
const endTime = new Date();
try {
for await (const messagesPromises of waku.store.queryGenerator(
[ChatDecoder],
{
pageSize: 5,
pageDirection: PageDirection.FORWARD,
timeFilter: {
startTime,
endTime,
},
}
)) {
const wakuMessages = await Promise.all(messagesPromises);
const messages: Message[] = [];
wakuMessages
.filter(isMessageDefined)
.map((wakuMsg) => Message.fromWakuMessage(wakuMsg))
.forEach((message) => {
if (message) {
messages.push(message);
}
});
setArchivedMessages(messages);
}
} catch (e) {
console.log("Failed to retrieve messages", e);
}
}
const useCreateWaku = (options: any): undefined | WakuLight => {
const [node, setNode] = React.useState<undefined | WakuLight>(undefined);
React.useEffect(() => {
Promise.resolve().then(async () => {
const waku = await createLightNode(options);
await waku.start();
await waitForRemotePeer(waku, [
Protocols.Store,
Protocols.Filter,
Protocols.LightPush,
]);
setNode(waku);
});
}, []);
return node;
};
const usePersistentNick = (): [ const usePersistentNick = (): [
string, string,
React.Dispatch<React.SetStateAction<string>> React.Dispatch<React.SetStateAction<string>>
@ -122,7 +62,7 @@ const usePersistentNick = (): [
return [nick, setNick]; return [nick, setNick];
}; };
const useFilterMessages = (waku: undefined | WakuLight): Message[] => { const useFilterMessages = (waku: undefined | LightNode): Message[] => {
const [messages, setMessages] = useState<Message[]>([]); const [messages, setMessages] = useState<Message[]>([]);
const appendMessages = (newMessages: Message[]) => { const appendMessages = (newMessages: Message[]) => {
@ -170,37 +110,19 @@ const useFilterMessages = (waku: undefined | WakuLight): Message[] => {
return messages; return messages;
}; };
export default function App() { const useStoreMessages = (waku: undefined | LightNode): Message[] => {
const [messages, dispatchMessages] = useReducer(reduceMessages, []); const [messages, setMessages] = useState<Message[]>([]);
const publicKey = "AOGECG2SPND25EEFMAJ5WF3KSGJNSGV356DSTL2YVLLZWIV6SAYBM"; const appendMessages = (newMessages: Message[]) => {
const fqdn = "test.waku.nodes.status.im"; if (!newMessages || !newMessages.length) {
const enrTree = `enrtree://${publicKey}@${fqdn}`; return;
const options = { }
libp2p: {
peerDiscovery: [ setMessages((prev) => [...prev, ...newMessages]);
wakuDnsDiscovery(enrTree, {
store: 1,
filter: 2,
lightpush: 2,
}),
wakuPeerExchangeDiscovery(),
],
},
}; };
const waku = useCreateWaku(options);
const [nick, setNick] = usePersistentNick();
const [historicalMessagesRetrieved, setHistoricalMessagesRetrieved] =
useState(false);
const msgs = useFilterMessages(waku);
console.log(msgs);
useEffect(() => { useEffect(() => {
if (!waku) return; if (!waku) return;
if (historicalMessagesRetrieved) return;
const retrieveMessages = async () => { const retrieveMessages = async () => {
await waitForRemotePeer(waku, [ await waitForRemotePeer(waku, [
@ -211,17 +133,59 @@ export default function App() {
console.log(`Retrieving archived messages`); console.log(`Retrieving archived messages`);
try { try {
retrieveStoreMessages(waku, dispatchMessages).then((length) => { const startTime = new Date();
console.log(`Messages retrieved:`, length); // Only retrieve a week of history
setHistoricalMessagesRetrieved(true); startTime.setTime(Date.now() - 1000 * 60 * 60 * 24 * 7);
});
const endTime = new Date();
try {
for await (const messagesPromises of waku.store.queryGenerator(
[ChatDecoder],
{
pageSize: 5,
pageDirection: PageDirection.FORWARD,
timeFilter: {
startTime,
endTime,
},
}
)) {
const wakuMessages = await Promise.all(messagesPromises);
const messages: Message[] = [];
wakuMessages
.filter(isMessageDefined)
.map((wakuMsg) => Message.fromWakuMessage(wakuMsg))
.forEach((message) => {
if (message) {
messages.push(message);
}
});
appendMessages(messages);
}
} catch (e) {
console.log("Failed to retrieve messages", e);
}
} catch (e) { } catch (e) {
console.log(`Error encountered when retrieving archived messages`, e); console.log(`Error encountered when retrieving archived messages`, e);
} }
}; };
retrieveMessages(); retrieveMessages();
}, [waku, historicalMessagesRetrieved]); }, [waku]);
return messages;
};
export default function App() {
const { node: waku } = useWaku<LightNode>();
const [nick, setNick] = usePersistentNick();
const msgs = useFilterMessages(waku);
const messages = useStoreMessages(waku);
console.log(msgs, messages);
return ( return (
<div <div
@ -232,14 +196,14 @@ export default function App() {
<ThemeProvider theme={themes}> <ThemeProvider theme={themes}>
<Room <Room
nick={nick} nick={nick}
messages={messages} messages={[...messages, ...msgs]}
commandHandler={(input: string) => { commandHandler={(input: string) => {
handleCommand(input, waku, setNick).then( handleCommand(input, waku, setNick).then(
({ command, response }) => { ({ command, response }) => {
const commandMessages = response.map((msg) => { const commandMessages = response.map((msg) => {
return Message.fromUtf8String(command, msg); return Message.fromUtf8String(command, msg);
}); });
dispatchMessages(commandMessages); console.log("trying to send", commandMessages);
} }
); );
}} }}
@ -250,10 +214,6 @@ export default function App() {
); );
} }
function reduceMessages(state: Message[], newMessages: Message[]) {
return state.concat(newMessages);
}
const isMessageDefined = ( const isMessageDefined = (
msg: DecodedMessage | undefined msg: DecodedMessage | undefined
): msg is DecodedMessage => { ): msg is DecodedMessage => {

View File

@ -1,4 +1,4 @@
import type { Message as WakuMessage } from "@waku/interfaces"; import type { IDecodedMessage as WakuMessage } from "@waku/interfaces";
import { ChatContentTopic } from "./App"; import { ChatContentTopic } from "./App";
import ChatList from "./ChatList"; import ChatList from "./ChatList";
import MessageInput from "./MessageInput"; import MessageInput from "./MessageInput";

View File

@ -1,5 +1,5 @@
import { createContext, useContext } from "react"; import { createContext, useContext } from "react";
import type { WakuLight } from "@waku/interfaces"; import type { LightNode as WakuLight } from "@waku/interfaces";
export type WakuContextType = { export type WakuContextType = {
waku?: WakuLight; waku?: WakuLight;

View File

@ -1,5 +1,5 @@
import { multiaddr } from "@multiformats/multiaddr"; import { multiaddr } from "@multiformats/multiaddr";
import type { WakuLight } from "@waku/interfaces"; import type { LightNode as WakuLight } from "@waku/interfaces";
function help(): string[] { function help(): string[] {
return [ return [

View File

@ -1,11 +1,36 @@
import React from "react"; import React from "react";
import ReactDOM from "react-dom"; import ReactDOM from "react-dom";
import { LightNodeProvider } from "@waku/react";
import { wakuDnsDiscovery } from "@waku/dns-discovery";
import { Protocols } from "@waku/interfaces";
import { wakuPeerExchangeDiscovery } from "@waku/peer-exchange";
import "./index.css"; import "./index.css";
import App from "./App"; import App from "./App";
const publicKey = "AOGECG2SPND25EEFMAJ5WF3KSGJNSGV356DSTL2YVLLZWIV6SAYBM";
const fqdn = "test.waku.nodes.status.im";
const enrTree = `enrtree://${publicKey}@${fqdn}`;
const options = {
libp2p: {
peerDiscovery: [
wakuDnsDiscovery(enrTree, {
store: 1,
filter: 2,
lightpush: 2,
}),
wakuPeerExchangeDiscovery(),
],
},
};
const protocols = [Protocols.Filter, Protocols.Store, Protocols.LightPush];
ReactDOM.render( ReactDOM.render(
<React.StrictMode> <React.StrictMode>
<App /> <LightNodeProvider options={options} protocols={protocols}>
<App />
</LightNodeProvider>
</React.StrictMode>, </React.StrictMode>,
document.getElementById("root") document.getElementById("root")
); );