defmodule LivebookWeb.AppLive do use LivebookWeb, :live_view import LivebookWeb.AppComponents @impl true def mount(%{"slug" => slug}, _session, socket) when socket.assigns.app_authenticated? do if socket.assigns.app_settings.multi_session do {:ok, app} = Livebook.Apps.fetch_app(slug) if connected?(socket) do Livebook.App.subscribe(slug) end {:ok, assign(socket, app: app)} else {:ok, pid} = Livebook.Apps.fetch_pid(slug) session_id = Livebook.App.get_session_id(pid, user: socket.assigns.current_user) {:ok, push_navigate(socket, to: ~p"/apps/#{slug}/sessions/#{session_id}")} end end def mount(%{"slug" => slug}, _session, socket) do if connected?(socket) do {:ok, push_navigate(socket, to: ~p"/apps/#{slug}/authenticate")} else {:ok, socket} end end @impl true def render(assigns) when assigns.app_authenticated? do ~H"""
<.link navigate={~p"/"}> logo livebook

<%= @app.notebook_name %>

<.content_skeleton :for={_idx <- 1..5} empty={false} />
<.modal id="sessions-modal" show width={:big} patch={~p"/apps"}>

<%= @app.notebook_name %>

<%= if @app_settings.show_existing_sessions do %> This is a multi-session app, pick an existing session or create a new one. <% else %> This is a multi-session app, create a new one to get started. <% end %>

<.button outlined patch={~p"/apps/#{@app.slug}/new"}> <.remix_icon icon="add-line" /> New session
<.link :for={app_session <- active_sessions(@app.sessions)} navigate={~p"/apps/#{@app.slug}/sessions/#{app_session.id}"} class="px-4 py-3 border border-gray-200 rounded-xl text-gray-800 pointer hover:bg-gray-50 flex justify-between" > Started by <%= app_session.started_by.name || "Anonymous" %> <%= LivebookWeb.HTMLHelpers.format_datetime_relatively(app_session.created_at) %> ago
<.app_status status={app_session.app_status} show_label={false} />
""" end def render(assigns), do: auth_placeholder(assigns) @impl true def handle_params(_params, _url, socket) when socket.assigns.live_action == :new_session do session_id = Livebook.App.get_session_id(socket.assigns.app.pid, user: socket.assigns.current_user) {:noreply, push_navigate(socket, to: ~p"/apps/#{socket.assigns.app.slug}/sessions/#{session_id}")} end def handle_params(_params, _url, socket), do: {:noreply, socket} @impl true def handle_info({:app_updated, app}, socket) do {:noreply, assign(socket, :app, app)} end def handle_info(_message, socket), do: {:noreply, socket} defp active_sessions(sessions) do Enum.filter(sessions, &(&1.app_status.lifecycle == :active)) end end