The code provided for tracking user’s presence on the product detail page seems more complicated than it needs to be, and for me at least, it doesn’t actually work as provided – it only tracks the first user that visits the product, but ignores any user after that – it seems that the call to Presence.update
doesn’t properly update the list of e-mail addresses.
I first tried to re-trace my steps and see if I missed something important, but then I just decided to re-write the code using a simplified logic for presence tracking, and a bit more convoluted logic for formatting the list of users. Here’s my suggested fix, if interested:
# lib/pento_web/presence.ex
def track_user(pid, product, token) do
user = Accounts.get_user_by_session_token(token)
Presence.track(pid, @user_activity_topic, product.name, %{email: user.email})
end
# lib/pento_web/live/user_activity_live.ex
defp assign_user_activity(socket) do
presence_map = Presence.list(@user_activity_topic)
user_activity =
presence_map
|> Enum.map(fn {product_name, _data} ->
emails =
get_in(presence_map, [product_name, :metas])
|> Enum.map(& &1.email)
|> Enum.uniq()
|> Enum.sort()
{product_name, emails}
end)
assign(socket, :user_activity, user_activity)
end
<!-- user_activity_live.html.leex -->
<div class="user-activity-component">
<h2>User Activity</h2>
<p>Active users currently viewing games</p>
<div>
<%= for {product_name, emails} <- @user_activity do %>
<h3><%= product_name %></h3>
<ul>
<%= for email <- emails do %>
<li><%= email %></li>
<% end %>
</ul>
<% end %>
</div>
</div>