Add Microwaveprop.Format.distance_km/1 and a matching formatDistanceKm helper for the JS side. Both emit "X mi (Y km)" with one decimal under 10 mi and whole numbers above. Replace the ad-hoc format_dist/format_km_mi helpers with the shared formatter and update every user-facing distance render: contact detail, contacts index column, user profile contact/involving tables, path finder summary + sounding list, contacts map line popups, beacon coverage tooltip, and propagation map range estimate + rain scatter cell popup.
30 lines
931 B
Elixir
30 lines
931 B
Elixir
defmodule Microwaveprop.Format do
|
|
@moduledoc """
|
|
Shared human-facing formatters. Miles are the primary distance unit
|
|
across the site; km appears parenthetically for readers working in
|
|
metric.
|
|
"""
|
|
|
|
@doc """
|
|
Format a distance in km as "X mi (Y km)". Under 10 miles the output
|
|
carries one decimal so near-LOS paths don't round to zero; longer
|
|
distances round to whole numbers.
|
|
"""
|
|
@spec distance_km(number() | Decimal.t() | nil) :: String.t()
|
|
def distance_km(nil), do: "—"
|
|
|
|
def distance_km(%Decimal{} = d), do: d |> Decimal.to_float() |> distance_km()
|
|
|
|
def distance_km(km) when is_number(km) do
|
|
mi = km / 1.609344
|
|
|
|
{mi_str, km_str} =
|
|
if mi < 10.0,
|
|
do: {one_decimal(mi), one_decimal(km)},
|
|
else: {Integer.to_string(round(mi)), Integer.to_string(round(km))}
|
|
|
|
"#{mi_str} mi (#{km_str} km)"
|
|
end
|
|
|
|
defp one_decimal(n), do: :erlang.float_to_binary(n * 1.0, decimals: 1)
|
|
end
|