defmodule LiveDebuggerWeb.WindowDashboardLive do @moduledoc """ This view is a variant of the LiveViews dashboard, but it is used to display LiveViews in the given window. It cannot be accessed from the browser directly, but: - it is used when there are many LiveViews in the same window, and we cannot find a single successor. - in case of extension this replaces the LiveViews dashboard, since extension works in a single window. """ use LiveDebuggerWeb, :live_view alias LiveDebugger.Utils.Parsers alias LiveDebuggerWeb.Helpers.RoutesHelper alias LiveDebugger.Services.LiveViewDiscoveryService alias LiveDebuggerWeb.Components.TabGroup alias LiveDebuggerWeb.Components.Navbar alias Phoenix.LiveView.AsyncResult @impl true def mount(%{"transport_pid" => string_transport_pid}, _session, socket) do string_transport_pid |> Parsers.string_to_pid() |> case do {:ok, transport_pid} -> socket |> assign(:transport_pid, transport_pid) |> assign_async_grouped_lv_processes() :error -> push_navigate(socket, to: RoutesHelper.error("invalid_pid")) end |> ok() end @impl true def render(assigns) do ~H"""
<.h1>Active LiveViews in a single window <.button phx-click="refresh">
<.icon name="icon-refresh" class="w-4 h-4" />

Refresh

<.async_result :let={grouped_lv_processes} assign={@grouped_lv_processes}> <:loading>
<.spinner size="md" />
<:failed> <.alert variant="danger" with_icon heading="Error fetching active LiveViews"> Check logs for more
<%= if Enum.empty?(grouped_lv_processes) do %>

No active LiveViews

<% else %> <% end %>
""" end @impl true def handle_event("refresh", _params, socket) do socket |> assign(:grouped_lv_processes, AsyncResult.loading()) |> assign_async_grouped_lv_processes() |> noreply() end defp assign_async_grouped_lv_processes(%{assigns: %{transport_pid: transport_pid}} = socket) do assign_async(socket, :grouped_lv_processes, fn -> lv_processes = with [] <- fetch_lv_processes_after(200, transport_pid), [] <- fetch_lv_processes_after(800, transport_pid) do fetch_lv_processes_after(1000, transport_pid) end {:ok, %{grouped_lv_processes: LiveViewDiscoveryService.group_lv_processes(lv_processes)}} end) end defp fetch_lv_processes_after(milliseconds, transport_pid) do Process.sleep(milliseconds) LiveViewDiscoveryService.debugged_lv_processes(transport_pid) end end