Gate beacon coverage toggle to 5.76 GHz and above

The estimated current coverage map is only meaningful on bands
where atmospheric attenuation shapes the reach — below 5.76 GHz
it's dominated by free-space loss and misleads. Disable the
toggle, show a helper note explaining the limit, and guard the
handle_event against clients that try to force it.
This commit is contained in:
Graham McIntire 2026-04-14 16:42:54 -05:00
parent c454fab83e
commit e3ddf107d9
No known key found for this signature in database
GPG key ID: F4ABF488E6029E59

View file

@ -60,14 +60,21 @@ defmodule MicrowavepropWeb.BeaconLive.Show do
</div>
<div class="mb-2 flex items-center justify-between flex-wrap gap-2">
<label class="label cursor-pointer gap-2 py-0">
<label class={[
"label gap-2 py-0",
if(@coverage_supported, do: "cursor-pointer", else: "cursor-not-allowed opacity-60")
]}>
<input
type="checkbox"
class="toggle toggle-sm toggle-primary"
checked={@show_coverage}
phx-click="toggle_coverage"
disabled={not @coverage_supported}
phx-click={if @coverage_supported, do: "toggle_coverage"}
/>
<span class="label-text text-sm">Show estimated current coverage</span>
<span :if={not @coverage_supported} class="label-text-alt text-xs opacity-70">
(5.76 GHz and up only atmospheric loss dominates on microwave bands)
</span>
</label>
</div>
@ -161,17 +168,28 @@ defmodule MicrowavepropWeb.BeaconLive.Show do
|> assign(:page_title, "Beacon")
|> assign(:beacon, beacon)
|> assign(:show_coverage, false)
|> assign(:coverage_supported, coverage_supported?(beacon))
|> assign(:estimate, RangeEstimate.estimate(beacon))}
end
# Estimated current coverage only makes sense from 5.76 GHz upward,
# where atmospheric attenuation meaningfully shapes the reach. Below
# that the free-space-loss-dominated map is misleading.
defp coverage_supported?(%{frequency_mhz: mhz}) when is_number(mhz), do: mhz >= 5760
defp coverage_supported?(_), do: false
@impl true
def handle_event("toggle_coverage", _params, socket) do
show = not socket.assigns.show_coverage
if socket.assigns.coverage_supported do
show = not socket.assigns.show_coverage
{:noreply,
socket
|> assign(:show_coverage, show)
|> push_event("toggle_coverage", %{show: show})}
{:noreply,
socket
|> assign(:show_coverage, show)
|> push_event("toggle_coverage", %{show: show})}
else
{:noreply, socket}
end
end
def handle_event("approve", _params, socket) do
@ -189,9 +207,13 @@ defmodule MicrowavepropWeb.BeaconLive.Show do
@impl true
def handle_info({:updated, %Beacon{id: id} = beacon}, %{assigns: %{beacon: %{id: id}}} = socket) do
supported = coverage_supported?(beacon)
{:noreply,
socket
|> assign(:beacon, beacon)
|> assign(:coverage_supported, supported)
|> assign(:show_coverage, socket.assigns.show_coverage and supported)
|> assign(:estimate, RangeEstimate.estimate(beacon))}
end