feat(chat): add unread message divider

This commit is contained in:
2024-11-25 23:22:31 +00:00
parent 24c457413d
commit 2430b41ce1
4 changed files with 88 additions and 10 deletions

View File

@@ -128,13 +128,21 @@ defmodule SlaxWeb.ChatRoomLive do
phx-hook="RoomMessages"
phx-update="stream"
>
<.message
:for={{dom_id, message} <- @streams.messages}
current_user={@current_user}
dom_id={dom_id}
message={message}
timezone={@timezone}
/>
<%= for {dom_id, message} <- @streams.messages do %>
<%= if message == :unread_marker do %>
<div id={dom_id} class="w-full flex text-red-500 items-center gap-3 pr-5">
<div class="w-full h-px grow bg-red-500"></div>
<div class="text-sm">New</div>
</div>
<% else %>
<.message
current_user={@current_user}
dom_id={dom_id}
message={message}
timezone={@timezone}
/>
<% end %>
<% end %>
</div>
<div :if={@joined?} class="h-12 bg-white px-4 pb-4">
<.form
@@ -205,13 +213,20 @@ defmodule SlaxWeb.ChatRoomLive do
OnlineUsers.subscribe()
socket =
assign(socket,
socket
|> assign(
hide_topic?: false,
online_users: OnlineUsers.list(),
rooms: rooms,
timezone: timezone,
users: users
)
|> stream_configure(:messages,
dom_id: fn
%Message{id: id} -> "messages-#{id}"
:unread_marker -> "messages-unread-marker"
end
)
{:ok, socket}
end
@@ -229,10 +244,14 @@ defmodule SlaxWeb.ChatRoomLive do
Chat.get_first_room!()
end
messages = Chat.list_messages_in_room(room)
last_read_id = Chat.get_last_read_id(room, socket.assigns.current_user)
messages = room |> Chat.list_messages_in_room() |> maybe_insert_unread_marker(last_read_id)
Chat.subscribe_to_room(room)
Chat.update_last_read_id(room, socket.assigns.current_user)
{:noreply,
socket
|> assign(
@@ -296,6 +315,10 @@ defmodule SlaxWeb.ChatRoomLive do
@impl Phoenix.LiveView
def handle_info({:new_message, message}, socket) do
if message.room_id == socket.assigns.room.id do
Chat.update_last_read_id(message.room, socket.assigns.current_user)
end
socket =
socket
|> stream_insert(:messages, message)
@@ -400,4 +423,18 @@ defmodule SlaxWeb.ChatRoomLive do
defp assign_message_form(socket, changeset) do
assign(socket, :new_message_form, to_form(changeset))
end
defp maybe_insert_unread_marker(messages, nil) do
messages
end
defp maybe_insert_unread_marker(messages, last_read_id) do
{read, unread} = Enum.split_while(messages, &(&1.id <= last_read_id))
if unread == [] do
read
else
read ++ [:unread_marker | unread]
end
end
end