Skip to content

Commit 02f89d8

Browse files
authored
Merge pull request #64 from tabuna/admin
Отступы, мобильное меню и webpush
2 parents bf4f683 + 33abb54 commit 02f89d8

27 files changed

+1363
-107
lines changed

app/Http/Controllers/CommentsController.php

+6
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44

55
use App\Models\Comment;
66
use App\Models\Post;
7+
use App\Notifications\CommentNotification;
8+
use App\Notifications\IdeaRequestAcceptedNotification;
9+
use App\Notifications\ReplyCommentNotification;
710
use Illuminate\Http\Request;
811

912
class CommentsController extends Controller
@@ -49,6 +52,8 @@ public function store(Request $request)
4952

5053
$comment->save();
5154

55+
$comment->post->author->notify(new CommentNotification($comment));
56+
5257

5358
return turbo_stream([
5459
turbo_stream()
@@ -113,6 +118,7 @@ public function reply(Request $request, Comment $comment)
113118
]);
114119

115120
$request->user()->comments()->saveMany([$reply]);
121+
$comment->post->author->notify(new ReplyCommentNotification($reply));
116122

117123
return turbo_stream([
118124
turbo_stream()->append(@dom_id($comment, 'thread'), view('comments._comment', ['comment' => $reply])),
+68
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
<?php
2+
3+
namespace App\Http\Controllers;
4+
5+
use Illuminate\Http\JsonResponse;
6+
use Illuminate\Http\Request;
7+
use Illuminate\Database\Eloquent\Builder;
8+
9+
class PushController extends Controller
10+
{
11+
/**
12+
* @param \Illuminate\Http\Request $request
13+
*
14+
* @return \Illuminate\Http\JsonResponse
15+
*/
16+
public function store(Request $request): JsonResponse
17+
{
18+
$request->validate([
19+
'endpoint' => 'required',
20+
'keys.auth' => 'required',
21+
'keys.p256dh' => 'required',
22+
]);
23+
24+
$request->user()->updatePushSubscription(
25+
$request->input('endpoint'),
26+
$request->input('keys.p256dh'),
27+
$request->input('keys.auth')
28+
);
29+
30+
return response()->json(['success' => true]);
31+
}
32+
33+
/**
34+
* @param \Illuminate\Http\Request $request
35+
*
36+
* @return \Illuminate\Http\JsonResponse
37+
*/
38+
public function check(Request $request): JsonResponse
39+
{
40+
$request->validate([
41+
'endpoint' => 'required',
42+
]);
43+
44+
$exists = $request->user()->whereHas('pushSubscriptions', fn (Builder $query) =>
45+
$query->where('endpoint', $request->input('endpoint'))
46+
)->exists();
47+
48+
return response()->json(['exists' => $exists]);
49+
}
50+
51+
/**
52+
* @param \Illuminate\Http\Request $request
53+
*
54+
* @return \Illuminate\Http\JsonResponse
55+
*/
56+
public function unsubscribe(Request $request): JsonResponse
57+
{
58+
$request->validate([
59+
'endpoint' => 'required',
60+
]);
61+
62+
$request->user()->deletePushSubscription(
63+
$request->input('endpoint'),
64+
);
65+
66+
return response()->json(['message' => 'Unsubscribed!']);
67+
}
68+
}

app/Models/User.php

+2-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
use Illuminate\Notifications\Notifiable;
1111
use Illuminate\Support\Facades\Hash;
1212
use Laravel\Sanctum\HasApiTokens;
13+
use NotificationChannels\WebPush\HasPushSubscriptions;
1314
use Orchid\Access\UserAccess;
1415
use Orchid\Filters\Filterable;
1516
use Orchid\Filters\Types\Like;
@@ -22,7 +23,7 @@
2223

2324
class User extends Authenticatable
2425
{
25-
use HasApiTokens, HasFactory, Notifiable, Liker, AsSource, Chartable, Filterable, UserAccess;
26+
use HasApiTokens, HasFactory, Notifiable, Liker, AsSource, Chartable, Filterable, UserAccess, HasPushSubscriptions;
2627

2728
/**
2829
* The attributes that are mass assignable.
+99
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
<?php
2+
3+
namespace App\Notifications;
4+
5+
use App\Models\Comment;
6+
use App\Models\IdeaKey;
7+
use App\Models\Post;
8+
use App\Models\User;
9+
use App\Notifications\Channels\SiteChannel;
10+
use App\Notifications\Channels\SiteMessage;
11+
use Illuminate\Bus\Queueable;
12+
use Illuminate\Contracts\Queue\ShouldQueue;
13+
use Illuminate\Notifications\Notification;
14+
use NotificationChannels\WebPush\WebPushChannel;
15+
use NotificationChannels\WebPush\WebPushMessage;
16+
17+
class CommentNotification extends Notification implements ShouldQueue
18+
{
19+
use Queueable;
20+
21+
private Comment $comment;
22+
23+
/**
24+
* FriendlyHugs constructor.
25+
*
26+
* @param IdeaKey $ideaKey
27+
*/
28+
public function __construct(Comment $comment)
29+
{
30+
$this->comment = $comment;
31+
}
32+
33+
/**
34+
* Get the notification's delivery channels.
35+
*
36+
* @param mixed $notifiable
37+
*
38+
* @return array
39+
*/
40+
public function via(User $user)
41+
{
42+
return [
43+
SiteChannel::class,
44+
WebPushChannel::class
45+
];
46+
}
47+
48+
/**
49+
* Get the app representation of the notification.
50+
*
51+
* @param mixed $user
52+
*
53+
* @return \Illuminate\Notifications\Messages\MailMessage
54+
*/
55+
public function toSite(User $user)
56+
{
57+
$url = route('post.show',$this->comment->post).'#'.dom_id($this->comment);
58+
return (new SiteMessage())
59+
->title('оставил комментарий к вашей публикации')
60+
->setCommentAuthor($this->comment->author->name)
61+
->img($this->comment->author->avatar)
62+
->action($url, $this->comment->post->title);
63+
}
64+
65+
/**
66+
* @param \App\Models\User $user
67+
*
68+
* @return \NotificationChannels\WebPush\WebPushMessage
69+
*/
70+
public function toWebPush(User $user)
71+
{
72+
$url = route('post.show', $this->comment->post) . '#' . dom_id($this->comment);
73+
74+
return (new WebPushMessage)
75+
->title('Комментарий к ваше публикации')
76+
->icon($this->comment->author->avatar)
77+
->body('Пользователь '.$this->comment->author->name."оставил комментарий к вашей публикации")
78+
->action('посмотреть',$url)
79+
->vibrate([300, 200, 300])
80+
->options([
81+
'TTL' => 86400, // in seconds - 24 hours,
82+
'urgency' => 'high',
83+
]);
84+
}
85+
86+
/**
87+
* Get the array representation of the notification.
88+
*
89+
* @param mixed $notifiable
90+
*
91+
* @return array
92+
*/
93+
public function toArray($notifiable)
94+
{
95+
return [
96+
//
97+
];
98+
}
99+
}

app/Notifications/IdeaRequestAcceptedNotification.php

+22-2
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
use Illuminate\Bus\Queueable;
1313
use Illuminate\Contracts\Queue\ShouldQueue;
1414
use Illuminate\Notifications\Notification;
15+
use NotificationChannels\WebPush\WebPushChannel;
16+
use NotificationChannels\WebPush\WebPushMessage;
1517

1618
class IdeaRequestAcceptedNotification extends Notification implements ShouldQueue
1719
{
@@ -36,11 +38,15 @@ public function __construct(IdeaKey $ideaKey)
3638
*
3739
* @return array
3840
*/
39-
public function via($notifiable)
41+
public function via(User $user)
4042
{
41-
return [SiteChannel::class];
43+
return [
44+
SiteChannel::class,
45+
WebPushChannel::class
46+
];
4247
}
4348

49+
4450
/**
4551
* Get the app representation of the notification.
4652
*
@@ -55,6 +61,20 @@ public function toSite(User $user)
5561
->action(route('idea.key', $this->ideaKey), 'по ссылке');
5662
}
5763

64+
public function toWebPush($notifiable, $notification)
65+
{
66+
return (new WebPushMessage)
67+
->title('Бесплатный ключ Laravel IDEA доступен')
68+
//->icon($this->author->avatar)
69+
//->body('Пользователь '.$this->author->name."ответил на ваш комментарий")
70+
->action('Посмотреть',route('idea.key', $this->ideaKey))
71+
->vibrate([300, 200, 300])
72+
->options([
73+
'TTL' => 86400, // in seconds - 24 hours,
74+
'urgency' => 'high',
75+
]);
76+
}
77+
5878
/**
5979
* Get the array representation of the notification.
6080
*

app/Notifications/ReplyCommentNotification.php

+36-17
Original file line numberDiff line numberDiff line change
@@ -2,37 +2,32 @@
22

33
namespace App\Notifications;
44

5-
use App\Casts\FriendlyHugsType;
65
use App\Models\Comment;
76
use App\Models\IdeaKey;
87
use App\Models\Post;
98
use App\Models\User;
10-
use App\Notifications\Channels\EmotionTrackerChannel;
11-
use App\Notifications\Channels\EmotionTrackerMessage;
129
use App\Notifications\Channels\SiteChannel;
1310
use App\Notifications\Channels\SiteMessage;
1411
use Illuminate\Bus\Queueable;
1512
use Illuminate\Contracts\Queue\ShouldQueue;
1613
use Illuminate\Notifications\Notification;
14+
use NotificationChannels\WebPush\WebPushChannel;
15+
use NotificationChannels\WebPush\WebPushMessage;
1716

1817
class ReplyCommentNotification extends Notification implements ShouldQueue
1918
{
2019
use Queueable;
2120

22-
private User $author;
23-
private Comment $comment;
24-
private Post $post;
21+
private Comment $reply;
2522

2623
/**
2724
* FriendlyHugs constructor.
2825
*
29-
* @param IdeaKey $ideaKey
26+
* @param Comment $reply
3027
*/
31-
public function __construct(User $author, Comment $comment, Post $post)
28+
public function __construct(Comment $reply)
3229
{
33-
$this->author = $author;
34-
$this->comment = $comment;
35-
$this->post = $post;
30+
$this->reply = $reply;
3631
}
3732

3833
/**
@@ -42,9 +37,12 @@ public function __construct(User $author, Comment $comment, Post $post)
4237
*
4338
* @return array
4439
*/
45-
public function via($notifiable)
40+
public function via(User $user)
4641
{
47-
return [SiteChannel::class];
42+
return [
43+
SiteChannel::class,
44+
WebPushChannel::class,
45+
];
4846
}
4947

5048
/**
@@ -56,12 +54,33 @@ public function via($notifiable)
5654
*/
5755
public function toSite(User $user)
5856
{
59-
$url = route('post.show',$this->post).'#'.dom_id($this->comment);
57+
$url = route('post.show', $this->reply->post) . '#' . dom_id($this->reply);
6058
return (new SiteMessage())
6159
->title('ответил на ваш комментарий')
62-
->setCommentAuthor($this->author->name)
63-
->img($this->author->avatar)
64-
->action($url, $this->post->title);
60+
->setCommentAuthor($this->reply->author->name)
61+
->img($this->reply->author->avatar)
62+
->action($url, $this->reply->post->title);
63+
}
64+
65+
/**
66+
* @param \App\Models\User $user
67+
*
68+
* @return \NotificationChannels\WebPush\WebPushMessage
69+
*/
70+
public function toWebPush(User $user)
71+
{
72+
$url = route('post.show', $this->reply->post) . '#' . dom_id($this->reply);
73+
74+
return (new WebPushMessage)
75+
->title('Пользователь ' . $this->reply->author->name . ' ответил на ваш комментарий')
76+
->icon($this->reply->author->avatar)
77+
//->body('Пользователь '.$this->author->name." ответил на ваш комментарий")
78+
->action('посмотреть', $url)
79+
->vibrate([300, 200, 300])
80+
->options([
81+
'TTL' => 86400, // in seconds - 24 hours,
82+
'urgency' => 'high',
83+
]);
6584
}
6685

6786
/**

composer.json

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
"intervention/image": "^2.7",
1414
"jolicode/jolitypo": "^1.4",
1515
"laminas/laminas-stdlib": "^3.18",
16+
"laravel-notification-channels/webpush": "^7.1",
1617
"laravel/framework": "^10.31",
1718
"laravel/sanctum": "^3.2",
1819
"laravel/scout": "^10.5",

0 commit comments

Comments
 (0)