diff --git a/src/components/PostEditor/NormalPostContent.tsx b/src/components/PostEditor/NormalPostContent.tsx index f90ca1c0..793e96dd 100644 --- a/src/components/PostEditor/NormalPostContent.tsx +++ b/src/components/PostEditor/NormalPostContent.tsx @@ -1,10 +1,11 @@ import { Button } from '@/components/ui/button' import { useToast } from '@/hooks/use-toast' import { createCommentDraftEvent, createShortTextNoteDraftEvent } from '@/lib/draft-event' +import { getRootEventTag } from '@/lib/event.ts' import { useNostr } from '@/providers/NostrProvider' import client from '@/services/client.service' import { ChevronDown, ImageUp, LoaderCircle } from 'lucide-react' -import { Event, kinds } from 'nostr-tools' +import { Event, kinds, nip19 } from 'nostr-tools' import { useState } from 'react' import { useTranslation } from 'react-i18next' import TextareaWithMentions from '../TextareaWithMentions.tsx' @@ -46,9 +47,35 @@ export default function NormalPostContent({ setPosting(true) try { const additionalRelayUrls: string[] = [] - if (parentEvent) { + if (parentEvent && !specifiedRelayUrls) { const relayList = await client.fetchRelayList(parentEvent.pubkey) - additionalRelayUrls.push(...relayList.read.slice(0, 5)) + additionalRelayUrls.push(...relayList.read.slice(0, 3)) + const rootEventTag = getRootEventTag(parentEvent) + if (rootEventTag) { + const [, rootEventId, rootEventRelay, , rootAuthor] = rootEventTag + if (rootAuthor) { + if (rootAuthor !== parentEvent.pubkey) { + const rootAuthorRelayList = await client.fetchRelayList(rootAuthor) + additionalRelayUrls.push(...rootAuthorRelayList.read.slice(0, 3)) + } + } else { + try { + const rootEvent = await client.fetchEvent( + nip19.neventEncode( + rootEventRelay + ? { id: rootEventId } + : { id: rootEventId, relays: [rootEventRelay] } + ) + ) + if (rootEvent && rootEvent.pubkey !== parentEvent.pubkey) { + const rootAuthorRelayList = await client.fetchRelayList(rootEvent.pubkey) + additionalRelayUrls.push(...rootAuthorRelayList.read.slice(0, 3)) + } + } catch { + // ignore + } + } + } } const draftEvent = parentEvent && parentEvent.kind !== kinds.ShortTextNote diff --git a/src/lib/event.ts b/src/lib/event.ts index 5cdd3335..4458fa85 100644 --- a/src/lib/event.ts +++ b/src/lib/event.ts @@ -65,7 +65,7 @@ export function getParentEventId(event?: Event) { } } -export function getRootEventId(event?: Event) { +export function getRootEventTag(event?: Event) { if (!event) return undefined let tag = event.tags.find(isRootETag) if (!tag) { @@ -74,6 +74,11 @@ export function getRootEventId(event?: Event) { ([tagName, tagValue]) => tagName === 'e' && !embeddedEventIds.includes(tagValue) ) } + return tag +} + +export function getRootEventId(event?: Event) { + const tag = getRootEventTag(event) if (!tag) return undefined try { diff --git a/src/providers/NostrProvider/index.tsx b/src/providers/NostrProvider/index.tsx index f49468f0..e20cb797 100644 --- a/src/providers/NostrProvider/index.tsx +++ b/src/providers/NostrProvider/index.tsx @@ -355,15 +355,16 @@ export function NostrProvider({ children }: { children: React.ReactNode }) { }: { additionalRelayUrls?: string[]; specifiedRelayUrls?: string[] } = {} ) => { const event = await signEvent(draftEvent) - await client.publishEvent( - specifiedRelayUrls?.length - ? specifiedRelayUrls - : (relayList?.write ?? []) - .concat(additionalRelayUrls ?? []) - .concat(client.getCurrentRelayUrls()) - .concat(BIG_RELAY_URLS), - event - ) + const relays = specifiedRelayUrls?.length + ? specifiedRelayUrls + : (relayList?.write.slice(0, 5) ?? []) + .concat(additionalRelayUrls ?? []) + .concat(client.getCurrentRelayUrls()) + if (!relays.length) { + relays.push(...BIG_RELAY_URLS) + } + + await client.publishEvent(relays, event) return event } diff --git a/src/services/client.service.ts b/src/services/client.service.ts index be9d93b5..33ddf4ab 100644 --- a/src/services/client.service.ts +++ b/src/services/client.service.ts @@ -108,8 +108,9 @@ class ClientService extends EventTarget { } async publishEvent(relayUrls: string[], event: NEvent) { + const uniqueRelayUrls = Array.from(new Set(relayUrls)) const result = await Promise.any( - relayUrls.map(async (url) => { + uniqueRelayUrls.map(async (url) => { // eslint-disable-next-line @typescript-eslint/no-this-alias const that = this const relay = await this.pool.ensureRelay(url)