'', ]; public $isEditing = false; public $editState = [ 'body' => '', ]; protected $listeners = [ 'refresh' => '$refresh', ]; protected $validationAttributes = [ 'replyState.body' => 'reply', ]; public function updatedIsEditing(bool $isEditing) { if (! $isEditing) { return; } $this->editState = [ 'body' => $this->comment->body, ]; } public function editComment() { $this->authorize('update', $this->comment); $this->comment->update($this->editState); $this->isEditing = false; } public function deleteComment() { $this->authorize('destroy', $this->comment); $user = Auth::user(); if ($user->hasRole(UserRole::ADMINISTRATOR) || $user->hasRole(UserRole::MODERATOR)) { // Log to ModLog ModLog::create([ 'moderator' => $user->name, 'data' => "Deleted comment {$this->comment->id} written by {$this->comment->user->id} with contents: {$this->comment->body}", ]); $this->comment->deleted_by_moderator_id = $user->id; $this->comment->save(); $this->dispatch('refresh'); return; } $this->comment->delete(); $this->dispatch('refresh'); } public function restoreComment() { $this->authorize('restore', $this->comment); $user = Auth::user(); if ($user->hasRole(UserRole::ADMINISTRATOR) || $user->hasRole(UserRole::MODERATOR)) { // Log to ModLog ModLog::create([ 'moderator' => $user->name, 'data' => "Restored comment {$this->comment->id} written by {$this->comment->user->id} with contents: {$this->comment->body}", ]); $this->comment->deleted_by_moderator_id = null; $this->comment->save(); $this->dispatch('refresh'); } } public function postReply() { if (! ($this->comment->depth() < 2)) { $this->addError('replyState.body', 'Too many sub comments.'); return; } $user = auth()->user(); $rateLimitKey = "send-comment:{$user->id}"; $rateLimitMinutes = 60 * 5; // 5 minutes if (RateLimiter::tooManyAttempts($rateLimitKey, 1)) { $seconds = RateLimiter::availableIn($rateLimitKey); $this->addError('replyState.body', "Too many comments. Try again in {$seconds} seconds."); return; } RateLimiter::hit($rateLimitKey, $rateLimitMinutes); $this->validate([ 'replyState.body' => 'required', ]); $reply = $this->comment->children()->make($this->replyState); $reply->user()->associate($user); $reply->commentable()->associate($this->comment->commentable); $reply->save(); // Notify if Episode and if not the same user if ($reply->commentable_type == Episode::class && $user->id !== $reply->parent->user->id) { $episode = Episode::where('id', $reply->commentable_id) ->firstOrFail(); $url = route('hentai.index', ['title' => $episode->slug]); $reply->parent->user->notify( new CommentNotification( "{$user->name} replied to your comment.", Str::limit($reply->body, 50), "{$url}#comment-{$reply->id}" ) ); } $this->replyState = [ 'body' => '', ]; $this->isReplying = false; $this->dispatch('refresh')->self(); } public function like() { if (! Auth::check()) { return; } Like::toggle($this->comment, User::where('id', Auth::user()->id)->firstOrFail()); Cache::forget('commentLikes'.$this->comment->id); if ($this->liked) { $this->liked = false; $this->likeCount--; return; } $this->liked = true; $this->likeCount++; } public function mount() { if (Auth::check()) { $this->likeCount = $this->comment->likeCount(); $this->liked = Like::has($this->comment, User::where('id', Auth::user()->id)->firstOrFail()); } } public function render() { return view('livewire.comment'); } }