Skip to content

Commit ff3bcdb

Browse files
authored
Merge pull request #30 from laravelcm/notifications
Notifications
2 parents 269b8d6 + 8fa2624 commit ff3bcdb

26 files changed

+507
-8
lines changed

app/Actions/Fortify/CreateNewUser.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use App\Models\User;
66
use Illuminate\Support\Facades\Hash;
77
use Illuminate\Support\Facades\Validator;
8+
use Illuminate\Support\Str;
89
use Illuminate\Validation\Rule;
910
use Laravel\Fortify\Contracts\CreatesNewUsers;
1011

@@ -35,6 +36,7 @@ public function create(array $input): User
3536
'string',
3637
'min:6',
3738
'max:20',
39+
'alpha_dash',
3840
Rule::unique(User::class, 'username'),
3941
],
4042
'password' => $this->passwordRules(),
@@ -43,9 +45,9 @@ public function create(array $input): User
4345
return User::create([
4446
'name' => $input['name'],
4547
'email' => $input['email'],
46-
'username' => $input['username'],
47-
'opt_in' => isset($input['opt_in']),
48+
'username' => Str::lower($input['username']),
4849
'password' => Hash::make($input['password']),
50+
'opt_in' => isset($input['opt_in']),
4951
]);
5052
}
5153
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
namespace App\Http\Controllers;
4+
5+
use App\Models\Reply;
6+
7+
class ReplyAbleController extends Controller
8+
{
9+
public function redirect($id, $type)
10+
{
11+
$reply = Reply::where('replyable_id', $id)->where('replyable_type', $type)->firstOrFail();
12+
13+
return redirect(route_to_reply_able($reply->replyAble));
14+
}
15+
}

app/Http/Controllers/SubscriptionController.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,11 @@ public function unsubscribe(Subscribe $subscription)
1717

1818
return redirect()->route('forum.show', $thread->slug());
1919
}
20+
21+
public function redirect($id, $type)
22+
{
23+
$subscribe = Subscribe::where('subscribeable_id', $id)->where('subscribeable_type', $type)->firstOrFail();
24+
25+
return redirect(route_to_reply_able($subscribe->subscribeAble));
26+
}
2027
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
3+
namespace App\Http\Livewire;
4+
5+
use Illuminate\Support\Facades\Auth;
6+
use Livewire\Component;
7+
8+
class NotificationCount extends Component
9+
{
10+
public int $count = 0;
11+
12+
protected $listeners = [
13+
'NotificationMarkedAsRead' => 'updateCount',
14+
];
15+
16+
public function updateCount(int $count): int
17+
{
18+
return $count;
19+
}
20+
21+
public function render()
22+
{
23+
$this->count = Auth::user()->unreadNotifications()->count();
24+
25+
return view('livewire.notification-count', [
26+
'count' => $this->count,
27+
]);
28+
}
29+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
namespace App\Http\Livewire;
4+
5+
use Illuminate\Support\Facades\Auth;
6+
use Livewire\Component;
7+
8+
class NotificationIndicator extends Component
9+
{
10+
public bool $hasNotification = false;
11+
12+
protected $listeners = [
13+
'NotificationMarkedAsRead' => 'setHasNotification',
14+
];
15+
16+
public function setHasNotification(int $count): bool
17+
{
18+
return $count > 0;
19+
}
20+
21+
public function render()
22+
{
23+
$this->hasNotification = $this->setHasNotification(
24+
Auth::user()->unreadNotifications()->count(),
25+
);
26+
27+
return view('livewire.notification-indicator', [
28+
'hasNotification' => $this->hasNotification,
29+
]);
30+
}
31+
}

app/Http/Livewire/Notifications.php

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
<?php
2+
3+
namespace App\Http\Livewire;
4+
5+
use App\Policies\NotificationPolicy;
6+
use Carbon\Carbon;
7+
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
8+
use Illuminate\Notifications\DatabaseNotification;
9+
use Illuminate\Support\Facades\Auth;
10+
use Livewire\Component;
11+
use WireUi\Traits\Actions;
12+
13+
class Notifications extends Component
14+
{
15+
use Actions, AuthorizesRequests;
16+
17+
public $notificationId;
18+
19+
public function mount(): void
20+
{
21+
abort_if(Auth::guest(), 403);
22+
}
23+
24+
public function getNotificationProperty(): DatabaseNotification
25+
{
26+
return DatabaseNotification::findOrFail($this->notificationId);
27+
}
28+
29+
public function markAsRead(string $notificationId): void
30+
{
31+
$this->notificationId = $notificationId;
32+
33+
$this->authorize(NotificationPolicy::MARK_AS_READ, $this->notification);
34+
35+
$this->notification->markAsRead();
36+
37+
$this->notification()->success('Notification', 'Cette notification a été marquée comme lue.');
38+
39+
$this->emit('NotificationMarkedAsRead', Auth::user()->unreadNotifications()->count());
40+
}
41+
42+
public function render()
43+
{
44+
return view('livewire.notifications', [
45+
'notifications' => Auth::user()
46+
->unreadNotifications()
47+
->take(10)
48+
->get()
49+
->groupBy(
50+
fn ($notification) => Carbon::parse($notification->created_at)->format('M, Y')
51+
),
52+
]);
53+
}
54+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?php
2+
3+
namespace App\Http\Livewire\User\Settings;
4+
5+
use App\Models\Subscribe;
6+
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
7+
use Illuminate\Support\Facades\Auth;
8+
use Livewire\Component;
9+
use WireUi\Traits\Actions;
10+
11+
class Notifications extends Component
12+
{
13+
use Actions, AuthorizesRequests;
14+
15+
public $subscribeId;
16+
17+
public function unsubscribe(string $subscribeId)
18+
{
19+
$this->subscribeId = $subscribeId;
20+
21+
$this->subscribe->delete();
22+
23+
$this->notification()->success('Désabonnement', 'Vous êtes maintenant désabonné de cet fil.');
24+
}
25+
26+
public function getSubscribeProperty(): Subscribe
27+
{
28+
return Subscribe::where('uuid', $this->subscribeId)->firstOrFail();
29+
}
30+
31+
public function render()
32+
{
33+
return view('livewire.user.settings.notifications', [
34+
'subscriptions' => Auth::user()->subscriptions,
35+
]);
36+
}
37+
}

app/Models/User.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,11 @@ public function discussions(): HasMany
187187
return $this->hasMany(Discussion::class);
188188
}
189189

190+
public function subscriptions(): HasMany
191+
{
192+
return $this->hasMany(Subscribe::class);
193+
}
194+
190195
public function deleteThreads()
191196
{
192197
// We need to explicitly iterate over the threads and delete them

app/Notifications/YouWereMentioned.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ public function toArray($notifiable): array
3939
'author_name' => $this->reply->author->name,
4040
'author_username' => $this->reply->author->username,
4141
'author_photo' => $this->reply->author->profile_photo_url,
42+
'replyable_id' => $this->reply->replyable_id,
4243
'replyable_type' => $this->reply->replyable_type,
4344
'replyable_subject' => $this->reply->replyAble->replyAbleSubject(),
4445
];

app/Policies/NotificationPolicy.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
namespace App\Policies;
4+
5+
use App\Models\User;
6+
use Illuminate\Notifications\DatabaseNotification;
7+
8+
class NotificationPolicy
9+
{
10+
const MARK_AS_READ = 'markAsRead';
11+
12+
/**
13+
* Determine if the given notification can be marked as read by the user.
14+
*/
15+
public function markAsRead(User $user, DatabaseNotification $notification): bool
16+
{
17+
return $notification->notifiable->is($user);
18+
}
19+
}

0 commit comments

Comments
 (0)