Files
hstream/app/Livewire/Comment.php

166 lines
3.8 KiB
PHP

<?php
namespace App\Livewire;
use App\Models\User;
use App\Models\Episode;
use App\Notifications\CommentNotification;
use Livewire\Component;
use Illuminate\Support\Str;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Maize\Markable\Models\Like;
class Comment extends Component
{
use AuthorizesRequests;
public $comment;
public $isReplying = false;
public $likeCount = 0;
public $liked = false;
public $replyState = [
'body' => ''
];
public $isEditing = false;
public $editState = [
'body' => ''
];
protected $listeners = [
'refresh' => '$refresh'
];
protected $validationAttributes = [
'replyState.body' => 'reply'
];
public function updatedIsEditing($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);
$this->comment->delete();
$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');
}
}