Agora, voltando as notificações
Vamos agora adicionar um espaço na barra de navegação para exibir nossas notificações.
Em resources/views/layouts/app.blade.php adicione o código abaixo para podermos usar o material icons:
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" />
Vamos criar o componente de notificações:
php artisan make:livewire components.notification
Em resources/views/livewire/layout/navigation.blade.php adicione:
@livewire('components.notification')
@livewire('components.notification')
Vamos incorporar o Laravel Echo para monitorar eventos de notificações. Dessa forma, assim que uma notificação for recebida, poderemos recarregar dinamicamente os componente de notificações e listagem de posts.
<script>
document.addEventListener('DOMContentLoaded', () => {
Echo.private('App.Models.User.{{auth()->user()->id}}')
.notification(() => {
Livewire.dispatch('refreshNotification');
Livewire.dispatch('refreshPostList');
});
});
</script>
Em resources/views/livewire/components/notification.blade.php:
<div>
<x-dropdown align="right" width="48">
<x-slot name="trigger">
<button
class="inline-flex items-center px-3 py-2 border border-transparent text-sm leading-4 font-medium rounded-md text-gray-500 dark:text-gray-400 bg-white dark:bg-gray-800 hover:text-gray-700 dark:hover:text-gray-300 focus:outline-none transition ease-in-out duration-150">
<span class="rounded-full p-1 bg-red-500 text-white">17</span>
<span class="material-symbols-outlined">
notifications
</span>
</button>
</x-slot>
<x-slot name="content">
<div class="p-3 text-center">
<p>some notifications</p>
</div>
</x-slot>
</x-dropdown>
</div>
Classe de notificação
Como vamos mandar nossas notificações via canal database, precisamos criar a tabela de notificações:
php artisan notifications:table
php artisan migrate
Para criar um classe de notificação:
php artisan make:notification PostCreated
Um novo diretório contendo nossa classe será criado:
Em app/Notifications/PostCreated.php vamos adicionar as configurações de broadcast:
O construtor:
public $userId;
public $dataNotify;
/**
* Create a new notification instance.
*/
public function __construct($userId, $dataNotify)
{
$this->userId = $userId;
$this->dataNotify = $dataNotify;
}
/**
* Get the notification's delivery channels.
*
* @return array<int, string>
*/
public function via(object $notifiable): array
{
return ['broadcast', 'database'];
}
public function broadcastType()
{
return 'broadcast.message';
}
public function toBroadcast(object $notifiable): BroadcastMessage
{
return (new BroadcastMessage($this->dataNotify))->onConnection('database');
}
public function broadcastOn(): Channel
{
return new PrivateChannel("App.Models.User.{$this->userId}");
}
Para enviar notificações, optaremos por utilizar a trait Notifiable, que já está incorporada no nosso modelo User por padrão. Isso nos proporciona uma abordagem eficiente e pronta para uso. Para obter mais informações sobre a utilização desta trait https://laravel.com/docs/10.x/notifications#using-the-notifiable-trait.
Em app/Livewire/Posts/PostCreate.php vamos adicionar a ação de notificar um novo Post para o usuário que for marcado:
if ($this->state['tagged_user_id']) {
$taggedUser = User::query()->find($this->state['tagged_user_id']);
$taggedUser?->notify(new PostCreated($taggedUser['id'], $this->state));
}
A documentação explica a maneira correta de recuperar as notificações dos usuários https://laravel.com/docs/10.x/notifications#accessing-the-notifications.
Vamos adicionar a lógica de recuperação das notificações em app/Livewire/Components/Notification.php:
protected $listeners = [
'refreshNotification' => '$refresh'
];
public $notifications;
public $notificationsCounter;
public function getNotifications()
{
$this->notifications = auth()->user()->unreadNotifications;
$this->notificationsCounter = $this->notifications->count();
}
public function render()
{
$this->getNotifications();
return view('livewire.components.notification');
}
E vamos modificar a blade para exibir o contador de notificações:
<div>
<x-dropdown align="right" width="48">
<x-slot name="trigger">
<button
class="inline-flex items-center px-3 py-2 border border-transparent text-sm leading-4 font-medium rounded-md text-gray-500 dark:text-gray-400 bg-white dark:bg-gray-800 hover:text-gray-700 dark:hover:text-gray-300 focus:outline-none transition ease-in-out duration-150">
@if($notificationsCounter)
<span class="rounded-full p-1 bg-red-500 text-white">{{$notificationsCounter}}</span>
@endif
<span class="material-symbols-outlined">
notifications
</span>
</button>
</x-slot>
<x-slot name="content">
@foreach($notifications as $notification)
<div class="p-3 text-center">
<p>You have been tagged in a new post!</p>
</div>
@endforeach
</x-slot>
</x-dropdown>
</div>
Vamos iniciar o nosso worker:
php artisan queue:work
Nesse momento nossas notificações já estão sendo processadas em filas e sendo direcionadas em tempo real para os usuários marcados, como a seguir:
Conclusão
Conseguimos construir, passo a passo, a funcionalidade de notificações em tempo real utilizando Laravel e Livewire, seguindo apenas as documentações oficiais. Apesar do sucesso, ainda há diversas melhorias possíveis para aprimorar o projeto, tais como:
- Criação da camada de validação.
- Criação da camada de repositório.
- Passar dados para a notificação, como o nome de quem marcou o usuário.
- Marcar as notificações como lidas.
Estou deixando o link do repositório para quem tiver interesse: https://github.com/northoniserhardt/still-loving-docs
Além disso, você é quem decide! Muito obrigado por ter acompanhado o tutorial.
Top comments (2)
👏👏👏
😁