*/ public ?array $editData = []; /** @var array */ public ?array $replyData = []; /** @var array */ public array $replyAttachments = []; public function mount(Comment $comment): void { $this->comment = $comment; } public function editForm(Schema $schema): Schema { return $schema ->components([ RichEditor::make('body') ->hiddenLabel() ->required() ->placeholder(__('Edit your comment...')) ->toolbarButtons(CommentsConfig::getEditorToolbar()) ->mentions([ CommentsConfig::makeMentionProvider(), ]), ]) ->statePath('editData'); } public function replyForm(Schema $schema): Schema { return $schema ->components([ RichEditor::make('body') ->hiddenLabel() ->required() ->placeholder(__('Write a reply...')) ->toolbarButtons(CommentsConfig::getEditorToolbar()) ->mentions([ CommentsConfig::makeMentionProvider(), ]), ]) ->statePath('replyData'); } public function startEdit(): void { $this->authorize('update', $this->comment); $this->isEditing = true; $this->editForm->fill(['body' => $this->comment->body]); } public function cancelEdit(): void { $this->isEditing = false; $this->editForm->fill(); } public function saveEdit(): void { $this->authorize('update', $this->comment); $data = $this->editForm->getState(); $this->comment->update([ 'body' => $data['body'] ?? '', 'edited_at' => now(), ]); event(new CommentUpdated($this->comment->fresh())); app(MentionParser::class)->syncMentions($this->comment->fresh()); $this->dispatch('commentUpdated'); $this->isEditing = false; $this->editForm->fill(); } public function deleteComment(): void { $this->authorize('delete', $this->comment); $this->comment->delete(); event(new CommentDeleted($this->comment)); $this->dispatch('commentDeleted'); } public function startReply(): void { if (! $this->comment->canReply()) { return; } $this->isReplying = true; $this->replyForm->fill(); } public function cancelReply(): void { $this->isReplying = false; $this->replyForm->fill(); $this->replyAttachments = []; } public function addReply(): void { $this->authorize('reply', $this->comment); $data = $this->replyForm->getState(); if (CommentsConfig::areAttachmentsEnabled()) { $maxSize = CommentsConfig::getAttachmentMaxSize(); $allowedTypes = implode(',', CommentsConfig::getAttachmentAllowedTypes()); $this->validate([ 'replyAttachments.*' => ['nullable', 'file', "max:{$maxSize}", "mimetypes:{$allowedTypes}"], ]); } $user = CommentsConfig::resolveAuthenticatedUser(); $reply = $this->comment->commentable->comments()->create([ 'body' => $data['body'] ?? '', 'parent_id' => $this->comment->id, 'commenter_id' => $user->getKey(), 'commenter_type' => $user->getMorphClass(), ]); if (CommentsConfig::areAttachmentsEnabled() && ! empty($this->replyAttachments)) { $disk = CommentsConfig::getAttachmentDisk(); foreach ($this->replyAttachments as $file) { $path = $file->store("comments/attachments/{$reply->id}", $disk); $reply->attachments()->create([ 'file_path' => $path, 'original_name' => $file->getClientOriginalName(), 'mime_type' => $file->getMimeType(), 'size' => $file->getSize(), 'disk' => $disk, ]); } } event(new CommentCreated($reply)); app(MentionParser::class)->syncMentions($reply); $this->comment->load(['replies.commenter', 'replies.mentions', 'replies.attachments', 'replies.reactions.commenter', 'replies.replies.commenter', 'replies.replies.mentions', 'replies.replies.attachments', 'replies.replies.reactions.commenter']); $this->dispatch('commentUpdated'); $this->isReplying = false; $this->replyForm->fill(); $this->replyAttachments = []; } public function removeReplyAttachment(int $index): void { $attachments = $this->replyAttachments; unset($attachments[$index]); $this->replyAttachments = array_values($attachments); } public function render(): View { return view('comments::livewire.comment-item'); } }