The Notification Bell Component is embedded in the Side Bar layout and Stacked Layout via core_components.ex. If you want to omit the Notification Bell Component, you can use the :show_notification_bell attribute:
Hereβs an example of how you could send an Org invitation notification for a User:
aliasPetalPro.NotificationsaliasPetalPro.Notifications.UserNotificationAttrsattrs =UserNotificationAttrs.invite_to_org_notification(org, sender_id, recipient_id)caseNotifications.create_user_notification(attrs) do {:ok, notification} ->Notifications.broadcast_user_notification(notification) {:error, changeset} ->raise"Failed to create notification: #{inspect(changeset)}"end
create_user_notification/1 will create and store the notification.
broadcast_user_notification/1 will send a message to the PetalProWeb.UserNotificationChannel.
Devices consuming the UserNotificationChannel will use the information to update the user. For example, any browser tab that includes the Notification Bell Component will automatically update itself (see Consuming Broadcast Messages).
Viewing Notifications
Notifications for the currently authenticated user are visible via the Notification Bell Component:
The Notification Bell Component comes with its own event handlers. This is why itβs implemented as a Live Component:
Clicking on a notification will navigate the user to a nominated route. The :require_authenticated_user hook has been updated to mark notifications read if the read path matches.
Consuming Broadcast Messages
The UserNotificationChannel is a Channel that is configured in user_socket.ex:
You can then consume this broadcast using any device (e.g. browser or mobile) using a client library that supports Phoenix Channels.
Broadcast messages can only be created and consumed by authenticated users. See user_socket.ex if you want to see how this works.
In the case of Petal Pro, the Notification Bell Component includes code that intercepts broadcast messages. This is achieved via a JavaScript Hook:
The NotificationBellHook consumes broadcast messages client-side
If a broadcast message is raised it pushes an event to the Notification Bell Component
The event causes the Notification Bell Component to update itself
Though data is sent via the Channel, ultimately the data that is displayed by the Notification Bell Component is loaded from the database (not the Channel).
The Read Path
If you look at UserNotificationAttrs.invite_to_org_notification/3:
definvite_to_org_notification(%Org{} = org, sender_id, recipient_id) do %{ read_path: ~p"/app/users/org-invitations", type: :invited_to_org, recipient_id: recipient_id, sender_id: sender_id, org_id: org.id, message: gettext("You have been invited to join the %{org_name} organisation!", org_name: org.name) }end
Youβll see that it has a read_path property. This must be a verified route - if the user navigates to this page, then the notification is marked as read (handled in the :require_authenticated_useron_mount hook).
Creating your own notification
If you want to create your own user notification, you'll need to implement the following:
Create a helper function in user_notification_attrs.ex
Add a notification_type to user_notification.ex
Add code to create/broadcast the new message
Add a notification_item to notification_components.ex
Let's create a notification for a user when they have been promoted to org admin!
Create the helper function
In user_notification_attrs.ex, add the following function:
defmodulePetalPro.Notifications.UserNotificationAttrsdo...defpromote_to_org_admin(%Org{} = org, sender_id, recipient_id) do %{ read_path: ~p"/app/org/#{org.slug}/team", type: :promoted_to_org_admin, recipient_id: recipient_id, sender_id: sender_id, org_id: org.id, message: gettext("You have been promoted to org admin for %{org_name}!", org_name: org.name) }end...end
Note that the read_path points to the org/team route - a path that would be inaccessible if the user was not an org admin.
Add the Notification Type
In user_notification.ex, add a new Notification Type:
This should allow the notification to be created/broadcast whenever a user's membership role has been changed to :admin. However, the Notification Bell Component needs to be updated to allow for the new Notification Type.
Add a Notification Item
Finally, the last thing we need to do is update the item template for the Notification Bell Component. You can do this by updating notification_components.ex:
This pattern matches on the new Notification Type :promoted_to_org_admin. If we didn't add the new call to notification_item, then any page with the Notification Bell will cause an error.
Just like the :invited_to_org notification, if the user clicks on the notification to navigate to the page, then the notification will be marked as read!