Add full notification preferences system

Users can now control which in-app and email notifications they receive
from their Settings tab on their channel page.

Bell (in-app) preferences:
- New comment on my video (default: on)
- Reply to my comment (default: on)
- Comment liked (default: on)
- Video liked (default: on)
- New subscriber (default: on)
- New video from channels I follow (default: on)
- New post from channels I follow (default: on)
- New user registration — super admins only (default: on)

Email preferences (same set plus):
- Comment liked (default: off — too noisy)
- Video liked (default: off — too noisy)
- New post from channels I follow (default: off)
- My video finished processing (default: on)
- Weekly activity digest every Monday (default: on)
- New user registration — super admins only (default: on)

Implementation:
- Migration: notification_preferences JSON column on users table
- User::notificationPref($key) helper with typed defaults
- All existing notification classes updated to check prefs in via()
- 4 new notification classes: NewSubscriberNotification,
  VideoLikedNotification, NewPostNotification, WeeklyDigestNotification
- 8 new email views matching existing dark theme
- SendWeeklyDigest artisan command, scheduled every Monday 09:00
- NewSubscriberNotification wired into UserController::toggleSubscribe
- VideoLikedNotification wired into UserController::toggleLike
- NewPostNotification wired into PostController::store (to all subscribers)
- Bell renderer updated for new_subscriber, video_like, new_post types
- Preferences saved via AJAX (POST /settings/notifications) — instant
  toggle with automatic revert on failure

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
This commit is contained in:
ghassanandClaude Sonnet 4.6 committed 2026-05-16 23:47:28 +03:00
1 parent 3fe167e33f
commit f8d13457fa
26 files changed
+808 -18

No files matched your search

+17 -1
View File
@@ -5,6 +5,7 @@ namespace App\Notifications;
use App\Models\Comment;
use App\Models\User;
use App\Models\Video;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
use Illuminate\Support\Str;
@@ -18,7 +19,10 @@ class NewCommentNotification extends Notification
public function via(object $notifiable): array
{
return ['database'];
$ch = [];
if ($notifiable->notificationPref('notif_new_comment')) $ch[] = 'database';
if ($notifiable->notificationPref('email_new_comment')) $ch[] = 'mail';
return $ch;
}
public function toArray(object $notifiable): array
@@ -35,4 +39,16 @@ class NewCommentNotification extends Notification
'comment_preview' => Str::limit($this->comment->body, 80),
];
}
public function toMail(object $notifiable): MailMessage
{
return (new MailMessage)
->subject($this->commenter->name . ' commented on your video')
->view('emails.new-comment', [
'video' => $this->video,
'comment' => $this->comment,
'commenter'=> $this->commenter,
'recipient'=> $notifiable,
]);
}
}