Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions app/Enums/LivewireEventEnum.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

enum LivewireEventEnum: string
{
case BlurReset = 'blur-reset';
case CommentDeleted = 'comment-deleted';
case CommentFlagCancelled = 'comment-flag-cancelled';
case CommentFlagDeleted = 'comment-flag-deleted';
Expand Down
13 changes: 10 additions & 3 deletions app/Livewire/Comments/CommentComponent.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
use App\Enums\CommentStateEnum;
use App\Enums\LivewireEventEnum;
use App\Enums\ModerationTypeEnum;
use App\Enums\RoleNameEnum;
use App\Models\Comment;
use App\Traits\AuthStatusTrait;
use App\Traits\CommentComponentTrait;
use Illuminate\Contracts\View\View;
use Illuminate\Support\Collection;
Expand All @@ -17,6 +17,7 @@

final class CommentComponent extends Component
{
use AuthStatusTrait;
use CommentComponentTrait;

// State
Expand All @@ -28,7 +29,9 @@ public function mount(int $commentId, ?Comment $comment, ?Collection $childComme
// and the moderator comments collection.
$this->commentId = $commentId;
$this->comment = $comment ?? Comment::find($commentId);
$this->childComments = $childComments;
if ($childComments) {
$this->childComments = $childComments;
}

// Decide whether to blur the component initially.
$this->isBlurred = $this->isInitiallyBlurred;
Expand All @@ -38,19 +41,23 @@ public function render(): View
{
$moderationType = $this->appearanceComment?->moderation_type ?? null;

$hasModeratorActions = $this->filterModeratorActions($this->childComments, $this->state === CommentStateEnum::Moderating)->isNotEmpty();

// If there are no decorations to apply, just render the basic comment component.
return view('livewire.comments.comment-component', [
'comment' => $this->comment,
'childComments' => $this->childComments,
'moderationType' => $moderationType,
'isInitiallyBlurred' => $this->isInitiallyBlurred,
'isRemoved' => $moderationType === ModerationTypeEnum::Remove && !auth()->user()?->hasRole(RoleNameEnum::MODERATOR->value),
'isRemoved' => $moderationType === ModerationTypeEnum::Remove && !$this->isModerator(),
'appearanceComment' => $this->appearanceComment,
'appearanceCommentId' => $this->appearanceComment?->id,
'blurCommentId' => $this->blurComment?->id,
'isEditing' => $this->state === CommentStateEnum::Editing,
'isFlagging' => $this->state === CommentStateEnum::Flagging,
'isReplying' => $this->state === CommentStateEnum::Replying,
'isModerating' => $this->state === CommentStateEnum::Moderating,
'hasModeratorActions' => $hasModeratorActions,
]);
}

Expand Down
5 changes: 4 additions & 1 deletion app/Livewire/Comments/CommentListComponent.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use App\Enums\LivewireEventEnum;
use App\Repositories\CommentRepositoryInterface;
use App\Traits\AuthStatusTrait;
use App\Traits\ModeratorActionsTrait;
use App\Traits\SubsiteTrait;
use Illuminate\Contracts\View\View;
use Illuminate\Support\Collection;
Expand All @@ -18,6 +19,7 @@
final class CommentListComponent extends Component
{
use AuthStatusTrait;
use ModeratorActionsTrait;
use SubsiteTrait;

#[Locked]
Expand Down Expand Up @@ -50,6 +52,7 @@ public function render(): View
{
return view('livewire.comments.comment-list-component', [
'comments' => $this->comments,
'isModerator' => $this->isModerator(),
]);
}

Expand All @@ -58,7 +61,7 @@ public function render(): View
LivewireEventEnum::CommentDeleted->value,
LivewireEventEnum::CommentUpdated->value,
])]
public function getComments(): void
public function refreshComments(): void
{
unset($this->comments);
}
Expand Down
27 changes: 0 additions & 27 deletions app/Livewire/Comments/CommentRemoval.php

This file was deleted.

27 changes: 0 additions & 27 deletions app/Livewire/Comments/CommentReplacement.php

This file was deleted.

2 changes: 2 additions & 0 deletions app/Livewire/Comments/CommentWrapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace App\Livewire\Comments;

use App\Enums\CommentStateEnum;
use App\Traits\CommentComponentTrait;
use App\Traits\CommentComponentStateTrait;
use Illuminate\Contracts\View\View;
Expand All @@ -24,6 +25,7 @@ public function render(): View
'childComments' => $this->childComments,
'moderatorComment' => $this->appearanceComment,
'isInitiallyBlurred' => $this->isInitiallyBlurred,
'isModerating' => $this->state === CommentStateEnum::Moderating,
]);
}
}
42 changes: 42 additions & 0 deletions app/Livewire/Comments/ModeratorComment.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?php

declare(strict_types=1);

namespace App\Livewire\Comments;

use App\Enums\CommentStateEnum;
use App\Enums\ModerationTypeEnum;
use App\Traits\CommentComponentTrait;
use App\Traits\CommentComponentStateTrait;
use Illuminate\Contracts\View\View;
use Livewire\Component;

final class ModeratorComment extends Component
{
use CommentComponentStateTrait;
use CommentComponentTrait;

#[Locked]
public bool $showModeratorToggle = false;

public function render(): View
{
$moderationAction = match ($this->comment->moderation_type) {
ModerationTypeEnum::Blur => 'blurred',
ModerationTypeEnum::Comment => 'commented',
ModerationTypeEnum::Edit => 'edited',
ModerationTypeEnum::Remove => 'removed',
ModerationTypeEnum::Replace => 'replaced',
ModerationTypeEnum::Wrap => 'wrapped',
ModerationTypeEnum::Restore => 'restored',
default => '',
};

return view('livewire.comments.moderator-comment', [
'comment' => $this->comment,
'isModerating' => $this->state === CommentStateEnum::Moderating,
'moderationAction' => $moderationAction,
'moderationClass' => 'moderator-' . $moderationAction,
]);
}
}
85 changes: 85 additions & 0 deletions app/Livewire/Comments/ModeratorCommentListComponent.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
<?php

declare(strict_types=1);

namespace App\Livewire\Comments;

use App\Enums\CommentStateEnum;
use App\Enums\LivewireEventEnum;
use App\Repositories\CommentRepositoryInterface;
use App\Traits\AuthStatusTrait;
use App\Traits\CommentComponentStateTrait;
use App\Traits\ModeratorActionsTrait;
use App\Traits\SubsiteTrait;
use Illuminate\Contracts\View\View;
use Illuminate\Support\Collection;
use Livewire\Attributes\Computed;
use Livewire\Attributes\Locked;
use Livewire\Attributes\On;
use Livewire\Component;

final class ModeratorCommentListComponent extends Component
{
use AuthStatusTrait;
use CommentComponentStateTrait;
use ModeratorActionsTrait;
use SubsiteTrait;

#[Locked]
public int $parentId = 0;

protected CommentRepositoryInterface $commentRepository;

public function boot(CommentRepositoryInterface $commentRepository): void
{
$this->commentRepository = $commentRepository;
}

public function mount(int $parentId, ?Collection $childComments): void
{
$this->parentId = $parentId;

if ($childComments) {
// If provided, use the child comments from the parent comment.
// This saves some time when all post comments were loaded up front.
$this->childComments = $childComments;
}
}

/**
* Returns all child comments in chronological order.
*/
#[Computed]
public function childComments(): Collection
{
return $this->commentRepository->getCommentsByParentId($this->parentId);
}

/**
* Returns all moderator actions in reverse chronological order.
*/
#[Computed]
public function moderatorActions(): Collection
{
return $this->filterModeratorActions($this->childComments, $this->state === CommentStateEnum::Moderating);
}

public function render(): View
{
return view('livewire.comments.moderator-comment-list-component', [
'comments' => $this->moderatorActions,
'isModerating' => $this->state === CommentStateEnum::Moderating,
'isModerator' => $this->isModerator(),
]);
}

#[On([
LivewireEventEnum::CommentStored->value,
LivewireEventEnum::CommentDeleted->value,
LivewireEventEnum::CommentUpdated->value,
])]
public function refreshChildComments(): void
{
unset($this->childComments);
}
}
2 changes: 1 addition & 1 deletion app/Traits/AuthStatusTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public function getAuthorizedUserId(): int|null

public function isModerator(): bool
{
return auth()->user()->hasRole(RoleNameEnum::MODERATOR->value);
return auth()->user()?->hasRole(RoleNameEnum::MODERATOR->value) ?? false;
}

public function loggedIn(): bool
Expand Down
36 changes: 9 additions & 27 deletions app/Traits/CommentComponentTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

use App\Enums\CommentStateEnum;
use App\Enums\LivewireEventEnum;
use App\Enums\ModerationTypeEnum;
use App\Models\Comment;
use App\Repositories\CommentRepositoryInterface;
use Illuminate\Support\Collection;
Expand All @@ -16,6 +15,8 @@

trait CommentComponentTrait
{
use ModeratorActionsTrait;

// Data
#[Locked]
public int $commentId = 0;
Expand Down Expand Up @@ -45,19 +46,7 @@ public function userFlagged(): bool
#[Computed]
public function appearanceComment(): ?Comment
{
$appearanceComment = $this->childComments?->last(
fn($comment) => $comment->moderation_type !== null && match ($comment->moderation_type) {
ModerationTypeEnum::Remove, ModerationTypeEnum::Replace, ModerationTypeEnum::Wrap, ModerationTypeEnum::Restore => true,
default => false,
},
);

// If the last appearance-modifying comment is a Restore, return null.
if ($appearanceComment && $appearanceComment->moderation_type === ModerationTypeEnum::Restore) {
return null;
}

return $appearanceComment;
return $this->findLastAppearanceComment($this->childComments);
}

/**
Expand All @@ -69,19 +58,7 @@ public function appearanceComment(): ?Comment
#[Computed]
public function blurComment(): ?Comment
{
$blurComment = $this->childComments?->last(
fn($comment) => $comment->moderation_type !== null && match ($comment->moderation_type) {
ModerationTypeEnum::Blur, ModerationTypeEnum::Remove, ModerationTypeEnum::Replace, ModerationTypeEnum::Restore => true,
default => false,
},
);

// If the last blur-modifying comment is not a Blur, return null.
if ($blurComment && $blurComment->moderation_type !== ModerationTypeEnum::Blur) {
return null;
}

return $blurComment;
return $this->findLastBlurComment($this->childComments);
}

#[Computed]
Expand Down Expand Up @@ -150,6 +127,11 @@ public function toggleModerating(): void
}
}

public function resetBlur(): void
{
$this->dispatch(LivewireEventEnum::BlurReset->value, id: $this->commentId);
}

public function requestStateChange(CommentStateEnum $state): void
{
$this->dispatch(LivewireEventEnum::CommentFormStateChanged->value, id: $this->commentId, state: $state);
Expand Down
Loading