fix: populate peers without waiting for an event (#230)

This commit is contained in:
Sasha 2023-04-22 01:04:39 +02:00 committed by GitHub
parent 700de9d740
commit e83dd13931
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 86 additions and 8 deletions

View File

@ -24,7 +24,11 @@ export default function MessageInput(props: Props) {
const onMessage = async () => {
if (props.sendMessage && inputText) {
await props.sendMessage(inputText);
try {
await props.sendMessage(inputText);
} catch (e) {
console.error(`Failed to send message: ${e}`);
}
setInputText("");
}
};
@ -36,6 +40,7 @@ export default function MessageInput(props: Props) {
const onKeyDown = async (event: KeyboardEvent<HTMLInputElement>) => {
if (
isActive &&
event.key === "Enter" &&
!event.altKey &&
!event.ctrlKey &&
@ -63,7 +68,7 @@ export default function MessageInput(props: Props) {
>
<Row align="center">
<Fill>
<TextInput value={inputText} />
<TextInput />
</Fill>
<Fit>
<SendButton />

View File

@ -1,11 +1,11 @@
import type { LightNode } from "@waku/interfaces";
import ChatList from "./ChatList";
import MessageInput from "./MessageInput";
import { useWaku, useContentPair, useLightPush, usePeers } from "@waku/react";
import { useWaku, useContentPair, useLightPush } from "@waku/react";
import { TitleBar } from "@livechat/ui-kit";
import { Message } from "./Message";
import { ChatMessage } from "./chat_message";
import { useNodePeers } from "./hooks";
import { useNodePeers, usePeers } from "./hooks";
interface Props {
messages: Message[];

View File

@ -2,7 +2,11 @@ import React, { useEffect, useState } from "react";
import { generate } from "server-name-generator";
import { Message } from "./Message";
import { Decoder } from "@waku/core/lib/message/version_0";
import { LightNode, StoreQueryOptions } from "@waku/interfaces";
import type {
Peer,
PeerProtocolsChangeData,
} from "@libp2p/interface-peer-store";
import type { LightNode, StoreQueryOptions, Waku } from "@waku/interfaces";
import { useFilterMessages, useStoreMessages } from "@waku/react";
@ -64,8 +68,7 @@ export const useNodePeers = (node: undefined | LightNode) => {
useEffect(() => {
if (!node) return;
// Update store peer when new peer connected & identified
node.libp2p.peerStore.addEventListener("change:protocols", async (evt) => {
const listener = async (evt: any) => {
const { peerId } = evt.detail;
const tags = (await node.libp2p.peerStore.getTags(peerId)).map(
(t) => t.name
@ -75,7 +78,13 @@ export const useNodePeers = (node: undefined | LightNode) => {
} else {
setBootstrapPeers((peers) => new Set(peers).add(peerId.toString()));
}
});
};
// Update store peer when new peer connected & identified
node.libp2p.peerStore.addEventListener("change:protocols", listener);
return () => {
node.libp2p.peerStore.removeEventListener("change:protocols", listener);
};
}, [node]);
useEffect(() => {
@ -91,3 +100,67 @@ export const useNodePeers = (node: undefined | LightNode) => {
peerExchangePeers,
};
};
type UsePeersParams = {
node: undefined | Waku;
};
type UsePeersResults = {
storePeers?: undefined | Peer[];
filterPeers?: undefined | Peer[];
lightPushPeers?: undefined | Peer[];
peerExchangePeers?: undefined | Peer[];
};
/**
* Hook returns map of peers for different protocols.
* If protocol is not implemented on the node peers are undefined.
* @example
* const { storePeers } = usePeers({ node });
* @param {Waku} params.node - Waku node, if not set then no peers will be returned
* @returns {Object} map of peers, if some of the protocols is not implemented then undefined
*/
export const usePeers = (params: UsePeersParams): UsePeersResults => {
const { node } = params;
const [peers, setPeers] = React.useState<UsePeersResults>({});
React.useEffect(() => {
if (!node) {
return;
}
const listener = async (_event?: CustomEvent<PeerProtocolsChangeData>) => {
const peers = await Promise.all([
handleCatch(node?.store?.peers()),
handleCatch(node?.filter?.peers()),
handleCatch(node?.lightPush?.peers()),
handleCatch(node?.peerExchange?.peers()),
]);
setPeers({
storePeers: peers[0],
filterPeers: peers[1],
lightPushPeers: peers[2],
peerExchangePeers: peers[3],
});
};
listener(); // populate peers before event is invoked
node.libp2p.peerStore.addEventListener("change:protocols", listener);
return () => {
node.libp2p.peerStore.removeEventListener("change:protocols", listener);
};
}, [node, setPeers]);
return peers;
};
function handleCatch(promise?: Promise<Peer[]>): Promise<Peer[] | undefined> {
if (!promise) {
return Promise.resolve(undefined);
}
return promise.catch((_) => {
return undefined;
});
}