Skip to content

Commit 690423d

Browse files
committed
Dispatching event with the save comment
1 parent bdb04e9 commit 690423d

File tree

6 files changed

+100
-33
lines changed

6 files changed

+100
-33
lines changed

resources/views/reaction-manager.blade.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
x-cloak
77
wire:click="handleReactionToggle('{{ $reactionData['reaction'] }}')"
88
type="button"
9-
class="inline-flex items-center justify-center gap-1 rounded-full border px-2 py-1 text-sm font-medium transition hover:bg-gray-100 dark:hover:bg-gray-800 focus:outline-none focus:ring-2 focus:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed
9+
class="inline-flex items-center justify-center gap-1 rounded-full border px-2 h-8 text-sm font-medium transition hover:bg-gray-100 dark:hover:bg-gray-800 focus:outline-none focus:ring-2 focus:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed
1010
{{ $reactionData['reacted_by_current_user']
1111
? 'bg-primary-100 dark:bg-primary-800 border-primary-300 dark:border-primary-600 text-primary-700 dark:text-primary-200'
1212
: 'bg-white dark:bg-gray-900 border-gray-300 dark:border-gray-600 text-gray-700 dark:text-gray-200' }}"
@@ -25,7 +25,7 @@ class="inline-flex items-center justify-center gap-1 rounded-full border px-2 py
2525
x-on:click="open = !open"
2626
type="button"
2727
@disabled(! auth()->check())
28-
class="inline-flex items-center justify-center gap-1 rounded-full border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-900 px-2 py-1 text-sm font-medium text-gray-700 dark:text-gray-200 transition hover:bg-gray-100 dark:hover:bg-gray-800 focus:outline-none focus:ring-2 focus:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed"
28+
class="inline-flex items-center justify-center gap-1 rounded-full border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-900 w-8 h-8 text-sm font-medium text-gray-700 dark:text-gray-200 transition hover:bg-gray-100 dark:hover:bg-gray-800 focus:outline-none focus:ring-2 focus:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed"
2929
title="Add Reaction"
3030
wire:key="add-reaction-button-{{ $comment->getId() }}"
3131
>
@@ -51,7 +51,7 @@ class="absolute bottom-full mb-2 z-10 bg-white dark:bg-gray-800 border border-gr
5151
x-on:click="open = false"
5252
type="button"
5353
@disabled(! auth()->check())
54-
class="inline-flex items-center justify-center gap-1 rounded-full border px-2 py-1 text-sm font-medium transition hover:bg-gray-100 dark:hover:bg-gray-800 focus:outline-none focus:ring-2 focus:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed
54+
class="inline-flex items-center justify-center gap-1 rounded-full border w-8 h-8 text-sm font-medium transition hover:bg-gray-100 dark:hover:bg-gray-800 focus:outline-none focus:ring-2 focus:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed
5555
{{ $reactionData['reacted_by_current_user']
5656
? 'bg-primary-100 dark:bg-primary-800 border-primary-300 dark:border-primary-600 text-primary-700 dark:text-primary-200'
5757
: 'bg-white dark:bg-gray-900 border-gray-300 dark:border-gray-600 text-gray-700 dark:text-gray-200' }}"
@@ -69,7 +69,7 @@ class="inline-flex items-center justify-center gap-1 rounded-full border px-2 py
6969
@if (! in_array($reactionEmoji, $allowedReactions) && $data['count'] > 0)
7070
<span
7171
wire:key="reaction-extra-{{ $reactionEmoji }}-{{ $comment->getId() }}"
72-
class="inline-flex items-center justify-center gap-1 rounded-full border border-gray-300 dark:border-gray-600 bg-gray-100 dark:bg-gray-800 px-2 py-1 text-sm font-medium text-gray-600 dark:text-gray-300"
72+
class="inline-flex items-center justify-center gap-1 rounded-full border border-gray-300 dark:border-gray-600 bg-gray-100 dark:bg-gray-800 w-8 h-8 text-sm font-medium text-gray-600 dark:text-gray-300"
7373
title="{{ $reactionEmoji }}"
7474
>
7575
<span>{{ $reactionEmoji }}</span>
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<?php
2+
3+
namespace Kirschbaum\Commentions\Actions;
4+
5+
use Illuminate\Foundation\Auth\User as Authenticatable;
6+
use Kirschbaum\Commentions\Comment;
7+
use Kirschbaum\Commentions\CommentReaction;
8+
use Kirschbaum\Commentions\Config;
9+
use Kirschbaum\Commentions\Events\CommentReactionToggledEvent;
10+
11+
class ToggleCommentReaction
12+
{
13+
public static function run(Comment $comment, string $reaction, ?Authenticatable $user = null): void
14+
{
15+
if (! $user) {
16+
return;
17+
}
18+
19+
if (! in_array($reaction, Config::getAllowedReactions())) {
20+
return;
21+
}
22+
23+
/** @var CommentReaction $existingReaction */
24+
$existingReaction = $comment
25+
->reactions()
26+
->where('reactor_id', $user->getKey())
27+
->where('reactor_type', $user->getMorphClass())
28+
->where('reaction', $reaction)
29+
->first();
30+
31+
if ($existingReaction) {
32+
$existingReaction->delete();
33+
event(new CommentReactionToggledEvent($comment, $existingReaction, $user, $reaction, false));
34+
} else {
35+
$newReaction = $comment->reactions()->create([
36+
'reactor_id' => $user->getKey(),
37+
'reactor_type' => $user->getMorphClass(),
38+
'reaction' => $reaction,
39+
]);
40+
event(new CommentReactionToggledEvent($comment, $newReaction, $user, $reaction, true));
41+
}
42+
}
43+
}

src/Comment.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
use Illuminate\Support\Collection;
1414
use Kirschbaum\Commentions\Actions\HtmlToMarkdown;
1515
use Kirschbaum\Commentions\Actions\ParseComment;
16+
use Kirschbaum\Commentions\Actions\ToggleCommentReaction;
1617
use Kirschbaum\Commentions\Contracts\Commentable;
1718
use Kirschbaum\Commentions\Contracts\Commenter;
1819
use Kirschbaum\Commentions\Contracts\RenderableComment;
@@ -167,6 +168,11 @@ public function canDelete(): bool
167168
return Config::allowDeletes() && $this->isAuthor(Config::resolveAuthenticatedUser());
168169
}
169170

171+
public function toggleReaction(string $reaction): void
172+
{
173+
ToggleCommentReaction::run($this, $reaction, Config::resolveAuthenticatedUser());
174+
}
175+
170176
public function getLabel(): ?string
171177
{
172178
return null;
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
namespace Kirschbaum\Commentions\Events;
4+
5+
use Illuminate\Foundation\Events\Dispatchable;
6+
use Illuminate\Queue\SerializesModels;
7+
use Kirschbaum\Commentions\Comment;
8+
use Kirschbaum\Commentions\CommentReaction;
9+
use Illuminate\Foundation\Auth\User as Authenticatable;
10+
11+
class CommentReactionToggledEvent
12+
{
13+
use Dispatchable, SerializesModels;
14+
15+
public function __construct(
16+
public Comment $comment,
17+
public ?CommentReaction $reaction,
18+
public Authenticatable $user,
19+
public string $reactionType,
20+
public bool $wasCreated
21+
) {
22+
}
23+
}

src/Livewire/Comment.php

Lines changed: 2 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -110,40 +110,14 @@ public function cancelEditing()
110110
$this->commentBody = '';
111111
}
112112

113-
// #[Renderless]
113+
#[Renderless]
114114
public function toggleReaction(string $reaction): void
115115
{
116-
$user = Config::resolveAuthenticatedUser();
117-
118-
if (! $user) {
119-
return;
120-
}
121-
122-
if (! in_array($reaction, Config::getAllowedReactions())) {
123-
return;
124-
}
125-
126116
if (! $this->comment instanceof CommentModel) {
127117
return;
128118
}
129119

130-
/** @var CommentReaction $existingReaction */
131-
$existingReaction = $this->comment
132-
->reactions()
133-
->where('reactor_id', $user->getKey())
134-
->where('reactor_type', $user->getMorphClass())
135-
->where('reaction', $reaction)
136-
->first();
137-
138-
if ($existingReaction) {
139-
$existingReaction->delete();
140-
} else {
141-
$this->comment->reactions()->create([
142-
'reactor_id' => $user->getKey(),
143-
'reactor_type' => $user->getMorphClass(),
144-
'reaction' => $reaction,
145-
]);
146-
}
120+
$this->comment->toggleReaction($reaction);
147121

148122
$this->dispatch('comment:reaction:saved');
149123
}

tests/Feature/CommentReactionTest.php

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
<?php
22

33
use Illuminate\Support\Facades\Auth;
4+
use Illuminate\Support\Facades\Event;
45
use Kirschbaum\Commentions\Comment as CommentModel;
56
use Kirschbaum\Commentions\Config;
7+
use Kirschbaum\Commentions\Events\CommentReactionToggledEvent;
68
use Kirschbaum\Commentions\Livewire\Comment as CommentComponent;
79
use Tests\Models\Post;
810
use Tests\Models\User;
@@ -13,6 +15,7 @@
1315
beforeEach(function () {
1416
config(['commentions.allowed_reactions' => ['👍', '❤️']]);
1517
Config::resolveAuthenticatedUserUsing(fn () => Auth::user());
18+
Event::fake();
1619
});
1720

1821
test('user can add configured reactions to a comment', function (string $reactionEmoji) {
@@ -27,6 +30,15 @@
2730
livewire(CommentComponent::class, ['comment' => $comment])
2831
->call('toggleReaction', $reactionEmoji);
2932

33+
Event::assertDispatched(CommentReactionToggledEvent::class, function (CommentReactionToggledEvent $event) use ($comment, $user, $reactionEmoji) {
34+
return $event->comment->is($comment)
35+
&& $event->user->is($user)
36+
&& $event->reactionType === $reactionEmoji
37+
&& $event->wasCreated === true
38+
&& $event->reaction !== null
39+
&& $event->reaction->reaction === $reactionEmoji;
40+
});
41+
3042
$this->assertDatabaseHas('comment_reactions', [
3143
'comment_id' => $comment->id,
3244
'reactor_id' => $user->id,
@@ -49,7 +61,7 @@
4961
$comment = CommentModel::factory()->author($user)->commentable($post)->create();
5062

5163
// Add reaction first
52-
$comment->reactions()->create([
64+
$reaction = $comment->reactions()->create([
5365
'reactor_id' => $user->id,
5466
'reactor_type' => $user->getMorphClass(),
5567
'reaction' => $reactionEmoji,
@@ -65,6 +77,15 @@
6577
livewire(CommentComponent::class, ['comment' => $comment])
6678
->call('toggleReaction', $reactionEmoji);
6779

80+
Event::assertDispatched(CommentReactionToggledEvent::class, function (CommentReactionToggledEvent $event) use ($comment, $user, $reactionEmoji, $reaction) {
81+
return $event->comment->is($comment)
82+
&& $event->user->is($user)
83+
&& $event->reactionType === $reactionEmoji
84+
&& $event->wasCreated === false
85+
&& $event->reaction !== null // The deleted reaction model is passed
86+
&& $event->reaction->is($reaction);
87+
});
88+
6889
$this->assertDatabaseMissing('comment_reactions', [
6990
'comment_id' => $comment->id,
7091
'reactor_id' => $user->id,

0 commit comments

Comments
 (0)