207 lines
6.0 KiB
PHP
207 lines
6.0 KiB
PHP
<?php
|
|
|
|
namespace Relaticle\Comments\Livewire;
|
|
|
|
use Filament\Actions\Concerns\InteractsWithActions;
|
|
use Filament\Actions\Contracts\HasActions;
|
|
use Filament\Forms\Components\RichEditor;
|
|
use Filament\Forms\Concerns\InteractsWithForms;
|
|
use Filament\Forms\Contracts\HasForms;
|
|
use Filament\Schemas\Schema;
|
|
use Illuminate\Contracts\View\View;
|
|
use Livewire\Component;
|
|
use Livewire\Features\SupportFileUploads\TemporaryUploadedFile;
|
|
use Livewire\WithFileUploads;
|
|
use Relaticle\Comments\CommentsConfig;
|
|
use Relaticle\Comments\Events\CommentCreated;
|
|
use Relaticle\Comments\Events\CommentDeleted;
|
|
use Relaticle\Comments\Events\CommentUpdated;
|
|
use Relaticle\Comments\Mentions\MentionParser;
|
|
use Relaticle\Comments\Models\Comment;
|
|
|
|
class CommentItem extends Component implements HasForms, HasActions
|
|
{
|
|
use InteractsWithForms;
|
|
use InteractsWithActions;
|
|
use WithFileUploads;
|
|
|
|
public Comment $comment;
|
|
|
|
public bool $isEditing = false;
|
|
|
|
public bool $isReplying = false;
|
|
|
|
/** @var array<string, mixed> */
|
|
public ?array $editData = [];
|
|
|
|
/** @var array<string, mixed> */
|
|
public ?array $replyData = [];
|
|
|
|
/** @var array<int, TemporaryUploadedFile> */
|
|
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');
|
|
}
|
|
}
|