Skip to content

Commit 7f8d521

Browse files
authored
wip: [LAR-112] discussion comment feature (#253)
1 parent c32db55 commit 7f8d521

File tree

29 files changed

+360
-414
lines changed

29 files changed

+360
-414
lines changed

app/Actions/Replies/CreateReply.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,17 @@
1212

1313
final class CreateReply
1414
{
15-
public function handle(string $body, User $user, Model $model): Reply
15+
public function __invoke(string $body, User $user, Model $model): Reply
1616
{
1717
$reply = new Reply(['body' => $body]);
1818
$reply->authoredBy($user);
19-
$reply->to($model);
19+
$reply->to($model); // @phpstan-ignore-line
2020
$reply->save();
2121

2222
$user->givePoint(new ReplyCreated($model, $user));
2323

2424
// On envoie un event pour une nouvelle réponse à tous les abonnés de la discussion
25-
event(new CommentWasAdded($reply, $model));
25+
event(new CommentWasAdded($reply, $model)); // @phpstan-ignore-line
2626

2727
return $reply;
2828
}

app/Actions/Replies/LikeReply.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
final class LikeReply
1212
{
13-
public function handle(User $user, Reply $reply, string $reaction = 'love'): void
13+
public function __invoke(User $user, Reply $reply, string $reaction = 'love'): void
1414
{
1515
/** @var Reaction $react */
1616
$react = Reaction::query()->where('name', $reaction)->first();
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Livewire\Components\Discussion;
6+
7+
use App\Actions\Replies\LikeReply;
8+
use App\Models\Reply;
9+
use Filament\Notifications\Notification;
10+
use Illuminate\Contracts\View\View;
11+
use Livewire\Attributes\Lazy;
12+
use Livewire\Component;
13+
14+
#[Lazy]
15+
final class Comment extends Component
16+
{
17+
public Reply $comment;
18+
19+
public function delete(): void
20+
{
21+
$this->comment->delete();
22+
23+
Notification::make()
24+
->title(__('notifications.discussion.delete_comment'))
25+
->success()
26+
->send();
27+
28+
$this->dispatch('comments.change');
29+
}
30+
31+
public function toggleLike(): void
32+
{
33+
$this->authorize('like', $this->comment);
34+
35+
app()->call(LikeReply::class, [
36+
'user' => auth()->user(),
37+
'reply' => $this->comment,
38+
]);
39+
}
40+
41+
public function placeholder(): View
42+
{
43+
return view('components.skeletons.comment');
44+
}
45+
46+
public function render(): View
47+
{
48+
return view('livewire.components.discussion.comment', [
49+
'count' => $this->comment->getReactionsSummary()->sum('count'),
50+
]);
51+
}
52+
}
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Livewire\Components\Discussion;
6+
7+
use App\Actions\Replies\CreateReply;
8+
use App\Models\Discussion;
9+
use App\Models\Reply;
10+
use Filament\Forms;
11+
use Filament\Forms\Concerns\InteractsWithForms;
12+
use Filament\Forms\Contracts\HasForms;
13+
use Filament\Forms\Form;
14+
use Filament\Notifications\Notification;
15+
use Illuminate\Contracts\View\View;
16+
use Illuminate\Support\Collection;
17+
use Illuminate\Support\Facades\Auth;
18+
use Livewire\Attributes\Computed;
19+
use Livewire\Attributes\On;
20+
use Livewire\Component;
21+
22+
/**
23+
* @property Form $form
24+
*/
25+
final class Comments extends Component implements HasForms
26+
{
27+
use InteractsWithForms;
28+
29+
public Discussion $discussion;
30+
31+
public ?array $data = [];
32+
33+
public function mount(): void
34+
{
35+
$this->form->fill();
36+
}
37+
38+
public function form(Form $form): Form
39+
{
40+
return $form
41+
->schema([
42+
Forms\Components\Textarea::make('body')
43+
->hiddenLabel()
44+
->placeholder(__('pages/discussion.placeholder'))
45+
->rows(3)
46+
->required(),
47+
])
48+
->statePath('data');
49+
}
50+
51+
public function save(): void
52+
{
53+
$this->validate();
54+
55+
app()->call(CreateReply::class, [
56+
'body' => data_get($this->form->getState(), 'body'),
57+
'user' => Auth::user(),
58+
'model' => $this->discussion,
59+
]);
60+
61+
Notification::make()
62+
->title(__('notifications.discussion.save_comment'))
63+
->success()
64+
->send();
65+
66+
$this->dispatch('comments.change');
67+
68+
$this->reset('data');
69+
}
70+
71+
#[Computed]
72+
#[On('comments.change')]
73+
public function comments(): Collection
74+
{
75+
$replies = collect();
76+
77+
foreach ($this->discussion->replies->load(['allChildReplies', 'user']) as $reply) {
78+
/** @var Reply $reply */
79+
if ($reply->allChildReplies->isNotEmpty()) {
80+
foreach ($reply->allChildReplies as $childReply) {
81+
$replies->add($childReply);
82+
}
83+
}
84+
85+
$replies->add($reply);
86+
}
87+
88+
return $replies;
89+
}
90+
91+
public function render(): View
92+
{
93+
return view('livewire.components.discussion.comments');
94+
}
95+
}

app/Livewire/Discussions/AddComment.php

Lines changed: 0 additions & 55 deletions
This file was deleted.

app/Livewire/Discussions/Comment.php

Lines changed: 0 additions & 54 deletions
This file was deleted.

app/Livewire/Discussions/Comments.php

Lines changed: 0 additions & 46 deletions
This file was deleted.

app/Livewire/Pages/Account/Profile.php

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,6 @@ final class Profile extends Component
1212
{
1313
public User $user;
1414

15-
public function mount(User $user): void
16-
{
17-
$this->user = $user->load([
18-
'activities',
19-
'articles',
20-
'articles.tags',
21-
'discussions',
22-
'discussions.tags',
23-
'threads',
24-
]);
25-
}
26-
2715
public function render(): View
2816
{
2917
return view('livewire.pages.account.profile', [

app/Livewire/Pages/Discussions/SingleDiscussion.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public function mount(Discussion $discussion): void
3737
->twitterSite('laravelcm')
3838
->withUrl();
3939

40-
$this->discussion = $discussion->load('tags');
40+
$this->discussion = $discussion->load('tags', 'replies', 'reactions', 'replies.user');
4141
}
4242

4343
public function editAction(): Action
@@ -85,6 +85,7 @@ public function deleteAction(): Action
8585

8686
public function render(): View
8787
{
88-
return view('livewire.pages.discussions.single-discussion')->title($this->discussion->title);
88+
return view('livewire.pages.discussions.single-discussion')
89+
->title($this->discussion->title);
8990
}
9091
}

app/Policies/ReplyPolicy.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,9 @@ public function report(User $user, Reply $reply): bool
3636
{
3737
return $user->hasVerifiedEmail() && ! $reply->isAuthoredBy($user);
3838
}
39+
40+
public function like(User $user, Reply $reply): bool
41+
{
42+
return $user->hasVerifiedEmail();
43+
}
3944
}

composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
"archtechx/laravel-seo": "^0.10",
1212
"awcodes/filament-badgeable-column": "^2.3",
1313
"blade-ui-kit/blade-heroicons": "^2.4",
14+
"codeat3/blade-phosphor-icons": "^2.0",
1415
"cyrildewit/eloquent-viewable": "^7.0",
1516
"doctrine/dbal": "^3.6.4",
1617
"dutchcodingcompany/livewire-recaptcha": "^1.0",

0 commit comments

Comments
 (0)