import { useEffect, useCallback } from 'react'
import { RelayPool } from 'applesauce-relay'
import { IEventStore } from 'applesauce-core'
import { createEventLoader } from 'applesauce-loaders/loaders'
import { NostrEvent } from 'nostr-tools'
import { ReadableContent } from '../services/readerService'
interface UseEventLoaderProps {
eventId?: string
relayPool?: RelayPool | null
eventStore?: IEventStore | null
setSelectedUrl: (url: string) => void
setReaderContent: (content: ReadableContent | undefined) => void
setReaderLoading: (loading: boolean) => void
setIsCollapsed: (collapsed: boolean) => void
}
export function useEventLoader({
eventId,
relayPool,
eventStore,
setSelectedUrl,
setReaderContent,
setReaderLoading,
setIsCollapsed
}: UseEventLoaderProps) {
const displayEvent = useCallback((event: NostrEvent) => {
// Format event metadata as HTML header
const metaHtml = `
Event ID: ${event.id.slice(0, 16)}...
Posted: ${new Date(event.created_at * 1000).toLocaleString()}
Kind: ${event.kind}
`
// Escape HTML in content and convert newlines to breaks for plain text display
const escapedContent = event.content
.replace(/&/g, '&')
.replace(//g, '>')
.replace(/\n/g, '
')
const content: ReadableContent = {
url: `nostr:${event.id}`,
html: metaHtml + `${escapedContent}
`,
title: `Note (${event.kind})`
}
setReaderContent(content)
}, [setReaderContent])
useEffect(() => {
if (!eventId) return
// Try to get from event store first - do this synchronously before setting loading state
if (eventStore) {
const cachedEvent = eventStore.getEvent(eventId)
if (cachedEvent) {
displayEvent(cachedEvent)
setReaderLoading(false)
setIsCollapsed(false)
setSelectedUrl(`nostr:${eventId}`)
return
}
}
// Event not in cache, now set loading state and fetch from relays
setReaderLoading(true)
setReaderContent(undefined)
setSelectedUrl(`nostr:${eventId}`)
setIsCollapsed(false)
// Otherwise fetch from relays
if (!relayPool) {
setReaderLoading(false)
return
}
const eventLoader = createEventLoader(relayPool, {
eventStore: eventStore ?? undefined
})
const subscription = eventLoader({ id: eventId }).subscribe({
next: (event) => {
displayEvent(event)
setReaderLoading(false)
},
error: (err) => {
const errorContent: ReadableContent = {
url: '',
html: `Error loading event: ${err instanceof Error ? err.message : 'Unknown error'}
`,
title: 'Error'
}
setReaderContent(errorContent)
setReaderLoading(false)
}
})
return () => subscription.unsubscribe()
}, [eventId, relayPool, eventStore, displayEvent, setReaderLoading, setSelectedUrl, setIsCollapsed, setReaderContent])
}