mirror of
https://github.com/hzrd149/nostrudel.git
synced 2025-09-26 03:28:38 +02:00
use nanoid for request and subscription ids
fix bug with useSubject hook
This commit is contained in:
@@ -27,6 +27,7 @@
|
|||||||
"leaflet": "^1.9.4",
|
"leaflet": "^1.9.4",
|
||||||
"leaflet.locatecontrol": "^0.79.0",
|
"leaflet.locatecontrol": "^0.79.0",
|
||||||
"light-bolt11-decoder": "^3.0.0",
|
"light-bolt11-decoder": "^3.0.0",
|
||||||
|
"nanoid": "^4.0.2",
|
||||||
"ngeohash": "^0.6.3",
|
"ngeohash": "^0.6.3",
|
||||||
"noble-secp256k1": "^1.2.14",
|
"noble-secp256k1": "^1.2.14",
|
||||||
"nostr-tools": "^1.14.0",
|
"nostr-tools": "^1.14.0",
|
||||||
|
@@ -1,11 +1,10 @@
|
|||||||
|
import { nanoid } from "nanoid";
|
||||||
import { Subject } from "./subject";
|
import { Subject } from "./subject";
|
||||||
import { NostrEvent } from "../types/nostr-event";
|
import { NostrEvent } from "../types/nostr-event";
|
||||||
import { NostrOutgoingMessage, NostrRequestFilter } from "../types/nostr-query";
|
import { NostrOutgoingMessage, NostrRequestFilter } from "../types/nostr-query";
|
||||||
import { IncomingEvent, Relay } from "./relay";
|
import { IncomingEvent, Relay } from "./relay";
|
||||||
import relayPoolService from "../services/relay-pool";
|
import relayPoolService from "../services/relay-pool";
|
||||||
|
|
||||||
let lastId = 0;
|
|
||||||
|
|
||||||
export class NostrMultiSubscription {
|
export class NostrMultiSubscription {
|
||||||
static INIT = "initial";
|
static INIT = "initial";
|
||||||
static OPEN = "open";
|
static OPEN = "open";
|
||||||
@@ -21,7 +20,7 @@ export class NostrMultiSubscription {
|
|||||||
seenEvents = new Set<string>();
|
seenEvents = new Set<string>();
|
||||||
|
|
||||||
constructor(relayUrls: string[], query?: NostrRequestFilter, name?: string) {
|
constructor(relayUrls: string[], query?: NostrRequestFilter, name?: string) {
|
||||||
this.id = String(name || lastId++);
|
this.id = nanoid();
|
||||||
this.query = query;
|
this.query = query;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.relayUrls = relayUrls;
|
this.relayUrls = relayUrls;
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
import { nanoid } from "nanoid";
|
||||||
import { isReplaceable } from "../helpers/nostr/events";
|
import { isReplaceable } from "../helpers/nostr/events";
|
||||||
import { addToLog } from "../services/publish-log";
|
import { addToLog } from "../services/publish-log";
|
||||||
import relayPoolService from "../services/relay-pool";
|
import relayPoolService from "../services/relay-pool";
|
||||||
@@ -7,10 +8,8 @@ import createDefer from "./deferred";
|
|||||||
import { IncomingCommandResult, Relay } from "./relay";
|
import { IncomingCommandResult, Relay } from "./relay";
|
||||||
import Subject, { PersistentSubject } from "./subject";
|
import Subject, { PersistentSubject } from "./subject";
|
||||||
|
|
||||||
let lastId = 0;
|
|
||||||
|
|
||||||
export default class NostrPublishAction {
|
export default class NostrPublishAction {
|
||||||
id = lastId++;
|
id = nanoid();
|
||||||
label: string;
|
label: string;
|
||||||
relays: string[];
|
relays: string[];
|
||||||
event: NostrEvent;
|
event: NostrEvent;
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
import { nanoid } from "nanoid";
|
||||||
import { NostrEvent } from "../types/nostr-event";
|
import { NostrEvent } from "../types/nostr-event";
|
||||||
import { NostrRequestFilter } from "../types/nostr-query";
|
import { NostrRequestFilter } from "../types/nostr-query";
|
||||||
import relayPoolService from "../services/relay-pool";
|
import relayPoolService from "../services/relay-pool";
|
||||||
@@ -5,8 +6,6 @@ import { IncomingEOSE, IncomingEvent, Relay } from "./relay";
|
|||||||
import Subject from "./subject";
|
import Subject from "./subject";
|
||||||
import createDefer from "./deferred";
|
import createDefer from "./deferred";
|
||||||
|
|
||||||
let lastId = 0;
|
|
||||||
|
|
||||||
const REQUEST_DEFAULT_TIMEOUT = 1000 * 5;
|
const REQUEST_DEFAULT_TIMEOUT = 1000 * 5;
|
||||||
export class NostrRequest {
|
export class NostrRequest {
|
||||||
static IDLE = "idle";
|
static IDLE = "idle";
|
||||||
@@ -21,8 +20,8 @@ export class NostrRequest {
|
|||||||
onComplete = createDefer<void>();
|
onComplete = createDefer<void>();
|
||||||
seenEvents = new Set<string>();
|
seenEvents = new Set<string>();
|
||||||
|
|
||||||
constructor(relayUrls: string[], timeout?: number, name?: string) {
|
constructor(relayUrls: string[], timeout?: number) {
|
||||||
this.id = name || `request-${lastId++}`;
|
this.id = nanoid();
|
||||||
this.relays = new Set(relayUrls.map((url) => relayPoolService.requestRelay(url)));
|
this.relays = new Set(relayUrls.map((url) => relayPoolService.requestRelay(url)));
|
||||||
|
|
||||||
for (const relay of this.relays) {
|
for (const relay of this.relays) {
|
||||||
|
@@ -3,8 +3,7 @@ import { NostrOutgoingMessage, NostrRequestFilter } from "../types/nostr-query";
|
|||||||
import { IncomingEOSE, Relay } from "./relay";
|
import { IncomingEOSE, Relay } from "./relay";
|
||||||
import relayPoolService from "../services/relay-pool";
|
import relayPoolService from "../services/relay-pool";
|
||||||
import { Subject } from "./subject";
|
import { Subject } from "./subject";
|
||||||
|
import { nanoid } from "nanoid";
|
||||||
let lastId = 10000;
|
|
||||||
|
|
||||||
export class NostrSubscription {
|
export class NostrSubscription {
|
||||||
static INIT = "initial";
|
static INIT = "initial";
|
||||||
@@ -20,7 +19,7 @@ export class NostrSubscription {
|
|||||||
onEOSE = new Subject<IncomingEOSE>();
|
onEOSE = new Subject<IncomingEOSE>();
|
||||||
|
|
||||||
constructor(relayUrl: string, query?: NostrRequestFilter, name?: string) {
|
constructor(relayUrl: string, query?: NostrRequestFilter, name?: string) {
|
||||||
this.id = String(name || lastId++);
|
this.id = nanoid();
|
||||||
this.query = query;
|
this.query = query;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
|
|
||||||
|
@@ -26,7 +26,6 @@ class RelayTimelineLoader {
|
|||||||
query: NostrRequestFilter;
|
query: NostrRequestFilter;
|
||||||
blockSize = BLOCK_SIZE;
|
blockSize = BLOCK_SIZE;
|
||||||
private name?: string;
|
private name?: string;
|
||||||
private requestId = 0;
|
|
||||||
private log: Debugger;
|
private log: Debugger;
|
||||||
|
|
||||||
loading = false;
|
loading = false;
|
||||||
@@ -41,7 +40,7 @@ class RelayTimelineLoader {
|
|||||||
this.query = query;
|
this.query = query;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
|
|
||||||
this.log = log || logger.extend(name);
|
this.log = log || logger.extend(this.name);
|
||||||
this.events = new EventStore(relay);
|
this.events = new EventStore(relay);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,7 +52,7 @@ class RelayTimelineLoader {
|
|||||||
query = addToQuery(query, { until: oldestEvent.created_at - 1 });
|
query = addToQuery(query, { until: oldestEvent.created_at - 1 });
|
||||||
}
|
}
|
||||||
|
|
||||||
const request = new NostrRequest([this.relay], undefined, this.name + "-" + this.requestId++);
|
const request = new NostrRequest([this.relay], 20 * 1000);
|
||||||
|
|
||||||
let gotEvents = 0;
|
let gotEvents = 0;
|
||||||
request.onEvent.subscribe((e) => {
|
request.onEvent.subscribe((e) => {
|
||||||
@@ -93,7 +92,7 @@ export class TimelineLoader {
|
|||||||
loadNextBlockBuffer = 2;
|
loadNextBlockBuffer = 2;
|
||||||
eventFilter?: (event: NostrEvent) => boolean;
|
eventFilter?: (event: NostrEvent) => boolean;
|
||||||
|
|
||||||
private name: string;
|
name: string;
|
||||||
private log: Debugger;
|
private log: Debugger;
|
||||||
private subscription: NostrMultiSubscription;
|
private subscription: NostrMultiSubscription;
|
||||||
|
|
||||||
@@ -166,6 +165,7 @@ export class TimelineLoader {
|
|||||||
|
|
||||||
this.removeLoaders();
|
this.removeLoaders();
|
||||||
|
|
||||||
|
this.log("set query", query);
|
||||||
this.query = query;
|
this.query = query;
|
||||||
this.events.clear();
|
this.events.clear();
|
||||||
this.timeline.next([]);
|
this.timeline.next([]);
|
||||||
|
@@ -1,40 +1,14 @@
|
|||||||
import { PropsWithChildren, createContext, useContext, useMemo, useState } from "react";
|
import { PropsWithChildren, createContext, useContext, useMemo, useState } from "react";
|
||||||
import { nip19 } from "nostr-tools";
|
import { Kind } from "nostr-tools";
|
||||||
|
|
||||||
import { useCurrentAccount } from "../../hooks/use-current-account";
|
import { useCurrentAccount } from "../../hooks/use-current-account";
|
||||||
import useUserContactList from "../../hooks/use-user-contact-list";
|
|
||||||
import { getPubkeysFromList } from "../../helpers/nostr/lists";
|
import { getPubkeysFromList } from "../../helpers/nostr/lists";
|
||||||
import useReplaceableEvent from "../../hooks/use-replaceable-event";
|
import useReplaceableEvent from "../../hooks/use-replaceable-event";
|
||||||
|
|
||||||
export type ListIdentifier = "following" | "global" | string;
|
|
||||||
|
|
||||||
export function useParsedNaddr(naddr?: string) {
|
|
||||||
if (!naddr) return;
|
|
||||||
try {
|
|
||||||
const parsed = nip19.decode(naddr);
|
|
||||||
|
|
||||||
if (parsed.type === "naddr") {
|
|
||||||
return parsed.data;
|
|
||||||
}
|
|
||||||
} catch (e) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function useListPeople(list: ListIdentifier) {
|
|
||||||
const account = useCurrentAccount();
|
|
||||||
const contacts = useUserContactList(account?.pubkey);
|
|
||||||
|
|
||||||
const listEvent = useReplaceableEvent(list.includes(":") ? list : undefined);
|
|
||||||
|
|
||||||
if (list === "following") return contacts ? getPubkeysFromList(contacts) : [];
|
|
||||||
if (listEvent) {
|
|
||||||
return getPubkeysFromList(listEvent);
|
|
||||||
}
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
export type PeopleListContextType = {
|
export type PeopleListContextType = {
|
||||||
list: string;
|
list?: string;
|
||||||
people: { pubkey: string; relay?: string }[];
|
people: { pubkey: string; relay?: string }[] | undefined;
|
||||||
setList: (list: string) => void;
|
setList: (list: string | undefined) => void;
|
||||||
};
|
};
|
||||||
const PeopleListContext = createContext<PeopleListContextType>({ list: "following", setList: () => {}, people: [] });
|
const PeopleListContext = createContext<PeopleListContextType>({ list: "following", setList: () => {}, people: [] });
|
||||||
|
|
||||||
@@ -44,16 +18,17 @@ export function usePeopleListContext() {
|
|||||||
|
|
||||||
export default function PeopleListProvider({ children }: PropsWithChildren) {
|
export default function PeopleListProvider({ children }: PropsWithChildren) {
|
||||||
const account = useCurrentAccount();
|
const account = useCurrentAccount();
|
||||||
const [list, setList] = useState(account ? "following" : "global");
|
const [listCord, setList] = useState(account ? `${Kind.Contacts}:${account.pubkey}` : undefined);
|
||||||
|
const listEvent = useReplaceableEvent(listCord);
|
||||||
|
|
||||||
const people = useListPeople(list);
|
const people = listEvent && getPubkeysFromList(listEvent);
|
||||||
const context = useMemo(
|
const context = useMemo(
|
||||||
() => ({
|
() => ({
|
||||||
people,
|
people,
|
||||||
list,
|
list: listCord,
|
||||||
setList,
|
setList,
|
||||||
}),
|
}),
|
||||||
[list, setList],
|
[listCord, setList, people],
|
||||||
);
|
);
|
||||||
|
|
||||||
return <PeopleListContext.Provider value={context}>{children}</PeopleListContext.Provider>;
|
return <PeopleListContext.Provider value={context}>{children}</PeopleListContext.Provider>;
|
||||||
|
@@ -13,7 +13,9 @@ function UserListOptions() {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{lists.map((list) => (
|
{lists.map((list) => (
|
||||||
<option value={getEventCoordinate(list)}>{getListName(list)}</option>
|
<option key={getEventCoordinate(list)} value={getEventCoordinate(list)}>
|
||||||
|
{getListName(list)}
|
||||||
|
</option>
|
||||||
))}
|
))}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
@@ -32,7 +34,7 @@ export default function PeopleListSelection({
|
|||||||
<Select
|
<Select
|
||||||
value={list}
|
value={list}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
setList(e.target.value);
|
setList(e.target.value === "global" ? undefined : e.target.value);
|
||||||
}}
|
}}
|
||||||
{...props}
|
{...props}
|
||||||
>
|
>
|
||||||
|
@@ -5,7 +5,7 @@ function useSubject<Value extends unknown>(subject: PersistentSubject<Value>): V
|
|||||||
function useSubject<Value extends unknown>(subject?: PersistentSubject<Value>): Value | undefined;
|
function useSubject<Value extends unknown>(subject?: PersistentSubject<Value>): Value | undefined;
|
||||||
function useSubject<Value extends unknown>(subject?: Subject<Value>): Value | undefined;
|
function useSubject<Value extends unknown>(subject?: Subject<Value>): Value | undefined;
|
||||||
function useSubject<Value extends unknown>(subject?: Subject<Value>) {
|
function useSubject<Value extends unknown>(subject?: Subject<Value>) {
|
||||||
const [value, setValue] = useState(subject?.value);
|
const [_, setValue] = useState(subject?.value);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const handler = (value: Value) => setValue(value);
|
const handler = (value: Value) => setValue(value);
|
||||||
setValue(subject?.value);
|
setValue(subject?.value);
|
||||||
@@ -16,7 +16,7 @@ function useSubject<Value extends unknown>(subject?: Subject<Value>) {
|
|||||||
};
|
};
|
||||||
}, [subject, setValue]);
|
}, [subject, setValue]);
|
||||||
|
|
||||||
return value;
|
return subject?.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default useSubject;
|
export default useSubject;
|
||||||
|
@@ -1,17 +1,12 @@
|
|||||||
import { truncatedId } from "../helpers/nostr/events";
|
|
||||||
import { NOTE_LIST_KIND, PEOPLE_LIST_KIND } from "../helpers/nostr/lists";
|
import { NOTE_LIST_KIND, PEOPLE_LIST_KIND } from "../helpers/nostr/lists";
|
||||||
import { useReadRelayUrls } from "./use-client-relays";
|
import { useReadRelayUrls } from "./use-client-relays";
|
||||||
import { useCurrentAccount } from "./use-current-account";
|
|
||||||
import useSubject from "./use-subject";
|
import useSubject from "./use-subject";
|
||||||
import useTimelineLoader from "./use-timeline-loader";
|
import useTimelineLoader from "./use-timeline-loader";
|
||||||
|
|
||||||
export default function useUserLists(pubkey: string, additionalRelays: string[] = []) {
|
export default function useUserLists(pubkey: string, additionalRelays: string[] = []) {
|
||||||
const account = useCurrentAccount();
|
|
||||||
if (!account) throw new Error("No Account");
|
|
||||||
|
|
||||||
const readRelays = useReadRelayUrls(additionalRelays);
|
const readRelays = useReadRelayUrls(additionalRelays);
|
||||||
const timeline = useTimelineLoader(truncatedId(account.pubkey) + "-lists", readRelays, {
|
const timeline = useTimelineLoader(`${pubkey}-lists`, readRelays, {
|
||||||
authors: [account.pubkey],
|
authors: [pubkey],
|
||||||
kinds: [PEOPLE_LIST_KIND, NOTE_LIST_KIND],
|
kinds: [PEOPLE_LIST_KIND, NOTE_LIST_KIND],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@@ -1,117 +0,0 @@
|
|||||||
import { nip19 } from "nostr-tools";
|
|
||||||
|
|
||||||
import { NostrRequest } from "../classes/nostr-request";
|
|
||||||
import { PersistentSubject } from "../classes/subject";
|
|
||||||
import { NostrEvent, isPTag } from "../types/nostr-event";
|
|
||||||
import { getEventRelays } from "./event-relays";
|
|
||||||
import relayScoreboardService from "./relay-scoreboard";
|
|
||||||
import { getEventCoordinate } from "../helpers/nostr/events";
|
|
||||||
import { draftAddPerson, draftRemovePerson, getListName } from "../helpers/nostr/lists";
|
|
||||||
import replaceableEventLoaderService from "./replaceable-event-requester";
|
|
||||||
|
|
||||||
/** @deprecated */
|
|
||||||
export class List {
|
|
||||||
event: NostrEvent;
|
|
||||||
cord: string;
|
|
||||||
people = new PersistentSubject<{ pubkey: string; relay?: string }[]>([]);
|
|
||||||
|
|
||||||
get author() {
|
|
||||||
return this.event.pubkey;
|
|
||||||
}
|
|
||||||
get name() {
|
|
||||||
return getListName(this.event)!;
|
|
||||||
}
|
|
||||||
|
|
||||||
getAddress() {
|
|
||||||
// pick fastest for event
|
|
||||||
const relays = relayScoreboardService.getRankedRelays(getEventRelays(this.event.id).value).slice(0, 1);
|
|
||||||
|
|
||||||
return nip19.naddrEncode({
|
|
||||||
pubkey: this.event.pubkey,
|
|
||||||
identifier: this.name,
|
|
||||||
relays,
|
|
||||||
kind: this.event.kind,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor(event: NostrEvent) {
|
|
||||||
this.event = event;
|
|
||||||
this.cord = getEventCoordinate(event);
|
|
||||||
this.updatePeople();
|
|
||||||
}
|
|
||||||
|
|
||||||
private updatePeople() {
|
|
||||||
const people = this.event.tags.filter(isPTag).map((p) => ({ pubkey: p[1], relay: p[2] }));
|
|
||||||
this.people.next(people);
|
|
||||||
}
|
|
||||||
handleEvent(event: NostrEvent) {
|
|
||||||
if (event.created_at > this.event.created_at) {
|
|
||||||
this.event = event;
|
|
||||||
this.updatePeople();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
draftAddPerson(pubkey: string, relay?: string) {
|
|
||||||
return draftAddPerson(this.event, pubkey, relay);
|
|
||||||
}
|
|
||||||
|
|
||||||
draftRemovePerson(pubkey: string) {
|
|
||||||
return draftRemovePerson(this.event, pubkey);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class ListsService {
|
|
||||||
private lists = new Map<string, List>();
|
|
||||||
private pubkeyLists = new Map<string, PersistentSubject<Record<string, List>>>();
|
|
||||||
|
|
||||||
private fetchingPubkeys = new Set();
|
|
||||||
fetchListsForPubkey(pubkey: string, relays: string[]) {
|
|
||||||
if (this.fetchingPubkeys.has(pubkey)) return this.pubkeyLists.get(pubkey)!;
|
|
||||||
this.fetchingPubkeys.add(pubkey);
|
|
||||||
|
|
||||||
if (!this.pubkeyLists.has(pubkey)) {
|
|
||||||
this.pubkeyLists.set(pubkey, new PersistentSubject<Record<string, List>>({}));
|
|
||||||
}
|
|
||||||
let subject = this.pubkeyLists.get(pubkey)!;
|
|
||||||
|
|
||||||
const request = new NostrRequest(relays);
|
|
||||||
request.onEvent.subscribe((event) => {
|
|
||||||
replaceableEventLoaderService.handleEvent(event);
|
|
||||||
|
|
||||||
const listName = getListName(event);
|
|
||||||
|
|
||||||
if (listName && event.kind === 30000) {
|
|
||||||
if (subject.value[listName]) {
|
|
||||||
subject.value[listName].handleEvent(event);
|
|
||||||
} else {
|
|
||||||
const list = new List(event);
|
|
||||||
this.lists.set(event.id, list);
|
|
||||||
subject.next({ ...subject.value, [listName]: list });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
request.start({ kinds: [30000], authors: [pubkey] });
|
|
||||||
|
|
||||||
return subject;
|
|
||||||
}
|
|
||||||
|
|
||||||
requestUserLists(pubkey: string, relays: string[], alwaysFetch = false) {
|
|
||||||
if (!this.pubkeyLists.has(pubkey) || alwaysFetch) {
|
|
||||||
return this.fetchListsForPubkey(pubkey, relays);
|
|
||||||
}
|
|
||||||
return this.pubkeyLists.get(pubkey)!;
|
|
||||||
}
|
|
||||||
|
|
||||||
getListsForPubkey(pubkey: string) {
|
|
||||||
return this.pubkeyLists.get(pubkey);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const listsService = new ListsService();
|
|
||||||
|
|
||||||
if (import.meta.env.DEV) {
|
|
||||||
//@ts-ignore
|
|
||||||
window.listsService = listsService;
|
|
||||||
}
|
|
||||||
|
|
||||||
export default listsService;
|
|
@@ -1,11 +1,11 @@
|
|||||||
import { useCallback, useMemo, useState } from "react";
|
import { useCallback, useState } from "react";
|
||||||
import { Code, Flex, Select, SimpleGrid } from "@chakra-ui/react";
|
import { Code, Flex, Select, SimpleGrid } from "@chakra-ui/react";
|
||||||
import useTimelineLoader from "../../hooks/use-timeline-loader";
|
import useTimelineLoader from "../../hooks/use-timeline-loader";
|
||||||
import IntersectionObserverProvider from "../../providers/intersection-observer";
|
import IntersectionObserverProvider from "../../providers/intersection-observer";
|
||||||
import { useTimelineCurserIntersectionCallback } from "../../hooks/use-timeline-cursor-intersection-callback";
|
import { useTimelineCurserIntersectionCallback } from "../../hooks/use-timeline-cursor-intersection-callback";
|
||||||
import useSubject from "../../hooks/use-subject";
|
import useSubject from "../../hooks/use-subject";
|
||||||
import StreamCard from "./components/stream-card";
|
import StreamCard from "./components/stream-card";
|
||||||
import { ParsedStream, STREAM_KIND, parseStreamEvent } from "../../helpers/nostr/stream";
|
import { STREAM_KIND, parseStreamEvent } from "../../helpers/nostr/stream";
|
||||||
import { NostrEvent } from "../../types/nostr-event";
|
import { NostrEvent } from "../../types/nostr-event";
|
||||||
import RelaySelectionButton from "../../components/relay-selection/relay-selection-button";
|
import RelaySelectionButton from "../../components/relay-selection/relay-selection-button";
|
||||||
import RelaySelectionProvider, { useRelaySelectionRelays } from "../../providers/relay-selection-provider";
|
import RelaySelectionProvider, { useRelaySelectionRelays } from "../../providers/relay-selection-provider";
|
||||||
@@ -32,15 +32,14 @@ function StreamsPage() {
|
|||||||
|
|
||||||
const { people, list } = usePeopleListContext();
|
const { people, list } = usePeopleListContext();
|
||||||
const query =
|
const query =
|
||||||
people.length > 0
|
people && people.length > 0
|
||||||
? [
|
? [
|
||||||
{ authors: people.map((p) => p.pubkey), kinds: [STREAM_KIND] },
|
{ authors: people.map((p) => p.pubkey), kinds: [STREAM_KIND] },
|
||||||
{ "#p": people.map((p) => p.pubkey), kinds: [STREAM_KIND] },
|
{ "#p": people.map((p) => p.pubkey), kinds: [STREAM_KIND] },
|
||||||
]
|
]
|
||||||
: { kinds: [STREAM_KIND] };
|
: { kinds: [STREAM_KIND] };
|
||||||
|
|
||||||
// TODO: put the list id into the timeline key so it refreshes (probably have to hash the list id since its >64)
|
const timeline = useTimelineLoader(`${list}-streams`, relays, query, { eventFilter });
|
||||||
const timeline = useTimelineLoader(`streams`, relays, query, { eventFilter });
|
|
||||||
|
|
||||||
useRelaysChanged(relays, () => timeline.reset());
|
useRelaysChanged(relays, () => timeline.reset());
|
||||||
|
|
||||||
|
@@ -5039,6 +5039,11 @@ nanoid@^3.3.6:
|
|||||||
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.6.tgz#443380c856d6e9f9824267d960b4236ad583ea4c"
|
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.6.tgz#443380c856d6e9f9824267d960b4236ad583ea4c"
|
||||||
integrity sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==
|
integrity sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==
|
||||||
|
|
||||||
|
nanoid@^4.0.2:
|
||||||
|
version "4.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-4.0.2.tgz#140b3c5003959adbebf521c170f282c5e7f9fb9e"
|
||||||
|
integrity sha512-7ZtY5KTCNheRGfEFxnedV5zFiORN1+Y1N6zvPTnHQd8ENUvfaDBeuJDZb2bN/oXwXxu3qkTXDzy57W5vAmDTBw==
|
||||||
|
|
||||||
ngeohash@^0.6.3:
|
ngeohash@^0.6.3:
|
||||||
version "0.6.3"
|
version "0.6.3"
|
||||||
resolved "https://registry.yarnpkg.com/ngeohash/-/ngeohash-0.6.3.tgz#10b1e80be5488262ec95c56cf2dbb6c45fbdf245"
|
resolved "https://registry.yarnpkg.com/ngeohash/-/ngeohash-0.6.3.tgz#10b1e80be5488262ec95c56cf2dbb6c45fbdf245"
|
||||||
|
Reference in New Issue
Block a user