Files
labelmaker/lib/labelmaker_web/tools.ex
2025-08-24 11:13:18 -04:00

120 lines
3.7 KiB
Elixir

defmodule LabelmakerWeb.Tools do
# for the ~p sigil
use Phoenix.VerifiedRoutes,
endpoint: LabelmakerWeb.Endpoint,
router: LabelmakerWeb.Router,
statics: LabelmakerWeb.static_paths()
alias LabelmakerWeb.Constants
def process_parameters(parameters) do
parameters =
Constants.defaults()
|> Map.new(fn {k, v} -> {Atom.to_string(k), v} end)
|> Map.merge(parameters)
parameters =
Constants.defaults()
|> Map.new(fn {k, v} -> {Atom.to_string(k), v} end)
|> Map.merge(parameters)
|> Map.take(Constants.permitted_keys())
|> Map.new(fn {k, v} -> {String.to_atom(k), v} end)
|> Enum.map(fn
{:align, align} ->
{:align, align |> String.downcase()}
{:font, font} ->
{:font, Constants.font_map()[String.downcase(font)]}
{:height, height} ->
{:height, process_height(height, parameters)}
{:label, label} ->
{:label, process_label(label)}
{:label_too_long, _} ->
{:label_too_long, String.length(parameters["label"]) > Constants.max_label_length()}
{:preview_height, _} ->
{:preview_height, calculate_preview_height(parameters)}
{:preview_text, _} ->
{:preview_text, String.split(parameters["label"], "\\n")}
{:width, width} ->
{:width, process_width(width, parameters)}
pair ->
pair
end)
|> Enum.filter(fn
{:align, align} -> align in Constants.permitted_alignments()
{:color, color} -> color in Constants.colors()
{:font, font} -> font in Map.values(Constants.font_map())
{:outline, outline} -> outline in Constants.outlines()
{:size, size} -> size in Constants.sizes()
_ -> true
end)
|> Map.new()
parameters = Map.merge(Constants.defaults(), parameters)
Map.put(parameters, :link, generate_link(parameters))
end
def process_gravity("left"), do: "west"
def process_gravity("middle"), do: "center"
def process_gravity("right"), do: "east"
def process_gravity(alignment), do: alignment |> String.downcase()
defp process_height("", _parameters), do: ""
# defp process_height("", parameters) do
# parameters["width"] |> String.to_integer() |> max(0) |> min(Constants.max_height())
# end
defp process_height(height, _parameters) do
height |> String.to_integer() |> max(0) |> min(Constants.max_height())
end
defp process_label(label) do
if String.length(label) > Constants.max_label_length() do
String.slice(label, 0, Constants.max_label_length())
else
label
end
end
defp generate_link(%{height: "", label: label, width: ""} = parameters) do
~p"/#{label}?#{Map.take(parameters, [:color, :font, :outline, :size])}"
end
defp generate_link(%{label: label} = parameters) do
~p"/#{label}?#{Map.take(parameters, [:align, :color, :font, :height, :outline, :width])}"
end
defp process_width("", _parameters), do: ""
# defp process_width("", parameters) do
# parameters["height"] |> String.to_integer() |> max(0) |> min(Constants.max_width())
# end
defp process_width(width, _parameters) do
width |> String.to_integer() |> max(0) |> min(Constants.max_width())
end
defp calculate_preview_height(parameters) do
size = parameters["size"] |> String.to_integer()
line_breaks = Regex.scan(~r/#{Regex.escape("\\n")}/, parameters["label"]) |> length()
size + size * line_breaks
end
def outline(_, error: true), do: outline(Constants.danger(), false)
def outline("none", _error), do: ""
def outline(color, _error),
do:
"text-shadow: -1px -1px 0 #{color}, 1px -1px 0 #{color}, -1px 1px 0 #{color}, 1px 1px 0 #{color};"
end