Compare commits
15 Commits
db6da608aa
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 5310908b0c | |||
| 4b05b3db6d | |||
| df47a926e4 | |||
| 1e9e95f35f | |||
| 2aa76baafd | |||
| aa50bb1f72 | |||
| dfedf4058e | |||
| 268e3eb4c2 | |||
| ab61574956 | |||
| 81038b6c26 | |||
| e949ba955a | |||
| 819e2fde27 | |||
| 3259e2197b | |||
| b133db0573 | |||
| 41c34e6d89 |
@@ -151,7 +151,7 @@ class ProfileController extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Update comments to deleted user
|
// Update comments to deleted user
|
||||||
DB::table('comments')->where('commenter_id', '=', $user->id)->update(['commenter_id' => 1]);
|
DB::table('comments')->where('user_id', '=', $user->id)->update(['user_id' => 1]);
|
||||||
|
|
||||||
// Delete Profile Picture
|
// Delete Profile Picture
|
||||||
if ($user->avatar) {
|
if ($user->avatar) {
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace App\Livewire;
|
namespace App\Livewire;
|
||||||
|
|
||||||
|
use App\Models\Comment;
|
||||||
use Livewire\Component;
|
use Livewire\Component;
|
||||||
use Livewire\WithPagination;
|
use Livewire\WithPagination;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
@@ -24,13 +25,19 @@ class AdminCommentSearch extends Component
|
|||||||
$this->resetPage();
|
$this->resetPage();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function deleteComment($commentId)
|
||||||
|
{
|
||||||
|
$comment = Comment::where('id', (int) $commentId)->firstOrFail();
|
||||||
|
$comment->delete();
|
||||||
|
|
||||||
|
cache()->flush();
|
||||||
|
}
|
||||||
|
|
||||||
public function render()
|
public function render()
|
||||||
{
|
{
|
||||||
$comments = DB::table('comments')
|
$comments = Comment::when($this->search !== '', fn ($query) => $query->where('body', 'LIKE', "%$this->search%"))
|
||||||
->join('users', 'comments.commenter_id', '=', 'users.id')
|
->when($this->userSearch !== '', fn ($query) => $query->whereHas('user', fn ($query) => $query->where('name', 'LIKE', "%{$this->userSearch}%")))
|
||||||
->select('comments.*', 'users.name')
|
->orderBy('created_at', 'DESC')
|
||||||
->when($this->search !== '', fn ($query) => $query->where('comment', 'LIKE', "%$this->search%"))
|
|
||||||
->when($this->userSearch !== '', fn ($query) => $query->where('name', 'LIKE', "%$this->userSearch%"))
|
|
||||||
->paginate(12);
|
->paginate(12);
|
||||||
|
|
||||||
return view('livewire.admin-comment-search', [
|
return view('livewire.admin-comment-search', [
|
||||||
|
|||||||
@@ -2,14 +2,13 @@
|
|||||||
|
|
||||||
namespace App\Livewire;
|
namespace App\Livewire;
|
||||||
|
|
||||||
|
use App\Models\Comment;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
|
|
||||||
use Livewire\Component;
|
use Livewire\Component;
|
||||||
use Livewire\WithPagination;
|
use Livewire\WithPagination;
|
||||||
use Livewire\Attributes\Url;
|
use Livewire\Attributes\Url;
|
||||||
|
|
||||||
use Illuminate\Support\Facades\DB;
|
|
||||||
|
|
||||||
class AdminUserSearch extends Component
|
class AdminUserSearch extends Component
|
||||||
{
|
{
|
||||||
use WithPagination;
|
use WithPagination;
|
||||||
@@ -31,8 +30,7 @@ class AdminUserSearch extends Component
|
|||||||
$user = User::where('id', $userID)
|
$user = User::where('id', $userID)
|
||||||
->firstOrFail();
|
->firstOrFail();
|
||||||
|
|
||||||
DB::table('comments')
|
Comment::where('user_id', $user->id)
|
||||||
->where('commenter_id', '=', $user->id)
|
|
||||||
->delete();
|
->delete();
|
||||||
|
|
||||||
cache()->flush();
|
cache()->flush();
|
||||||
|
|||||||
@@ -1,10 +1,22 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
|
||||||
namespace App\Livewire;
|
namespace App\Livewire;
|
||||||
|
|
||||||
|
use App\Models\User;
|
||||||
|
use App\Models\Episode;
|
||||||
|
use App\Notifications\CommentNotification;
|
||||||
|
|
||||||
use Livewire\Component;
|
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 Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||||
|
|
||||||
|
use Maize\Markable\Models\Like;
|
||||||
|
|
||||||
class Comment extends Component
|
class Comment extends Component
|
||||||
{
|
{
|
||||||
use AuthorizesRequests;
|
use AuthorizesRequests;
|
||||||
@@ -13,6 +25,10 @@ class Comment extends Component
|
|||||||
|
|
||||||
public $isReplying = false;
|
public $isReplying = false;
|
||||||
|
|
||||||
|
public $likeCount = 0;
|
||||||
|
|
||||||
|
public $liked = false;
|
||||||
|
|
||||||
public $replyState = [
|
public $replyState = [
|
||||||
'body' => ''
|
'body' => ''
|
||||||
];
|
];
|
||||||
@@ -62,20 +78,50 @@ class Comment extends Component
|
|||||||
|
|
||||||
public function postReply()
|
public function postReply()
|
||||||
{
|
{
|
||||||
if (! $this->comment->depth() < 2) {
|
if (!($this->comment->depth() < 2)) {
|
||||||
|
$this->addError('replyState.body', "Too many sub comments.");
|
||||||
return;
|
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([
|
$this->validate([
|
||||||
'replyState.body' => 'required'
|
'replyState.body' => 'required'
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$reply = $this->comment->children()->make($this->replyState);
|
$reply = $this->comment->children()->make($this->replyState);
|
||||||
$reply->user()->associate(auth()->user());
|
$reply->user()->associate($user);
|
||||||
$reply->commentable()->associate($this->comment->commentable);
|
$reply->commentable()->associate($this->comment->commentable);
|
||||||
|
|
||||||
$reply->save();
|
$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 = [
|
$this->replyState = [
|
||||||
'body' => ''
|
'body' => ''
|
||||||
];
|
];
|
||||||
@@ -85,6 +131,34 @@ class Comment extends Component
|
|||||||
$this->dispatch('refresh')->self();
|
$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()
|
public function render()
|
||||||
{
|
{
|
||||||
return view('livewire.comment');
|
return view('livewire.comment');
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ namespace App\Livewire;
|
|||||||
use Livewire\Component;
|
use Livewire\Component;
|
||||||
use Livewire\WithPagination;
|
use Livewire\WithPagination;
|
||||||
|
|
||||||
|
use Illuminate\Support\Facades\RateLimiter;
|
||||||
|
|
||||||
class Comments extends Component
|
class Comments extends Component
|
||||||
{
|
{
|
||||||
use WithPagination;
|
use WithPagination;
|
||||||
@@ -29,8 +31,21 @@ class Comments extends Component
|
|||||||
'newCommentState.body' => 'required'
|
'newCommentState.body' => 'required'
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
$user = auth()->user();
|
||||||
|
$rateLimitKey = "send-comment:{$user->id}";
|
||||||
|
$rateLimitMinutes = 60 * 5; // 5 minutes
|
||||||
|
|
||||||
|
if (RateLimiter::tooManyAttempts($rateLimitKey, 1)) {
|
||||||
|
$seconds = RateLimiter::availableIn($rateLimitKey);
|
||||||
|
|
||||||
|
$this->addError('newCommentState.body', "Too many comments. Try again in {$seconds} seconds.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
RateLimiter::hit($rateLimitKey, $rateLimitMinutes);
|
||||||
|
|
||||||
$comment = $this->model->comments()->make($this->newCommentState);
|
$comment = $this->model->comments()->make($this->newCommentState);
|
||||||
$comment->user()->associate(auth()->user());
|
$comment->user()->associate($user);
|
||||||
$comment->save();
|
$comment->save();
|
||||||
|
|
||||||
$this->newCommentState = [
|
$this->newCommentState = [
|
||||||
|
|||||||
@@ -8,9 +8,16 @@ use Illuminate\Database\Eloquent\SoftDeletes;
|
|||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
|
|
||||||
|
use Maize\Markable\Markable;
|
||||||
|
use Maize\Markable\Models\Like;
|
||||||
|
|
||||||
class Comment extends Model
|
class Comment extends Model
|
||||||
{
|
{
|
||||||
use HasFactory, SoftDeletes;
|
use HasFactory, SoftDeletes, Markable;
|
||||||
|
|
||||||
|
protected static $marks = [
|
||||||
|
Like::class
|
||||||
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The attributes that are mass assignable.
|
* The attributes that are mass assignable.
|
||||||
@@ -58,4 +65,12 @@ class Comment extends Model
|
|||||||
? $this->parent->depth() + 1
|
? $this->parent->depth() + 1
|
||||||
: 0;
|
: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get cached like count
|
||||||
|
*/
|
||||||
|
public function likeCount(): int
|
||||||
|
{
|
||||||
|
return cache()->remember('commentLikes' . $this->id, 300, fn() => $this->likes->count());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,7 @@
|
|||||||
src="{{ $episode->cover_url }}"></img>
|
src="{{ $episode->cover_url }}"></img>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="w-[60vw] pt-4">
|
<div class="w-[60vw] pt-4 bg-neutral-100 dark:bg-neutral-800 rounded-lg pl-4">
|
||||||
@include('partials.comment', ['comment' => $comment])
|
@include('partials.comment', ['comment' => $comment])
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -59,7 +59,7 @@
|
|||||||
src="{{ $hentai->episodes->first()->cover_url }}"></img>
|
src="{{ $hentai->episodes->first()->cover_url }}"></img>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="w-[60vw]">
|
<div class="w-[60vw] pt-4 bg-neutral-100 dark:bg-neutral-800 rounded-lg pl-4">
|
||||||
@include('partials.comment', ['comment' => $comment])
|
@include('partials.comment', ['comment' => $comment])
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -296,8 +296,8 @@
|
|||||||
<div class="pb-1 text-center w-full">
|
<div class="pb-1 text-center w-full">
|
||||||
<x-responsive-nav-link :href="route('login')">
|
<x-responsive-nav-link :href="route('login')">
|
||||||
<div
|
<div
|
||||||
class="relative bg-blue-700 hover:bg-blue-600 text-white font-bold px-4 h-10 rounded text-center p-[10px]">
|
class="relative bg-rose-700 hover:bg-rose-600 text-white font-bold px-4 h-10 rounded text-center p-[10px]">
|
||||||
<i class="fa-brands fa-discord"></i> {{ __('nav.login') }}
|
<i class="fa-solid fa-arrow-right-to-bracket"></i> {{ __('nav.login') }}
|
||||||
</div>
|
</div>
|
||||||
</x-responsive-nav-link>
|
</x-responsive-nav-link>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -25,6 +25,8 @@
|
|||||||
placeholder="Search..."
|
placeholder="Search..."
|
||||||
>
|
>
|
||||||
</th>
|
</th>
|
||||||
|
<th scope="col" class="px-6 py-3">
|
||||||
|
</th>
|
||||||
<th scope="col" class="px-6 py-3">
|
<th scope="col" class="px-6 py-3">
|
||||||
Actions
|
Actions
|
||||||
</th>
|
</th>
|
||||||
@@ -34,17 +36,18 @@
|
|||||||
@foreach($comments as $comment)
|
@foreach($comments as $comment)
|
||||||
<tr wire:key="comment-{{ $comment->id }}" class="bg-white border-t dark:bg-neutral-800 dark:border-pink-700">
|
<tr wire:key="comment-{{ $comment->id }}" class="bg-white border-t dark:bg-neutral-800 dark:border-pink-700">
|
||||||
<td class="px-6 py-4">
|
<td class="px-6 py-4">
|
||||||
{{ $comment->name }}
|
{{ $comment->user->name }}
|
||||||
</td>
|
</td>
|
||||||
<th scope="row" class="px-6 py-4 font-medium text-gray-900 dark:text-white max-w-lg">
|
<th scope="row" class="px-6 py-4 font-medium text-gray-900 dark:text-white max-w-lg">
|
||||||
{{ $comment->comment }}
|
{{ $comment->body }}
|
||||||
|
</th>
|
||||||
|
<th scope="row" class="px-6 py-4 font-medium text-gray-900 dark:text-white max-w-lg">
|
||||||
|
{{ $comment->created_at }}
|
||||||
</th>
|
</th>
|
||||||
<td class="px-6 py-4">
|
<td class="px-6 py-4">
|
||||||
<a href="{{ route('comments.destroy', $comment->id) }}" onclick="event.preventDefault();document.getElementById('comment-delete-form-{{ $comment->id }}').submit();" class="inline-flex items-center px-4 py-2 bg-red-600 border border-transparent rounded-md font-semibold text-xs text-white uppercase tracking-widest hover:bg-red-500 active:bg-red-700 focus:outline-none focus:ring-2 focus:ring-red-500 focus:ring-offset-2 dark:focus:ring-offset-gray-800 transition ease-in-out duration-150 mt-2">@lang('comments::comments.delete')</a>
|
<button wire:click="deleteComment({{$comment->id}})" type="button" class="inline-flex items-center px-4 py-2 bg-red-600 border border-transparent rounded-md font-semibold text-xs text-white uppercase tracking-widest hover:bg-red-500 active:bg-red-700 focus:outline-none focus:ring-2 focus:ring-red-500 focus:ring-offset-2 dark:focus:ring-offset-gray-800 transition ease-in-out duration-150 mt-2">
|
||||||
<form id="comment-delete-form-{{ $comment->id }}" action="{{ route('comments.destroy', $comment->id) }}" method="POST" style="display: none;">
|
Delete
|
||||||
@method('DELETE')
|
</button>
|
||||||
@csrf
|
|
||||||
</form>
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@endforeach
|
@endforeach
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<div>
|
<div>
|
||||||
<div class="flex">
|
<div class="flex" id="comment-{{ $comment->id }}">
|
||||||
<div class="flex-shrink-0 mr-4">
|
<div class="flex-shrink-0 mr-4">
|
||||||
<img class="h-10 w-10 rounded-full" src="{{ $comment->user->getAvatar() }}" alt="{{ $comment->user->name }}">
|
<img class="h-10 w-10 rounded-full" src="{{ $comment->user->getAvatar() }}" alt="{{ $comment->user->name }}">
|
||||||
</div>
|
</div>
|
||||||
@@ -28,7 +28,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="mt-3 flex items-center justify-between">
|
<div class="mt-3 flex items-center justify-between">
|
||||||
<button type="submit"
|
<button type="submit"
|
||||||
class="inline-flex items-center justify-center px-4 py-2 border border-transparent font-medium rounded-md shadow-sm text-white bg-rose-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-rose-500">
|
class="inline-flex items-center justify-center px-4 py-2 border border-transparent font-medium rounded-md shadow-sm text-white bg-rose-600 hover:bg-rose-700 focus:outline-none focus:ring-2 focus:ring-rose-500">
|
||||||
Edit
|
Edit
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -37,10 +37,28 @@
|
|||||||
<div class="text-gray-700 dark:text-gray-200">{!! $comment->presenter()->markdownBody() !!}</div>
|
<div class="text-gray-700 dark:text-gray-200">{!! $comment->presenter()->markdownBody() !!}</div>
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-2 space-x-2">
|
<div class="mt-2 space-x-2 flex flex-row">
|
||||||
<span class="text-gray-500 dark:text-gray-300 font-medium">
|
<span class="text-gray-500 dark:text-gray-300">
|
||||||
{{ $comment->presenter()->relativeCreatedAt() }}
|
{{ $comment->presenter()->relativeCreatedAt() }}
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
|
@guest
|
||||||
|
<span data-te-toggle="tooltip" title="Please login to like the episode" class="text-gray-800 cursor-pointer dark:text-gray-200">
|
||||||
|
<i class="fa-regular fa-heart"></i> {{ $comment->likeCount() }}
|
||||||
|
</span>
|
||||||
|
@endguest
|
||||||
|
|
||||||
|
@auth
|
||||||
|
<!-- Like Button -->
|
||||||
|
<button class="text-gray-800 dark:text-gray-200 leading-tight cursor-pointer whitespace-nowrap" wire:click="like">
|
||||||
|
@if ($liked)
|
||||||
|
<i class="fa-solid fa-heart text-rose-600"></i> {{ $likeCount }}
|
||||||
|
@else
|
||||||
|
<i class="fa-solid fa-heart"></i> {{ $likeCount }}
|
||||||
|
@endif
|
||||||
|
</button>
|
||||||
|
@endauth
|
||||||
|
|
||||||
@auth
|
@auth
|
||||||
@if ($comment->depth() < 2)
|
@if ($comment->depth() < 2)
|
||||||
<button wire:click="$toggle('isReplying')" type="button" class="text-gray-900 dark:text-gray-100 font-medium">
|
<button wire:click="$toggle('isReplying')" type="button" class="text-gray-900 dark:text-gray-100 font-medium">
|
||||||
|
|||||||
@@ -4,19 +4,8 @@
|
|||||||
<div class="px-4 py-5 sm:px-6">
|
<div class="px-4 py-5 sm:px-6">
|
||||||
<h2 class="text-lg font-medium text-gray-900 dark:text-gray-200">Comments</h2>
|
<h2 class="text-lg font-medium text-gray-900 dark:text-gray-200">Comments</h2>
|
||||||
</div>
|
</div>
|
||||||
<div class="px-4 py-6 sm:px-6">
|
<div>
|
||||||
<div class="space-y-8">
|
<!-- Comment Input -->
|
||||||
@if ($comments->isNotEmpty())
|
|
||||||
@foreach($comments as $comment)
|
|
||||||
<livewire:comment :comment="$comment" :key="$comment->id"/>
|
|
||||||
@endforeach
|
|
||||||
{{ $comments->links('pagination::tailwind') }}
|
|
||||||
@else
|
|
||||||
<p class="text-gray-900 dark:text-gray-200">No comments yet.</p>
|
|
||||||
@endif
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="bg-gray-50 dark:bg-neutral-800 px-4 py-6 sm:px-6">
|
<div class="bg-gray-50 dark:bg-neutral-800 px-4 py-6 sm:px-6">
|
||||||
@auth
|
@auth
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
@@ -28,7 +17,7 @@
|
|||||||
<div>
|
<div>
|
||||||
<label for="comment" class="sr-only">Comment body</label>
|
<label for="comment" class="sr-only">Comment body</label>
|
||||||
<textarea id="comment" name="comment" rows="3"
|
<textarea id="comment" name="comment" rows="3"
|
||||||
class="bg-white dark:bg-neutral-700 shadow-sm block w-full focus:ring-rose-500 focus:border-rose-500 border-gray-300 dark:border-gray-400/40 text-gray-900 dark:text-gray-200 placeholder:text-gray-400 rounded-md
|
class="peer block min-h-[auto] w-full border-1 bg-transparent px-3 py-[0.32rem] leading-[1.6] outline-none transition-all duration-200 ease-linear dark:placeholder:text-neutral-200 border-gray-300 dark:border-neutral-950 dark:bg-neutral-900 dark:text-gray-300 focus:border-rose-500 dark:focus:border-rose-600 focus:ring-rose-500 dark:focus:ring-rose-600 rounded-md shadow-sm
|
||||||
@error('newCommentState.body') border-red-500 @enderror"
|
@error('newCommentState.body') border-red-500 @enderror"
|
||||||
placeholder="Write something" wire:model.defer="newCommentState.body"></textarea>
|
placeholder="Write something" wire:model.defer="newCommentState.body"></textarea>
|
||||||
@error('newCommentState.body')
|
@error('newCommentState.body')
|
||||||
@@ -50,5 +39,22 @@
|
|||||||
<p class="text-gray-900 dark:text-gray-200">Log in to comment.</p>
|
<p class="text-gray-900 dark:text-gray-200">Log in to comment.</p>
|
||||||
@endguest
|
@endguest
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Comments -->
|
||||||
|
<div class="px-4 py-6 sm:px-6">
|
||||||
|
<div class="space-y-8">
|
||||||
|
@if ($comments->isNotEmpty())
|
||||||
|
@foreach($comments as $comment)
|
||||||
|
<livewire:comment :comment="$comment" :key="$comment->id"/>
|
||||||
|
@endforeach
|
||||||
|
{{ $comments->links('pagination::tailwind') }}
|
||||||
|
@else
|
||||||
|
<p class="text-gray-900 dark:text-gray-200">No comments yet.</p>
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
@@ -88,6 +88,20 @@
|
|||||||
<i class="fa-regular fa-heart"></i> {{ $episode->likeCount() }}
|
<i class="fa-regular fa-heart"></i> {{ $episode->likeCount() }}
|
||||||
<i class="fa-regular fa-comment"></i> {{ $episode->commentCount() }}
|
<i class="fa-regular fa-comment"></i> {{ $episode->commentCount() }}
|
||||||
</p>
|
</p>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
@elseif($comment->commentable_type == \App\Models\Hentai::class)
|
||||||
|
@php
|
||||||
|
$hentai = \App\Models\Hentai::find($comment->commentable_id);
|
||||||
|
$episode = $hentai->episodes->first();
|
||||||
|
@endphp
|
||||||
|
<div class="relative p-1 w-full transition duration-300 ease-in-out md:p-2 md:hover:-translate-y-1 md:hover:scale-110">
|
||||||
|
<a href="{{ route('hentai.index', ['title' => $hentai->slug]) }}">
|
||||||
|
<img alt="{{ $episode->title }}" loading="lazy" width="1000"
|
||||||
|
class="block object-cover object-center relative z-20 rounded-lg aspect-video"
|
||||||
|
src="{{ $episode->gallery->first()->thumbnail_url }}" />
|
||||||
|
|
||||||
|
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
|
|||||||
Reference in New Issue
Block a user