mirror of
https://github.com/hzrd149/nostrudel.git
synced 2025-09-27 12:07:43 +02:00
small fixes
This commit is contained in:
@@ -8,7 +8,7 @@ interface ConnectableApi<T> {
|
||||
connect(connectable: Connectable<T>): this;
|
||||
disconnect(connectable: Connectable<T>): this;
|
||||
}
|
||||
type Connection<From, To = From, Prev = To> = (value: From, next: (value: To) => any, prevValue: Prev) => void;
|
||||
export type Connection<From, To = From, Prev = To> = (value: From, next: (value: To) => any, prevValue: Prev) => void;
|
||||
|
||||
export class Subject<Value> implements Connectable<Value> {
|
||||
listeners: [ListenerFn<Value>, Object | undefined][] = [];
|
||||
|
@@ -23,6 +23,10 @@ export function safeRelayUrl(relayUrl: string) {
|
||||
return null;
|
||||
}
|
||||
|
||||
export function safeRelayUrls(urls: string[]): string[] {
|
||||
return urls.map(safeRelayUrl).filter(Boolean) as string[];
|
||||
}
|
||||
|
||||
export function replaceDomain(url: string | URL, replacementUrl: string | URL) {
|
||||
const newUrl = new URL(url);
|
||||
replacementUrl = convertToUrl(replacementUrl);
|
||||
|
@@ -5,8 +5,9 @@ import { DraftNostrEvent, RTag } from "../types/nostr-event";
|
||||
import accountService from "./account";
|
||||
import { RelayConfig, RelayMode } from "../classes/relay";
|
||||
import userRelaysService, { ParsedUserRelays } from "./user-relays";
|
||||
import { PersistentSubject, Subject } from "../classes/subject";
|
||||
import { Connection, PersistentSubject, Subject } from "../classes/subject";
|
||||
import signingService from "./signing";
|
||||
import { logger } from "../helpers/debug";
|
||||
|
||||
export type RelayDirectory = Record<string, { read: boolean; write: boolean }>;
|
||||
|
||||
@@ -18,21 +19,30 @@ const DEFAULT_RELAYS = [
|
||||
{ url: "wss://nos.lol", mode: RelayMode.READ },
|
||||
];
|
||||
|
||||
const userRelaysToRelayConfig: Connection<ParsedUserRelays, RelayConfig[], RelayConfig[] | undefined> = (
|
||||
userRelays,
|
||||
next
|
||||
) => next(userRelays.relays);
|
||||
|
||||
class ClientRelayService {
|
||||
bootstrapRelays = new Set<string>();
|
||||
relays = new PersistentSubject<RelayConfig[]>([]);
|
||||
writeRelays = new PersistentSubject<RelayConfig[]>([]);
|
||||
readRelays = new PersistentSubject<RelayConfig[]>([]);
|
||||
|
||||
log = logger.extend("ClientRelays");
|
||||
|
||||
constructor() {
|
||||
let lastSubject: Subject<ParsedUserRelays> | undefined;
|
||||
accountService.current.subscribe((account) => {
|
||||
if (!account) {
|
||||
this.log("No account, using default relays");
|
||||
this.relays.next(DEFAULT_RELAYS);
|
||||
return;
|
||||
} else this.relays.next([]);
|
||||
|
||||
if (account.relays) {
|
||||
this.log("Found bootstrap relays");
|
||||
this.bootstrapRelays.clear();
|
||||
for (const relay of account.relays) {
|
||||
this.bootstrapRelays.add(relay);
|
||||
@@ -40,41 +50,47 @@ class ClientRelayService {
|
||||
}
|
||||
|
||||
if (lastSubject) {
|
||||
lastSubject.unsubscribe(this.handleRelayChanged, this);
|
||||
this.log("Disconnecting from previous user relays");
|
||||
this.relays.disconnect(lastSubject);
|
||||
lastSubject = undefined;
|
||||
}
|
||||
|
||||
// load the relays from cache or bootstrap relays
|
||||
this.log("Load users relays from cache or bootstrap relays");
|
||||
lastSubject = userRelaysService.requestRelays(account.pubkey, Array.from(this.bootstrapRelays));
|
||||
setTimeout(() => {
|
||||
// double check for new relay notes
|
||||
this.log("Requesting latest relays from the write relays");
|
||||
userRelaysService.requestRelays(account.pubkey, this.getWriteUrls(), true);
|
||||
}, 1000);
|
||||
|
||||
lastSubject.subscribe(this.handleRelayChanged, this);
|
||||
this.relays.connectWithHandler(lastSubject, userRelaysToRelayConfig);
|
||||
});
|
||||
|
||||
this.relays.subscribe((relays) => this.writeRelays.next(relays.filter((r) => r.mode & RelayMode.WRITE)));
|
||||
this.relays.subscribe((relays) => this.readRelays.next(relays.filter((r) => r.mode & RelayMode.READ)));
|
||||
}
|
||||
|
||||
private handleRelayChanged(relays: ParsedUserRelays) {
|
||||
this.relays.next(relays.relays);
|
||||
// set the read and write relays
|
||||
this.relays.subscribe((relays) => {
|
||||
this.log("Got new relay list");
|
||||
this.writeRelays.next(relays.filter((r) => r.mode & RelayMode.WRITE));
|
||||
this.readRelays.next(relays.filter((r) => r.mode & RelayMode.READ));
|
||||
});
|
||||
}
|
||||
|
||||
async addRelay(url: string, mode: RelayMode) {
|
||||
this.log(`Adding ${url} relay`);
|
||||
if (!this.relays.value.some((r) => r.url === url)) {
|
||||
const newRelays = [...this.relays.value, { url, mode }];
|
||||
await this.postUpdatedRelays(newRelays);
|
||||
}
|
||||
}
|
||||
async updateRelay(url: string, mode: RelayMode) {
|
||||
this.log(`Updating ${url} relay`);
|
||||
if (this.relays.value.some((r) => r.url === url)) {
|
||||
const newRelays = this.relays.value.map((r) => (r.url === url ? { url, mode } : r));
|
||||
await this.postUpdatedRelays(newRelays);
|
||||
}
|
||||
}
|
||||
async removeRelay(url: string) {
|
||||
this.log(`Removing ${url} relay`);
|
||||
if (this.relays.value.some((r) => r.url === url)) {
|
||||
const newRelays = this.relays.value.filter((r) => r.url !== url);
|
||||
await this.postUpdatedRelays(newRelays);
|
||||
|
@@ -1,5 +1,6 @@
|
||||
import createDefer, { Deferred } from "../classes/deferred";
|
||||
import { NostrRequest } from "../classes/nostr-request";
|
||||
import { safeRelayUrl, safeRelayUrls } from "../helpers/url";
|
||||
import { NostrEvent } from "../types/nostr-event";
|
||||
|
||||
class SingleEventService {
|
||||
@@ -11,7 +12,7 @@ class SingleEventService {
|
||||
const event = this.eventCache.get(id);
|
||||
if (event) return event;
|
||||
|
||||
this.pending.set(id, this.pending.get(id)?.concat(relays) ?? relays);
|
||||
this.pending.set(id, this.pending.get(id)?.concat(relays) ?? safeRelayUrls(relays));
|
||||
const deferred = createDefer<NostrEvent>();
|
||||
this.pendingPromises.set(id, deferred);
|
||||
return deferred;
|
||||
|
@@ -29,7 +29,13 @@ class UserRelaysService {
|
||||
}
|
||||
requestRelays(pubkey: string, relays: string[], alwaysRequest = false) {
|
||||
const sub = this.subjects.get(pubkey);
|
||||
const requestSub = replaceableEventLoaderService.requestEvent(relays, Kind.RelayList, pubkey);
|
||||
const requestSub = replaceableEventLoaderService.requestEvent(
|
||||
relays,
|
||||
Kind.RelayList,
|
||||
pubkey,
|
||||
undefined,
|
||||
alwaysRequest
|
||||
);
|
||||
sub.connectWithHandler(requestSub, (event, next) => next(parseRelaysEvent(event)));
|
||||
|
||||
// also fetch the relays from the users contacts
|
||||
|
@@ -38,7 +38,7 @@ export default function RelaysView() {
|
||||
|
||||
return (
|
||||
<Flex direction="column" gap="2" p="2">
|
||||
<Flex alignItems="center" gap="2">
|
||||
<Flex alignItems="center" gap="2" wrap="wrap">
|
||||
<Input type="search" placeholder="search" value={search} onChange={(e) => setSearch(e.target.value)} w="auto" />
|
||||
<Switch isChecked={showAll.isOpen} onChange={showAll.onToggle}>
|
||||
Show All
|
||||
|
@@ -105,7 +105,7 @@ function RelayPage({ relay }: { relay: string }) {
|
||||
<RelayJoinAction url={relay} />
|
||||
</Flex>
|
||||
<RelayMetadata url={relay} />
|
||||
<Flex gap="2">
|
||||
<Flex gap="2" wrap="wrap">
|
||||
{info?.supported_nips?.map((nip) => (
|
||||
<NipTag key={nip} nip={nip} />
|
||||
))}
|
||||
|
Reference in New Issue
Block a user