diff --git a/assets/controllers/tabular_publish_controller.js b/assets/controllers/tabular_publish_controller.js new file mode 100644 index 0000000..c9a9c6c --- /dev/null +++ b/assets/controllers/tabular_publish_controller.js @@ -0,0 +1,102 @@ +import { Controller } from '@hotwired/stimulus'; + +export default class extends Controller { + static targets = ['publishButton', 'status']; + static values = { + publishUrl: String, + csrfToken: String, + eventData: Object + }; + + connect() { + console.log('Tabular data publish controller connected'); + } + + 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; + } + + if (!window.nostr) { + this.showError('Nostr extension not found'); + return; + } + + this.publishButtonTarget.disabled = true; + this.showStatus('Requesting signature from Nostr extension...'); + + try { + // Prepare the event data + const eventData = this.eventDataValue; + delete eventData.sig; // Remove sig if present + delete eventData.id; // Remove id if present + + // Sign the event with Nostr extension + const signedEvent = await window.nostr.signEvent(eventData); + + this.showStatus('Publishing tabular data...'); + + // Send to backend + await this.sendToBackend(signedEvent); + + this.showSuccess('Tabular data published successfully!'); + + // Redirect to the event page + setTimeout(() => { + window.location.href = `/e/${signedEvent.id}`; + }, 2000); + + } catch (error) { + console.error('Publishing error:', error); + this.showError(`Publishing failed: ${error.message}`); + } finally { + this.publishButtonTarget.disabled = false; + } + } + + async sendToBackend(signedEvent) { + const response = await fetch(this.publishUrlValue, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'X-Requested-With': 'XMLHttpRequest', + 'X-CSRF-TOKEN': this.csrfTokenValue + }, + body: JSON.stringify({ + event: signedEvent + }) + }); + + if (!response.ok) { + const errorData = await response.json().catch(() => ({})); + throw new Error(errorData.message || `HTTP ${response.status}: ${response.statusText}`); + } + + return await response.json(); + } + + showStatus(message) { + if (this.hasStatusTarget) { + this.statusTarget.innerHTML = `
Here is the generated event. Click "Sign and Publish" to sign with your Nostr key and publish to relays.
+{{ event|json_encode(constant('JSON_PRETTY_PRINT')) }}
+
+
+ Back
+