defmodule MicrowavepropWeb.LiveHelpers do @moduledoc """ Small helpers shared across LiveView modules. Use sparingly — most view-specific logic belongs in its own LiveView. """ # ── Parse helpers ──────────────────────────────────────────────────── alias Phoenix.LiveView.Socket @doc """ Parses a value into a float, returning `default` for nil, empty, or unparseable input. Accepts strings, numbers, or any value with a `String.Chars` impl. """ @spec parse_float(term(), float()) :: float() def parse_float(nil, default), do: default def parse_float("", default), do: default def parse_float(value, default) do case value |> to_string() |> Float.parse() do {n, _} -> n :error -> default end end @doc """ Parses a value into an integer, returning `default` for nil, empty, or unparseable input. """ @spec parse_int(term(), integer()) :: integer() def parse_int(nil, default), do: default def parse_int("", default), do: default def parse_int(value, default) do case value |> to_string() |> Integer.parse() do {n, _} -> n :error -> default end end # ── User helpers ───────────────────────────────────────────────────── @doc """ Extracts the current user from a LiveView socket or assigns map. Returns the `%User{}` struct or `nil` if not authenticated. """ @spec current_user(Socket.t() | map()) :: Ecto.Schema.t() | nil def current_user(%Socket{assigns: assigns}) do current_user(assigns) end @spec current_user(map()) :: Ecto.Schema.t() | nil def current_user(%{current_scope: %{user: %_{} = user}}), do: user def current_user(%{user: %_{} = user}), do: user def current_user(_), do: nil # ── PubSub helpers ─────────────────────────────────────────────────── @doc """ Subscribes the socket to a Phoenix.PubSub topic, but only when the socket is connected (WebSocket). Safe to call unconditionally in mount/3. """ @spec subscribe(Socket.t(), String.t()) :: :ok def subscribe(%Socket{} = socket, topic) when is_binary(topic) do if Phoenix.LiveView.connected?(socket) do Phoenix.PubSub.subscribe(Microwaveprop.PubSub, topic) end :ok end # ── URL helpers ────────────────────────────────────────────────────── @doc """ Merges URL params with defaults for handle_params/3. Returns a map of merged values suitable for assigning to the socket. """ @spec assign_url_params(map(), map()) :: map() def assign_url_params(params, defaults) when is_map(params) and is_map(defaults) do Map.merge(defaults, Map.take(params, Map.keys(defaults))) end end