Current section

Files

Jump to
livebook lib livebook users user.ex
Raw

lib/livebook/users/user.ex

defmodule Livebook.Users.User do
@moduledoc false
# Represents a Livebook user.
#
# Livebook users are not regular web app accounts,
# but rather ephemeral data about the clients
# using the app. Every person using Livebook
# can provide data like name and cursor color
# to improve visibility during collaboration.
defstruct [:id, :name, :hex_color]
alias Livebook.Utils
@type t :: %__MODULE__{
id: id(),
name: String.t() | nil,
hex_color: hex_color()
}
@type id :: Utils.id()
@type hex_color :: String.t()
@doc """
Generates a new user.
"""
@spec new() :: t()
def new() do
%__MODULE__{
id: Utils.random_id(),
name: nil,
hex_color: random_hex_color()
}
end
@doc """
Validates `attrs` and returns an updated user.
In case of validation errors `{:error, errors, user}` tuple
is returned, where `user` is partially updated by using
only the valid attributes.
"""
@spec change(t(), %{binary() => any()}) ::
{:ok, t()} | {:error, list({atom(), String.t()}), t()}
def change(user, attrs \\ %{}) do
{user, []}
|> change_name(attrs)
|> change_hex_color(attrs)
|> case do
{user, []} -> {:ok, user}
{user, errors} -> {:error, errors, user}
end
end
defp change_name({user, errors}, %{"name" => ""}) do
{%{user | name: nil}, errors}
end
defp change_name({user, errors}, %{"name" => name}) do
{%{user | name: name}, errors}
end
defp change_name({user, errors}, _attrs), do: {user, errors}
defp change_hex_color({user, errors}, %{"hex_color" => hex_color}) do
if Utils.valid_hex_color?(hex_color) do
{%{user | hex_color: hex_color}, errors}
else
{user, [{:hex_color, "not a valid color"} | errors]}
end
end
defp change_hex_color({user, errors}, _attrs), do: {user, errors}
@doc """
Returns a random hex color for a user.
## Options
* `:except` - a list of colors to omit
"""
def random_hex_color(opts \\ []) do
colors = [
# red
"#F87171",
# yellow
"#FBBF24",
# green
"#6EE7B7",
# blue
"#60A5FA",
# purple
"#A78BFA",
# pink
"#F472B6",
# salmon
"#FA8072",
# mat green
"#9ED9CC"
]
except = opts[:except] || []
colors = colors -- except
Enum.random(colors)
end
end