diff --git a/app/Livewire/Shared/Comments/CommentCard.php b/app/Livewire/Shared/Comments/CommentCard.php index 33b6d430..c386e76c 100644 --- a/app/Livewire/Shared/Comments/CommentCard.php +++ b/app/Livewire/Shared/Comments/CommentCard.php @@ -50,7 +50,7 @@ class CommentCard extends Component public string $body; - public object $createdAt; + public string $createdAt; public bool $isEdited; diff --git a/app/Livewire/Shared/Comments/CommentGroup.php b/app/Livewire/Shared/Comments/CommentGroup.php index d4cebe92..ff82b316 100644 --- a/app/Livewire/Shared/Comments/CommentGroup.php +++ b/app/Livewire/Shared/Comments/CommentGroup.php @@ -2,24 +2,17 @@ namespace App\Livewire\Shared\Comments; -use App\Enums\CommentOrder; use App\Models\Comment; use App\Models\Post; use Illuminate\Auth\Access\AuthorizationException; -use Illuminate\Database\Eloquent\Builder; -use Illuminate\Database\Eloquent\Collection; use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Illuminate\Support\Facades\DB; use Illuminate\View\View; -use Livewire\Attributes\Computed; use Livewire\Attributes\Locked; use Livewire\Attributes\On; use Livewire\Component; use Throwable; -/** - * @property Collection $comments - */ class CommentGroup extends Component { use AuthorizesRequests; @@ -52,20 +45,29 @@ class CommentGroup extends Component #[Locked] public string $commentGroupName; - #[Locked] - public CommentOrder $order = CommentOrder::LATEST; - /** - * Comment ids. - * - * @var array + * Comments array, the format is like: + * [ + * 1 => ["id" => 1, "body" => "hello" ...], + * 2 => ["id" => 2, "body" => "world" ...], + * ], */ - public array $commentIds = []; + public array $comments = []; - #[On('append-new-id-to-{commentGroupName}')] - public function appendCommentIdInGroup(int $id): void + #[On('insert-new-comment-to-{commentGroupName}')] + public function insertComment(int $id): void { - $this->commentIds[] = $id; + $comment = Comment::query() + ->select(['id', 'user_id', 'body', 'created_at', 'updated_at']) + ->withCount('children') + ->where('id', $id) + ->orderByDesc('children_count') + ->with('user:id,name,email') + ->with('children') + ->first() + ->toArray(); + + $this->comments = [$comment['id'] => $comment] + $this->comments; } /** @@ -95,37 +97,13 @@ public function destroy(int $commentId): void $post->decrement('comment_counts'); }); + unset($this->comments[$commentId]); + $this->dispatch('update-comment-counts'); $this->dispatch('info-badge', status: 'success', message: '成功刪除留言!'); } - /** - * @return Collection - */ - #[Computed] - public function comments(): Collection - { - return Comment::query() - ->select(['id', 'body', 'user_id', 'created_at', 'updated_at']) - ->withCount('children') - ->when($this->order === CommentOrder::LATEST, function (Builder $query) { - $query->latest('id'); - }) - ->when($this->order === CommentOrder::OLDEST, function (Builder $query) { - $query->oldest('id'); - }) - ->when($this->order === CommentOrder::POPULAR, function (Builder $query) { - $query->orderByDesc('children_count'); - }) - ->whereIn('id', $this->commentIds) - ->where('post_id', $this->postId) - ->where('parent_id', $this->parentId) - ->with('user:id,name,email') - ->with('children') - ->get(); - } - public function render(): View { return view('livewire.shared.comments.comment-group'); diff --git a/app/Livewire/Shared/Comments/CommentList.php b/app/Livewire/Shared/Comments/CommentList.php index 692be38f..ae8cadf7 100644 --- a/app/Livewire/Shared/Comments/CommentList.php +++ b/app/Livewire/Shared/Comments/CommentList.php @@ -42,16 +42,19 @@ class CommentList extends Component public CommentOrder $order = CommentOrder::LATEST; /** - * Comment ids list, example: + * Comments list array, the format is like: * [ - * [1, 2, 3, 4, 5], - * [6, 7, 8, 9, 10], - * [11, 12, 13, 14, 15], + * [ + * 1 => ["id" => 1, "body" => "hello" ...], + * 2 => ["id" => 2, "body" => "world" ...], + * ], + * [ + * 3 => ["id" => 3, "body" => "foo" ...], + * 4 => ["id" => 4, "body" => "bar" ...], + * ], * ] - * - * @var array> */ - public array $commentIdsList = []; + public array $commentsList = []; public int $skipCounts = 0; @@ -78,11 +81,11 @@ public function appendNewIdToNewCommentIds(int $id): void public function showMoreComments(): void { - $commentIds = $this->getCommentIds(); + $comments = $this->getComments(); $this->updateSkipCounts(); - $this->updateCommentIdsList($commentIds); - $this->updateShowMoreButtonStatus($commentIds); + $this->updateCommentsList($comments); + $this->updateShowMoreButtonStatus($comments); } public function render(): View @@ -90,10 +93,10 @@ public function render(): View return view('livewire.shared.comments.comment-list'); } - private function getCommentIds(): array + private function getComments(): array { return Comment::query() - ->select('id') + ->select(['id', 'user_id', 'body', 'created_at', 'updated_at']) // use a sub query to generate children_count column ->withCount('children') ->when($this->order === CommentOrder::LATEST, function (Builder $query) { @@ -115,7 +118,10 @@ private function getCommentIds(): array ->skip($this->skipCounts) // Plus one is needed here because we need to determine whether there is a next page. ->take($this->perPage + 1) - ->pluck('id') + ->with('user:id,name,email') + ->with('children') + ->get() + ->keyBy('id') ->toArray(); } @@ -124,16 +130,16 @@ private function updateSkipCounts(): void $this->skipCounts += $this->perPage; } - private function updateCommentIdsList(array $commentIds): void + private function updateCommentsList(array $comments): void { - if (count($commentIds) > 0) { - $this->commentIdsList[] = array_slice($commentIds, 0, $this->perPage); + if (count($comments) > 0) { + $this->commentsList[] = array_slice($comments, 0, $this->perPage, true); } } - private function updateShowMoreButtonStatus(array $commentIds): void + private function updateShowMoreButtonStatus(array $comments): void { - if (count($commentIds) <= $this->perPage) { + if (count($comments) <= $this->perPage) { $this->showMoreButtonIsActive = false; } } diff --git a/app/Livewire/Shared/Comments/CreateCommentModal.php b/app/Livewire/Shared/Comments/CreateCommentModal.php index 7e2271c8..f814c775 100644 --- a/app/Livewire/Shared/Comments/CreateCommentModal.php +++ b/app/Livewire/Shared/Comments/CreateCommentModal.php @@ -101,7 +101,7 @@ public function store(?int $parentId = null): void // Notify the article author of new comments. $post->user->notifyNewComment(new NewComment($comment)); - $this->dispatch('append-new-id-to-'.($parentId ?? 'root').'-new-comment-group', id: $comment->id); + $this->dispatch('insert-new-comment-to-'.($parentId ?? 'root').'-new-comment-group', id: $comment->id); $this->dispatch('append-new-id-to-'.($parentId ?? 'root').'-comment-list', id: $comment->id); }); diff --git a/resources/views/livewire/shared/comments/comment-card.blade.php b/resources/views/livewire/shared/comments/comment-card.blade.php index 26c62f2d..fe00f8a1 100644 --- a/resources/views/livewire/shared/comments/comment-card.blade.php +++ b/resources/views/livewire/shared/comments/comment-card.blade.php @@ -46,8 +46,8 @@ class="size-10 rounded-full hover:ring-2 hover:ring-blue-400" + datetime="{{ date('d-m-Y', strtotime($createdAt)) }}" + >{{ date('Y 年 m 月 d 日', strtotime($createdAt)) }} @if ($isEdited) (已編輯) diff --git a/resources/views/livewire/shared/comments/comment-group.blade.php b/resources/views/livewire/shared/comments/comment-group.blade.php index 2f27cfed..537a2706 100644 --- a/resources/views/livewire/shared/comments/comment-group.blade.php +++ b/resources/views/livewire/shared/comments/comment-group.blade.php @@ -37,25 +37,23 @@ class="w-full" x-data="commentGroup" > - @if (count($commentIds) > 0) - @foreach ($this->comments as $comment) - - @endforeach - @endif + @foreach ($comments as $comment) + + @endforeach diff --git a/resources/views/livewire/shared/comments/comment-list.blade.php b/resources/views/livewire/shared/comments/comment-list.blade.php index fbd73971..360dc902 100644 --- a/resources/views/livewire/shared/comments/comment-list.blade.php +++ b/resources/views/livewire/shared/comments/comment-list.blade.php @@ -41,17 +41,16 @@ class="w-full" x-data="commentList" > - @foreach ($commentIdsList as $commentIds) + @foreach ($commentsList as $comments) @endforeach diff --git a/tests/Feature/Comments/CreateCommentTest.php b/tests/Feature/Comments/CreateCommentTest.php index 28791eb3..6cb85932 100644 --- a/tests/Feature/Comments/CreateCommentTest.php +++ b/tests/Feature/Comments/CreateCommentTest.php @@ -18,7 +18,7 @@ ->set('body', $body) ->set('captchaToken', 'fake-captcha-response') ->call('store') - ->assertDispatched('append-new-id-to-root-new-comment-group') + ->assertDispatched('insert-new-comment-to-root-new-comment-group') ->assertDispatched('close-create-comment-modal') ->assertDispatched('update-comment-counts') ->assertDispatched('info-badge', @@ -45,7 +45,7 @@ ->set('body', $body) ->set('captchaToken', 'fake-captcha-response') ->call('store') - ->assertDispatched('append-new-id-to-root-new-comment-group') + ->assertDispatched('insert-new-comment-to-root-new-comment-group') ->assertDispatched('close-create-comment-modal') ->assertDispatched('update-comment-counts') ->assertDispatched('info-badge', @@ -157,7 +157,7 @@ ->set('body', 'Hello World!') ->set('captchaToken', 'fake-captcha-response') ->call('store', parentId: $comment->id) - ->assertDispatched('append-new-id-to-'.$comment->id.'-new-comment-group') + ->assertDispatched('insert-new-comment-to-'.$comment->id.'-new-comment-group') ->assertDispatched('close-create-comment-modal') ->assertDispatched('update-comment-counts') ->assertDispatched('info-badge',