Return updated metas to client.

Fixes presences being removed when user has
active tabs
This commit is contained in:
Chris McCord 2022-01-12 14:15:06 -05:00
parent 924da28b6b
commit a39bb0a5ac
2 changed files with 25 additions and 22 deletions

View file

@ -94,7 +94,7 @@ defmodule Phoenix.Presence.Client do
if Map.has_key?(state.topics, topic) do if Map.has_key?(state.topics, topic) do
state state
else else
update_topics_state(:add_new_topic, state, topic) put_new_topic(state, topic)
end end
# merge diff into state.topics # merge diff into state.topics
@ -104,49 +104,49 @@ defmodule Phoenix.Presence.Client do
# if no more presences for given topic, unsubscribe and remove topic # if no more presences for given topic, unsubscribe and remove topic
if topic_presences_count(updated_state, topic) == 0 do if topic_presences_count(updated_state, topic) == 0 do
Phoenix.PubSub.unsubscribe(state.pubsub, topic) Phoenix.PubSub.unsubscribe(state.pubsub, topic)
update_topics_state(:remove_topic, updated_state, topic) remove_topic(updated_state, topic)
else else
updated_state updated_state
end end
end end
defp handle_join({joined_key, meta}, {state, topic}) do defp handle_join({joined_key, presence}, {state, topic}) do
joined_meta = Map.get(meta, :metas, []) joined_metas = Map.get(presence, :metas, [])
updated_state = {updated_state, new_metas} = add_new_presence_or_metas(state, topic, joined_key, joined_metas)
update_topics_state(:add_new_presence_or_metas, state, topic, joined_key, joined_meta) new_presence = Map.put(presence, :metas, new_metas)
{:ok, updated_client_state} = {:ok, updated_client_state} =
state.client.handle_join(topic, joined_key, meta, state.client_state) state.client.handle_join(topic, joined_key, new_presence, state.client_state)
updated_state = Map.put(updated_state, :client_state, updated_client_state) updated_state = Map.put(updated_state, :client_state, updated_client_state)
{updated_state, topic} {updated_state, topic}
end end
defp handle_leave({left_key, meta}, {state, topic}) do defp handle_leave({left_key, presence}, {state, topic}) do
updated_state = update_topics_state(:remove_presence_or_metas, state, topic, left_key, meta) {updated_state, new_metas} = remove_presence_or_metas(state, topic, left_key, presence)
new_presence = Map.put(presence, :metas, new_metas)
{:ok, updated_client_state} = {:ok, updated_client_state} =
state.client.handle_leave(topic, left_key, meta, state.client_state) state.client.handle_leave(topic, left_key, new_presence, state.client_state)
updated_state = Map.put(updated_state, :client_state, updated_client_state) updated_state = Map.put(updated_state, :client_state, updated_client_state)
{updated_state, topic} {updated_state, topic}
end end
defp update_topics_state(:add_new_topic, %{topics: topics} = state, topic) do defp put_new_topic(%{topics: topics} = state, topic) do
updated_topics = Map.put_new(topics, topic, %{}) updated_topics = Map.put_new(topics, topic, %{})
Map.put(state, :topics, updated_topics) Map.put(state, :topics, updated_topics)
end end
defp update_topics_state(:remove_topic, %{topics: topics} = state, topic) do defp remove_topic(%{topics: topics} = state, topic) do
updated_topics = Map.delete(topics, topic) updated_topics = Map.delete(topics, topic)
Map.put(state, :topics, updated_topics) Map.put(state, :topics, updated_topics)
end end
defp update_topics_state( defp add_new_presence_or_metas(
:add_new_presence_or_metas,
%{topics: topics} = state, %{topics: topics} = state,
topic, topic,
key, key,
@ -154,26 +154,25 @@ defmodule Phoenix.Presence.Client do
) do ) do
topic_info = topics[topic] topic_info = topics[topic]
updated_topic = {updated_topic, updated_metas} =
case Map.fetch(topic_info, key) do case Map.fetch(topic_info, key) do
# existing presence, add new metas # existing presence, add new metas
{:ok, existing_metas} -> {:ok, existing_metas} ->
remaining_metas = new_metas -- existing_metas remaining_metas = new_metas -- existing_metas
updated_metas = existing_metas ++ remaining_metas updated_metas = existing_metas ++ remaining_metas
Map.put(topic_info, key, updated_metas) {Map.put(topic_info, key, updated_metas), updated_metas}
:error -> :error ->
# there are no presences for that key # there are no presences for that key
Map.put(topic_info, key, new_metas) {Map.put(topic_info, key, new_metas), new_metas}
end end
updated_topics = Map.put(topics, topic, updated_topic) updated_topics = Map.put(topics, topic, updated_topic)
Map.put(state, :topics, updated_topics) {Map.put(state, :topics, updated_topics), updated_metas}
end end
defp update_topics_state( defp remove_presence_or_metas(
:remove_presence_or_metas,
%{topics: topics} = state, %{topics: topics} = state,
topic, topic,
key, key,
@ -194,7 +193,7 @@ defmodule Phoenix.Presence.Client do
updated_topics = Map.put(topics, topic, updated_topic) updated_topics = Map.put(topics, topic, updated_topic)
Map.put(state, :topics, updated_topics) {Map.put(state, :topics, updated_topics), remaining_metas}
end end
defp topic_presences_count(state, topic) do defp topic_presences_count(state, topic) do

View file

@ -150,7 +150,11 @@ defmodule LiveBeatsWeb.ProfileLive do
def handle_info({LiveBeats.PresenceClient, %{user_left: presence}}, socket) do def handle_info({LiveBeats.PresenceClient, %{user_left: presence}}, socket) do
%{user: user} = presence %{user: user} = presence
if presence.metas == [] do
{:noreply, push_event(socket, "remove-el", %{id: "presence-#{user.id}"})} {:noreply, push_event(socket, "remove-el", %{id: "presence-#{user.id}"})}
else
{:noreply, socket}
end
end end
def handle_info({Accounts, %Accounts.Events.ActiveProfileChanged{} = event}, socket) do def handle_info({Accounts, %Accounts.Events.ActiveProfileChanged{} = event}, socket) do