diff --git a/web/src/lib/Api.ts b/web/src/lib/Api.ts index 45b130def..a1d4fa582 100644 --- a/web/src/lib/Api.ts +++ b/web/src/lib/Api.ts @@ -9,7 +9,7 @@ import { Signer } from './Signer'; import { channelMetadataEvents } from './cache/Events'; import { cachedEvents as newCachedEvents } from './cache/Events'; import { chronological, reverseChronological } from './Constants'; -import { metadataReqEmit } from './timelines/MainTimeline'; +import { referencesReqEmit } from './timelines/MainTimeline'; export class Api { public static readonly replaceableKinds = [ @@ -205,7 +205,7 @@ export class Api { return undefined; } - metadataReqEmit(event); + referencesReqEmit(event); // // Return // const nostrEvent = event as NostrEvent; @@ -259,7 +259,7 @@ export class Api { const referencedEvents = await this.fetchEventsByIds([...referencedEventIds]); for (const event of [...events, ...referencedEvents]) { - metadataReqEmit(event); + referencesReqEmit(event); } events.sort(reverseChronological); diff --git a/web/src/lib/Content.ts b/web/src/lib/Content.ts index 21de86f1a..6e9c29218 100644 --- a/web/src/lib/Content.ts +++ b/web/src/lib/Content.ts @@ -1,5 +1,5 @@ import { nip19 } from 'nostr-tools'; -import type { EventPointer } from 'nostr-tools/lib/nip19'; +import type { EventPointer, ProfilePointer } from 'nostr-tools/lib/nip19'; export class Token { constructor( @@ -103,6 +103,26 @@ export class Content { .filter((x): x is string => x !== undefined); } + static findNpubsAndNprofilesToPubkeys(content: string): string[] { + return this.findNpubsAndNprofiles(content) + .map((x) => { + try { + const { type, data } = nip19.decode(x); + switch (type) { + case 'npub': + return data as string; + case 'nprofile': + return (data as ProfilePointer).pubkey; + default: + return undefined; + } + } catch (error) { + return undefined; + } + }) + .filter((x): x is string => x !== undefined); + } + static findNotesAndNevents(content: string): string[] { const matches = content.matchAll(/(?<=^|\s)(nostr:)?(?(note|nevent)1\w{6,})\b/g); return [...matches] diff --git a/web/src/lib/Search.ts b/web/src/lib/Search.ts index 4f9c3e536..7d42bd112 100644 --- a/web/src/lib/Search.ts +++ b/web/src/lib/Search.ts @@ -5,7 +5,7 @@ import { EventItem } from './Items'; import { pool } from '../stores/Pool'; import { Api } from './Api'; import { readRelays } from '../stores/Author'; -import { metadataReqEmit } from './timelines/MainTimeline'; +import { referencesReqEmit } from './timelines/MainTimeline'; export class Search { parseQuery(query: string): Filter { @@ -70,7 +70,7 @@ export class Search { const events = await api.fetchEvents([filter]); console.log('[search events]', events); for (const event of events) { - metadataReqEmit(event); + referencesReqEmit(event); } events.sort(reverseChronological); return events.map((event) => new EventItem(event)); diff --git a/web/src/lib/Timeline.ts b/web/src/lib/Timeline.ts index 34c8ba3cf..b0a61fe96 100644 --- a/web/src/lib/Timeline.ts +++ b/web/src/lib/Timeline.ts @@ -11,7 +11,7 @@ import { userTimelineEvents } from '../stores/Events'; import { chunk } from './Array'; import { filterLimitItems } from './Constants'; import { Content } from './Content'; -import { metadataReqEmit } from './timelines/MainTimeline'; +import { referencesReqEmit } from './timelines/MainTimeline'; export class Timeline { private readonly $pool: SimplePool; @@ -99,7 +99,7 @@ export class Timeline { return; } - metadataReqEmit(event); + referencesReqEmit(event); // Cache note events const eventIds = new Set([ diff --git a/web/src/lib/timelines/MainTimeline.ts b/web/src/lib/timelines/MainTimeline.ts index 7dd8ccd17..3d7753a3d 100644 --- a/web/src/lib/timelines/MainTimeline.ts +++ b/web/src/lib/timelines/MainTimeline.ts @@ -11,10 +11,17 @@ import { Content } from '$lib/Content'; export const rxNostr = createRxNostr({ timeout }); // Based on NIP-65 const metadataReq = createRxBackwardReq(); -const referencesReq = createRxBackwardReq(); +const eventsReq = createRxBackwardReq(); -export function metadataReqEmit(event: Event): void { - for (const pubkey of [event.pubkey, ...filterTags('p', event.tags)]) { +export function referencesReqEmit(event: Event): void { + console.debug('[rx-nostr references REQ emit]', event); + for (const pubkey of [ + ...new Set([ + event.pubkey, + ...filterTags('p', event.tags), + ...Content.findNpubsAndNprofilesToPubkeys(event.content) + ]) + ]) { console.debug('[rx-nostr metadata REQ emit]', pubkey); metadataReq.emit({ kinds: [0], @@ -23,10 +30,8 @@ export function metadataReqEmit(event: Event): void { }); } - const ids = Content.findNotesAndNeventsToIds(event.content); - const $eventItemStore = get(eventItemStore); - referencesReq.emit({ + eventsReq.emit({ ids: [ ...new Set([ ...event.tags @@ -35,7 +40,7 @@ export function metadataReqEmit(event: Event): void { tagName === 'e' && id !== undefined && !$eventItemStore.has(id) ) .map(([, id]) => id), - ...ids + ...Content.findNotesAndNeventsToIds(event.content) ]) ] }); @@ -56,10 +61,10 @@ rxNostr }); rxNostr - .use(referencesReq.pipe(bufferTime(1000, null, 10), batch())) + .use(eventsReq.pipe(bufferTime(1000, null, 10), batch())) .pipe(uniq()) .subscribe(async (packet) => { - console.log('[rx-nostr id]', packet); + console.log('[rx-nostr event]', packet); const eventItem = new EventItem(packet.event); const $eventItemStore = get(eventItemStore); $eventItemStore.set(eventItem.event.id, eventItem); diff --git a/web/src/routes/[npub=npub]/+page.svelte b/web/src/routes/[npub=npub]/+page.svelte index 02562f5d1..2ebde0219 100644 --- a/web/src/routes/[npub=npub]/+page.svelte +++ b/web/src/routes/[npub=npub]/+page.svelte @@ -4,7 +4,7 @@ import { nip05, nip19, SimplePool, type Event } from 'nostr-tools'; import { createRxOneshotReq, now, uniq } from 'rx-nostr'; import { tap, bufferTime } from 'rxjs'; - import { metadataReqEmit, rxNostr } from '$lib/timelines/MainTimeline'; + import { referencesReqEmit, rxNostr } from '$lib/timelines/MainTimeline'; import type { User } from '../types'; import { pool } from '../../stores/Pool'; import TimelineView from '../TimelineView.svelte'; @@ -132,7 +132,7 @@ .use(pastEventsReq) .pipe( uniq(), - tap(({ event }: { event: Event }) => metadataReqEmit(event)), + tap(({ event }: { event: Event }) => referencesReqEmit(event)), bufferTime(timelineBufferMs) ) .subscribe({ diff --git a/web/src/routes/[npub=npub]/bookmark/+page.svelte b/web/src/routes/[npub=npub]/bookmark/+page.svelte index cef1d65c1..aa32bfccf 100644 --- a/web/src/routes/[npub=npub]/bookmark/+page.svelte +++ b/web/src/routes/[npub=npub]/bookmark/+page.svelte @@ -10,7 +10,7 @@ import TimelineView from '../../TimelineView.svelte'; import { Signer } from '$lib/Signer'; import { EventItem } from '$lib/Items'; - import { metadataReqEmit } from '$lib/timelines/MainTimeline'; + import { referencesReqEmit } from '$lib/timelines/MainTimeline'; let publicBookmarkEventItems: EventItem[] = []; let privateBookmarkEventItems: EventItem[] = []; @@ -56,7 +56,7 @@ console.log('[bookmarks]', originalPublicBookmarkEvents, originalPrivateBookmarkEvents); for (const event of [...originalPublicBookmarkEvents, ...originalPrivateBookmarkEvents]) { - metadataReqEmit(event); + referencesReqEmit(event); } publicBookmarkEventItems = originalPublicBookmarkEvents.map( diff --git a/web/src/routes/[npub=npub]/timeline/UserFollowingTimeline.svelte b/web/src/routes/[npub=npub]/timeline/UserFollowingTimeline.svelte index 99b9ae908..e93b6b31f 100644 --- a/web/src/routes/[npub=npub]/timeline/UserFollowingTimeline.svelte +++ b/web/src/routes/[npub=npub]/timeline/UserFollowingTimeline.svelte @@ -12,7 +12,7 @@ import { userTimelineEvents as items } from '../../../stores/Events'; import { Kind, SimplePool, type Event, nip19 } from 'nostr-tools'; import { minTimelineLength, reverseChronologicalItem, timelineBufferMs } from '$lib/Constants'; - import { rxNostr, metadataReqEmit } from '$lib/timelines/MainTimeline'; + import { rxNostr, referencesReqEmit } from '$lib/timelines/MainTimeline'; import { EventItem } from '$lib/Items'; export let pubkey: string; @@ -77,7 +77,7 @@ .use(pastEventsReq) .pipe( uniq(), - tap(({ event }: { event: Event }) => metadataReqEmit(event)), + tap(({ event }: { event: Event }) => referencesReqEmit(event)), bufferTime(timelineBufferMs) ) .subscribe({ diff --git a/web/src/routes/[slug=note]/+page.svelte b/web/src/routes/[slug=note]/+page.svelte index c964e2517..c48376af5 100644 --- a/web/src/routes/[slug=note]/+page.svelte +++ b/web/src/routes/[slug=note]/+page.svelte @@ -1,7 +1,7 @@