diff --git a/lib/microwaveprop_web/components/layouts.ex b/lib/microwaveprop_web/components/layouts.ex index 1e8d020b..0af5b7ee 100644 --- a/lib/microwaveprop_web/components/layouts.ex +++ b/lib/microwaveprop_web/components/layouts.ex @@ -100,16 +100,6 @@ defmodule MicrowavepropWeb.Layouts do North Texas Microwave Society -
- Found this useful? - - Donate to NTMS - -
<.link navigate="/privacy" class="link link-hover">Privacy
diff --git a/lib/microwaveprop_web/live/contact_live/show.ex b/lib/microwaveprop_web/live/contact_live/show.ex index 5c07f0e1..f085883c 100644 --- a/lib/microwaveprop_web/live/contact_live/show.ex +++ b/lib/microwaveprop_web/live/contact_live/show.ex @@ -74,9 +74,6 @@ defmodule MicrowavepropWeb.ContactLive.Show do socket = if connected?(socket) do Phoenix.PubSub.subscribe(Microwaveprop.PubSub, "contact_enrichment:#{contact.id}") - Phoenix.PubSub.subscribe(Microwaveprop.PubSub, "contact_enrichment:hrrr") - Phoenix.PubSub.subscribe(Microwaveprop.PubSub, "contact_enrichment:weather") - Phoenix.PubSub.subscribe(Microwaveprop.PubSub, "contact_enrichment:solar") kickoff_hydration(socket, contact) else @@ -91,19 +88,7 @@ defmodule MicrowavepropWeb.ContactLive.Show do # clauses below update the matching slot and re-run the derived analysis. defp kickoff_hydration(socket, contact) do socket - |> assign( - :hydration_pending, - MapSet.new([ - :weather, - :solar, - :hrrr_path, - :narr_path, - :native_profile, - :terrain, - :iemre, - :radar - ]) - ) + |> assign(:hydration_pending, pending_slots(contact)) |> start_async(:weather, fn -> load_weather(contact) end) |> start_async(:solar, fn -> load_solar(contact) end) |> start_async(:hrrr_path, fn -> Weather.hrrr_profiles_for_path(contact) end) @@ -114,6 +99,25 @@ defmodule MicrowavepropWeb.ContactLive.Show do |> start_async(:radar, fn -> load_radar(contact) end) end + # A slot shows its loading spinner only while the corresponding enrichment + # column on the contact says the work is genuinely in flight. For contacts + # whose status is :complete (or :pending/:unavailable/:failed), the async + # query just returns whatever is cached without any intermediate flash. + defp pending_slots(contact) do + in_flight = [:queued, :processing] + slots = [] + slots = if contact.weather_status in in_flight, do: [:weather | slots], else: slots + + slots = + if contact.hrrr_status in in_flight, + do: [:hrrr_path, :narr_path, :native_profile | slots], + else: slots + + slots = if contact.terrain_status in in_flight, do: [:terrain | slots], else: slots + slots = if contact.iemre_status in in_flight, do: [:iemre | slots], else: slots + MapSet.new(slots) + end + defp mark_hydrated(socket, slot) do assign(socket, :hydration_pending, MapSet.delete(socket.assigns.hydration_pending, slot)) end @@ -458,57 +462,6 @@ defmodule MicrowavepropWeb.ContactLive.Show do )} end - def handle_info({:hrrr_ready, _info}, socket) do - contact = socket.assigns.contact - hrrr_path = Weather.hrrr_profiles_for_path(contact) - hrrr = List.first(hrrr_path) - - if hrrr do - contact = %{contact | hrrr_status: :complete} - soundings = socket.assigns.soundings - terrain = socket.assigns.terrain - elevation_profile = compute_elevation_profile(contact, hrrr_path, soundings) - propagation_analysis = build_propagation_analysis(contact, hrrr_path, terrain, elevation_profile, soundings) - - {:noreply, - assign(socket, - contact: contact, - hrrr: hrrr, - queue_counts: fetch_queue_counts(), - elevation_profile: elevation_profile, - propagation_analysis: propagation_analysis - )} - else - {:noreply, socket} - end - end - - def handle_info({:weather_ready, _info}, socket) do - contact = %{socket.assigns.contact | weather_status: :complete} - weather = load_weather(contact) - soundings = weather.soundings - - hrrr_path = Weather.hrrr_profiles_for_path(contact) - terrain = socket.assigns.terrain - - elevation_profile = compute_elevation_profile(contact, hrrr_path, soundings) - propagation_analysis = build_propagation_analysis(contact, hrrr_path, terrain, elevation_profile, soundings) - - {:noreply, - assign(socket, - contact: contact, - surface_observations: weather.surface_observations, - soundings: soundings, - elevation_profile: elevation_profile, - propagation_analysis: propagation_analysis - )} - end - - def handle_info({:solar_ready, _date}, socket) do - solar = load_solar(socket.assigns.contact) - {:noreply, assign(socket, solar: solar)} - end - defp maybe_enqueue_weather(weather, contact) do has_data = weather.surface_observations != [] or weather.soundings != []