import { NostrEvent } from '@nostr/tools/pure' import { decodeNostrURI } from '@nostr/tools/nip19' import { normalizeURL } from '@nostr/tools/utils' import { getInboxRelaysFor, getOutboxRelaysFor, getWindowNostr, pool } from './nostr.js' import { debounce } from './utils.js' export default class NostrRSVP extends HTMLElement { static observedAttributes = ['ref'] root: HTMLDivElement eventData: NostrEvent | null = null constructor() { super() this.attachShadow({ mode: 'open' }) const { shadowRoot } = this this.root = document.createElement('div') shadowRoot!.appendChild(this.root) } connectedCallback() { this.style.display = 'block' this.style.width = 'fit-content' this.style.height = 'fit-content' this.set() } attributeChangedCallback() { this.set() } set: () => void = debounce(async () => { let input = this.getAttribute('ref') if (!input) return let { type, data } = decodeNostrURI(input) let relays: string[] = [] let author: string | undefined let filter: any if (type === 'nevent') { let d = data as any relays = d.relays || [] author = d.author filter = { ids: [d.id] } } else if (type === 'naddr') { let d = data as any relays = d.relays || [] author = d.pubkey filter = { authors: [d.pubkey], kinds: [d.kind], '#d': [d.identifier], } } else if (input.match(/[0-9a-f]{64}/)) { filter = { ids: [input] } } else { return } relays = relays.map(normalizeURL) if (author) { let authorRelays = await getOutboxRelaysFor(author) relays.push(...authorRelays) } let evt = await pool.get(relays, filter) if (!evt || (evt.kind !== 31922 && evt.kind !== 31923)) { this.root.innerHTML = '
Not a valid calendar event.
' return } this.eventData = evt // get title from tags const title = evt.tags.find((t: string[]) => t[0] === 'title')?.[1] || 'Untitled Event' // get start/end times or dates let timeStr = '' if (evt.kind === 31922) { // date-based event const start = evt.tags.find((t: string[]) => t[0] === 'start')?.[1] const end = evt.tags.find((t: string[]) => t[0] === 'end')?.[1] || start timeStr = `${start}${end !== start ? ` to ${end}` : ''}` } else { // time-based event const start = evt.tags.find((t: string[]) => t[0] === 'start')?.[1] const end = evt.tags.find((t: string[]) => t[0] === 'end')?.[1] if (start) { const startDate = new Date(parseInt(start) * 1000) timeStr = startDate.toLocaleString() if (end) { const endDate = new Date(parseInt(end) * 1000) timeStr += ` to ${endDate.toLocaleString()}` } } } const identifier = evt.tags.find((t: string[]) => t[0] === 'd')?.[1] || '' this.root.innerHTML = `${title}
${timeStr}
${evt.content}