mirror of
https://github.com/hzrd149/nostrudel.git
synced 2025-04-11 05:09:36 +02:00
add relay management drawer
This commit is contained in:
parent
91f4c7c92e
commit
238a3be17e
@ -1,7 +1,7 @@
|
||||
import relayScoreboardService from "../services/relay-scoreboard";
|
||||
import { RawIncomingNostrEvent, NostrEvent, CountResponse } from "../types/nostr-event";
|
||||
import { NostrOutgoingMessage } from "../types/nostr-query";
|
||||
import { Subject } from "./subject";
|
||||
import { PersistentSubject, Subject } from "./subject";
|
||||
|
||||
export type IncomingEvent = {
|
||||
type: "EVENT";
|
||||
@ -43,6 +43,7 @@ const CONNECTION_TIMEOUT = 1000 * 30;
|
||||
|
||||
export default class Relay {
|
||||
url: string;
|
||||
status = new PersistentSubject<number>(WebSocket.CLOSED);
|
||||
onOpen = new Subject<Relay>(undefined, false);
|
||||
onClose = new Subject<Relay>(undefined, false);
|
||||
onEvent = new Subject<IncomingEvent>(undefined, false);
|
||||
@ -88,6 +89,7 @@ export default class Relay {
|
||||
this.ws.onopen = () => {
|
||||
window.clearTimeout(connectionTimeout);
|
||||
this.onOpen.next(this);
|
||||
this.status.next(this.ws!.readyState);
|
||||
|
||||
this.ejectTimer = relayScoreboardService.relayEjectTime.get(this.url).createTimer();
|
||||
if (this.connectionTimer) {
|
||||
@ -99,6 +101,7 @@ export default class Relay {
|
||||
};
|
||||
this.ws.onclose = () => {
|
||||
this.onClose.next(this);
|
||||
this.status.next(this.ws!.readyState);
|
||||
|
||||
if (!this.intentionalClose && this.ejectTimer) {
|
||||
this.ejectTimer();
|
||||
|
@ -8,14 +8,14 @@ import { NostrEvent } from "../../../types/nostr-event";
|
||||
import useChannelMetadata from "../../../hooks/use-channel-metadata";
|
||||
import HoverLinkOverlay from "../../hover-link-overlay";
|
||||
import singleEventService from "../../../services/single-event";
|
||||
import { useReadRelayUrls } from "../../../hooks/use-client-relays";
|
||||
import { useReadRelays } from "../../../hooks/use-client-relays";
|
||||
|
||||
export default function EmbeddedChannel({
|
||||
channel,
|
||||
additionalRelays,
|
||||
...props
|
||||
}: Omit<CardProps, "children"> & { channel: NostrEvent; additionalRelays?: string[] }) {
|
||||
const readRelays = useReadRelayUrls(additionalRelays);
|
||||
const readRelays = useReadRelays(additionalRelays);
|
||||
const { metadata } = useChannelMetadata(channel.id, readRelays);
|
||||
|
||||
if (!channel || !metadata) return null;
|
||||
|
@ -5,12 +5,12 @@ import { NostrEvent } from "../../types/nostr-event";
|
||||
import UserAvatarLink from "../user-avatar-link";
|
||||
import UserLink from "../user-link";
|
||||
import useTimelineLoader from "../../hooks/use-timeline-loader";
|
||||
import { useReadRelayUrls } from "../../hooks/use-client-relays";
|
||||
import { useReadRelays } from "../../hooks/use-client-relays";
|
||||
import useSubject from "../../hooks/use-subject";
|
||||
import Timestamp from "../timestamp";
|
||||
|
||||
export default function RepostDetails({ event }: { event: NostrEvent }) {
|
||||
const readRelays = useReadRelayUrls();
|
||||
const readRelays = useReadRelays();
|
||||
const timeline = useTimelineLoader(`${event.id}-reposts`, readRelays, {
|
||||
kinds: [kinds.Repost, kinds.GenericRepost],
|
||||
"#e": [event.id],
|
||||
|
@ -12,7 +12,7 @@ import UserAvatar from "../user-avatar";
|
||||
import UserLink from "../user-link";
|
||||
import { GhostIcon } from "../icons";
|
||||
import useTimelineLoader from "../../hooks/use-timeline-loader";
|
||||
import { useReadRelayUrls } from "../../hooks/use-client-relays";
|
||||
import { useReadRelays } from "../../hooks/use-client-relays";
|
||||
import TimelineLoader from "../../classes/timeline-loader";
|
||||
import { NostrEvent } from "../../types/nostr-event";
|
||||
import { getSharableEventAddress } from "../../helpers/nip19";
|
||||
@ -96,7 +96,7 @@ export default function GhostToolbar() {
|
||||
const account = useCurrentAccount()!;
|
||||
const isGhost = useSubject(accountService.isGhost);
|
||||
|
||||
const readRelays = useReadRelayUrls();
|
||||
const readRelays = useReadRelays();
|
||||
const [since] = useState(dayjs().subtract(6, "hours").unix());
|
||||
|
||||
const timeline = useTimelineLoader(`${account.pubkey}-ghost`, readRelays, { since, authors: [account.pubkey] });
|
||||
|
@ -30,7 +30,7 @@ import { kinds } from "nostr-tools";
|
||||
|
||||
import { ChevronDownIcon, ChevronUpIcon, UploadImageIcon } from "../icons";
|
||||
import NostrPublishAction from "../../classes/nostr-publish-action";
|
||||
import { useWriteRelayUrls } from "../../hooks/use-client-relays";
|
||||
import { useWriteRelays } from "../../hooks/use-client-relays";
|
||||
import { useSigningContext } from "../../providers/global/signing-provider";
|
||||
import { NoteContents } from "../note/text-note-contents";
|
||||
import { PublishDetails } from "../publish-details";
|
||||
@ -87,7 +87,7 @@ export default function PostModal({
|
||||
const { noteDifficulty } = useAppSettings();
|
||||
const { requestSignature } = useSigningContext();
|
||||
const additionalRelays = useAdditionalRelayContext();
|
||||
const writeRelays = useWriteRelayUrls(additionalRelays);
|
||||
const writeRelays = useWriteRelays(additionalRelays);
|
||||
const [miningTarget, setMiningTarget] = useState(0);
|
||||
const [publishAction, setPublishAction] = useState<NostrPublishAction>();
|
||||
const emojis = useContextEmojis();
|
||||
|
134
src/components/relay-management-drawer/index.tsx
Normal file
134
src/components/relay-management-drawer/index.tsx
Normal file
@ -0,0 +1,134 @@
|
||||
import {
|
||||
Button,
|
||||
Drawer,
|
||||
DrawerBody,
|
||||
DrawerCloseButton,
|
||||
DrawerContent,
|
||||
DrawerHeader,
|
||||
DrawerOverlay,
|
||||
DrawerProps,
|
||||
Flex,
|
||||
Heading,
|
||||
IconButton,
|
||||
Switch,
|
||||
Text,
|
||||
} from "@chakra-ui/react";
|
||||
import { useReadRelays, useWriteRelays } from "../../hooks/use-client-relays";
|
||||
import { useMemo } from "react";
|
||||
import relayPoolService from "../../services/relay-pool";
|
||||
import useSubject from "../../hooks/use-subject";
|
||||
import { RelayUrlInput } from "../relay-url-input";
|
||||
import { useForm } from "react-hook-form";
|
||||
import clientRelaysService from "../../services/client-relays";
|
||||
import { RelayMode } from "../../classes/relay";
|
||||
import RelaySet from "../../classes/relay-set";
|
||||
import { CloseIcon } from "@chakra-ui/icons";
|
||||
import Circle from "../icons/circle";
|
||||
import { safeRelayUrl } from "../../helpers/relay";
|
||||
import UploadCloud01 from "../icons/upload-cloud-01";
|
||||
import { RelayFavicon } from "../relay-favicon";
|
||||
|
||||
function RelayControl({ url }: { url: string }) {
|
||||
const relay = useMemo(() => relayPoolService.requestRelay(url, false), [url]);
|
||||
const status = useSubject(relay.status);
|
||||
const writeRelays = useSubject(clientRelaysService.writeRelays);
|
||||
|
||||
let color = "gray";
|
||||
switch (status) {
|
||||
case WebSocket.OPEN:
|
||||
color = "green";
|
||||
break;
|
||||
case WebSocket.CONNECTING:
|
||||
color = "yellow";
|
||||
break;
|
||||
case WebSocket.CLOSED:
|
||||
color = "red";
|
||||
break;
|
||||
}
|
||||
|
||||
const onChange = () => {
|
||||
if (writeRelays.has(url)) clientRelaysService.removeRelay(url, RelayMode.WRITE);
|
||||
else clientRelaysService.addRelay(url, RelayMode.WRITE);
|
||||
};
|
||||
|
||||
return (
|
||||
<Flex gap="2" alignItems="center">
|
||||
<RelayFavicon relay={url} size="xs" outline="2px solid" outlineColor={color} />
|
||||
<Text fontFamily="monospace" fontSize="md" flexGrow={1} isTruncated title={url}>
|
||||
{url}
|
||||
</Text>
|
||||
<IconButton
|
||||
aria-label="Toggle Write"
|
||||
icon={<UploadCloud01 />}
|
||||
size="sm"
|
||||
variant={writeRelays.has(url) ? "solid" : "ghost"}
|
||||
colorScheme={writeRelays.has(url) ? "green" : "gray"}
|
||||
onClick={onChange}
|
||||
title="Toggle Write"
|
||||
/>
|
||||
<IconButton
|
||||
aria-label="Remove Relay"
|
||||
icon={<CloseIcon />}
|
||||
size="sm"
|
||||
colorScheme="red"
|
||||
onClick={() => clientRelaysService.removeRelay(url, RelayMode.ALL)}
|
||||
/>
|
||||
</Flex>
|
||||
);
|
||||
}
|
||||
|
||||
function AddRelayForm() {
|
||||
const { register, handleSubmit, reset } = useForm({
|
||||
defaultValues: {
|
||||
url: "",
|
||||
},
|
||||
});
|
||||
|
||||
const submit = handleSubmit((values) => {
|
||||
const url = safeRelayUrl(values.url);
|
||||
if (!url) return;
|
||||
clientRelaysService.addRelay(url, RelayMode.READ);
|
||||
reset();
|
||||
});
|
||||
|
||||
return (
|
||||
<Flex as="form" display="flex" gap="2" onSubmit={submit}>
|
||||
<RelayUrlInput {...register("url")} placeholder="wss://relay.example.com" />
|
||||
<Button type="submit">Add</Button>
|
||||
</Flex>
|
||||
);
|
||||
}
|
||||
|
||||
export default function RelayManagementDrawer({ isOpen, onClose, ...props }: Omit<DrawerProps, "children">) {
|
||||
const readRelays = useReadRelays();
|
||||
const writeRelays = useWriteRelays();
|
||||
|
||||
const sorted = useMemo(() => RelaySet.from(readRelays, writeRelays).urls.sort(), [readRelays, writeRelays]);
|
||||
const others = Array.from(relayPoolService.relays.values())
|
||||
.filter((r) => !r.closed && !sorted.includes(r.url))
|
||||
.map((r) => r.url)
|
||||
.sort();
|
||||
|
||||
return (
|
||||
<Drawer isOpen={isOpen} placement="right" onClose={onClose} size="md" {...props}>
|
||||
<DrawerOverlay />
|
||||
<DrawerContent>
|
||||
<DrawerCloseButton />
|
||||
<DrawerHeader px="4" py="2">
|
||||
Relays
|
||||
</DrawerHeader>
|
||||
|
||||
<DrawerBody px={{ base: 2, md: 4 }} pb="2" pt="0" display="flex" gap="2" flexDir="column">
|
||||
<AddRelayForm />
|
||||
{sorted.map((url) => (
|
||||
<RelayControl key={url} url={url} />
|
||||
))}
|
||||
<Heading size="sm">Other Relays</Heading>
|
||||
{others.map((url) => (
|
||||
<RelayControl key={url} url={url} />
|
||||
))}
|
||||
</DrawerBody>
|
||||
</DrawerContent>
|
||||
</Drawer>
|
||||
);
|
||||
}
|
@ -2,7 +2,7 @@ import { Button, ButtonProps, useDisclosure } from "@chakra-ui/react";
|
||||
|
||||
import { RelayIcon } from "../icons";
|
||||
import { useRelaySelectionContext } from "../../providers/local/relay-selection-provider";
|
||||
import RelaySelectionModal from "./relay-selection-modal";
|
||||
import RelayManagementDrawer from "../relay-management-drawer";
|
||||
|
||||
export default function RelaySelectionButton({ ...props }: ButtonProps) {
|
||||
const relaysModal = useDisclosure();
|
||||
@ -13,9 +13,7 @@ export default function RelaySelectionButton({ ...props }: ButtonProps) {
|
||||
<Button leftIcon={<RelayIcon />} onClick={relaysModal.onOpen} {...props}>
|
||||
{relays.length} {relays.length === 1 ? "Relay" : "Relays"}
|
||||
</Button>
|
||||
{relaysModal.isOpen && (
|
||||
<RelaySelectionModal selected={relays} onSubmit={setSelected} onClose={relaysModal.onClose} />
|
||||
)}
|
||||
<RelayManagementDrawer isOpen={relaysModal.isOpen} onClose={relaysModal.onClose} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ import {
|
||||
useToast,
|
||||
} from "@chakra-ui/react";
|
||||
|
||||
import { useReadRelayUrls } from "../../hooks/use-client-relays";
|
||||
import { useReadRelays } from "../../hooks/use-client-relays";
|
||||
import { RelayFavicon } from "../relay-favicon";
|
||||
import { RelayUrlInput } from "../relay-url-input";
|
||||
import { unique } from "../../helpers/array";
|
||||
@ -61,7 +61,7 @@ export default function RelaySelectionModal({
|
||||
onClose: () => void;
|
||||
}) {
|
||||
const [newSelected, setSelected] = useState<string[]>(selected);
|
||||
const relays = useReadRelayUrls([...selected, ...newSelected, ...Array.from(manuallyAddedRelays)]);
|
||||
const relays = useReadRelays([...selected, ...newSelected, ...Array.from(manuallyAddedRelays)]);
|
||||
|
||||
return (
|
||||
<Modal isOpen={true} onClose={onClose}>
|
||||
|
@ -1,105 +1,27 @@
|
||||
import { forwardRef, useState } from "react";
|
||||
import {
|
||||
Button,
|
||||
Flex,
|
||||
IconButton,
|
||||
Input,
|
||||
InputGroup,
|
||||
InputLeftElement,
|
||||
InputProps,
|
||||
InputRightElement,
|
||||
Modal,
|
||||
ModalBody,
|
||||
ModalCloseButton,
|
||||
ModalContent,
|
||||
ModalHeader,
|
||||
ModalOverlay,
|
||||
ModalProps,
|
||||
useDisclosure,
|
||||
} from "@chakra-ui/react";
|
||||
import { forwardRef } from "react";
|
||||
import { Input, InputProps } from "@chakra-ui/react";
|
||||
import { useAsync } from "react-use";
|
||||
|
||||
import { unique } from "../helpers/array";
|
||||
import { RelayIcon, SearchIcon } from "./icons";
|
||||
|
||||
function RelayPickerModal({
|
||||
onSelect,
|
||||
onClose,
|
||||
...props
|
||||
}: { onSelect: (relay: string) => void } & Omit<ModalProps, "children">) {
|
||||
const [search, setSearch] = useState("");
|
||||
const { value: onlineRelays } = useAsync(async () =>
|
||||
fetch("https://api.nostr.watch/v1/online").then((res) => res.json() as Promise<string[]>),
|
||||
);
|
||||
const relayList = unique(onlineRelays ?? []);
|
||||
|
||||
const filteredRelays = search ? relayList.filter((url) => url.includes(search)) : relayList;
|
||||
|
||||
return (
|
||||
<Modal onClose={onClose} {...props}>
|
||||
<ModalOverlay />
|
||||
<ModalContent>
|
||||
<ModalHeader>Pick Relay</ModalHeader>
|
||||
<ModalCloseButton />
|
||||
<ModalBody pt="0" px="4" pb="4">
|
||||
<InputGroup mb="2">
|
||||
<InputLeftElement pointerEvents="none" children={<SearchIcon />} />
|
||||
<Input
|
||||
type="search"
|
||||
placeholder="Search"
|
||||
name="relay-search"
|
||||
value={search}
|
||||
onChange={(e) => setSearch(e.target.value)}
|
||||
/>
|
||||
</InputGroup>
|
||||
<Flex gap="2" direction="column">
|
||||
{filteredRelays.map((url) => (
|
||||
<Button
|
||||
value={url}
|
||||
onClick={() => {
|
||||
onSelect(url);
|
||||
onClose();
|
||||
}}
|
||||
variant="outline"
|
||||
size="sm"
|
||||
>
|
||||
{url}
|
||||
</Button>
|
||||
))}
|
||||
</Flex>
|
||||
</ModalBody>
|
||||
</ModalContent>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
|
||||
export type RelayUrlInputProps = Omit<InputProps, "type">;
|
||||
|
||||
export const RelayUrlInput = forwardRef(
|
||||
({ onChange, ...props }: Omit<RelayUrlInputProps, "onChange"> & { onChange: (url: string) => void }, ref) => {
|
||||
const { isOpen, onClose, onOpen } = useDisclosure();
|
||||
const { value: relaysJson } = useAsync(async () =>
|
||||
fetch("https://api.nostr.watch/v1/online").then((res) => res.json() as Promise<string[]>),
|
||||
);
|
||||
const relaySuggestions = unique(relaysJson ?? []);
|
||||
export const RelayUrlInput = forwardRef(({ ...props }: Omit<InputProps, "type">, ref) => {
|
||||
const { value: relaysJson } = useAsync(async () =>
|
||||
fetch("https://api.nostr.watch/v1/online").then((res) => res.json() as Promise<string[]>),
|
||||
);
|
||||
const relaySuggestions = unique(relaysJson ?? []);
|
||||
|
||||
return (
|
||||
<>
|
||||
<InputGroup>
|
||||
<Input ref={ref} list="relay-suggestions" type="url" onChange={(e) => onChange(e.target.value)} {...props} />
|
||||
<datalist id="relay-suggestions">
|
||||
{relaySuggestions.map((url) => (
|
||||
<option key={url} value={url}>
|
||||
{url}
|
||||
</option>
|
||||
))}
|
||||
</datalist>
|
||||
<InputRightElement>
|
||||
<IconButton icon={<RelayIcon />} aria-label="Pick from list" size="sm" onClick={onOpen} />
|
||||
</InputRightElement>
|
||||
</InputGroup>
|
||||
<RelayPickerModal onClose={onClose} isOpen={isOpen} onSelect={(url) => onChange(url)} size="2xl" />
|
||||
</>
|
||||
);
|
||||
},
|
||||
);
|
||||
return (
|
||||
<>
|
||||
<Input ref={ref} list="relay-suggestions" type="url" {...props} />
|
||||
<datalist id="relay-suggestions">
|
||||
{relaySuggestions.map((url) => (
|
||||
<option key={url} value={url}>
|
||||
{url}
|
||||
</option>
|
||||
))}
|
||||
</datalist>
|
||||
</>
|
||||
);
|
||||
});
|
||||
|
@ -1,12 +1,12 @@
|
||||
import clientRelaysService from "../services/client-relays";
|
||||
import useSubject from "./use-subject";
|
||||
|
||||
export function useReadRelayUrls(additional?: Iterable<string>) {
|
||||
export function useReadRelays(additional?: Iterable<string>) {
|
||||
const set = useSubject(clientRelaysService.readRelays);
|
||||
if (additional) return set.clone().merge(additional);
|
||||
return set;
|
||||
}
|
||||
export function useWriteRelayUrls(additional?: Iterable<string>) {
|
||||
export function useWriteRelays(additional?: Iterable<string>) {
|
||||
const set = useSubject(clientRelaysService.writeRelays);
|
||||
if (additional) return set.clone().merge(additional);
|
||||
return set;
|
||||
|
@ -1,10 +1,10 @@
|
||||
import { useMemo } from "react";
|
||||
import eventReactionsService from "../services/event-reactions";
|
||||
import { useReadRelayUrls } from "./use-client-relays";
|
||||
import { useReadRelays } from "./use-client-relays";
|
||||
import useSubject from "./use-subject";
|
||||
|
||||
export default function useEventReactions(eventId: string, additionalRelays?: Iterable<string>, alwaysRequest = true) {
|
||||
const relays = useReadRelayUrls(additionalRelays);
|
||||
const relays = useReadRelays(additionalRelays);
|
||||
|
||||
const subject = useMemo(
|
||||
() => eventReactionsService.requestReactions(eventId, relays, alwaysRequest),
|
||||
|
@ -1,12 +1,12 @@
|
||||
import { useMemo } from "react";
|
||||
|
||||
import eventZapsService from "../services/event-zaps";
|
||||
import { useReadRelayUrls } from "./use-client-relays";
|
||||
import { useReadRelays } from "./use-client-relays";
|
||||
import useSubject from "./use-subject";
|
||||
import { parseZapEvent } from "../helpers/nostr/zaps";
|
||||
|
||||
export default function useEventZaps(eventUID: string, additionalRelays?: Iterable<string>, alwaysRequest = true) {
|
||||
const readRelays = useReadRelayUrls(additionalRelays);
|
||||
const readRelays = useReadRelays(additionalRelays);
|
||||
|
||||
const subject = useMemo(
|
||||
() => eventZapsService.requestZaps(eventUID, readRelays, alwaysRequest),
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { useEffect, useMemo, useState } from "react";
|
||||
import eventReactionsService from "../services/event-reactions";
|
||||
import { useReadRelayUrls } from "./use-client-relays";
|
||||
import { useReadRelays } from "./use-client-relays";
|
||||
import { NostrEvent } from "../types/nostr-event";
|
||||
import Subject from "../classes/subject";
|
||||
|
||||
@ -9,7 +9,7 @@ export default function useEventsReactions(
|
||||
additionalRelays?: Iterable<string>,
|
||||
alwaysRequest = true,
|
||||
) {
|
||||
const readRelays = useReadRelayUrls(additionalRelays);
|
||||
const readRelays = useReadRelays(additionalRelays);
|
||||
|
||||
// get subjects
|
||||
const subjects = useMemo(() => {
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { useMemo } from "react";
|
||||
|
||||
import { useReadRelayUrls } from "./use-client-relays";
|
||||
import { useReadRelays } from "./use-client-relays";
|
||||
import replaceableEventLoaderService, { RequestOptions } from "../services/replaceable-event-requester";
|
||||
import { CustomAddressPointer, parseCoordinate } from "../helpers/nostr/events";
|
||||
import useSubject from "./use-subject";
|
||||
@ -10,7 +10,7 @@ export default function useReplaceableEvent(
|
||||
additionalRelays?: Iterable<string>,
|
||||
opts: RequestOptions = {},
|
||||
) {
|
||||
const readRelays = useReadRelayUrls(additionalRelays);
|
||||
const readRelays = useReadRelays(additionalRelays);
|
||||
const sub = useMemo(() => {
|
||||
const parsed = typeof cord === "string" ? parseCoordinate(cord) : cord;
|
||||
if (!parsed) return;
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { useMemo } from "react";
|
||||
|
||||
import { useReadRelayUrls } from "./use-client-relays";
|
||||
import { useReadRelays } from "./use-client-relays";
|
||||
import replaceableEventLoaderService, { RequestOptions } from "../services/replaceable-event-requester";
|
||||
import { CustomAddressPointer, parseCoordinate } from "../helpers/nostr/events";
|
||||
import Subject from "../classes/subject";
|
||||
@ -12,7 +12,7 @@ export default function useReplaceableEvents(
|
||||
additionalRelays?: Iterable<string>,
|
||||
opts: RequestOptions = {},
|
||||
) {
|
||||
const readRelays = useReadRelayUrls(additionalRelays);
|
||||
const readRelays = useReadRelays(additionalRelays);
|
||||
const subs = useMemo(() => {
|
||||
if (!coordinates) return undefined;
|
||||
const subs: Subject<NostrEvent>[] = [];
|
||||
|
@ -1,10 +1,10 @@
|
||||
import singleEventService from "../services/single-event";
|
||||
import { useReadRelayUrls } from "./use-client-relays";
|
||||
import { useReadRelays } from "./use-client-relays";
|
||||
import { useMemo } from "react";
|
||||
import useSubject from "./use-subject";
|
||||
|
||||
export default function useSingleEvent(id?: string, additionalRelays?: Iterable<string>) {
|
||||
const readRelays = useReadRelayUrls(additionalRelays);
|
||||
const readRelays = useReadRelays(additionalRelays);
|
||||
const subject = useMemo(() => {
|
||||
if (id) return singleEventService.requestEvent(id, readRelays);
|
||||
}, [id, readRelays.urls.join("|")]);
|
||||
|
@ -1,11 +1,11 @@
|
||||
import { useMemo } from "react";
|
||||
|
||||
import singleEventService from "../services/single-event";
|
||||
import { useReadRelayUrls } from "./use-client-relays";
|
||||
import { useReadRelays } from "./use-client-relays";
|
||||
import useSubjects from "./use-subjects";
|
||||
|
||||
export default function useSingleEvents(ids?: string[], additionalRelays?: Iterable<string>) {
|
||||
const readRelays = useReadRelayUrls(additionalRelays);
|
||||
const readRelays = useReadRelays(additionalRelays);
|
||||
const subjects = useMemo(() => {
|
||||
return ids?.map((id) => singleEventService.requestEvent(id, readRelays)) ?? [];
|
||||
}, [ids, readRelays.urls.join("|")]);
|
||||
|
@ -3,13 +3,13 @@ import { useEffect, useState } from "react";
|
||||
import { GOAL_KIND } from "../helpers/nostr/goal";
|
||||
import { ParsedStream, getATag } from "../helpers/nostr/stream";
|
||||
import { NostrEvent } from "../types/nostr-event";
|
||||
import { useReadRelayUrls } from "./use-client-relays";
|
||||
import { useReadRelays } from "./use-client-relays";
|
||||
import NostrRequest from "../classes/nostr-request";
|
||||
import useSingleEvent from "./use-single-event";
|
||||
|
||||
export default function useStreamGoal(stream: ParsedStream) {
|
||||
const [goal, setGoal] = useState<NostrEvent>();
|
||||
const readRelays = useReadRelayUrls(stream.relays);
|
||||
const readRelays = useReadRelays(stream.relays);
|
||||
|
||||
const streamGoal = useSingleEvent(stream.goal);
|
||||
|
||||
|
@ -1,13 +1,13 @@
|
||||
import { useCallback } from "react";
|
||||
|
||||
import { NOTE_LIST_KIND, PEOPLE_LIST_KIND, isJunkList } from "../helpers/nostr/lists";
|
||||
import { useReadRelayUrls } from "./use-client-relays";
|
||||
import { useReadRelays } from "./use-client-relays";
|
||||
import useSubject from "./use-subject";
|
||||
import useTimelineLoader from "./use-timeline-loader";
|
||||
import { NostrEvent } from "../types/nostr-event";
|
||||
|
||||
export default function useUserLists(pubkey?: string, additionalRelays?: Iterable<string>) {
|
||||
const readRelays = useReadRelayUrls(additionalRelays);
|
||||
const readRelays = useReadRelays(additionalRelays);
|
||||
const eventFilter = useCallback((event: NostrEvent) => {
|
||||
return !isJunkList(event);
|
||||
}, []);
|
||||
|
@ -1,18 +1,18 @@
|
||||
import RelaySet from "../classes/relay-set";
|
||||
import { RequestOptions } from "../services/replaceable-event-requester";
|
||||
import userMailboxesService from "../services/user-mailboxes";
|
||||
import { useReadRelayUrls } from "./use-client-relays";
|
||||
import { useReadRelays } from "./use-client-relays";
|
||||
import useSubject from "./use-subject";
|
||||
|
||||
export default function useUserMailboxes(pubkey: string, opts?: RequestOptions) {
|
||||
const readRelays = useReadRelayUrls();
|
||||
const sub = userMailboxesService.requestMailboxes(pubkey, readRelays, opts);
|
||||
export default function useUserMailboxes(pubkey?: string, opts?: RequestOptions) {
|
||||
const readRelays = useReadRelays();
|
||||
const sub = pubkey ? userMailboxesService.requestMailboxes(pubkey, readRelays, opts) : undefined;
|
||||
const value = useSubject(sub);
|
||||
return value;
|
||||
}
|
||||
export function useUserInbox(pubkey: string, opts?: RequestOptions) {
|
||||
export function useUserInbox(pubkey?: string, opts?: RequestOptions) {
|
||||
return useUserMailboxes(pubkey, opts)?.inbox ?? new RelaySet();
|
||||
}
|
||||
export function useUserOutbox(pubkey: string, opts?: RequestOptions) {
|
||||
export function useUserOutbox(pubkey?: string, opts?: RequestOptions) {
|
||||
return useUserMailboxes(pubkey, opts)?.outbox ?? new RelaySet();
|
||||
}
|
||||
|
@ -1,12 +1,12 @@
|
||||
import { useMemo } from "react";
|
||||
import userMetadataService from "../services/user-metadata";
|
||||
import { useReadRelayUrls } from "./use-client-relays";
|
||||
import { useReadRelays } from "./use-client-relays";
|
||||
import useSubject from "./use-subject";
|
||||
import { RequestOptions } from "../services/replaceable-event-requester";
|
||||
import { COMMON_CONTACT_RELAY } from "../const";
|
||||
|
||||
export function useUserMetadata(pubkey: string, additionalRelays: Iterable<string> = [], opts: RequestOptions = {}) {
|
||||
const relays = useReadRelayUrls([...additionalRelays, COMMON_CONTACT_RELAY]);
|
||||
const relays = useReadRelays([...additionalRelays, COMMON_CONTACT_RELAY]);
|
||||
|
||||
const subject = useMemo(() => userMetadataService.requestMetadata(pubkey, relays, opts), [pubkey, relays]);
|
||||
const metadata = useSubject(subject);
|
||||
|
@ -4,13 +4,13 @@ import { kinds } from "nostr-tools";
|
||||
import { getPubkeysFromList } from "../helpers/nostr/lists";
|
||||
import useUserContactList from "./use-user-contact-list";
|
||||
import replaceableEventLoaderService from "../services/replaceable-event-requester";
|
||||
import { useReadRelayUrls } from "./use-client-relays";
|
||||
import { useReadRelays } from "./use-client-relays";
|
||||
import useSubjects from "./use-subjects";
|
||||
import userMetadataService from "../services/user-metadata";
|
||||
import { Kind0ParsedContent } from "../helpers/user-metadata";
|
||||
|
||||
export function useUsersMetadata(pubkeys: string[], additionalRelays?: Iterable<string>) {
|
||||
const readRelays = useReadRelayUrls(additionalRelays);
|
||||
const readRelays = useReadRelays(additionalRelays);
|
||||
const metadataSubjects = useMemo(() => {
|
||||
return pubkeys.map((pubkey) => userMetadataService.requestMetadata(pubkey, readRelays));
|
||||
}, [pubkeys]);
|
||||
@ -28,7 +28,7 @@ export function useUsersMetadata(pubkeys: string[], additionalRelays?: Iterable<
|
||||
}
|
||||
|
||||
export default function useUserNetwork(pubkey: string, additionalRelays?: Iterable<string>) {
|
||||
const readRelays = useReadRelayUrls(additionalRelays);
|
||||
const readRelays = useReadRelays(additionalRelays);
|
||||
const contacts = useUserContactList(pubkey);
|
||||
const contactsPubkeys = contacts ? getPubkeysFromList(contacts) : [];
|
||||
|
||||
|
@ -2,14 +2,14 @@ import { useMemo } from "react";
|
||||
|
||||
import userMailboxesService from "../services/user-mailboxes";
|
||||
import useSubject from "./use-subject";
|
||||
import { useReadRelayUrls } from "./use-client-relays";
|
||||
import { useReadRelays } from "./use-client-relays";
|
||||
import { RequestOptions } from "../services/replaceable-event-requester";
|
||||
import { COMMON_CONTACT_RELAY } from "../const";
|
||||
import RelaySet from "../classes/relay-set";
|
||||
|
||||
/** @deprecated */
|
||||
export function useUserRelays(pubkey: string, additionalRelays: Iterable<string> = [], opts: RequestOptions = {}) {
|
||||
const readRelays = useReadRelayUrls([...additionalRelays, COMMON_CONTACT_RELAY]);
|
||||
const readRelays = useReadRelays([...additionalRelays, COMMON_CONTACT_RELAY]);
|
||||
const subject = useMemo(
|
||||
() => userMailboxesService.requestMailboxes(pubkey, readRelays, opts),
|
||||
[pubkey, readRelays.urls.join("|")],
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { PropsWithChildren, createContext, useCallback, useContext, useMemo } from "react";
|
||||
import { kinds } from "nostr-tools";
|
||||
|
||||
import { useReadRelayUrls } from "../../hooks/use-client-relays";
|
||||
import { useReadRelays } from "../../hooks/use-client-relays";
|
||||
import useCurrentAccount from "../../hooks/use-current-account";
|
||||
import TimelineLoader from "../../classes/timeline-loader";
|
||||
import { NostrEvent } from "../../types/nostr-event";
|
||||
@ -23,7 +23,7 @@ export function useDMTimeline() {
|
||||
|
||||
export default function DMTimelineProvider({ children }: PropsWithChildren) {
|
||||
const account = useCurrentAccount();
|
||||
const inbox = useReadRelayUrls();
|
||||
const inbox = useReadRelays();
|
||||
|
||||
const userMuteFilter = useClientSideMuteFilter();
|
||||
const eventFilter = useCallback(
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { PropsWithChildren, createContext, useCallback, useContext, useMemo } from "react";
|
||||
import { kinds } from "nostr-tools";
|
||||
|
||||
import { useReadRelayUrls } from "../../hooks/use-client-relays";
|
||||
import { useReadRelays } from "../../hooks/use-client-relays";
|
||||
import useCurrentAccount from "../../hooks/use-current-account";
|
||||
import TimelineLoader from "../../classes/timeline-loader";
|
||||
import { NostrEvent } from "../../types/nostr-event";
|
||||
@ -24,7 +24,7 @@ export function useNotificationTimeline() {
|
||||
|
||||
export default function NotificationTimelineProvider({ children }: PropsWithChildren) {
|
||||
const account = useCurrentAccount();
|
||||
const inbox = useReadRelayUrls();
|
||||
const inbox = useReadRelays();
|
||||
|
||||
const userMuteFilter = useClientSideMuteFilter();
|
||||
const eventFilter = useCallback(
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { PropsWithChildren, createContext, useCallback, useContext, useMemo } from "react";
|
||||
import { useLocation, useNavigate } from "react-router-dom";
|
||||
|
||||
import { useReadRelayUrls } from "../../hooks/use-client-relays";
|
||||
import { useReadRelays } from "../../hooks/use-client-relays";
|
||||
import { unique } from "../../helpers/array";
|
||||
|
||||
type RelaySelectionContextType = {
|
||||
@ -34,7 +34,7 @@ export default function RelaySelectionProvider({
|
||||
const navigate = useNavigate();
|
||||
const location = useLocation();
|
||||
|
||||
const readRelays = useReadRelayUrls();
|
||||
const readRelays = useReadRelays();
|
||||
const relays = useMemo(() => {
|
||||
if (location.state?.relays) return location.state.relays as string[];
|
||||
if (overrideDefault) return Array.from(overrideDefault);
|
||||
|
@ -34,7 +34,7 @@ import NostrPublishAction from "../../classes/nostr-publish-action";
|
||||
import { Tag } from "../../types/nostr-event";
|
||||
import deleteEventService from "../../services/delete-events";
|
||||
import { EmbedEvent } from "../../components/embed-event";
|
||||
import { useWriteRelayUrls } from "../../hooks/use-client-relays";
|
||||
import { useWriteRelays } from "../../hooks/use-client-relays";
|
||||
|
||||
type DeleteEventContextType = {
|
||||
isLoading: boolean;
|
||||
@ -59,7 +59,7 @@ export default function DeleteEventProvider({ children }: PropsWithChildren) {
|
||||
const [reason, setReason] = useState("");
|
||||
|
||||
const eventRelays = useEventRelays(event && getEventUID(event));
|
||||
const writeRelays = useWriteRelayUrls(eventRelays);
|
||||
const writeRelays = useWriteRelays(eventRelays);
|
||||
|
||||
const deleteEvent = useCallback((event: Event) => {
|
||||
setEvent(event);
|
||||
|
@ -1,44 +1,34 @@
|
||||
import accountService from "./account";
|
||||
import { RelayMode } from "../classes/relay";
|
||||
import userMailboxesService, { UserMailboxes } from "./user-mailboxes";
|
||||
import { PersistentSubject, Subject } from "../classes/subject";
|
||||
import userMailboxesService from "./user-mailboxes";
|
||||
import { PersistentSubject } from "../classes/subject";
|
||||
import { logger } from "../helpers/debug";
|
||||
import appSettings from "./settings/app-settings";
|
||||
import RelaySet from "../classes/relay-set";
|
||||
import { safeUrl } from "../helpers/parse";
|
||||
|
||||
export type RelayDirectory = Record<string, { read: boolean; write: boolean }>;
|
||||
|
||||
// const userRelaysToRelayConfig: Connection<ParsedUserRelays, RelayConfig[], RelayConfig[] | undefined> = (
|
||||
// userRelays,
|
||||
// next,
|
||||
// ) => next(userRelays.relays);
|
||||
|
||||
class ClientRelayService {
|
||||
readRelays = new PersistentSubject(new RelaySet());
|
||||
writeRelays = new PersistentSubject(new RelaySet());
|
||||
// outbox = new PersistentSubject(new RelaySet());
|
||||
// inbox = new PersistentSubject(new RelaySet());
|
||||
|
||||
log = logger.extend("ClientRelays");
|
||||
|
||||
constructor() {
|
||||
accountService.loading.subscribe(this.handleAccountChange, this);
|
||||
accountService.current.subscribe(this.handleAccountChange, this);
|
||||
const cachedRead = localStorage.getItem("read-relays")?.split(",");
|
||||
if (cachedRead) this.readRelays.next(RelaySet.from(cachedRead));
|
||||
|
||||
appSettings.subscribe(this.handleSettingsChange, this);
|
||||
|
||||
// set the read and write relays
|
||||
// this.relays.subscribe((relays) => {
|
||||
// this.log("Got new relay list", relays);
|
||||
// this.outbox.next(relays.filter((r) => r.mode & RelayMode.WRITE));
|
||||
// this.inbox.next(relays.filter((r) => r.mode & RelayMode.READ));
|
||||
// });
|
||||
const cachedWrite = localStorage.getItem("write-relays")?.split(",");
|
||||
if (cachedWrite) this.writeRelays.next(RelaySet.from(cachedWrite));
|
||||
}
|
||||
|
||||
addRelay(url: string, mode: RelayMode) {
|
||||
if (mode & RelayMode.WRITE) this.writeRelays.next(this.writeRelays.value.clone().add(url));
|
||||
if (mode & RelayMode.READ) this.readRelays.next(this.readRelays.value.clone().add(url));
|
||||
if (mode & RelayMode.WRITE && !this.writeRelays.value.has(url))
|
||||
this.writeRelays.next(this.writeRelays.value.clone().add(url));
|
||||
|
||||
if (mode & RelayMode.READ && !this.readRelays.value.has(url))
|
||||
this.readRelays.next(this.readRelays.value.clone().add(url));
|
||||
|
||||
this.saveRelays();
|
||||
}
|
||||
removeRelay(url: string, mode: RelayMode) {
|
||||
if (mode & RelayMode.WRITE) {
|
||||
@ -51,67 +41,23 @@ class ClientRelayService {
|
||||
next.delete(url);
|
||||
this.readRelays.next(next);
|
||||
}
|
||||
|
||||
this.saveRelays();
|
||||
}
|
||||
|
||||
private handleSettingsChange() {
|
||||
this.readRelays.next(RelaySet.from(appSettings.value.defaultRelays));
|
||||
this.writeRelays.next(new RelaySet());
|
||||
saveRelays() {
|
||||
localStorage.setItem("read-relays", this.readRelays.value.urls.join(","));
|
||||
localStorage.setItem("write-relays", this.writeRelays.value.urls.join(","));
|
||||
}
|
||||
|
||||
private userRelaySub: Subject<UserMailboxes> | undefined;
|
||||
private handleAccountChange() {
|
||||
// skip if account is loading
|
||||
if (accountService.loading.value) return;
|
||||
|
||||
// disconnect the relay list subject
|
||||
// if (this.userRelaySub) {
|
||||
// this.relays.disconnect(this.userRelaySub);
|
||||
// this.userRelaySub.unsubscribe(this.handleUserRelays, this);
|
||||
// this.userRelaySub = undefined;
|
||||
// }
|
||||
|
||||
const account = accountService.current.value;
|
||||
if (!account) return;
|
||||
|
||||
// connect the relay subject with the account relay subject
|
||||
// this.userRelaySub = userMailboxesService.requestMailboxes(account.pubkey, [COMMON_CONTACT_RELAY]);
|
||||
// this.userRelaySub.subscribe(this.handleUserRelays, this);
|
||||
// this.relays.connectWithHandler(this.userRelaySub, userRelaysToRelayConfig);
|
||||
|
||||
// load the relays from cache
|
||||
// if (!userRelaysService.getRelays(account.pubkey).value) {
|
||||
// this.log("Load users relay list from cache");
|
||||
// userRelaysService.loadFromCache(account.pubkey).then(() => {
|
||||
// if (this.relays.value.length === 0) {
|
||||
// const bootstrapRelays = account.relays ?? [COMMON_CONTACT_RELAY];
|
||||
|
||||
// this.log("Loading relay list from bootstrap relays", bootstrapRelays);
|
||||
// userRelaysService.requestRelays(account.pubkey, bootstrapRelays, { alwaysRequest: true });
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
|
||||
// double check for new relay notes
|
||||
// setTimeout(() => {
|
||||
// if (this.relays.value.length === 0) return;
|
||||
|
||||
// this.log("Requesting latest relay list from relays");
|
||||
// userRelaysService.requestRelays(account.pubkey, this.getOutboxURLs(), { alwaysRequest: true });
|
||||
// }, 5000);
|
||||
}
|
||||
|
||||
// private handleUserRelays(userRelays: UserMailboxes) {
|
||||
// if (userRelays.pubkey === accountService.current.value?.pubkey) {
|
||||
// this.inbox.next(userRelays.mailboxes.filter(RelayMode.READ));
|
||||
// this.outbox.next(userRelays.mailboxes.filter(RelayMode.WRITE));
|
||||
// }
|
||||
// }
|
||||
|
||||
/** @deprecated */
|
||||
get outbox() {
|
||||
const account = accountService.current.value;
|
||||
if (account) return userMailboxesService.getMailboxes(account.pubkey).value?.outbox ?? this.writeRelays.value;
|
||||
return this.writeRelays.value;
|
||||
}
|
||||
|
||||
/** @deprecated */
|
||||
get inbox() {
|
||||
const account = accountService.current.value;
|
||||
if (account) return userMailboxesService.getMailboxes(account.pubkey).value?.inbox ?? this.readRelays.value;
|
||||
|
@ -22,7 +22,7 @@ import { EventRelays } from "../../components/note/note-relays";
|
||||
import { getBadgeAwardPubkeys, getBadgeDescription, getBadgeImage, getBadgeName } from "../../helpers/nostr/badges";
|
||||
import BadgeMenu from "./components/badge-menu";
|
||||
import useTimelineLoader from "../../hooks/use-timeline-loader";
|
||||
import { useReadRelayUrls } from "../../hooks/use-client-relays";
|
||||
import { useReadRelays } from "../../hooks/use-client-relays";
|
||||
import IntersectionObserverProvider from "../../providers/local/intersection-observer";
|
||||
import { useTimelineCurserIntersectionCallback } from "../../hooks/use-timeline-cursor-intersection-callback";
|
||||
import useSubject from "../../hooks/use-subject";
|
||||
@ -85,7 +85,7 @@ function BadgeDetailsPage({ badge }: { badge: NostrEvent }) {
|
||||
const image = getBadgeImage(badge);
|
||||
const description = getBadgeDescription(badge);
|
||||
|
||||
const readRelays = useReadRelayUrls();
|
||||
const readRelays = useReadRelays();
|
||||
const coordinate = getEventCoordinate(badge);
|
||||
const awardsTimeline = useTimelineLoader(`${coordinate}-awards`, readRelays, {
|
||||
"#a": [coordinate],
|
||||
|
@ -4,7 +4,7 @@ import { kinds } from "nostr-tools";
|
||||
import PeopleListProvider, { usePeopleListContext } from "../../providers/local/people-list-provider";
|
||||
import PeopleListSelection from "../../components/people-list-selection/people-list-selection";
|
||||
import useTimelineLoader from "../../hooks/use-timeline-loader";
|
||||
import { useReadRelayUrls } from "../../hooks/use-client-relays";
|
||||
import { useReadRelays } from "../../hooks/use-client-relays";
|
||||
import IntersectionObserverProvider from "../../providers/local/intersection-observer";
|
||||
import { useTimelineCurserIntersectionCallback } from "../../hooks/use-timeline-cursor-intersection-callback";
|
||||
import useSubject from "../../hooks/use-subject";
|
||||
@ -15,7 +15,7 @@ import VerticalPageLayout from "../../components/vertical-page-layout";
|
||||
function BadgesBrowsePage() {
|
||||
const { filter, listId } = usePeopleListContext();
|
||||
|
||||
const readRelays = useReadRelayUrls();
|
||||
const readRelays = useReadRelays();
|
||||
const timeline = useTimelineLoader(
|
||||
`${listId}-badges`,
|
||||
readRelays,
|
||||
|
@ -8,7 +8,7 @@ import VerticalPageLayout from "../../components/vertical-page-layout";
|
||||
import useTimelineLoader from "../../hooks/use-timeline-loader";
|
||||
import PeopleListProvider, { usePeopleListContext } from "../../providers/local/people-list-provider";
|
||||
import PeopleListSelection from "../../components/people-list-selection/people-list-selection";
|
||||
import { useReadRelayUrls } from "../../hooks/use-client-relays";
|
||||
import { useReadRelays } from "../../hooks/use-client-relays";
|
||||
import useSubject from "../../hooks/use-subject";
|
||||
import IntersectionObserverProvider from "../../providers/local/intersection-observer";
|
||||
import { useTimelineCurserIntersectionCallback } from "../../hooks/use-timeline-cursor-intersection-callback";
|
||||
@ -27,7 +27,7 @@ function BadgesPage() {
|
||||
},
|
||||
[muteFilter],
|
||||
);
|
||||
const readRelays = useReadRelayUrls();
|
||||
const readRelays = useReadRelays();
|
||||
const timeline = useTimelineLoader(
|
||||
`${listId}-lists`,
|
||||
readRelays,
|
||||
|
@ -23,7 +23,7 @@ import HoverLinkOverlay from "../../../components/hover-link-overlay";
|
||||
import UserAvatarLink from "../../../components/user-avatar-link";
|
||||
import UserLink from "../../../components/user-link";
|
||||
import useSingleEvent from "../../../hooks/use-single-event";
|
||||
import { useReadRelayUrls } from "../../../hooks/use-client-relays";
|
||||
import { useReadRelays } from "../../../hooks/use-client-relays";
|
||||
import singleEventService from "../../../services/single-event";
|
||||
|
||||
export default function ChannelCard({
|
||||
@ -31,7 +31,7 @@ export default function ChannelCard({
|
||||
additionalRelays,
|
||||
...props
|
||||
}: Omit<CardProps, "children"> & { channel: NostrEvent; additionalRelays?: string[] }) {
|
||||
const readRelays = useReadRelayUrls(additionalRelays);
|
||||
const readRelays = useReadRelays(additionalRelays);
|
||||
const { metadata } = useChannelMetadata(channel.id, readRelays);
|
||||
|
||||
const ref = useRef<HTMLDivElement | null>(null);
|
||||
|
@ -7,7 +7,7 @@ import { PointerCommunityCard } from "./components/community-card";
|
||||
import VerticalPageLayout from "../../components/vertical-page-layout";
|
||||
import { COMMUNITY_DEFINITION_KIND } from "../../helpers/nostr/communities";
|
||||
import { ErrorBoundary } from "../../components/error-boundary";
|
||||
import { useReadRelayUrls } from "../../hooks/use-client-relays";
|
||||
import { useReadRelays } from "../../hooks/use-client-relays";
|
||||
import useSubjects from "../../hooks/use-subjects";
|
||||
import replaceableEventLoaderService from "../../services/replaceable-event-requester";
|
||||
import { COMMUNITIES_LIST_KIND, getCoordinatesFromList } from "../../helpers/nostr/lists";
|
||||
@ -18,7 +18,7 @@ import UserAvatarLink from "../../components/user-avatar-link";
|
||||
import { AddressPointer } from "nostr-tools/lib/types/nip19";
|
||||
|
||||
export function useUsersJoinedCommunitiesLists(pubkeys: string[], additionalRelays?: Iterable<string>) {
|
||||
const readRelays = useReadRelayUrls(additionalRelays);
|
||||
const readRelays = useReadRelays(additionalRelays);
|
||||
const communityListsSubjects = useMemo(() => {
|
||||
return pubkeys.map((pubkey) =>
|
||||
replaceableEventLoaderService.requestEvent(readRelays, COMMUNITIES_LIST_KIND, pubkey),
|
||||
|
@ -41,7 +41,7 @@ import NostrPublishAction from "../../classes/nostr-publish-action";
|
||||
import clientRelaysService from "../../services/client-relays";
|
||||
import replaceableEventLoaderService, { createCoordinate } from "../../services/replaceable-event-requester";
|
||||
import { getImageSize } from "../../helpers/image";
|
||||
import { useReadRelayUrls } from "../../hooks/use-client-relays";
|
||||
import { useReadRelays } from "../../hooks/use-client-relays";
|
||||
import useTimelineLoader from "../../hooks/use-timeline-loader";
|
||||
import useSubject from "../../hooks/use-subject";
|
||||
import useUserMuteFilter from "../../hooks/use-user-mute-filter";
|
||||
@ -60,7 +60,7 @@ function CommunitiesHomePage() {
|
||||
const account = useCurrentAccount()!;
|
||||
const createModal = useDisclosure();
|
||||
|
||||
const readRelays = useReadRelayUrls();
|
||||
const readRelays = useReadRelays();
|
||||
const { pointers: communityCoordinates } = useUserCommunitiesList(account.pubkey, readRelays, {
|
||||
alwaysRequest: true,
|
||||
});
|
||||
|
@ -23,7 +23,7 @@ import Hourglass03 from "../../components/icons/hourglass-03";
|
||||
import VerticalCommunityDetails from "./components/vertical-community-details";
|
||||
import { useBreakpointValue } from "../../providers/global/breakpoint-provider";
|
||||
import HorizontalCommunityDetails from "./components/horizonal-community-details";
|
||||
import { useReadRelayUrls } from "../../hooks/use-client-relays";
|
||||
import { useReadRelays } from "../../hooks/use-client-relays";
|
||||
import useTimelineLoader from "../../hooks/use-timeline-loader";
|
||||
import { getEventCoordinate, getEventUID } from "../../helpers/nostr/events";
|
||||
import { WritingIcon } from "../../components/icons";
|
||||
@ -50,7 +50,7 @@ export default function CommunityHomePage({ community }: { community: NostrEvent
|
||||
const verticalLayout = useBreakpointValue({ base: true, xl: false });
|
||||
|
||||
const communityRelays = getCommunityRelays(community);
|
||||
const readRelays = useReadRelayUrls(communityRelays);
|
||||
const readRelays = useReadRelays(communityRelays);
|
||||
const timeline = useTimelineLoader(`${getEventUID(community)}-timeline`, readRelays, {
|
||||
kinds: [kinds.ShortTextNote, kinds.Repost, kinds.GenericRepost, COMMUNITY_APPROVAL_KIND],
|
||||
"#a": [communityCoordinate],
|
||||
|
@ -14,7 +14,7 @@ import {
|
||||
|
||||
import { NostrEvent } from "../../../types/nostr-event";
|
||||
import useTimelineLoader from "../../../hooks/use-timeline-loader";
|
||||
import { useReadRelayUrls } from "../../../hooks/use-client-relays";
|
||||
import { useReadRelays } from "../../../hooks/use-client-relays";
|
||||
import { getCommunityRelays } from "../../../helpers/nostr/communities";
|
||||
import { getEventCoordinate } from "../../../helpers/nostr/events";
|
||||
import { COMMUNITIES_LIST_KIND } from "../../../helpers/nostr/lists";
|
||||
@ -44,7 +44,7 @@ export default function CommunityMembersModal({
|
||||
...props
|
||||
}: Omit<ModalProps, "children"> & { community: NostrEvent }) {
|
||||
const communityCoordinate = getEventCoordinate(community);
|
||||
const readRelays = useReadRelayUrls(getCommunityRelays(community));
|
||||
const readRelays = useReadRelays(getCommunityRelays(community));
|
||||
const timeline = useTimelineLoader(`${communityCoordinate}-members`, readRelays, [
|
||||
{ "#a": [communityCoordinate], kinds: [COMMUNITIES_LIST_KIND] },
|
||||
]);
|
||||
|
@ -27,7 +27,7 @@ import { getEventUID, parseHardcodedNoteContent } from "../../../helpers/nostr/e
|
||||
import UserLink from "../../../components/user-link";
|
||||
import UserAvatarLink from "../../../components/user-avatar-link";
|
||||
import useUserMuteFilter from "../../../hooks/use-user-mute-filter";
|
||||
import { useReadRelayUrls } from "../../../hooks/use-client-relays";
|
||||
import { useReadRelays } from "../../../hooks/use-client-relays";
|
||||
import useSingleEvent from "../../../hooks/use-single-event";
|
||||
import CommunityPostMenu from "./community-post-menu";
|
||||
|
||||
@ -129,7 +129,7 @@ export function CommunityRepostPost({
|
||||
const encodedRepost = parseHardcodedNoteContent(event);
|
||||
|
||||
const [_, eventId, relay] = event.tags.find(isETag) ?? [];
|
||||
const readRelays = useReadRelayUrls(relay ? [relay] : []);
|
||||
const readRelays = useReadRelays(relay ? [relay] : []);
|
||||
|
||||
const loadedRepost = useSingleEvent(eventId, readRelays);
|
||||
const repost = encodedRepost || loadedRepost;
|
||||
|
@ -2,7 +2,7 @@ import { useCallback } from "react";
|
||||
import { Navigate, useParams } from "react-router-dom";
|
||||
import { Heading, SimpleGrid } from "@chakra-ui/react";
|
||||
|
||||
import { useReadRelayUrls } from "../../hooks/use-client-relays";
|
||||
import { useReadRelays } from "../../hooks/use-client-relays";
|
||||
import { COMMUNITY_DEFINITION_KIND, validateCommunity } from "../../helpers/nostr/communities";
|
||||
import useTimelineLoader from "../../hooks/use-timeline-loader";
|
||||
import { NostrEvent } from "../../types/nostr-event";
|
||||
@ -23,7 +23,7 @@ export default function CommunityFindByNameView() {
|
||||
return <Navigate to={`/c/${decoded.data.identifier}/${decoded.data.pubkey}`} replace />;
|
||||
}
|
||||
|
||||
const readRelays = useReadRelayUrls();
|
||||
const readRelays = useReadRelays();
|
||||
const eventFilter = useCallback((event: NostrEvent) => {
|
||||
return validateCommunity(event);
|
||||
}, []);
|
||||
|
@ -24,7 +24,7 @@ import NostrPublishAction from "../../../classes/nostr-publish-action";
|
||||
import CommunityPost from "../components/community-post";
|
||||
import { RouterContext } from "../community-home";
|
||||
import useUserMuteFilter from "../../../hooks/use-user-mute-filter";
|
||||
import { useWriteRelayUrls } from "../../../hooks/use-client-relays";
|
||||
import { useWriteRelays } from "../../../hooks/use-client-relays";
|
||||
|
||||
type PendingProps = {
|
||||
event: NostrEvent;
|
||||
@ -40,7 +40,7 @@ function ModPendingPost({ event, community, approvals }: PendingProps) {
|
||||
useRegisterIntersectionEntity(ref, getEventUID(event));
|
||||
|
||||
const communityRelays = getCommunityRelays(community);
|
||||
const writeRelays = useWriteRelayUrls(communityRelays);
|
||||
const writeRelays = useWriteRelays(communityRelays);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const approve = useCallback(async () => {
|
||||
setLoading(true);
|
||||
|
@ -27,7 +27,7 @@ import NostrPublishAction from "../../../classes/nostr-publish-action";
|
||||
import { useSigningContext } from "../../../providers/global/signing-provider";
|
||||
import { DraftNostrEvent } from "../../../types/nostr-event";
|
||||
import clientRelaysService from "../../../services/client-relays";
|
||||
import { useReadRelayUrls } from "../../../hooks/use-client-relays";
|
||||
import { useReadRelays } from "../../../hooks/use-client-relays";
|
||||
import { DVMAvatarLink } from "./dvm-avatar";
|
||||
import DVMLink from "./dvm-name";
|
||||
import { AddressPointer } from "nostr-tools/lib/types/nip19";
|
||||
@ -38,7 +38,7 @@ function NextPageButton({ chain, pointer }: { pointer: AddressPointer; chain: Ch
|
||||
const toast = useToast();
|
||||
const { requestSignature } = useSigningContext();
|
||||
const dvmRelays = useUserMailboxes(pointer.pubkey)?.relays;
|
||||
const readRelays = useReadRelayUrls();
|
||||
const readRelays = useReadRelays();
|
||||
|
||||
const lastJob = chain[chain.length - 1];
|
||||
const requestNextPage = async () => {
|
||||
|
@ -30,7 +30,7 @@ import clientRelaysService from "../../services/client-relays";
|
||||
import VerticalPageLayout from "../../components/vertical-page-layout";
|
||||
import useSubject from "../../hooks/use-subject";
|
||||
import useTimelineLoader from "../../hooks/use-timeline-loader";
|
||||
import { useReadRelayUrls } from "../../hooks/use-client-relays";
|
||||
import { useReadRelays } from "../../hooks/use-client-relays";
|
||||
import { useSigningContext } from "../../providers/global/signing-provider";
|
||||
import useCurrentAccount from "../../hooks/use-current-account";
|
||||
import RequireCurrentAccount from "../../providers/route/require-current-account";
|
||||
@ -52,7 +52,7 @@ function DVMFeedPage({ pointer }: { pointer: AddressPointer }) {
|
||||
const debugModal = useDisclosure();
|
||||
|
||||
const dvmRelays = useUserMailboxes(pointer.pubkey)?.relays;
|
||||
const readRelays = useReadRelayUrls(dvmRelays);
|
||||
const readRelays = useReadRelays(dvmRelays);
|
||||
const timeline = useTimelineLoader(`${pointer.kind}:${pointer.pubkey}:${pointer.identifier}-jobs`, readRelays, [
|
||||
{ authors: [account.pubkey], "#p": [pointer.pubkey], kinds: [DVM_CONTENT_DISCOVERY_JOB_KIND], since },
|
||||
{
|
||||
|
@ -4,7 +4,7 @@ import VerticalPageLayout from "../../components/vertical-page-layout";
|
||||
import DVMCard from "./components/dvm-card";
|
||||
import { DVM_CONTENT_DISCOVERY_JOB_KIND } from "../../helpers/nostr/dvm";
|
||||
import useTimelineLoader from "../../hooks/use-timeline-loader";
|
||||
import { useReadRelayUrls } from "../../hooks/use-client-relays";
|
||||
import { useReadRelays } from "../../hooks/use-client-relays";
|
||||
import useSubject from "../../hooks/use-subject";
|
||||
import RequireCurrentAccount from "../../providers/route/require-current-account";
|
||||
import { getEventCoordinate } from "../../helpers/nostr/events";
|
||||
@ -12,7 +12,7 @@ import { useTimelineCurserIntersectionCallback } from "../../hooks/use-timeline-
|
||||
import IntersectionObserverProvider from "../../providers/local/intersection-observer";
|
||||
|
||||
function DVMFeedHomePage() {
|
||||
const readRelays = useReadRelayUrls();
|
||||
const readRelays = useReadRelays();
|
||||
const timeline = useTimelineLoader("content-discovery-dvms", readRelays, {
|
||||
kinds: [31990],
|
||||
"#k": [String(DVM_CONTENT_DISCOVERY_JOB_KIND)],
|
||||
|
@ -4,7 +4,7 @@ import { Flex, SimpleGrid, Switch, useDisclosure } from "@chakra-ui/react";
|
||||
import PeopleListProvider, { usePeopleListContext } from "../../providers/local/people-list-provider";
|
||||
import PeopleListSelection from "../../components/people-list-selection/people-list-selection";
|
||||
import useTimelineLoader from "../../hooks/use-timeline-loader";
|
||||
import { useReadRelayUrls } from "../../hooks/use-client-relays";
|
||||
import { useReadRelays } from "../../hooks/use-client-relays";
|
||||
import { NostrEvent } from "../../types/nostr-event";
|
||||
import IntersectionObserverProvider from "../../providers/local/intersection-observer";
|
||||
import { useTimelineCurserIntersectionCallback } from "../../hooks/use-timeline-cursor-intersection-callback";
|
||||
@ -25,7 +25,7 @@ function EmojiPacksBrowsePage() {
|
||||
},
|
||||
[showEmpty.isOpen],
|
||||
);
|
||||
const readRelays = useReadRelayUrls();
|
||||
const readRelays = useReadRelays();
|
||||
const timeline = useTimelineLoader(
|
||||
`${listId}-browse-emoji-packs`,
|
||||
readRelays,
|
||||
|
@ -4,7 +4,7 @@ import { Link as RouterLink } from "react-router-dom";
|
||||
import useCurrentAccount from "../../hooks/use-current-account";
|
||||
import { ExternalLinkIcon } from "../../components/icons";
|
||||
import { getEventCoordinate, getEventUID } from "../../helpers/nostr/events";
|
||||
import { useReadRelayUrls } from "../../hooks/use-client-relays";
|
||||
import { useReadRelays } from "../../hooks/use-client-relays";
|
||||
import useTimelineLoader from "../../hooks/use-timeline-loader";
|
||||
import { EMOJI_PACK_KIND, getPackCordsFromFavorites } from "../../helpers/nostr/emoji-packs";
|
||||
import useSubject from "../../hooks/use-subject";
|
||||
@ -18,7 +18,7 @@ function UserEmojiPackMangerPage() {
|
||||
const account = useCurrentAccount()!;
|
||||
|
||||
const favoritePacks = useFavoriteEmojiPacks(account.pubkey);
|
||||
const readRelays = useReadRelayUrls();
|
||||
const readRelays = useReadRelays();
|
||||
const timeline = useTimelineLoader(
|
||||
`${account.pubkey}-emoji-packs`,
|
||||
readRelays,
|
||||
|
@ -5,7 +5,7 @@ import dayjs from "dayjs";
|
||||
import PeopleListProvider, { usePeopleListContext } from "../../providers/local/people-list-provider";
|
||||
import PeopleListSelection from "../../components/people-list-selection/people-list-selection";
|
||||
import useTimelineLoader from "../../hooks/use-timeline-loader";
|
||||
import { useReadRelayUrls } from "../../hooks/use-client-relays";
|
||||
import { useReadRelays } from "../../hooks/use-client-relays";
|
||||
import IntersectionObserverProvider from "../../providers/local/intersection-observer";
|
||||
import { useTimelineCurserIntersectionCallback } from "../../hooks/use-timeline-cursor-intersection-callback";
|
||||
import useSubject from "../../hooks/use-subject";
|
||||
@ -20,7 +20,7 @@ function GoalsBrowsePage() {
|
||||
const { filter, listId } = usePeopleListContext();
|
||||
const showClosed = useDisclosure();
|
||||
|
||||
const readRelays = useReadRelayUrls();
|
||||
const readRelays = useReadRelays();
|
||||
const eventFilter = useCallback(
|
||||
(event: NostrEvent) => {
|
||||
const closed = getGoalClosedDate(event);
|
||||
|
@ -4,7 +4,7 @@ import ZapModal from "../../../components/event-zap-modal";
|
||||
import eventZapsService from "../../../services/event-zaps";
|
||||
import { getEventUID } from "../../../helpers/nostr/events";
|
||||
import { getGoalRelays } from "../../../helpers/nostr/goal";
|
||||
import { useReadRelayUrls } from "../../../hooks/use-client-relays";
|
||||
import { useReadRelays } from "../../../hooks/use-client-relays";
|
||||
|
||||
export default function GoalZapButton({
|
||||
goal,
|
||||
@ -12,7 +12,7 @@ export default function GoalZapButton({
|
||||
}: Omit<ButtonProps, "children" | "onClick"> & { goal: NostrEvent }) {
|
||||
const modal = useDisclosure();
|
||||
|
||||
const readRelays = useReadRelayUrls(getGoalRelays(goal));
|
||||
const readRelays = useReadRelays(getGoalRelays(goal));
|
||||
const onZapped = async () => {
|
||||
modal.onClose();
|
||||
setTimeout(() => {
|
||||
|
@ -4,7 +4,7 @@ import { Navigate, Link as RouterLink } from "react-router-dom";
|
||||
import useCurrentAccount from "../../hooks/use-current-account";
|
||||
import { ExternalLinkIcon } from "../../components/icons";
|
||||
import { getEventUID } from "../../helpers/nostr/events";
|
||||
import { useReadRelayUrls } from "../../hooks/use-client-relays";
|
||||
import { useReadRelays } from "../../hooks/use-client-relays";
|
||||
import useTimelineLoader from "../../hooks/use-timeline-loader";
|
||||
import useSubject from "../../hooks/use-subject";
|
||||
import GoalCard from "./components/goal-card";
|
||||
@ -14,7 +14,7 @@ import VerticalPageLayout from "../../components/vertical-page-layout";
|
||||
function UserGoalsManagerPage() {
|
||||
const account = useCurrentAccount()!;
|
||||
|
||||
const readRelays = useReadRelayUrls();
|
||||
const readRelays = useReadRelays();
|
||||
const timeline = useTimelineLoader(
|
||||
`${account.pubkey}-goals`,
|
||||
readRelays,
|
||||
|
@ -3,7 +3,7 @@ import { Flex, Select, SimpleGrid, Switch, useDisclosure } from "@chakra-ui/reac
|
||||
import PeopleListProvider, { usePeopleListContext } from "../../providers/local/people-list-provider";
|
||||
import PeopleListSelection from "../../components/people-list-selection/people-list-selection";
|
||||
import useTimelineLoader from "../../hooks/use-timeline-loader";
|
||||
import { useReadRelayUrls } from "../../hooks/use-client-relays";
|
||||
import { useReadRelays } from "../../hooks/use-client-relays";
|
||||
import {
|
||||
MUTE_LIST_KIND,
|
||||
NOTE_LIST_KIND,
|
||||
@ -42,7 +42,7 @@ function BrowseListPage() {
|
||||
},
|
||||
[showEmpty.isOpen, showMute.isOpen, listKind],
|
||||
);
|
||||
const readRelays = useReadRelayUrls();
|
||||
const readRelays = useReadRelays();
|
||||
const timeline = useTimelineLoader(
|
||||
`${listId}-lists`,
|
||||
readRelays,
|
||||
|
@ -1,11 +1,11 @@
|
||||
import { Text } from "@chakra-ui/react";
|
||||
import { Note } from "../../../components/note";
|
||||
import { NoteLink } from "../../../components/note-link";
|
||||
import { useReadRelayUrls } from "../../../hooks/use-client-relays";
|
||||
import { useReadRelays } from "../../../hooks/use-client-relays";
|
||||
import useSingleEvent from "../../../hooks/use-single-event";
|
||||
|
||||
export default function NoteCard({ id, relay }: { id: string; relay?: string }) {
|
||||
const readRelays = useReadRelayUrls(relay ? [relay] : []);
|
||||
const readRelays = useReadRelays(relay ? [relay] : []);
|
||||
const event = useSingleEvent(id, readRelays);
|
||||
|
||||
return event ? (
|
||||
|
@ -10,7 +10,7 @@ import "leaflet.locatecontrol";
|
||||
|
||||
import useSubject from "../../hooks/use-subject";
|
||||
import useTimelineLoader from "../../hooks/use-timeline-loader";
|
||||
import { useReadRelayUrls } from "../../hooks/use-client-relays";
|
||||
import { useReadRelays } from "../../hooks/use-client-relays";
|
||||
|
||||
import { debounce } from "../../helpers/function";
|
||||
import TimelineActionAndStatus from "../../components/timeline-page/timeline-action-and-status";
|
||||
@ -119,7 +119,7 @@ export default function MapView() {
|
||||
|
||||
const [cells, setCells] = useState<string[]>([]);
|
||||
|
||||
const readRelays = useReadRelayUrls();
|
||||
const readRelays = useReadRelays();
|
||||
const timeline = useTimelineLoader(
|
||||
"geo-events",
|
||||
readRelays,
|
||||
|
@ -18,7 +18,7 @@ import NostrPublishAction from "../../classes/nostr-publish-action";
|
||||
import { ExternalLinkIcon } from "../../components/icons";
|
||||
import { isLNURL } from "../../helpers/lnurl";
|
||||
import { Kind0ParsedContent } from "../../helpers/user-metadata";
|
||||
import { useReadRelayUrls, useWriteRelayUrls } from "../../hooks/use-client-relays";
|
||||
import { useReadRelays, useWriteRelays } from "../../hooks/use-client-relays";
|
||||
import useCurrentAccount from "../../hooks/use-current-account";
|
||||
import { useUserMetadata } from "../../hooks/use-user-metadata";
|
||||
import dnsIdentityService from "../../services/dns-identity";
|
||||
@ -189,8 +189,8 @@ const MetadataForm = ({ defaultValues, onSubmit }: MetadataFormProps) => {
|
||||
};
|
||||
|
||||
export const ProfileEditView = () => {
|
||||
const writeRelays = useWriteRelayUrls([COMMON_CONTACT_RELAY]);
|
||||
const readRelays = useReadRelayUrls();
|
||||
const writeRelays = useWriteRelays([COMMON_CONTACT_RELAY]);
|
||||
const readRelays = useReadRelays();
|
||||
const toast = useToast();
|
||||
const account = useCurrentAccount()!;
|
||||
const metadata = useUserMetadata(account.pubkey, readRelays, { alwaysRequest: true });
|
||||
|
@ -170,7 +170,6 @@ export default function RelayCard({ url, ...props }: { url: string } & Omit<Card
|
||||
{/* <RelayModeAction url={url} /> */}
|
||||
|
||||
<RelayShareButton relay={url} ml="auto" size="sm" />
|
||||
<RelayDebugButton url={url} size="sm" title="Show raw NIP-11 metadata" />
|
||||
</CardFooter>
|
||||
</Card>
|
||||
</>
|
||||
|
@ -11,7 +11,7 @@ import { RelayMode } from "../../classes/relay";
|
||||
import { ErrorBoundary } from "../../components/error-boundary";
|
||||
import VerticalPageLayout from "../../components/vertical-page-layout";
|
||||
import { isValidRelayURL } from "../../helpers/relay";
|
||||
import { useReadRelayUrls, useWriteRelayUrls } from "../../hooks/use-client-relays";
|
||||
import { useReadRelays, useWriteRelays } from "../../hooks/use-client-relays";
|
||||
|
||||
export default function RelaysView() {
|
||||
const [search, setSearch] = useState("");
|
||||
@ -19,8 +19,8 @@ export default function RelaysView() {
|
||||
const isSearching = deboundedSearch.length > 2;
|
||||
const addRelayModal = useDisclosure();
|
||||
|
||||
const readRelays = useReadRelayUrls();
|
||||
const writeRelays = useWriteRelayUrls();
|
||||
const readRelays = useReadRelays();
|
||||
const writeRelays = useWriteRelays();
|
||||
const discoveredRelays = relayPoolService
|
||||
.getRelays()
|
||||
.filter((r) => !readRelays.has(r.url) && !writeRelays.has(r.url))
|
||||
|
@ -16,7 +16,7 @@ import { Link as RouterLink, useNavigate } from "react-router-dom";
|
||||
|
||||
import VerticalPageLayout from "../../components/vertical-page-layout";
|
||||
import { getPubkeysFromList } from "../../helpers/nostr/lists";
|
||||
import { useReadRelayUrls } from "../../hooks/use-client-relays";
|
||||
import { useReadRelays } from "../../hooks/use-client-relays";
|
||||
import useCurrentAccount from "../../hooks/use-current-account";
|
||||
import useSubjects from "../../hooks/use-subjects";
|
||||
import useUserContactList from "../../hooks/use-user-contact-list";
|
||||
@ -29,7 +29,7 @@ import UserAvatar from "../../components/user-avatar";
|
||||
import { RelayMetadata, RelayPaidTag } from "./components/relay-card";
|
||||
|
||||
function usePopularContactsRelays(list?: NostrEvent) {
|
||||
const readRelays = useReadRelayUrls();
|
||||
const readRelays = useReadRelays();
|
||||
const subs = list
|
||||
? getPubkeysFromList(list).map((p) => userMailboxesService.requestMailboxes(p.pubkey, readRelays))
|
||||
: [];
|
||||
|
@ -2,7 +2,7 @@ import { Button, Flex, FlexProps, Heading, Textarea, useToast } from "@chakra-ui
|
||||
import { useForm } from "react-hook-form";
|
||||
import dayjs from "dayjs";
|
||||
|
||||
import { useWriteRelayUrls } from "../../../hooks/use-client-relays";
|
||||
import { useWriteRelays } from "../../../hooks/use-client-relays";
|
||||
import StarRating from "../../../components/star-rating";
|
||||
import { DraftNostrEvent } from "../../../types/nostr-event";
|
||||
import { RELAY_REVIEW_LABEL, RELAY_REVIEW_LABEL_NAMESPACE, REVIEW_KIND } from "../../../helpers/nostr/reviews";
|
||||
@ -16,7 +16,7 @@ export default function RelayReviewForm({
|
||||
}: { onClose: () => void; relay: string } & Omit<FlexProps, "children">) {
|
||||
const toast = useToast();
|
||||
const { requestSignature } = useSigningContext();
|
||||
const writeRelays = useWriteRelayUrls();
|
||||
const writeRelays = useWriteRelays();
|
||||
const { register, getValues, watch, handleSubmit, setValue } = useForm({
|
||||
defaultValues: {
|
||||
quality: 0.6,
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { Flex } from "@chakra-ui/react";
|
||||
|
||||
import { RELAY_REVIEW_LABEL } from "../../../helpers/nostr/reviews";
|
||||
import { useReadRelayUrls } from "../../../hooks/use-client-relays";
|
||||
import { useReadRelays } from "../../../hooks/use-client-relays";
|
||||
import useSubject from "../../../hooks/use-subject";
|
||||
import useTimelineLoader from "../../../hooks/use-timeline-loader";
|
||||
import RelayReviewNote from "../components/relay-review-note";
|
||||
@ -10,7 +10,7 @@ import { usePeopleListContext } from "../../../providers/local/people-list-provi
|
||||
|
||||
export default function RelayReviews({ relay }: { relay: string }) {
|
||||
useAppTitle(`${relay} - Reviews`);
|
||||
const readRelays = useReadRelayUrls();
|
||||
const readRelays = useReadRelays();
|
||||
|
||||
const { filter } = usePeopleListContext();
|
||||
const timeline = useTimelineLoader(
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { Button, Flex, Heading } from "@chakra-ui/react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
|
||||
import { useReadRelayUrls } from "../../hooks/use-client-relays";
|
||||
import { useReadRelays } from "../../hooks/use-client-relays";
|
||||
import useTimelineLoader from "../../hooks/use-timeline-loader";
|
||||
import useSubject from "../../hooks/use-subject";
|
||||
import RelayReviewNote from "./components/relay-review-note";
|
||||
@ -14,7 +14,7 @@ import { ChevronLeftIcon } from "../../components/icons";
|
||||
|
||||
function RelayReviewsPage() {
|
||||
const navigate = useNavigate();
|
||||
const readRelays = useReadRelayUrls();
|
||||
const readRelays = useReadRelays();
|
||||
|
||||
const { filter } = usePeopleListContext();
|
||||
const timeline = useTimelineLoader(
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { useMemo } from "react";
|
||||
import { Card, CardBody, CardHeader, CardProps, Heading, Image, LinkBox, LinkOverlay } from "@chakra-ui/react";
|
||||
|
||||
import { useReadRelayUrls } from "../../../hooks/use-client-relays";
|
||||
import { useReadRelays } from "../../../hooks/use-client-relays";
|
||||
import { useRelaySelectionRelays } from "../../../providers/local/relay-selection-provider";
|
||||
import replaceableEventLoaderService from "../../../services/replaceable-event-requester";
|
||||
import useSubject from "../../../hooks/use-subject";
|
||||
@ -25,7 +25,7 @@ function useStreamerCardsCords(pubkey: string, relays: Iterable<string>) {
|
||||
|
||||
function StreamerCard({ cord, relay, ...props }: { cord: string; relay?: string } & CardProps) {
|
||||
const contextRelays = useRelaySelectionRelays();
|
||||
const readRelays = useReadRelayUrls(relay ? [...contextRelays, relay] : contextRelays);
|
||||
const readRelays = useReadRelays(relay ? [...contextRelays, relay] : contextRelays);
|
||||
|
||||
const card = useReplaceableEvent(cord, readRelays);
|
||||
if (!card || card.kind !== STREAMER_CARD_TYPE) return null;
|
||||
@ -62,7 +62,7 @@ function StreamerCard({ cord, relay, ...props }: { cord: string; relay?: string
|
||||
|
||||
export default function StreamerCards({ pubkey, ...props }: Omit<CardProps, "children"> & { pubkey: string }) {
|
||||
const contextRelays = useRelaySelectionRelays();
|
||||
const readRelays = useReadRelayUrls(contextRelays);
|
||||
const readRelays = useReadRelays(contextRelays);
|
||||
|
||||
const cardCords = useStreamerCardsCords(pubkey, readRelays);
|
||||
|
||||
|
@ -13,7 +13,7 @@ import useTimelineLoader from "../../../hooks/use-timeline-loader";
|
||||
import RequireCurrentAccount from "../../../providers/route/require-current-account";
|
||||
import useCurrentAccount from "../../../hooks/use-current-account";
|
||||
import { getEventUID } from "../../../helpers/nostr/events";
|
||||
import { useReadRelayUrls } from "../../../hooks/use-client-relays";
|
||||
import { useReadRelays } from "../../../hooks/use-client-relays";
|
||||
import { ChevronLeftIcon } from "../../../components/icons";
|
||||
import RelaySelectionProvider from "../../../providers/local/relay-selection-provider";
|
||||
import UsersCard from "./users-card";
|
||||
@ -70,7 +70,7 @@ function StreamModerationDashboard({ stream }: { stream: ParsedStream }) {
|
||||
function StreamModerationPage() {
|
||||
const navigate = useNavigate();
|
||||
const account = useCurrentAccount()!;
|
||||
const readRelays = useReadRelayUrls();
|
||||
const readRelays = useReadRelays();
|
||||
|
||||
const timeline = useTimelineLoader(account.pubkey + "-streams", readRelays, [
|
||||
{
|
||||
|
@ -21,7 +21,7 @@ import { nip19 } from "nostr-tools";
|
||||
import { Global, css } from "@emotion/react";
|
||||
|
||||
import { ParsedStream, STREAM_KIND, parseStreamEvent } from "../../../helpers/nostr/stream";
|
||||
import { useReadRelayUrls } from "../../../hooks/use-client-relays";
|
||||
import { useReadRelays } from "../../../hooks/use-client-relays";
|
||||
import { unique } from "../../../helpers/array";
|
||||
import { LiveVideoPlayer } from "../../../components/live-video-player";
|
||||
import StreamChat, { ChatDisplayMode } from "./stream-chat";
|
||||
@ -243,7 +243,7 @@ export default function StreamView() {
|
||||
|
||||
if (!naddr) return <Navigate replace to="/streams" />;
|
||||
|
||||
const readRelays = useReadRelayUrls();
|
||||
const readRelays = useReadRelays();
|
||||
const [streamRelays, setStreamRelays] = useState<string[]>([]);
|
||||
|
||||
const subject = useMemo(() => {
|
||||
|
@ -18,7 +18,7 @@ import {
|
||||
} from "../../../helpers/nostr/post";
|
||||
import useCurrentAccount from "../../../hooks/use-current-account";
|
||||
import { useSigningContext } from "../../../providers/global/signing-provider";
|
||||
import { useWriteRelayUrls } from "../../../hooks/use-client-relays";
|
||||
import { useWriteRelays } from "../../../hooks/use-client-relays";
|
||||
import NostrPublishAction from "../../../classes/nostr-publish-action";
|
||||
import MagicTextArea, { RefType } from "../../../components/magic-textarea";
|
||||
import { useContextEmojis } from "../../../providers/global/emoji-provider";
|
||||
@ -39,7 +39,7 @@ export default function ReplyForm({ item, onCancel, onSubmitted, replyKind = kin
|
||||
const account = useCurrentAccount();
|
||||
const emojis = useContextEmojis();
|
||||
const { requestSignature } = useSigningContext();
|
||||
const writeRelays = useWriteRelayUrls();
|
||||
const writeRelays = useWriteRelays();
|
||||
|
||||
const threadMembers = useMemo(() => getThreadMembers(item, account?.pubkey), [item, account?.pubkey]);
|
||||
const { setValue, getValues, watch, handleSubmit } = useForm({
|
||||
|
@ -6,7 +6,7 @@ import { nip19 } from "nostr-tools";
|
||||
import Note from "../../components/note";
|
||||
import { ThreadPost } from "./components/thread-post";
|
||||
import VerticalPageLayout from "../../components/vertical-page-layout";
|
||||
import { useReadRelayUrls } from "../../hooks/use-client-relays";
|
||||
import { useReadRelays } from "../../hooks/use-client-relays";
|
||||
import { ThreadItem, buildThread } from "../../helpers/thread";
|
||||
import IntersectionObserverProvider from "../../providers/local/intersection-observer";
|
||||
import { useTimelineCurserIntersectionCallback } from "../../hooks/use-timeline-cursor-intersection-callback";
|
||||
@ -101,7 +101,7 @@ function ThreadPage({
|
||||
|
||||
export default function ThreadView() {
|
||||
const pointer = useParamsEventPointer("id");
|
||||
const readRelays = useReadRelayUrls(pointer.relays);
|
||||
const readRelays = useReadRelays(pointer.relays);
|
||||
|
||||
const focusedEvent = useSingleEvent(pointer.id, pointer.relays);
|
||||
const { rootPointer, events, timeline } = useThreadTimelineLoader(focusedEvent, readRelays);
|
||||
|
@ -6,7 +6,7 @@ import VerticalPageLayout from "../../components/vertical-page-layout";
|
||||
import PeopleListProvider, { usePeopleListContext } from "../../providers/local/people-list-provider";
|
||||
import PeopleListSelection from "../../components/people-list-selection/people-list-selection";
|
||||
import useTimelineLoader from "../../hooks/use-timeline-loader";
|
||||
import { useReadRelayUrls } from "../../hooks/use-client-relays";
|
||||
import { useReadRelays } from "../../hooks/use-client-relays";
|
||||
import { useTimelineCurserIntersectionCallback } from "../../hooks/use-timeline-cursor-intersection-callback";
|
||||
import IntersectionObserverProvider, {
|
||||
useRegisterIntersectionEntity,
|
||||
@ -41,7 +41,7 @@ export function DMTimelinePage() {
|
||||
},
|
||||
[clientMuteFilter],
|
||||
);
|
||||
const readRelays = useReadRelayUrls();
|
||||
const readRelays = useReadRelays();
|
||||
const timeline = useTimelineLoader(
|
||||
`${listId ?? "global"}-dm-feed`,
|
||||
readRelays,
|
||||
|
@ -18,7 +18,7 @@ import RequireCurrentAccount from "../../providers/route/require-current-account
|
||||
import { useUsersMetadata } from "../../hooks/use-user-network";
|
||||
import { MUTE_LIST_KIND, getPubkeysFromList, isPubkeyInList } from "../../helpers/nostr/lists";
|
||||
import useUserContactList from "../../hooks/use-user-contact-list";
|
||||
import { useReadRelayUrls } from "../../hooks/use-client-relays";
|
||||
import { useReadRelays } from "../../hooks/use-client-relays";
|
||||
import replaceableEventLoaderService from "../../services/replaceable-event-requester";
|
||||
import useSubjects from "../../hooks/use-subjects";
|
||||
import { useUserMetadata } from "../../hooks/use-user-metadata";
|
||||
@ -26,7 +26,7 @@ import { useNavigate } from "react-router-dom";
|
||||
import { ChevronLeftIcon } from "../../components/icons";
|
||||
|
||||
export function useUsersMuteLists(pubkeys: string[], additionalRelays?: Iterable<string>) {
|
||||
const readRelays = useReadRelayUrls(additionalRelays);
|
||||
const readRelays = useReadRelays(additionalRelays);
|
||||
const muteListSubjects = useMemo(() => {
|
||||
return pubkeys.map((pubkey) => replaceableEventLoaderService.requestEvent(readRelays, MUTE_LIST_KIND, pubkey));
|
||||
}, [pubkeys]);
|
||||
|
@ -3,7 +3,7 @@ import { Button, Flex, Select, useToast } from "@chakra-ui/react";
|
||||
import dayjs from "dayjs";
|
||||
import codes from "iso-language-codes";
|
||||
|
||||
import { useReadRelayUrls } from "../../../../hooks/use-client-relays";
|
||||
import { useReadRelays } from "../../../../hooks/use-client-relays";
|
||||
import useTimelineLoader from "../../../../hooks/use-timeline-loader";
|
||||
import { getEventUID } from "../../../../helpers/nostr/events";
|
||||
import {
|
||||
@ -28,7 +28,7 @@ export default function NoteTextToSpeechPage({ note }: { note: NostrEvent }) {
|
||||
const account = useCurrentAccount();
|
||||
|
||||
const [lang, setLang] = useState(navigator.language.split("-")[0] ?? "en");
|
||||
const readRelays = useReadRelayUrls();
|
||||
const readRelays = useReadRelays();
|
||||
const requestReading = useCallback(async () => {
|
||||
try {
|
||||
const top8Relays = relayScoreboardService.getRankedRelays(readRelays).slice(0, 8);
|
||||
|
@ -18,7 +18,7 @@ import codes from "iso-language-codes";
|
||||
import { DraftNostrEvent, NostrEvent } from "../../../../types/nostr-event";
|
||||
import useTimelineLoader from "../../../../hooks/use-timeline-loader";
|
||||
import { getEventUID } from "../../../../helpers/nostr/events";
|
||||
import { useReadRelayUrls } from "../../../../hooks/use-client-relays";
|
||||
import { useReadRelays } from "../../../../hooks/use-client-relays";
|
||||
import useSubject from "../../../../hooks/use-subject";
|
||||
import { useSigningContext } from "../../../../providers/global/signing-provider";
|
||||
import relayScoreboardService from "../../../../services/relay-scoreboard";
|
||||
@ -40,7 +40,7 @@ export function NoteTranslationsPage({ note }: { note: NostrEvent }) {
|
||||
const toast = useToast();
|
||||
|
||||
const [lang, setLang] = useState(navigator.language.split("-")[0] ?? "en");
|
||||
const readRelays = useReadRelayUrls();
|
||||
const readRelays = useReadRelays();
|
||||
const requestTranslation = useCallback(async () => {
|
||||
try {
|
||||
const top8Relays = relayScoreboardService.getRankedRelays(readRelays).slice(0, 8);
|
||||
|
@ -9,7 +9,7 @@ import VerticalPageLayout from "../../components/vertical-page-layout";
|
||||
import PeopleListProvider, { usePeopleListContext } from "../../providers/local/people-list-provider";
|
||||
import PeopleListSelection from "../../components/people-list-selection/people-list-selection";
|
||||
import useTimelineLoader from "../../hooks/use-timeline-loader";
|
||||
import { useReadRelayUrls } from "../../hooks/use-client-relays";
|
||||
import { useReadRelays } from "../../hooks/use-client-relays";
|
||||
import { useTimelineCurserIntersectionCallback } from "../../hooks/use-timeline-cursor-intersection-callback";
|
||||
import IntersectionObserverProvider, {
|
||||
useRegisterIntersectionEntity,
|
||||
@ -77,7 +77,7 @@ export function UnknownTimelinePage() {
|
||||
},
|
||||
[clientMuteFilter],
|
||||
);
|
||||
const readRelays = useReadRelayUrls();
|
||||
const readRelays = useReadRelays();
|
||||
const timeline = useTimelineLoader(`${listId ?? "global"}-unknown-feed`, readRelays, filter, { eventFilter });
|
||||
|
||||
const events = useSubject(timeline.timeline);
|
||||
|
@ -2,7 +2,7 @@ import { memo, useMemo, useRef, useState } from "react";
|
||||
|
||||
import { NostrEvent } from "../../../types/nostr-event";
|
||||
import { TORRENT_COMMENT_KIND } from "../../../helpers/nostr/torrents";
|
||||
import { useReadRelayUrls } from "../../../hooks/use-client-relays";
|
||||
import { useReadRelays } from "../../../hooks/use-client-relays";
|
||||
import useThreadTimelineLoader from "../../../hooks/use-thread-timeline-loader";
|
||||
import { ThreadItem, buildThread, countReplies } from "../../../helpers/thread";
|
||||
import { useTimelineCurserIntersectionCallback } from "../../../hooks/use-timeline-cursor-intersection-callback";
|
||||
@ -157,7 +157,7 @@ export const ThreadPost = memo(({ post, level = -1 }: { post: ThreadItem; level?
|
||||
});
|
||||
|
||||
export default function TorrentComments({ torrent }: { torrent: NostrEvent }) {
|
||||
const readRelays = useReadRelayUrls();
|
||||
const readRelays = useReadRelays();
|
||||
const { timeline, events } = useThreadTimelineLoader(torrent, readRelays, TORRENT_COMMENT_KIND);
|
||||
|
||||
const thread = useMemo(() => buildThread(events), [events]);
|
||||
|
@ -2,7 +2,7 @@ import { Flex, SimpleGrid } from "@chakra-ui/react";
|
||||
import { useOutletContext } from "react-router-dom";
|
||||
import { Event, kinds } from "nostr-tools";
|
||||
|
||||
import { useReadRelayUrls } from "../../hooks/use-client-relays";
|
||||
import { useReadRelays } from "../../hooks/use-client-relays";
|
||||
import useTimelineLoader from "../../hooks/use-timeline-loader";
|
||||
import useSubject from "../../hooks/use-subject";
|
||||
import { useTimelineCurserIntersectionCallback } from "../../hooks/use-timeline-cursor-intersection-callback";
|
||||
@ -29,7 +29,7 @@ function FollowerItem({ event }: { event: Event }) {
|
||||
|
||||
export default function UserFollowersTab() {
|
||||
const { pubkey } = useOutletContext() as { pubkey: string };
|
||||
const readRelays = useReadRelayUrls();
|
||||
const readRelays = useReadRelays();
|
||||
|
||||
const timeline = useTimelineLoader(`${pubkey}-followers`, readRelays, {
|
||||
"#p": [pubkey],
|
||||
|
@ -31,7 +31,7 @@ import { Outlet, useMatches, useNavigate } from "react-router-dom";
|
||||
import { useUserMetadata } from "../../hooks/use-user-metadata";
|
||||
import { getUserDisplayName } from "../../helpers/user-metadata";
|
||||
import { useAppTitle } from "../../hooks/use-app-title";
|
||||
import { useReadRelayUrls } from "../../hooks/use-client-relays";
|
||||
import { useReadRelays } from "../../hooks/use-client-relays";
|
||||
import relayScoreboardService from "../../services/relay-scoreboard";
|
||||
import { AdditionalRelayProvider } from "../../providers/local/additional-relay-context";
|
||||
import { unique } from "../../helpers/array";
|
||||
@ -68,7 +68,7 @@ const tabs = [
|
||||
|
||||
function useUserBestOutbox(pubkey: string, count: number = 4) {
|
||||
const mailbox = useUserMailboxes(pubkey);
|
||||
const relays = useReadRelayUrls(mailbox?.outbox);
|
||||
const relays = useReadRelays(mailbox?.outbox);
|
||||
const sorted = relayScoreboardService.getRankedRelays(relays);
|
||||
return !count ? sorted : sorted.slice(0, count);
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ import { Link as RouterLink, useOutletContext } from "react-router-dom";
|
||||
import UserAvatarLink from "../../components/user-avatar-link";
|
||||
import UserLink from "../../components/user-link";
|
||||
import useTimelineLoader from "../../hooks/use-timeline-loader";
|
||||
import { useReadRelayUrls } from "../../hooks/use-client-relays";
|
||||
import { useReadRelays } from "../../hooks/use-client-relays";
|
||||
import { MUTE_LIST_KIND, PEOPLE_LIST_KIND, getListName, getPubkeysFromList } from "../../helpers/nostr/lists";
|
||||
import useSubject from "../../hooks/use-subject";
|
||||
import IntersectionObserverProvider, {
|
||||
@ -45,7 +45,7 @@ const User = memo(({ pubkey, lists }: { pubkey: string; lists: NostrEvent[] }) =
|
||||
export default function UserMutedByTab() {
|
||||
const { pubkey } = useOutletContext() as { pubkey: string };
|
||||
|
||||
const readRelays = useReadRelayUrls();
|
||||
const readRelays = useReadRelays();
|
||||
const timeline = useTimelineLoader(`${pubkey}-muted-by`, readRelays, [
|
||||
{ kinds: [MUTE_LIST_KIND], "#p": [pubkey] },
|
||||
{ kinds: [PEOPLE_LIST_KIND], "#d": ["mute"], "#p": [pubkey] },
|
||||
|
@ -6,7 +6,7 @@ import { nip25 } from "nostr-tools";
|
||||
import useTimelineLoader from "../../hooks/use-timeline-loader";
|
||||
import { NostrEvent } from "../../types/nostr-event";
|
||||
import { useAdditionalRelayContext } from "../../providers/local/additional-relay-context";
|
||||
import { useReadRelayUrls } from "../../hooks/use-client-relays";
|
||||
import { useReadRelays } from "../../hooks/use-client-relays";
|
||||
import TimelineActionAndStatus from "../../components/timeline-page/timeline-action-and-status";
|
||||
import useSubject from "../../hooks/use-subject";
|
||||
import IntersectionObserverProvider, {
|
||||
@ -49,7 +49,7 @@ const Reaction = ({ reaction: reaction }: { reaction: NostrEvent }) => {
|
||||
export default function UserReactionsTab() {
|
||||
const { pubkey } = useOutletContext() as { pubkey: string };
|
||||
const contextRelays = useAdditionalRelayContext();
|
||||
const readRelays = useReadRelayUrls(contextRelays);
|
||||
const readRelays = useReadRelays(contextRelays);
|
||||
|
||||
const timeline = useTimelineLoader(`${pubkey}-likes`, readRelays, { authors: [pubkey], kinds: [7] });
|
||||
|
||||
|
@ -2,7 +2,7 @@ import { useOutletContext, Link as RouterLink } from "react-router-dom";
|
||||
import { Button, Flex, Heading, Spacer, StackDivider, Tag, VStack } from "@chakra-ui/react";
|
||||
|
||||
import useTimelineLoader from "../../hooks/use-timeline-loader";
|
||||
import { useReadRelayUrls } from "../../hooks/use-client-relays";
|
||||
import { useReadRelays } from "../../hooks/use-client-relays";
|
||||
import useSubject from "../../hooks/use-subject";
|
||||
import { NostrEvent } from "../../types/nostr-event";
|
||||
import RelayReviewNote from "../relays/components/relay-review-note";
|
||||
@ -58,7 +58,7 @@ const UserRelaysTab = () => {
|
||||
const { pubkey } = useOutletContext() as { pubkey: string };
|
||||
const mailboxes = useUserMailboxes(pubkey);
|
||||
|
||||
const readRelays = useReadRelayUrls(mailboxes?.outbox);
|
||||
const readRelays = useReadRelays(mailboxes?.outbox);
|
||||
const timeline = useTimelineLoader(`${pubkey}-relay-reviews`, readRelays, {
|
||||
authors: [pubkey],
|
||||
kinds: [1985],
|
||||
|
@ -13,7 +13,7 @@ import { isProfileZap, isNoteZap, parseZapEvent, totalZaps } from "../../helpers
|
||||
import useTimelineLoader from "../../hooks/use-timeline-loader";
|
||||
import { NostrEvent, isATag, isETag, isPTag } from "../../types/nostr-event";
|
||||
import { useAdditionalRelayContext } from "../../providers/local/additional-relay-context";
|
||||
import { useReadRelayUrls } from "../../hooks/use-client-relays";
|
||||
import { useReadRelays } from "../../hooks/use-client-relays";
|
||||
import TimelineActionAndStatus from "../../components/timeline-page/timeline-action-and-status";
|
||||
import useSubject from "../../hooks/use-subject";
|
||||
import IntersectionObserverProvider, {
|
||||
@ -83,7 +83,7 @@ const UserZapsTab = () => {
|
||||
const { pubkey } = useOutletContext() as { pubkey: string };
|
||||
const [filter, setFilter] = useState("both");
|
||||
const contextRelays = useAdditionalRelayContext();
|
||||
const relays = useReadRelayUrls(contextRelays);
|
||||
const relays = useReadRelays(contextRelays);
|
||||
|
||||
const eventFilter = useCallback(
|
||||
(event: NostrEvent) => {
|
||||
|
@ -21,7 +21,7 @@ import SimpleLikeButton from "../../components/event-reactions/simple-like-butto
|
||||
import SimpleDislikeButton from "../../components/event-reactions/simple-dislike-button";
|
||||
import { ErrorBoundary } from "../../components/error-boundary";
|
||||
import QuoteRepostButton from "../../components/note/components/quote-repost-button";
|
||||
import { useReadRelayUrls } from "../../hooks/use-client-relays";
|
||||
import { useReadRelays } from "../../hooks/use-client-relays";
|
||||
import useTimelineLoader from "../../hooks/use-timeline-loader";
|
||||
import useSubject from "../../hooks/use-subject";
|
||||
import VideoCard from "./components/video-card";
|
||||
@ -31,7 +31,7 @@ import { useBreakpointValue } from "../../providers/global/breakpoint-provider";
|
||||
import SimpleBookmarkButton from "../../components/simple-bookmark-button";
|
||||
|
||||
function VideoRecommendations({ video }: { video: NostrEvent }) {
|
||||
const readRelays = useReadRelayUrls();
|
||||
const readRelays = useReadRelays();
|
||||
const timeline = useTimelineLoader(video.pubkey + "-videos", readRelays, {
|
||||
authors: [video.pubkey],
|
||||
kinds: [FLARE_VIDEO_KIND],
|
||||
|
Loading…
x
Reference in New Issue
Block a user