2021-06-26 22:47:52 +08:00
|
|
|
defmodule LivebookWeb.Output.MarkdownComponent do
|
|
|
|
use LivebookWeb, :live_component
|
|
|
|
|
2023-02-16 05:18:13 +08:00
|
|
|
@impl true
|
|
|
|
def mount(socket) do
|
2023-10-28 02:49:46 +08:00
|
|
|
{:ok,
|
|
|
|
socket
|
2024-01-26 16:17:46 +08:00
|
|
|
|> assign(allowed_uri_schemes: Livebook.Config.allowed_uri_schemes(), initialized: false)
|
2023-10-28 02:49:46 +08:00
|
|
|
|> stream(:chunks, [])}
|
2023-02-16 05:18:13 +08:00
|
|
|
end
|
|
|
|
|
2021-06-26 22:47:52 +08:00
|
|
|
@impl true
|
2024-01-26 16:17:46 +08:00
|
|
|
def update(%{event: {:append, text}}, socket) do
|
|
|
|
{:ok, append_text(socket, text)}
|
|
|
|
end
|
|
|
|
|
2021-06-26 22:47:52 +08:00
|
|
|
def update(assigns, socket) do
|
2023-08-22 19:21:22 +08:00
|
|
|
{text, assigns} = Map.pop(assigns, :text)
|
2021-06-26 22:47:52 +08:00
|
|
|
socket = assign(socket, assigns)
|
|
|
|
|
2024-01-26 16:17:46 +08:00
|
|
|
if socket.assigns.initialized do
|
2023-08-22 19:21:22 +08:00
|
|
|
{:ok, socket}
|
2024-01-26 16:17:46 +08:00
|
|
|
else
|
|
|
|
{:ok,
|
|
|
|
socket
|
|
|
|
|> append_text(text)
|
|
|
|
|> assign(:initialized, true)}
|
2023-08-22 19:21:22 +08:00
|
|
|
end
|
2021-06-26 22:47:52 +08:00
|
|
|
end
|
|
|
|
|
2024-01-26 16:17:46 +08:00
|
|
|
defp append_text(socket, text) do
|
|
|
|
chunk = %{id: Livebook.Utils.random_long_id(), text: text}
|
|
|
|
stream_insert(socket, :chunks, chunk)
|
|
|
|
end
|
|
|
|
|
2021-06-26 22:47:52 +08:00
|
|
|
@impl true
|
|
|
|
def render(assigns) do
|
2021-07-07 20:32:49 +08:00
|
|
|
~H"""
|
2022-08-02 21:51:02 +08:00
|
|
|
<div
|
2023-10-28 02:49:46 +08:00
|
|
|
id={@id}
|
2021-06-26 22:47:52 +08:00
|
|
|
phx-hook="MarkdownRenderer"
|
2023-11-23 23:18:06 +08:00
|
|
|
data-p-base-path={hook_prop(~p"/sessions/#{@session_id}")}
|
|
|
|
data-p-allowed-uri-schemes={hook_prop(@allowed_uri_schemes)}
|
2022-08-02 21:51:02 +08:00
|
|
|
>
|
2023-08-22 19:21:22 +08:00
|
|
|
<div
|
|
|
|
data-template
|
2023-10-28 02:49:46 +08:00
|
|
|
id={"#{@id}-template"}
|
2023-08-22 19:21:22 +08:00
|
|
|
class="text-gray-700 whitespace-pre-wrap hidden"
|
2023-10-28 02:49:46 +08:00
|
|
|
phx-update="stream"
|
2023-08-22 19:21:22 +08:00
|
|
|
phx-no-format
|
2023-10-28 02:49:46 +08:00
|
|
|
><span :for={{dom_id, chunk}<- @streams.chunks} id={dom_id}><%= chunk.text %></span></div>
|
|
|
|
<div data-content class="markdown" id={"#{@id}-content"} phx-update="ignore"></div>
|
2021-06-26 22:47:52 +08:00
|
|
|
</div>
|
|
|
|
"""
|
|
|
|
end
|
|
|
|
end
|