mirror of
https://github.com/livebook-dev/livebook.git
synced 2025-09-07 21:44:36 +08:00
Don't render cell initial data and make a request instead
This commit is contained in:
parent
e0d2adfa64
commit
cc752542de
3 changed files with 61 additions and 45 deletions
|
@ -18,44 +18,42 @@ import Markdown from "./markdown";
|
|||
* * `data-type` - editor type (i.e. language), either "markdown" or "elixir" is expected
|
||||
* * `data-focused` - whether the cell is currently focused
|
||||
* * `data-expanded` - whether the cell is currently expanded (relevant for markdown cells)
|
||||
*
|
||||
* Additionally the root element should have a `div[data-init]` child (rendered once)
|
||||
* holding the initial data rendered only once:
|
||||
*
|
||||
* * `data-source` - the initial cell source
|
||||
* * `data-revision` - the initial cell revision corresponding to the source
|
||||
*/
|
||||
const Cell = {
|
||||
mounted() {
|
||||
this.props = getProps(this);
|
||||
|
||||
const editorContainer = this.el.querySelector("[data-editor-container]");
|
||||
// Remove the content placeholder.
|
||||
editorContainer.firstElementChild.remove();
|
||||
// Create an empty container for the editor to be mounted in.
|
||||
const editorElement = document.createElement("div");
|
||||
editorContainer.appendChild(editorElement);
|
||||
// Setup the editor instance.
|
||||
this.liveEditor = new LiveEditor(
|
||||
this,
|
||||
editorElement,
|
||||
this.props.cellId,
|
||||
this.props.type,
|
||||
this.props.init.source,
|
||||
this.props.init.revision
|
||||
);
|
||||
this.pushEvent("cell_init", { cell_id: this.props.cellId }, (payload) => {
|
||||
const { source, revision } = payload;
|
||||
|
||||
// Setup markdown rendering.
|
||||
if (this.props.type === "markdown") {
|
||||
const markdownContainer = this.el.querySelector(
|
||||
"[data-markdown-container]"
|
||||
const editorContainer = this.el.querySelector("[data-editor-container]");
|
||||
// Remove the content placeholder.
|
||||
editorContainer.firstElementChild.remove();
|
||||
// Create an empty container for the editor to be mounted in.
|
||||
const editorElement = document.createElement("div");
|
||||
editorContainer.appendChild(editorElement);
|
||||
// Setup the editor instance.
|
||||
this.liveEditor = new LiveEditor(
|
||||
this,
|
||||
editorElement,
|
||||
this.props.cellId,
|
||||
this.props.type,
|
||||
source,
|
||||
revision
|
||||
);
|
||||
const markdown = new Markdown(markdownContainer, this.props.init.source);
|
||||
|
||||
this.liveEditor.onChange((newSource) => {
|
||||
markdown.setContent(newSource);
|
||||
});
|
||||
}
|
||||
// Setup markdown rendering.
|
||||
if (this.props.type === "markdown") {
|
||||
const markdownContainer = this.el.querySelector(
|
||||
"[data-markdown-container]"
|
||||
);
|
||||
const markdown = new Markdown(markdownContainer, source);
|
||||
|
||||
this.liveEditor.onChange((newSource) => {
|
||||
markdown.setContent(newSource);
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
updated() {
|
||||
|
@ -73,17 +71,11 @@ const Cell = {
|
|||
};
|
||||
|
||||
function getProps(hook) {
|
||||
const initElement = hook.el.querySelector("[data-init]");
|
||||
|
||||
return {
|
||||
cellId: getAttributeOrThrow(hook.el, "data-cell-id"),
|
||||
type: getAttributeOrThrow(hook.el, "data-type"),
|
||||
isFocused: getAttributeOrThrow(hook.el, "data-focused", parseBoolean),
|
||||
isExpanded: getAttributeOrThrow(hook.el, "data-expanded", parseBoolean),
|
||||
init: {
|
||||
source: getAttributeOrThrow(initElement, "data-source"),
|
||||
revision: getAttributeOrThrow(initElement, "data-revision", parseInteger),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -10,11 +10,6 @@ defmodule LiveBookWeb.Cell do
|
|||
data-focused="<%= @focused %>"
|
||||
data-expanded="<%= @expanded %>"
|
||||
class="flex flex-col relative mr-10 border-l-4 pl-4 -ml-4 border-blue-100 border-opacity-0 hover:border-opacity-100 <%= if @focused, do: "border-blue-300 border-opacity-100"%>">
|
||||
<div id="init-container-<%= @cell.id %>" phx-update="ignore">
|
||||
<div data-init data-source="<%= @cell.source %>" data-revision="<%= @cell_info.revision %>">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<%= render_cell_content(assigns) %>
|
||||
</div>
|
||||
"""
|
||||
|
@ -33,7 +28,7 @@ defmodule LiveBookWeb.Cell do
|
|||
</div>
|
||||
|
||||
<div class="markdown" data-markdown-container id="markdown-container-<%= @cell.id %>" phx-update="ignore">
|
||||
<%= render_markdown_content_placeholder() %>
|
||||
<%= render_markdown_content_placeholder(@cell.source) %>
|
||||
</div>
|
||||
"""
|
||||
end
|
||||
|
@ -59,7 +54,7 @@ defmodule LiveBookWeb.Cell do
|
|||
data-editor-container
|
||||
id="editor-container-<%= cell.id %>"
|
||||
phx-update="ignore">
|
||||
<%= render_editor_content_placeholder() %>
|
||||
<%= render_editor_content_placeholder(cell.source) %>
|
||||
</div>
|
||||
"""
|
||||
end
|
||||
|
@ -68,7 +63,13 @@ defmodule LiveBookWeb.Cell do
|
|||
# There may be a tiny delay before the markdown is rendered
|
||||
# or and editors are mounted, so show neat placeholders immediately.
|
||||
|
||||
defp render_markdown_content_placeholder() do
|
||||
defp render_markdown_content_placeholder("" = _content) do
|
||||
~E"""
|
||||
<div class="h-4"></div>
|
||||
"""
|
||||
end
|
||||
|
||||
defp render_markdown_content_placeholder(_content) do
|
||||
~E"""
|
||||
<div class="max-w-2xl w-full animate-pulse">
|
||||
<div class="flex-1 space-y-4">
|
||||
|
@ -80,7 +81,13 @@ defmodule LiveBookWeb.Cell do
|
|||
"""
|
||||
end
|
||||
|
||||
defp render_editor_content_placeholder() do
|
||||
defp render_editor_content_placeholder("" = _content) do
|
||||
~E"""
|
||||
<div class="h-4"></div>
|
||||
"""
|
||||
end
|
||||
|
||||
defp render_editor_content_placeholder(_content) do
|
||||
~E"""
|
||||
<div class="px-8 max-w-2xl w-full animate-pulse">
|
||||
<div class="flex-1 space-y-4 py-1">
|
||||
|
|
|
@ -88,6 +88,23 @@ defmodule LiveBookWeb.SessionLive do
|
|||
end
|
||||
|
||||
@impl true
|
||||
def handle_event("cell_init", %{"cell_id" => cell_id}, socket) do
|
||||
data = socket.assigns.data
|
||||
|
||||
case Notebook.fetch_cell_and_section(data.notebook, cell_id) do
|
||||
{:ok, cell, _section} ->
|
||||
payload = %{
|
||||
source: cell.source,
|
||||
revision: data.cell_infos[cell.id].revision
|
||||
}
|
||||
|
||||
{:reply, payload, socket}
|
||||
|
||||
:error ->
|
||||
{:noreply, socket}
|
||||
end
|
||||
end
|
||||
|
||||
def handle_event("add_section", _params, socket) do
|
||||
end_index = length(socket.assigns.data.notebook.sections)
|
||||
Session.insert_section(socket.assigns.session_id, end_index)
|
||||
|
|
Loading…
Add table
Reference in a new issue