diff --git a/assets/controllers/editor/header_controller.js b/assets/controllers/editor/header_controller.js new file mode 100644 index 0000000..0275da4 --- /dev/null +++ b/assets/controllers/editor/header_controller.js @@ -0,0 +1,20 @@ +import { Controller } from "@hotwired/stimulus"; + +export default class extends Controller { + connect() { + // For debug + // console.log("Header controller connected"); + } + + saveDraft(event) { + event.preventDefault(); + const btn = document.querySelector('[data-editor--layout-target="saveDraftSubmit"]'); + if (btn) btn.click(); + } + + publish(event) { + event.preventDefault(); + const btn = document.querySelector('[data-editor--layout-target="publishSubmit"]'); + if (btn) btn.click(); + } +} diff --git a/assets/controllers/editor/json-panel_controller.js b/assets/controllers/editor/json-panel_controller.js index 3df50b2..7f5c394 100644 --- a/assets/controllers/editor/json-panel_controller.js +++ b/assets/controllers/editor/json-panel_controller.js @@ -92,6 +92,12 @@ export default class extends Controller { const nostrController = this.getNostrPublishController(); if (nostrController && nostrController.hasJsonTextareaTarget && this.hasJsonTextareaTarget) { this.jsonTextareaTarget.value = nostrController.jsonTextareaTarget.value; + // Update CodeMirror document to match textarea + if (this.cmView) { + this.cmView.dispatch({ + changes: {from: 0, to: this.cmView.state.doc.length, insert: this.jsonTextareaTarget.value} + }); + } this.updateJsonContentFromMarkdown(); this.formatJson(); this.isDirty = false; @@ -108,6 +114,12 @@ export default class extends Controller { const json = nostrController.jsonTextareaTarget.value; if (json && this.hasJsonTextareaTarget) { this.jsonTextareaTarget.value = json; + // Update CodeMirror document to match textarea + if (this.cmView) { + this.cmView.dispatch({ + changes: {from: 0, to: this.cmView.state.doc.length, insert: this.jsonTextareaTarget.value} + }); + } this.updateJsonContentFromMarkdown(); this.formatJson(); } @@ -124,6 +136,12 @@ export default class extends Controller { setTimeout(() => { if (nostrController.hasJsonTextareaTarget && this.hasJsonTextareaTarget) { this.jsonTextareaTarget.value = nostrController.jsonTextareaTarget.value; + // Update CodeMirror document to match textarea + if (this.cmView) { + this.cmView.dispatch({ + changes: {from: 0, to: this.cmView.state.doc.length, insert: this.jsonTextareaTarget.value} + }); + } this.formatJson(); this.isDirty = false; this.updateDirtyHint(); diff --git a/assets/controllers/editor/layout_controller.js b/assets/controllers/editor/layout_controller.js index 22fde58..227fb46 100644 --- a/assets/controllers/editor/layout_controller.js +++ b/assets/controllers/editor/layout_controller.js @@ -6,7 +6,8 @@ export default class extends Controller { 'modeTab', 'editPane', 'markdownPane', 'jsonPane', 'previewPane', 'previewBody', 'previewTitle', 'previewSummary', 'previewImage', 'previewImagePlaceholder', 'previewAuthor', 'previewDate', - 'markdownEditor', 'markdownTitle', 'markdownCode', 'status' + 'markdownEditor', 'markdownTitle', 'markdownCode', 'status', + 'saveDraftSubmit', 'publishSubmit' ]; connect() { @@ -214,12 +215,15 @@ export default class extends Controller { } saveDraft() { - console.log('Saving draft...'); + // Only for mobile actions, not header + alert('[Editor] saveDraft called'); // Mark as draft - set checkbox to true const draftCheckbox = this.element.querySelector('input[name*="[isDraft]"]'); if (draftCheckbox) { draftCheckbox.checked = true; + } else { + console.warn('[Editor] Draft checkbox not found'); } // Submit the form @@ -227,16 +231,22 @@ export default class extends Controller { if (form) { this.updateStatus('Saving draft...'); form.requestSubmit(); + console.log('[Editor] Form submitted for draft'); + } else { + console.error('[Editor] Form not found for saveDraft'); } } publish() { - console.log('Publishing article...'); + // Only for mobile actions, not header + alert('[Editor] publish called'); // Mark as NOT draft - set checkbox to false const draftCheckbox = this.element.querySelector('input[name*="[isDraft]"]'); if (draftCheckbox) { draftCheckbox.checked = false; + } else { + console.warn('[Editor] Draft checkbox not found'); } // Find the Nostr publish controller and trigger publish @@ -246,10 +256,19 @@ export default class extends Controller { ); if (nostrController) { + console.log('[Editor] Nostr publish controller found, calling publish()'); nostrController.publish(); } else { - console.error('Nostr publish controller not found'); - alert('Could not find publishing controller. Please try again.'); + // Fallback: submit the form + const form = this.element.querySelector('form'); + if (form) { + this.updateStatus('Publishing...'); + form.requestSubmit(); + console.log('[Editor] Form submitted for publish'); + } else { + console.error('[Editor] Form not found for publish'); + alert('Could not find publishing controller or form. Please try again.'); + } } } diff --git a/assets/styles/03-components/form.css b/assets/styles/03-components/form.css index d62ecaa..1397f0a 100644 --- a/assets/styles/03-components/form.css +++ b/assets/styles/03-components/form.css @@ -54,8 +54,8 @@ input:focus, textarea:focus, select:focus { .help-text { font-size: 0.8rem; - color: var(--color-text); - font-weight: lighter; + color: var(--color-text-mid); + margin-bottom: var(--spacing-1); } #editor_actions { diff --git a/templates/editor/layout.html.twig b/templates/editor/layout.html.twig index d9bbfa2..e15d87e 100644 --- a/templates/editor/layout.html.twig +++ b/templates/editor/layout.html.twig @@ -13,7 +13,7 @@ {% endblock %} {% block header %} -
+
← Back
@@ -26,10 +26,10 @@ {% if article.id %}Editing{% else %}New article{% endif %} - -
@@ -265,6 +265,9 @@
+ + + {# Right sidebar (last grid column) #}