defmodule BDS.Desktop.ShellLive do @moduledoc false use Phoenix.LiveView import Phoenix.HTML alias BDS.Desktop.ShellData alias BDS.UI.Registry alias BDS.UI.Workbench @refresh_interval 1_500 embed_templates "shell_live/*" @impl true def mount(_params, _session, socket) do if connected?(socket) do :timer.send_interval(@refresh_interval, :refresh_task_status) end workbench = Workbench.new() {:ok, socket |> assign(:page_title, ShellData.title()) |> assign(:page_language, ShellData.ui_language()) |> assign(:offline_mode, true) |> assign(:tab_meta, %{}) |> reload_shell(workbench)} end @impl true def handle_event("toggle_sidebar", _params, socket) do {:noreply, reload_shell(socket, Workbench.toggle_sidebar(socket.assigns.workbench))} end def handle_event("toggle_panel", _params, socket) do {:noreply, reload_shell(socket, Workbench.toggle_panel(socket.assigns.workbench))} end def handle_event("toggle_assistant_sidebar", _params, socket) do {:noreply, reload_shell(socket, Workbench.toggle_assistant_sidebar(socket.assigns.workbench))} end def handle_event("select_view", %{"view" => view_id}, socket) do workbench = Workbench.click_activity(socket.assigns.workbench, String.to_existing_atom(view_id)) {:noreply, reload_shell(socket, workbench)} end def handle_event("select_panel_tab", %{"tab" => tab}, socket) do workbench = socket.assigns.workbench |> Workbench.set_panel_visible(true) |> Workbench.set_panel_tab(String.to_existing_atom(tab)) {:noreply, reload_shell(socket, workbench)} end def handle_event("open_sidebar_item", %{"route" => route, "id" => id} = params, socket) do route_atom = sidebar_route_atom(route) tab_id = tab_id_for_route(route_atom, id) workbench = Workbench.open_tab(socket.assigns.workbench, route_atom, tab_id, tab_intent(route_atom)) tab_meta = Map.put(socket.assigns.tab_meta, {route_atom, tab_id}, %{ title: Map.get(params, "title", ""), subtitle: Map.get(params, "subtitle", "") }) {:noreply, socket |> assign(:tab_meta, tab_meta) |> reload_shell(workbench)} end def handle_event("select_tab", %{"type" => type, "id" => id}, socket) do workbench = Workbench.open_tab(socket.assigns.workbench, String.to_existing_atom(type), id, :preview) {:noreply, reload_shell(socket, workbench)} end def handle_event("close_tab", %{"type" => type, "id" => id}, socket) do type_atom = String.to_existing_atom(type) workbench = Workbench.close_tab(socket.assigns.workbench, type_atom, id) tab_meta = Map.delete(socket.assigns.tab_meta, {type_atom, id}) {:noreply, socket |> assign(:tab_meta, tab_meta) |> reload_shell(workbench)} end def handle_event("toggle_offline_mode", _params, socket) do socket = assign(socket, :offline_mode, not socket.assigns.offline_mode) {:noreply, reload_shell(socket, socket.assigns.workbench)} end @impl true def handle_info(:refresh_task_status, socket) do task_status = BDS.Tasks.status_snapshot() {:noreply, socket |> assign(:task_status, task_status) |> assign(:editor_meta, ShellData.editor_meta(task_status)) |> assign( :status, ShellData.status_bar(socket.assigns.workbench, task_status, socket.assigns.dashboard, ui_language: socket.assigns.page_language, offline_mode: socket.assigns.offline_mode ) )} end @impl true def render(assigns), do: index(assigns) defp reload_shell(socket, workbench) do projects = ShellData.project_snapshot() dashboard = ShellData.dashboard(projects.active_project_id) sidebar_data = ShellData.sidebar_view(projects.active_project_id, Atom.to_string(workbench.active_view)) task_status = BDS.Tasks.status_snapshot() activity_buttons = Workbench.activity_buttons(workbench, 0) page_language = socket.assigns[:page_language] || ShellData.ui_language() offline_mode = Map.get(socket.assigns, :offline_mode, true) socket |> assign(:workbench, workbench) |> assign(:projects, projects) |> assign(:current_project, ShellData.current_project(projects)) |> assign(:dashboard, dashboard) |> assign(:dashboard_timeline_entries, Map.get(dashboard, :timeline_entries, [])) |> assign(:dashboard_category_counts, Map.get(dashboard, :category_counts, [])) |> assign(:dashboard_recent_posts, Map.get(dashboard, :recent_posts, [])) |> assign(:dashboard_tag_cloud_items, ShellData.dashboard_tag_cloud_items(Map.get(dashboard, :tag_cloud_items, []))) |> assign(:sidebar_data, sidebar_data) |> assign(:sidebar_header, active_sidebar_label(activity_buttons, workbench.active_view, sidebar_data)) |> assign(:assistant_cards, ShellData.assistant_cards()) |> assign(:editor_meta, ShellData.editor_meta(task_status)) |> assign(:task_status, task_status) |> assign( :status, ShellData.status_bar(workbench, task_status, dashboard, ui_language: page_language, offline_mode: offline_mode ) ) |> assign(:activity_buttons, activity_buttons) |> assign(:panel_tabs, ShellData.panel_tabs(workbench)) |> assign(:supported_ui_languages, ShellData.supported_ui_languages()) |> assign(:current_tab, current_tab(workbench)) end defp render_sidebar_body(assigns) do case assigns.sidebar_data.layout do "post_list" -> render_post_sidebar(assigns) "media_grid" -> render_media_sidebar(assigns) "entity_list" -> render_entity_sidebar(assigns) "nav_list" -> render_nav_sidebar(assigns) _other -> render_default_sidebar(assigns) end end defp render_post_sidebar(assigns) do ~H""" <%= for section <- Map.get(@sidebar_data, :sections, []) do %> <% end %> <%= if Enum.empty?(Map.get(@sidebar_data, :sections, [])) do %>
<% end %> """ end defp render_media_sidebar(assigns) do ~H""" <%= if Enum.any?(Map.get(@sidebar_data, :items, [])) do %> <% else %> <% end %> """ end defp render_entity_sidebar(assigns) do ~H""" <%= if Enum.any?(Map.get(@sidebar_data, :items, [])) do %>