feat(chat): notify message add/removal with pubsub

This commit is contained in:
João Paulo Dubas 2024-11-06 00:22:50 +00:00
parent c788bfa8d8
commit 137b9b4581
Signed by: joao.dubas
SSH Key Fingerprint: SHA256:V1mixgOGRc/YMhGx/DNkOSmJxgA2vHNrDZEk3wt/kOA
2 changed files with 47 additions and 11 deletions

View File

@ -10,6 +10,8 @@ defmodule Slax.Chat do
alias Slax.Chat.Room
alias Slax.Repo
@pubsub Slax.PubSub
def create_room(attrs) do
%Room{}
|> change_room(attrs)
@ -53,9 +55,13 @@ defmodule Slax.Chat do
end
def create_message(room, user, attrs) do
%Message{room: room, user: user}
|> change_message(attrs)
|> Repo.insert()
with {:ok, message} <-
%Message{room: room, user: user}
|> change_message(attrs)
|> Repo.insert() do
Phoenix.PubSub.broadcast!(@pubsub, topic(room), {:new_message, message})
{:ok, message}
end
end
def change_message(message, attrs \\ %{}) do
@ -63,8 +69,24 @@ defmodule Slax.Chat do
end
def delete_message_by_id(message_id, %User{id: user_id}) do
Message
|> Repo.get_by(id: message_id, user_id: user_id)
|> Repo.delete()
with {:ok, message} <-
Message
|> Repo.get_by(id: message_id, user_id: user_id)
|> Repo.delete() do
Phoenix.PubSub.broadcast!(@pubsub, topic(message.room_id), {:deleted_message, message})
{:ok, message}
end
end
def subscribe_to_room(room) do
Phoenix.PubSub.subscribe(@pubsub, topic(room))
end
def unsubscribe_from_room(room) do
Phoenix.PubSub.unsubscribe(@pubsub, topic(room))
end
defp topic(%Room{id: room_id}), do: "chat_room:#{room_id}"
defp topic(room_id), do: topic(%Room{id: room_id})
end

View File

@ -2,6 +2,8 @@ defmodule SlaxWeb.ChatRoomLive do
@moduledoc false
use SlaxWeb, :live_view
require Logger
alias Slax.Accounts.User
alias Slax.Chat
alias Slax.Chat.Message
@ -133,6 +135,8 @@ defmodule SlaxWeb.ChatRoomLive do
@impl Phoenix.LiveView
def handle_params(params, _session, socket) do
if socket.assigns[:room], do: Chat.unsubscribe_from_room(socket.assigns.room)
room =
case Map.fetch(params, "id") do
{:ok, id} ->
@ -144,6 +148,8 @@ defmodule SlaxWeb.ChatRoomLive do
messages = Chat.list_messages_in_room(room)
Chat.subscribe_to_room(room)
{:noreply,
socket
|> assign(hide_topic?: false, page_title: "# #{room.name}", room: room)
@ -168,10 +174,8 @@ defmodule SlaxWeb.ChatRoomLive do
socket =
case Chat.create_message(room, user, message_params) do
{:ok, message} ->
socket
|> stream_insert(:messages, message)
|> assign_message_form(Chat.change_message(%Message{}))
{:ok, _message} ->
assign_message_form(socket, Chat.change_message(%Message{}))
{:error, changeset} ->
assign_message_form(socket, changeset)
@ -182,8 +186,18 @@ defmodule SlaxWeb.ChatRoomLive do
@impl Phoenix.LiveView
def handle_event("delete-message", %{"id" => message_id}, socket) do
{:ok, message} = Chat.delete_message_by_id(message_id, socket.assigns.current_user)
Chat.delete_message_by_id(message_id, socket.assigns.current_user)
{:noreply, socket}
end
@impl Phoenix.LiveView
def handle_info({:new_message, message}, socket) do
{:noreply, stream_insert(socket, :messages, message)}
end
@impl Phoenix.LiveView
def handle_info({:deleted_message, message}, socket) do
{:noreply, stream_delete(socket, :messages, message)}
end