diff --git a/app/Livewire/Posts/PostFormComponent.php b/app/Livewire/Posts/PostFormComponent.php
index 9288485e..043a91bd 100644
--- a/app/Livewire/Posts/PostFormComponent.php
+++ b/app/Livewire/Posts/PostFormComponent.php
@@ -5,14 +5,13 @@
namespace App\Livewire\Posts;
use App\Dtos\PostDto;
-use App\Enums\LivewireEventEnum;
use App\Enums\PostStateEnum;
use App\Http\Requests\Post\StorePostRequest;
use App\Services\PostService;
use App\Traits\LoggingTrait;
use App\Traits\SubsiteTrait;
use Illuminate\Contracts\View\View;
-use Livewire\Attributes\On;
+use Livewire\Attributes\Locked;
use Livewire\Component;
final class PostFormComponent extends Component
@@ -24,7 +23,11 @@ final class PostFormComponent extends Component
public string $body = '';
public string $more_inside = '';
public string $tags = '';
+
+ #[Locked]
public int $subsiteId = 0;
+
+ #[Locked]
public int $userId = 0;
private PostService $postService;
@@ -49,17 +52,6 @@ public function render(): View
return view('livewire.posts.post-form-component');
}
- #[On(LivewireEventEnum::EditorUpdated->value)]
- public function saveEditorContent($editorId, $content): void
- {
- if ($editorId === 'post-body') {
- $this->body = $content;
- }
- if ($editorId === 'more-inside') {
- $this->more_inside = $content;
- }
- }
-
public function store(): void
{
$this->validate();
diff --git a/app/Livewire/Wysiwyg/WysiwygComponent.php b/app/Livewire/Wysiwyg/WysiwygComponent.php
index 8d9b5807..0d1ba8fb 100644
--- a/app/Livewire/Wysiwyg/WysiwygComponent.php
+++ b/app/Livewire/Wysiwyg/WysiwygComponent.php
@@ -6,13 +6,22 @@
use App\Enums\LivewireEventEnum;
use Illuminate\Contracts\View\View;
+use Livewire\Attributes\Locked;
+use Livewire\Attributes\Modelable;
use Livewire\Component;
final class WysiwygComponent extends Component
{
+ #[Modelable]
public string $content = '';
+
+ #[Locked]
public string $editorId;
+
+ #[Locked]
public string $label;
+
+ #[Locked]
public string $name;
public function mount(string $editorId, string $content = '', string $label = '', string $name = ''): void
diff --git a/app/Services/PostService.php b/app/Services/PostService.php
index 85690f94..8d2869ee 100644
--- a/app/Services/PostService.php
+++ b/app/Services/PostService.php
@@ -34,7 +34,6 @@ public function store(PostDto $dto): ?Post
'more_inside' => $this->purifierService->clean($dto->more_inside),
'user_id' => $dto->user_id,
'subsite_id' => $dto->subsite_id,
- 'state' => $dto->state,
'published_at' => $dto->published_at,
'is_published' => $dto->is_published,
];
diff --git a/resources/js/wysiwyg.js b/resources/js/wysiwyg.js
index 0defe637..479aaea4 100644
--- a/resources/js/wysiwyg.js
+++ b/resources/js/wysiwyg.js
@@ -4,34 +4,76 @@ const cleanupKey = Symbol('cleanup');
// Set up a single textarea with CKEditor
async function initializeEditor(textarea, component) {
try {
- const editorConfig = JSON.parse(document.querySelector('meta[name="ckeditor-config"]')?.content || 'null') || {}
+ let globalEditorConfig = null;
+ try {
+ globalEditorConfig = JSON.parse(document.querySelector('meta[name="ckeditor-config"]')?.content || 'null');
+ } catch (e) {
+ // Ignore
+ console.debug('Unable to parse CKEditor config from meta tag', e);
+ }
+
+ let localEditorConfig = null;
+ try {
+ localEditorConfig = JSON.parse(textarea.dataset.editorConfig || 'null');
+ } catch (e) {
+ // Ignore
+ console.debug('Unable to parse CKEditor config from textarea data-editor-config', e);
+ }
+
+ const editorConfig = {
+ ...(globalEditorConfig || {}),
+ ...(localEditorConfig || {}),
+ toolbar: {
+ items: [
+ 'bold', 'italic', 'link',
+ 'bulletedList', 'numberedList', 'blockQuote', '|',
+ 'heading', 'insertTable', 'mediaEmbed', '|',
+ 'undo', 'redo'
+ ],
+ // Collapse into three dots menu when the toolbar is full.
+ shouldNotGroupWhenFull: false
+ }
+ }
+
const editor = await ClassicEditor.create(textarea, editorConfig);
const editorId = textarea.dataset.editorId;
- // Listen for changes to the editor content and update the component's content property
- editor.model.document.on('change:data', () => {
- component.$wire.$set('content', editor.getData());
+ // Listen for changes to the editor content and update the component's content property.
+ const sync = () => {
+ const content = editor.getData();
+ textarea.value = content;
+ component.$wire.$set('content', content, false);
+ };
+
+ editor.model.document.on('change:data', sync);
+
+ // Also sync when the editor loses focus.
+ editor.ui.focusTracker.on('change:isFocused', ( _event, _name, isFocused ) => {
+ if (!isFocused) sync();
});
// Reset the editor content when we receive a notification from the backend.
- const onEditorClear = (event) => {
+ const clearEditor = (event) => {
if (event.detail.editorId === editorId) {
editor.setData('');
+ textarea.value = '';
}
};
- document.addEventListener('editor:clear', onEditorClear);
+ document.addEventListener('editor:clear', clearEditor);
// Update the component's content property when the force sync event is received
- const onForceSync = () => {
- component.$wire.$set('content', editor.getData());
+ const syncAndFlush = () => {
+ const content = editor.getData();
+ textarea.value = content;
+ component.$wire.$set('content', content);
};
- document.addEventListener('livewire:force-sync', onForceSync);
+ document.addEventListener('livewire:force-sync', syncAndFlush);
textarea[cleanupKey] = () => {
- document.removeEventListener('editor:clear', onEditorClear);
- document.removeEventListener('livewire:force-sync', onForceSync);
+ document.removeEventListener('editor:clear', clearEditor);
+ document.removeEventListener('livewire:force-sync', syncAndFlush);
editor.destroy().catch(e => console.error('Error destroying editor', e));
};
} catch (error) {
diff --git a/resources/sass/modules/_forms.scss b/resources/sass/modules/_forms.scss
index 836d6b17..9890da9d 100644
--- a/resources/sass/modules/_forms.scss
+++ b/resources/sass/modules/_forms.scss
@@ -157,6 +157,9 @@ fieldset {
border: none;
position: relative;
margin: 0;
+ // Reset min-inline-size to unset - Chrome sets it to min-content, which
+ // prevents CKEditor from responding to the screen width correctly.
+ min-inline-size: unset;
padding: 0;
}
diff --git a/resources/views/livewire/comments/comment-form-component.blade.php b/resources/views/livewire/comments/comment-form-component.blade.php
index 33603023..6dafaecf 100644
--- a/resources/views/livewire/comments/comment-form-component.blade.php
+++ b/resources/views/livewire/comments/comment-form-component.blade.php
@@ -19,7 +19,7 @@