mirror of
https://github.com/fly-apps/live_beats.git
synced 2024-11-21 15:41:00 +00:00
Implement handle_leave and handle_join in presence_client
- The profile Liveview is subscribed to active_users topic - user_joined and user_left events are sent - Users are added and removed from presences assign
This commit is contained in:
parent
4634d32295
commit
463faafe71
4 changed files with 61 additions and 18 deletions
|
@ -21,6 +21,10 @@ defmodule LiveBeats.Accounts do
|
|||
Repo.all(from u in User, limit: ^Keyword.fetch!(opts, :limit))
|
||||
end
|
||||
|
||||
def list_users_by_ids(user_ids) when is_list(user_ids) do
|
||||
Repo.all(from u in User, where: u.id in ^user_ids)
|
||||
end
|
||||
|
||||
def lists_users_by_active_profile(id, opts) do
|
||||
Repo.all(
|
||||
from u in User, where: u.active_profile_user_id == ^id, limit: ^Keyword.fetch!(opts, :limit)
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
defmodule LiveBeats.PresenceClient do
|
||||
@behaviour Phoenix.Presence.Client
|
||||
|
||||
@presence LiveBeats.Presence
|
||||
@presence LiveBeatsWeb.Presence
|
||||
@pubsub LiveBeats.PubSub
|
||||
|
||||
def start_link(opts) do
|
||||
Phoenix.Presence.Client.start_link(presence: @presence, client: __MODULE__)
|
||||
|
@ -16,13 +17,33 @@ defmodule LiveBeats.PresenceClient do
|
|||
{:ok, %{}}
|
||||
end
|
||||
|
||||
def handle_join(key, presence, state) do
|
||||
# can local pubsub to LVs about new join
|
||||
def handle_join(topic, key, meta, state) do
|
||||
active_users_topic =
|
||||
topic
|
||||
|> profile_identifier()
|
||||
|> active_users_topic()
|
||||
|
||||
Phoenix.PubSub.broadcast!(@pubsub, active_users_topic, {__MODULE__, %{user_joined: key}})
|
||||
|
||||
{:ok, state}
|
||||
end
|
||||
|
||||
def handle_leave(key, presence, state) do
|
||||
# can local pubsub to LVs about new leave
|
||||
def handle_leave(topic, key, presence, state) do
|
||||
active_users_topic =
|
||||
topic
|
||||
|> profile_identifier()
|
||||
|> active_users_topic()
|
||||
|
||||
Phoenix.PubSub.broadcast!(@pubsub, active_users_topic, {__MODULE__, %{user_left: key}})
|
||||
{:ok, state}
|
||||
end
|
||||
|
||||
defp active_users_topic(user_id) do
|
||||
"active_users:#{user_id}"
|
||||
end
|
||||
|
||||
defp profile_identifier(topic) do
|
||||
"active_profile:" <> identifier = topic
|
||||
identifier
|
||||
end
|
||||
end
|
||||
|
|
|
@ -10,6 +10,7 @@ defmodule LiveBeatsWeb.Presence do
|
|||
|
||||
import Phoenix.LiveView.Helpers
|
||||
import LiveBeatsWeb.LiveHelpers
|
||||
@pubsub LiveBeats.PubSub
|
||||
|
||||
def listening_now(assigns) do
|
||||
~H"""
|
||||
|
@ -31,4 +32,12 @@ defmodule LiveBeatsWeb.Presence do
|
|||
</div>
|
||||
"""
|
||||
end
|
||||
|
||||
def subscribe(user_id) do
|
||||
Phoenix.PubSub.subscribe(@pubsub, topic(user_id))
|
||||
end
|
||||
|
||||
defp topic(profile) do
|
||||
"active_users:#{profile.user_id}"
|
||||
end
|
||||
end
|
||||
|
|
|
@ -87,6 +87,7 @@ defmodule LiveBeatsWeb.ProfileLive do
|
|||
if connected?(socket) do
|
||||
MediaLibrary.subscribe_to_profile(profile)
|
||||
Accounts.subscribe(current_user.id)
|
||||
LiveBeatsWeb.Presence.subscribe(profile)
|
||||
Phoenix.Presence.Client.track(topic(profile.user_id),
|
||||
current_user.id,
|
||||
%{}
|
||||
|
@ -146,6 +147,22 @@ defmodule LiveBeatsWeb.ProfileLive do
|
|||
{:noreply, socket}
|
||||
end
|
||||
|
||||
def handle_info({LiveBeats.PresenceClient, %{user_joined: user_id}}, socket) do
|
||||
new_user = Accounts.get_user!(user_id)
|
||||
updated_presences =
|
||||
if new_user in socket.assigns.presences do
|
||||
socket.assigns.presences
|
||||
else
|
||||
[new_user | socket.assigns.presences]
|
||||
end
|
||||
{:noreply, assign(socket, :presences, updated_presences)}
|
||||
end
|
||||
|
||||
def handle_info({LiveBeats.PresenceClient, %{user_left: user_id}}, socket) do
|
||||
updated_presences = socket.assign.presences |> Enum.reject(fn user -> user.id == user_id end)
|
||||
{:noreply, assign(socket, :presences, updated_presences)}
|
||||
end
|
||||
|
||||
def handle_info({Accounts, %Accounts.Events.ActiveProfileChanged{} = event}, socket) do
|
||||
{:noreply, assign(socket, active_profile_id: event.new_profile_user_id)}
|
||||
end
|
||||
|
@ -173,14 +190,6 @@ defmodule LiveBeatsWeb.ProfileLive do
|
|||
|
||||
def handle_info({Accounts, _}, socket), do: {:noreply, socket}
|
||||
|
||||
def handle_info(
|
||||
%{event: "presence_diff", payload: %{joins: _joins, leaves: _leaves}},
|
||||
%{assigns: %{presences: _users}} = socket
|
||||
) do
|
||||
|
||||
{:noreply, assign_presences(socket)}
|
||||
end
|
||||
|
||||
defp stop_song(socket, song_id) do
|
||||
SongRowComponent.send_status(song_id, :stopped)
|
||||
|
||||
|
@ -256,11 +265,11 @@ defmodule LiveBeatsWeb.ProfileLive do
|
|||
defp assign_presences(socket) do
|
||||
presences = socket.assigns.profile.user_id
|
||||
|> topic()
|
||||
|> Presence.list()
|
||||
|> Enum.map(fn {_user_id, user_data} ->
|
||||
user_data[:metas]
|
||||
|> List.first()
|
||||
|> LiveBeats.PresenceClient.list()
|
||||
|> Enum.map(fn {user_id, _user_data} ->
|
||||
user_id
|
||||
end)
|
||||
|> Accounts.list_users_by_ids()
|
||||
|
||||
assign(socket, presences: presences)
|
||||
end
|
||||
|
@ -272,5 +281,5 @@ defmodule LiveBeatsWeb.ProfileLive do
|
|||
uri.host <> uri.path
|
||||
end
|
||||
|
||||
defp topic(user_id) when is_integer(user_id), do: "profile:#{user_id}"
|
||||
defp topic(user_id) when is_integer(user_id), do: "active_profile:#{user_id}"
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue