Browse Source

reveal embedded events

imwald
Silberengel 2 weeks ago
parent
commit
8100c3d71c
  1. 31
      src/components/Embedded/EmbeddedNote.tsx
  2. 4
      src/constants.ts
  3. 16
      src/services/client-events.service.ts

31
src/components/Embedded/EmbeddedNote.tsx

@ -5,7 +5,10 @@ import { getFavoritesFeedRelayUrls } from '@/lib/favorites-feed-relays'
import { LIVE_ACTIVITY_KINDS } from '@/lib/live-activities' import { LIVE_ACTIVITY_KINDS } from '@/lib/live-activities'
import { isCalendarEventKind } from '@/lib/calendar-event' import { isCalendarEventKind } from '@/lib/calendar-event'
import { isRenderableNoteKind } from '@/lib/note-renderable-kinds' import { isRenderableNoteKind } from '@/lib/note-renderable-kinds'
import { shouldDropEventOnIngest } from '@/lib/event-ingest-filter' import {
shouldDropEventOnIngest,
type ShouldDropEventOnIngestOptions
} from '@/lib/event-ingest-filter'
import { normalizeUrl } from '@/lib/url' import { normalizeUrl } from '@/lib/url'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
import client, { eventService } from '@/services/client.service' import client, { eventService } from '@/services/client.service'
@ -19,7 +22,11 @@ import {
syncViewerRelayStackNostrLandAggrEligible, syncViewerRelayStackNostrLandAggrEligible,
urlsForViewerNostrLandAggrEligibilitySync urlsForViewerNostrLandAggrEligibilitySync
} from '@/lib/nostr-land-relay-eligibility' } from '@/lib/nostr-land-relay-eligibility'
import { sanitizeRelayUrlsForFetch } from '@/lib/read-only-relay-personal' import {
enterMetadataRelaysOnlyBypass,
leaveMetadataRelaysOnlyBypass,
sanitizeRelayUrlsForFetch
} from '@/lib/read-only-relay-personal'
import { useFavoriteRelays } from '@/providers/favorite-relays-context' import { useFavoriteRelays } from '@/providers/favorite-relays-context'
import { useIsEventDeleted } from '@/providers/DeletedEventProvider' import { useIsEventDeleted } from '@/providers/DeletedEventProvider'
import { useReply } from '@/providers/ReplyProvider' import { useReply } from '@/providers/ReplyProvider'
@ -73,6 +80,12 @@ function coordinateFromNoteId(noteId: string): string | null {
} }
} }
/** Match {@link EventService.fetchEvent} / wide-relay ingest: explicit id lookup relaxes kind-1 spam filters. */
function embedIngestOptsForNoteKey(noteKey: string): ShouldDropEventOnIngestOptions | undefined {
const hex = hexEventIdFromNoteId(noteKey)
return hex ? { explicitNoteLookupHexId: hex } : undefined
}
/** True if `fetchEventWithExternalRelays(noteId, …)` can build a REQ filter (hex, note, nevent, naddr). */ /** True if `fetchEventWithExternalRelays(noteId, …)` can build a REQ filter (hex, note, nevent, naddr). */
function canSearchOnExternalRelays(noteId: string): boolean { function canSearchOnExternalRelays(noteId: string): boolean {
if (hexEventIdFromNoteId(noteId)) return true if (hexEventIdFromNoteId(noteId)) return true
@ -221,6 +234,8 @@ function EmbeddedNoteFetched({
const [isFetching, setIsFetching] = useState(true) const [isFetching, setIsFetching] = useState(true)
const eventRef = useRef<Event | undefined>(undefined) const eventRef = useRef<Event | undefined>(undefined)
const retryIntervalRef = useRef<ReturnType<typeof setInterval> | null>(null) const retryIntervalRef = useRef<ReturnType<typeof setInterval> | null>(null)
const embedNoteKeyRef = useRef(noteId.trim())
embedNoteKeyRef.current = noteId.trim()
eventRef.current = event eventRef.current = event
const relayHintsFromParent = useMemo( const relayHintsFromParent = useMemo(
@ -259,12 +274,13 @@ function EmbeddedNoteFetched({
const resolveAndSet = useCallback( const resolveAndSet = useCallback(
(ev: Event | undefined) => { (ev: Event | undefined) => {
if (!ev || isEventDeleted(ev) || shouldDropEventOnIngest(ev)) return false const ingestOpts = embedIngestOptsForNoteKey(embedNoteKeyRef.current)
if (!ev || isEventDeleted(ev) || shouldDropEventOnIngest(ev, ingestOpts)) return false
if (retryIntervalRef.current) { if (retryIntervalRef.current) {
clearInterval(retryIntervalRef.current) clearInterval(retryIntervalRef.current)
retryIntervalRef.current = null retryIntervalRef.current = null
} }
client.addEventToCache(ev) client.addEventToCache(ev, ingestOpts)
setEvent(ev) setEvent(ev)
addReplies([ev]) addReplies([ev])
return true return true
@ -289,12 +305,15 @@ function EmbeddedNoteFetched({
containingEventRef.current = containingEvent containingEventRef.current = containingEvent
useEffect(() => { useEffect(() => {
enterMetadataRelaysOnlyBypass()
let cancelled = false let cancelled = false
const noteKey = noteId.trim() const noteKey = noteId.trim()
embedNoteKeyRef.current = noteKey
eventRef.current = undefined eventRef.current = undefined
setEvent(undefined) setEvent(undefined)
setIsFetching(true) setIsFetching(true)
const ingestOpts = embedIngestOptsForNoteKey(noteKey)
const resolve = (ev: Event | undefined) => resolveAndSetRef.current(ev) const resolve = (ev: Event | undefined) => resolveAndSetRef.current(ev)
const tryShortcuts = (): boolean => { const tryShortcuts = (): boolean => {
@ -315,7 +334,7 @@ function EmbeddedNoteFetched({
const { fetchRelayOpts: opts, wideRelaysStatic: wideUrls } = embedFetchCtxRef.current const { fetchRelayOpts: opts, wideRelaysStatic: wideUrls } = embedFetchCtxRef.current
const hex = hexEventIdFromNoteId(noteKey) const hex = hexEventIdFromNoteId(noteKey)
const isUsable = (e: Event) => const isUsable = (e: Event) =>
!isEventDeletedRef.current(e) && !shouldDropEventOnIngest(e) !isEventDeletedRef.current(e) && !shouldDropEventOnIngest(e, ingestOpts)
try { try {
const chosen = await firstResolvedUsableEmbedEvent( const chosen = await firstResolvedUsableEmbedEvent(
[ [
@ -367,6 +386,7 @@ function EmbeddedNoteFetched({
if (eventRef.current) { if (eventRef.current) {
return () => { return () => {
cancelled = true cancelled = true
leaveMetadataRelaysOnlyBypass()
if (retryIntervalRef.current) { if (retryIntervalRef.current) {
clearInterval(retryIntervalRef.current) clearInterval(retryIntervalRef.current)
retryIntervalRef.current = null retryIntervalRef.current = null
@ -386,6 +406,7 @@ function EmbeddedNoteFetched({
return () => { return () => {
cancelled = true cancelled = true
leaveMetadataRelaysOnlyBypass()
if (retryIntervalRef.current) { if (retryIntervalRef.current) {
clearInterval(retryIntervalRef.current) clearInterval(retryIntervalRef.current)
retryIntervalRef.current = null retryIntervalRef.current = null

4
src/constants.ts

@ -462,7 +462,9 @@ export const READ_ONLY_RELAY_URLS = [
'wss://search.nos.today', 'wss://search.nos.today',
'wss://relay.nip46.com', 'wss://relay.nip46.com',
'wss://filter.nostr.wine', 'wss://filter.nostr.wine',
'wss://primus.nostr1.com' 'wss://primus.nostr1.com',
'wss://feeds.nostrarchives.com',
'wss://feeds.nostrarchives.com/notes/trending/reactions/today'
] ]
/** /**

16
src/services/client-events.service.ts

@ -513,7 +513,7 @@ export class EventService {
} }
const hexIds = [...hexSet].filter((id) => { const hexIds = [...hexSet].filter((id) => {
if (this.getSessionEventIfAllowed(id)) return false if (this.getSessionEventIfAllowed(id, true)) return false
if (this.embeddedPrefetchHexScheduled.has(id)) return false if (this.embeddedPrefetchHexScheduled.has(id)) return false
this.embeddedPrefetchHexScheduled.add(id) this.embeddedPrefetchHexScheduled.add(id)
return true return true
@ -558,14 +558,17 @@ export class EventService {
.filter((id) => /^[0-9a-f]{64}$/.test(id)) .filter((id) => /^[0-9a-f]{64}$/.test(id))
) )
] ]
let toFetch = hexIds.filter((id) => !this.getSessionEventIfAllowed(id)) let toFetch = hexIds.filter((id) => !this.getSessionEventIfAllowed(id, true))
if (toFetch.length === 0) return if (toFetch.length === 0) return
const archived = await prefetchArchivedEvents(toFetch) const archived = await prefetchArchivedEvents(toFetch)
for (const ev of archived) { for (const ev of archived) {
if (!shouldDropEventOnIngest(ev)) this.addEventToCache(ev) const hex = ev.id?.toLowerCase()
const ingestOpts =
hex && /^[0-9a-f]{64}$/.test(hex) ? { explicitNoteLookupHexId: hex } : undefined
this.addEventToCache(ev, ingestOpts)
} }
toFetch = toFetch.filter((id) => !this.getSessionEventIfAllowed(id)) toFetch = toFetch.filter((id) => !this.getSessionEventIfAllowed(id, true))
if (toFetch.length === 0) return if (toFetch.length === 0) return
const hints = (opts?.relayHints ?? []) const hints = (opts?.relayHints ?? [])
@ -590,7 +593,10 @@ export class EventService {
} }
) )
for (const ev of events) { for (const ev of events) {
this.addEventToCache(ev) const hex = ev.id?.toLowerCase()
const ingestOpts =
hex && /^[0-9a-f]{64}$/.test(hex) ? { explicitNoteLookupHexId: hex } : undefined
this.addEventToCache(ev, ingestOpts)
} }
} }
} }

Loading…
Cancel
Save