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 %>
<% 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