livebook/lib/livebook_web/live/hooks/user_hook.ex
2023-09-25 11:18:30 -03:00

53 lines
1.5 KiB
Elixir

defmodule LivebookWeb.UserHook do
import Phoenix.Component
import Phoenix.LiveView
alias Livebook.Users.User
def on_mount(:default, _params, %{"identity_data" => identity_data} = session, socket) do
if connected?(socket) do
Livebook.Users.subscribe(identity_data.id)
end
socket =
socket
|> assign_new(:current_user, fn -> build_current_user(session, socket) end)
|> attach_hook(:current_user_subscription, :handle_info, &info/2)
{:cont, socket}
end
defp info(
{:user_change, %{id: id} = user},
%{assigns: %{current_user: %{id: id}}} = socket
) do
{:halt, assign(socket, :current_user, user)}
end
defp info(_message, socket), do: {:cont, socket}
# Builds `Livebook.Users.User` using information from
# session and socket.
#
# Uses `user_data` from socket `connect_params` as initial
# attributes if the socket is connected. Otherwise uses
# `user_data` from session.
defp build_current_user(session, socket) do
identity_data = Map.new(session["identity_data"], fn {k, v} -> {Atom.to_string(k), v} end)
connect_params = get_connect_params(socket) || %{}
attrs = connect_params["user_data"] || session["user_data"] || %{}
attrs =
case Map.merge(attrs, identity_data) do
%{"name" => nil, "email" => email} = attrs -> %{attrs | "name" => email}
attrs -> attrs
end
user = User.new(attrs["id"])
case Livebook.Users.update_user(user, attrs) do
{:ok, user} -> user
{:error, _changeset} -> user
end
end
end