fix reconnecting to relay

small fixes for task manager
This commit is contained in:
hzrd149 2024-05-23 16:55:56 -05:00
parent d8ad659b6a
commit 87b22d40d8
5 changed files with 80 additions and 19 deletions

View File

@ -5,7 +5,6 @@ import relayPoolService from "../services/relay-pool";
import createDefer from "./deferred";
import { PersistentSubject } from "./subject";
import ControlledObservable from "./controlled-observable";
import dayjs from "dayjs";
export type PublishResult = { relay: AbstractRelay; success: boolean; message: string };

View File

@ -12,6 +12,7 @@ import processManager from "../services/process-manager";
export type Notice = {
message: string;
date: number;
relay: AbstractRelay;
};
export default class RelayPool {
@ -24,6 +25,9 @@ export default class RelayPool {
connectionErrors = new SuperMap<AbstractRelay, Error[]>(() => []);
connecting = new SuperMap<AbstractRelay, PersistentSubject<boolean>>(() => new PersistentSubject(false));
authForPublish = new SuperMap<AbstractRelay, Subject<boolean>>(() => new Subject());
authForSubscribe = new SuperMap<AbstractRelay, Subject<boolean>>(() => new Subject());
log = logger.extend("RelayPool");
getRelay(relayOrUrl: string | URL | AbstractRelay) {
@ -110,7 +114,10 @@ export default class RelayPool {
handleRelayNotice(relay: AbstractRelay, message: string) {
const subject = this.notices.get(relay);
subject.next([...subject.value, { message, date: dayjs().unix() }]);
subject.next([...subject.value, { message, date: dayjs().unix(), relay }]);
const authForSubscribe = this.authForSubscribe.get(relay);
if (!authForSubscribe.value) authForSubscribe.next(true);
}
disconnectFromUnused() {
@ -128,6 +135,10 @@ export default class RelayPool {
if (disconnect) {
this.log(`No active processes using ${relay.url}, disconnecting`);
relay.close();
// NOTE: fix nostr-tools not resetting the connection promise
// @ts-expect-error
relay.connectionPromise = false;
}
}
}

View File

@ -1,6 +1,7 @@
import { useMemo, useState } from "react";
import { Button, Card, CardBody, CardHeader, CardProps, Flex, Heading, Link, LinkBox, Text } from "@chakra-ui/react";
import { Link as RouterLink, useNavigate } from "react-router-dom";
import { nip19 } from "nostr-tools";
import KeyboardShortcut from "../../../components/keyboard-shortcut";
import useCurrentAccount from "../../../hooks/use-current-account";
@ -18,7 +19,6 @@ import UserAvatar from "../../../components/user/user-avatar";
import HoverLinkOverlay from "../../../components/hover-link-overlay";
import UserName from "../../../components/user/user-name";
import UserDnsIdentity from "../../../components/user/user-dns-identity";
import { nip19 } from "nostr-tools";
import { useDecryptionContainer, useDecryptionContext } from "../../../providers/global/decryption-provider";
import Timestamp from "../../../components/timestamp";
@ -59,7 +59,7 @@ export default function DMsCard({ ...props }: Omit<CardProps, "children">) {
const grouped = groupIntoConversations(messages)
.map((c) => identifyConversation(c, account.pubkey))
.filter((c) => {
if (c.messages.some((m) => m.pubkey === c.correspondent)) return hasResponded(c);
if (c.messages.some((m) => m.pubkey === c.correspondent)) return !hasResponded(c);
else return false;
});
const sorted = sortConversationsByLastReceived(grouped);

View File

@ -1,4 +1,19 @@
import { Flex, LinkBox, Spacer } from "@chakra-ui/react";
import {
Box,
Flex,
Heading,
LinkBox,
Spacer,
Tab,
TabIndicator,
TabList,
TabPanel,
TabPanels,
Tabs,
Text,
useForceUpdate,
useInterval,
} from "@chakra-ui/react";
import { Link as RouterLink } from "react-router-dom";
import { AbstractRelay } from "nostr-tools";
@ -7,6 +22,8 @@ import { RelayFavicon } from "../../../components/relay-favicon";
import { RelayStatus } from "../../../components/relay-status";
import HoverLinkOverlay from "../../../components/hover-link-overlay";
import { localRelay } from "../../../services/local-relay";
import useSubjects from "../../../hooks/use-subjects";
import Timestamp from "../../../components/timestamp";
function RelayRow({ relay }: { relay: AbstractRelay }) {
return (
@ -22,14 +39,50 @@ function RelayRow({ relay }: { relay: AbstractRelay }) {
}
export default function TaskManagerRelays() {
const update = useForceUpdate();
useInterval(update, 2000);
const relays = Array.from(relayPoolService.relays.values())
.filter((r) => r !== localRelay)
.sort((a, b) => +b.connected - +a.connected || a.url.localeCompare(b.url));
const notices = useSubjects(Array.from(relayPoolService.notices.values()))
.flat()
.sort((a, b) => b.date - a.date);
return (
<Flex direction="column">
{localRelay instanceof AbstractRelay && <RelayRow relay={localRelay} />}
{Array.from(relayPoolService.relays.values())
.filter((r) => r !== localRelay)
.map((relay) => (
<RelayRow key={relay.url} relay={relay} />
))}
</Flex>
<Tabs position="relative" variant="unstyled">
<TabList>
<Tab>Relays ({relays.length})</Tab>
<Tab>Notices ({notices.length})</Tab>
</TabList>
<TabIndicator mt="-1.5px" height="2px" bg="primary.500" borderRadius="1px" />
<TabPanels>
<TabPanel p="0">
<Flex direction="column">
{localRelay instanceof AbstractRelay && <RelayRow relay={localRelay} />}
{relays.map((relay) => (
<RelayRow key={relay.url} relay={relay} />
))}
</Flex>
</TabPanel>
<TabPanel p="0">
{notices.map((notice) => (
<LinkBox key={notice.date + notice.message} px="2" py="1">
<HoverLinkOverlay
as={RouterLink}
to={`/r/${encodeURIComponent(notice.relay.url)}`}
fontFamily="monospace"
fontWeight="bold"
>
{notice.relay.url}
</HoverLinkOverlay>
<Text fontFamily="monospace">{notice.message}</Text>
</LinkBox>
))}
</TabPanel>
</TabPanels>
</Tabs>
);
}

View File

@ -26,6 +26,7 @@ import useSubject from "../../../hooks/use-subject";
import ProcessBranch from "../processes/process/process-tree";
import processManager from "../../../services/process-manager";
import RelayAuthButton from "../../../components/relays/relay-auth-button";
import { RelayStatus } from "../../../components/relay-status";
import Timestamp from "../../../components/timestamp";
export default function InspectRelayView() {
@ -55,15 +56,12 @@ export default function InspectRelayView() {
<Flex gap="2" alignItems="center" wrap="wrap">
<BackButton size="sm" />
<Heading size="md">{url}</Heading>
<RelayStatus relay={relay} />
<Spacer />
<ButtonGroup size="sm">
<RelayAuthButton relay={relay} />
<Button
variant="outline"
colorScheme={connecting ? "orange" : relay.connected ? "green" : "red"}
onClick={connect}
>
{connecting ? "Connecting..." : relay.connected ? "Connected" : "Disconnected"}
<Button variant="outline" colorScheme={connecting ? "orange" : "green"} onClick={connect}>
{connecting ? "Connecting..." : relay.connected ? "Connected" : "Connect"}
</Button>
</ButtonGroup>
</Flex>