我的菲尼克斯1.5.8 LiveView应用程序使用身份验证进行用户身份验证。
@current_user。@current_visitors_count。现在,我想使用@current_users_count来显示以用户身份登录的访问者数量。但我不知道如何在handle_info中处理这个问题。计算这两个数字的最佳方法是什么?
lib/example_web/live/page_live.ex
defmodule ExampleWeb.PageLive do
use ExampleWeb, :live_view
@impl true
def mount(_params, session, socket) do
socket =
socket
|> assign_current_user(session)
|> assign_current_visitors_count()
{:ok, socket}
end
@impl true
def handle_info(
%{event: "presence_diff", payload: %{joins: joins, leaves: leaves}},
%{assigns: %{current_visitors_count: count}} = socket
) do
current_visitors_count = count + map_size(joins) - map_size(leaves)
{:noreply, assign(socket, :current_visitors_count, current_visitors_count)}
end
endlib/example_web/live/live_helpers.ex
defmodule ExampleWeb.LiveHelpers do
import Phoenix.LiveView
alias Example.Accounts
alias Example.Presence
def assign_current_user(socket, session) do
assign_new(
socket,
:current_user,
fn ->
case session["user_token"] do
nil -> nil
user_token -> Accounts.get_user_by_session_token(user_token)
end
end
)
end
def assign_current_visitors_count(socket) do
topic = "current_visitors"
initial_count = Presence.list(topic) |> map_size
ExampleWeb.Endpoint.subscribe(topic)
Presence.track(
self(),
topic,
socket.id,
%{}
)
assign(socket, :current_visitors_count, initial_count)
end
end发布于 2021-03-08 15:11:31
lib/example_web/live/page_live.ex
defmodule ExampleWeb.PageLive do
use ExampleWeb, :live_view
alias Example.Presence
alias Example.Accounts
alias Phoenix.Socket.Broadcast
@impl true
def mount(_params, session, socket) do
current_user = get_current_user(session)
[chat_user_id, user_status] =
case current_user do
nil -> [UUID.uuid4(), "guest"]
user -> [user.id, "user"]
end
Phoenix.PubSub.subscribe(Example.PubSub, "room:lobby")
{:ok, _} = Presence.track(self(), "room:lobby", chat_user_id, %{status: user_status})
socket =
socket
|> assign_user_count()
|> assign(:current_user, current_user)
|> assign(:chat_user_id, chat_user_id)
|> assign(:current_users_count, 0)
|> assign(:guests_count, 0)
{:ok, socket}
end
@impl true
def handle_info(%Broadcast{event: "presence_diff"}, socket) do
socket =
socket
|> assign(:current_users_count, length(current_user_ids(socket)))
|> assign(:guests_count, length(current_guests_ids(socket)))
{:noreply, socket}
end
defp current_user_ids(socket) do
Presence.list("room:lobby")
|> Enum.filter(fn {id, x} -> hd(x.metas).status == "user" end)
|> Enum.map(fn {k, _} -> k end)
end
defp current_guests_ids(socket) do
Presence.list("room:lobby")
|> Enum.filter(fn {id, x} -> hd(x.metas).status == "guest" end)
|> Enum.map(fn {k, _} -> k end)
end
endlib/example_web/live/live_helpers.ex
defmodule ExampleWeb.LiveHelpers do
import Phoenix.LiveView
alias Example.Accounts
alias Example.Repo
alias Example.Presence
import Ecto.Query, only: [from: 2]
def get_current_user(session) do
case session["user_token"] do
nil -> nil
user_token -> Accounts.get_user_by_session_token(user_token)
end
end
endhttps://stackoverflow.com/questions/66508466
复制相似问题