send leaves and joines separated

This commit is contained in:
Berenice Medel 2022-01-27 16:25:21 -06:00
parent 6c3eacf66f
commit 979469d23e
3 changed files with 46 additions and 22 deletions

View file

@ -29,7 +29,12 @@ defmodule LiveBeats.UserTracker do
@impl true @impl true
def init(_opts) do def init(_opts) do
{:ok, schedule_updates(%{})} {:ok,
schedule_updates(%{
active_users: %{},
user_leaves: [],
user_joins: []
})}
end end
@impl true @impl true
@ -49,8 +54,14 @@ defmodule LiveBeats.UserTracker do
@impl true @impl true
def handle_info(:send_updates, state) do def handle_info(:send_updates, state) do
broadcast_updates(state) leaves = state.user_leaves -- state.user_joins
{:noreply, schedule_updates(state)} joins = state.user_joins -- state.user_leaves
broadcast_updates(leaves, joins)
# cleaning joins and leaves for each interval
new_state = %{state | user_leaves: [], user_joins: []}
{:noreply, schedule_updates(new_state)}
end end
defp schedule_updates(state) do defp schedule_updates(state) do
@ -58,17 +69,23 @@ defmodule LiveBeats.UserTracker do
state state
end end
defp handle_join(state, presence) do defp handle_join(state, %{user: user}) do
if Map.has_key?(state, presence.user.id) do if Map.has_key?(state.active_users, user.id) do
state state
else else
Map.put_new(state, presence.user.id, presence.user) updated_active_users = Map.put_new(state.active_users, user.id, user)
updated_user_joins = [user | state.user_joins]
%{state | active_users: updated_active_users, user_joins: updated_user_joins}
end end
end end
defp handle_leave(state, presence) do defp handle_leave(state, %{user: user, metas: metas}) do
if Map.has_key?(state, presence.user.id) and presence.metas == [] do if Map.has_key?(state.active_users, user.id) and metas == [] do
Map.delete(state, presence.user.id) updated_active_users = Map.delete(state.active_users, user.id)
updated_user_leaves = [user | state.user_leaves]
%{state | active_users: updated_active_users, user_leaves: updated_user_leaves}
else else
state state
end end
@ -78,15 +95,15 @@ defmodule LiveBeats.UserTracker do
"active_users" "active_users"
end end
defp broadcast_updates(state) do defp broadcast_updates(leaves, joins) do
Phoenix.PubSub.local_broadcast( Phoenix.PubSub.local_broadcast(
@pubsub, @pubsub,
topic(), topic(),
{LiveBeats.UserTracker, %{active_users: list_users(state)}} {LiveBeats.UserTracker, %{user_leaves: leaves, user_joins: joins}}
) )
end end
defp list_users(state) do defp list_users(state) do
Enum.map(state, fn {_key, value} -> value end) Enum.map(state.active_users, fn {_key, value} -> value end)
end end
end end

View file

@ -8,19 +8,13 @@ defmodule LiveBeatsWeb.Nav do
UserTracker.subscribe() UserTracker.subscribe()
end end
socket =
socket socket
|> assign(:active_users, UserTracker.list_active_users()) |> assign(:active_users, UserTracker.list_active_users())
|> assign(:region, System.get_env("FLY_REGION")) |> assign(:region, System.get_env("FLY_REGION"))
|> attach_hook(:active_tab, :handle_params, &handle_active_tab_params/3) |> attach_hook(:active_tab, :handle_params, &handle_active_tab_params/3)
|> attach_hook(:ping, :handle_event, &handle_event/3) |> attach_hook(:ping, :handle_event, &handle_event/3)
|> attach_hook(:actie_users, :handle_info, fn |> attach_hook(:active_users, :handle_info, &handle_info/2)
{LiveBeats.UserTracker, %{active_users: users}}, socket ->
{:halt, assign(socket, :active_users, users)}
_params, socket ->
{:cont, socket}
end)
{:cont, socket} {:cont, socket}
end end
@ -49,6 +43,19 @@ defmodule LiveBeatsWeb.Nav do
defp handle_event(_, _, socket), do: {:cont, socket} defp handle_event(_, _, socket), do: {:cont, socket}
defp handle_info({UserTracker, %{user_leaves: leaves, user_joins: joins}}, socket) do
updated_socket =
Enum.reduce(leaves, socket, fn user, socket ->
socket
|> push_event("remove-el", %{id: "mobile-active-users-container-#{user.id}"})
|> push_event("remove-el", %{id: "desktop-active-users-container-#{user.id}"})
end)
{:halt, update(updated_socket, :active_users, &(joins ++ &1))}
end
defp handle_info(_params, socket), do: {:cont, socket}
defp current_user_profile_username(socket) do defp current_user_profile_username(socket) do
if user = socket.assigns.current_user do if user = socket.assigns.current_user do
user.username user.username

View file

@ -17,13 +17,13 @@ defmodule LiveBeatsWeb.LayoutView do
class="mt-1 space-y-1" class="mt-1 space-y-1"
role="group" role="group"
aria-labelledby={@id} aria-labelledby={@id}
id="listening-now" id={"#{@id}-container"}
phx-update="prepend" phx-update="prepend"
> >
<%= for user <- @users do %> <%= for user <- @users do %>
<.link navigate={profile_path(user)} <.link navigate={profile_path(user)}
class="group flex items-center px-3 py-2 text-base leading-5 font-medium text-gray-600 rounded-md hover:text-gray-900 hover:bg-gray-50" class="group flex items-center px-3 py-2 text-base leading-5 font-medium text-gray-600 rounded-md hover:text-gray-900 hover:bg-gray-50"
id={"active-user#{user.id}"} id={"#{@id}-#{user.id}"}
> >
<span class="w-2.5 h-2.5 mr-4 bg-indigo-500 rounded-full" aria-hidden="true"></span> <span class="w-2.5 h-2.5 mr-4 bg-indigo-500 rounded-full" aria-hidden="true"></span>
<span class="truncate"> <span class="truncate">