import { Controller } from '@hotwired/stimulus'; import { getSigner } from './signer_manager.js'; // NIP-22 Comment Publishing Controller // Usage: Attach to a form with data attributes for root/parent context export default class extends Controller { static targets = ['publishButton', 'status']; static values = { publishUrl: String, csrfToken: String }; connect() { console.log('Nostr comment controller connected'); try { console.debug('[nostr-comment] publishUrl:', this.publishUrlValue || '(none)'); console.debug('[nostr-comment] has csrfToken:', Boolean(this.csrfTokenValue)); } catch (_) {} } async publish(event) { event.preventDefault(); if (!this.publishUrlValue) { this.showError('Publish URL is not configured'); return; } if (!this.csrfTokenValue) { this.showError('Missing CSRF token'); return; } let signer; try { signer = await getSigner(); } catch (e) { this.showError('No Nostr signer available. Please connect Amber or install a Nostr signer extension.'); return; } this.publishButtonTarget.disabled = true; this.showStatus('Preparing comment for signing...'); try { // Collect form data and context const formData = this.collectFormData(); // Validate required fields if (!formData.content) { throw new Error('Comment content is required'); } if (!formData.root || !formData.parent) { throw new Error('Missing root or parent context'); } if (!this.isPlaintext(formData.content)) { throw new Error('Comment must be plaintext (no formatting)'); } // Create NIP-22 event const nostrEvent = await this.createNip22Event(formData, signer); this.showStatus('Requesting signature from Nostr signer...'); const signedEvent = await signer.signEvent(nostrEvent); this.showStatus('Publishing comment...'); await this.sendToBackend(signedEvent, formData); this.showSuccess('Comment published successfully!'); // Optionally reload or clear form setTimeout(() => { window.location.reload(); }, 1500); } catch (error) { console.error('Publishing error:', error); this.showError(`Publishing failed: ${error.message}`); } finally { this.publishButtonTarget.disabled = false; } } collectFormData() { // Use the form element directly (this.element is the