import { Controller } from '@hotwired/stimulus'; const LOADING_HTML = `
Loading preview…
`; const UNAVAILABLE_HTML = `
Preview unavailable.
`; export default class extends Controller { static values = { identifier: String, type: String, decoded: String, fullMatch: String, }; static targets = ['container']; connect() { this.fetchPreview(); } async fetchPreview() { if (!this.hasContainerTarget) { return; } this.containerTarget.innerHTML = LOADING_HTML; try { if (this.typeValue === 'url' && this.fullMatchValue) { const res = await fetch('/og-preview/', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ url: this.fullMatchValue }), }); if (!res.ok) { throw new Error(`HTTP ${res.status}`); } this.containerTarget.innerHTML = await res.text(); return; } const res = await fetch('/preview/', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ identifier: this.identifierValue, type: this.typeValue, decoded: this.decodedValue, }), }); if (!res.ok) { throw new Error(`HTTP ${res.status}`); } this.containerTarget.innerHTML = await res.text(); } catch (e) { // NetworkError / offline: avoid console.error noise; one inline fallback per block console.debug('nostr_preview: fetch failed', e); this.containerTarget.innerHTML = this.typeValue === 'url' && this.fullMatchValue ? `
Unable to load link preview for ${this.fullMatchValue}.
` : UNAVAILABLE_HTML; } } }