diff --git a/lib/livebook/utils.ex b/lib/livebook/utils.ex
index 6e2738d1d..0376e9d8c 100644
--- a/lib/livebook/utils.ex
+++ b/lib/livebook/utils.ex
@@ -277,6 +277,27 @@ defmodule Livebook.Utils do
|> URI.to_string()
end
+ @doc """
+ Infers file name from the given URL.
+
+ ## Examples
+
+ iex> Livebook.Utils.url_basename("https://example.com/data.csv")
+ "data.csv"
+
+ iex> Livebook.Utils.url_basename("https://example.com")
+ ""
+
+ """
+ @spec url_basename(String.t()) :: String.t()
+ def url_basename(url) do
+ uri = URI.parse(url)
+
+ (uri.path || "/")
+ |> String.split("/")
+ |> List.last()
+ end
+
@doc ~S"""
Wraps the given line into lines that fit in `width` characters.
diff --git a/lib/livebook_web/live/session_live/add_file_entry_file_component.ex b/lib/livebook_web/live/session_live/add_file_entry_file_component.ex
index 2a0b591da..16a6db54c 100644
--- a/lib/livebook_web/live/session_live/add_file_entry_file_component.ex
+++ b/lib/livebook_web/live/session_live/add_file_entry_file_component.ex
@@ -79,7 +79,7 @@ defmodule LivebookWeb.SessionLive.AddFileEntryFileComponent do
phx-target={@myself}
>
- <.text_field field={f[:name]} label="Name" autocomplete="off" phx-debounce="blur" />
+ <.text_field field={f[:name]} label="Name" autocomplete="off" phx-debounce="200" />
<.radio_field
field={f[:copy]}
options={[
diff --git a/lib/livebook_web/live/session_live/add_file_entry_upload_component.ex b/lib/livebook_web/live/session_live/add_file_entry_upload_component.ex
index 2b5342e67..a34eccd75 100644
--- a/lib/livebook_web/live/session_live/add_file_entry_upload_component.ex
+++ b/lib/livebook_web/live/session_live/add_file_entry_upload_component.ex
@@ -59,7 +59,7 @@ defmodule LivebookWeb.SessionLive.AddFileEntryUploadComponent do
label="Name"
id="add-file-entry-form-name"
autocomplete="off"
- phx-debounce="blur"
+ phx-debounce="200"
/>
diff --git a/lib/livebook_web/live/session_live/add_file_entry_url_component.ex b/lib/livebook_web/live/session_live/add_file_entry_url_component.ex
index f0677af5e..a954b6856 100644
--- a/lib/livebook_web/live/session_live/add_file_entry_url_component.ex
+++ b/lib/livebook_web/live/session_live/add_file_entry_url_component.ex
@@ -52,8 +52,21 @@ defmodule LivebookWeb.SessionLive.AddFileEntryUrlComponent do
phx-target={@myself}
>
- <.text_field field={f[:url]} label="URL" autocomplete="off" phx-debounce="blur" />
- <.text_field field={f[:name]} label="Name" autocomplete="off" phx-debounce="blur" />
+ <.text_field
+ field={f[:url]}
+ label="URL"
+ autocomplete="off"
+ phx-debounce="200"
+ phx-blur="url_blur"
+ phx-target={@myself}
+ />
+ <.text_field
+ field={f[:name]}
+ label="Name"
+ id="add-file-entry-form-name"
+ autocomplete="off"
+ phx-debounce="200"
+ />
<.radio_field
field={f[:copy]}
options={[
@@ -86,6 +99,28 @@ defmodule LivebookWeb.SessionLive.AddFileEntryUrlComponent do
{:noreply, assign(socket, changeset: changeset)}
end
+ def handle_event("url_blur", %{"value" => url}, socket) do
+ name = Livebook.Utils.url_basename(url)
+
+ socket =
+ if socket.assigns.changeset.params["name"] == "" and name != "" do
+ # Emulate input event to make sure validation errors are shown
+ exec_js(
+ socket,
+ JS.dispatch("lb:set_value",
+ to: "#add-file-entry-form-name",
+ detail: %{value: name}
+ )
+ |> JS.dispatch("input", to: "#add-file-entry-form-name")
+ |> JS.dispatch("blur", to: "#add-file-entry-form-name")
+ )
+ else
+ socket
+ end
+
+ {:noreply, socket}
+ end
+
def handle_event("add", %{"data" => data}, socket) do
data
|> changeset()
diff --git a/lib/livebook_web/live/session_live/files_list_component.ex b/lib/livebook_web/live/session_live/files_list_component.ex
index 37fda2996..dd7cb855d 100644
--- a/lib/livebook_web/live/session_live/files_list_component.ex
+++ b/lib/livebook_web/live/session_live/files_list_component.ex
@@ -110,7 +110,7 @@ defmodule LivebookWeb.SessionLive.FilesListComponent do
<.menu_item>
<.remix_icon icon="download-2-line" />
Download
diff --git a/lib/livebook_web/live/session_live/insert_image_component.ex b/lib/livebook_web/live/session_live/insert_image_component.ex
index 90b1ea807..e7e6f4847 100644
--- a/lib/livebook_web/live/session_live/insert_image_component.ex
+++ b/lib/livebook_web/live/session_live/insert_image_component.ex
@@ -64,7 +64,7 @@ defmodule LivebookWeb.SessionLive.InsertImageComponent do
label="Name"
id="insert-image-form-name"
autocomplete="off"
- phx-debounce="blur"
+ phx-debounce="200"
/>