Packages
livebook
0.7.0
0.19.8
0.19.7
0.19.6
0.19.5
0.19.4
0.19.3
0.19.2
0.19.1
0.19.0
0.18.6
0.18.5
0.18.4
0.18.3
0.18.2
0.18.1
0.18.0
0.17.3
0.17.2
0.17.1
0.17.0
0.16.4
0.16.3
0.16.2
0.16.1
0.16.0
0.15.5
0.15.4
0.15.3
0.15.2
0.15.1
0.15.0
0.14.7
0.14.6
0.14.5
0.14.4
0.14.3
0.14.2
0.14.1
0.14.0
0.14.0-rc.1
0.14.0-rc.0
0.13.3
0.13.2
0.13.1
0.13.0
0.12.1
0.12.0
0.11.4
0.11.3
0.11.2
0.11.1
0.11.0
0.10.0
0.9.3
0.9.2
0.9.1
0.9.0
0.8.2
0.8.1
0.8.0
0.7.2
0.7.1
0.7.0
0.6.3
0.6.2
0.6.1
0.6.0
0.5.2
0.5.1
0.5.0
0.4.1
0.4.0
0.3.2
0.3.1
0.3.0
0.2.3
0.2.2
0.2.1
0.2.0
0.1.2
0.1.1
0.1.0
Automate code & data workflows with interactive notebooks
Current section
Files
Jump to
Current section
Files
lib/livebook_web/live/session_live/cell_upload_component.ex
defmodule LivebookWeb.SessionLive.CellUploadComponent do
use LivebookWeb, :live_component
alias Livebook.FileSystem
@impl true
def mount(socket) do
{:ok, assign(socket, name: "", error_message: nil)}
end
@impl true
def render(assigns) do
~H"""
<div class="p-6 flex flex-col space-y-8">
<h3 class="text-2xl font-semibold text-gray-800">
Insert image
</h3>
<%= if @uploads.cell_image.errors != [] do %>
<div class="error-box">
Invalid image file. The image must be either GIF, JPEG, SVG or PNG and cannot exceed 5MB in size.
</div>
<% end %>
<%= if @error_message do %>
<div class="error-box">
<%= @error_message %>
</div>
<% end %>
<%= for entry <- @uploads.cell_image.entries do %>
<div class="flex flex-col space-y-1">
<div class="flex justify-between text-gray-700">
<span><%= entry.client_name %></span>
<span><%= entry.progress %>%</span>
</div>
<div class="w-full h-2 rounded-lg bg-blue-200">
<div
class="h-full rounded-lg bg-blue-600 transition-all ease-out duration-1000"
style={"width: #{entry.progress}%"}
>
</div>
</div>
</div>
<% end %>
<form phx-submit="save" phx-change="validate" phx-target={@myself}>
<div class="w-full flex space-x-2">
<div>
<label>
<%= live_file_input(@uploads.cell_image, class: "hidden") %>
<div class="cursor-pointer button-base button-gray button-square-icon">
<.remix_icon icon="folder-upload-line" />
</div>
</label>
</div>
<div class="grow">
<input class="input" name="name" value={@name} placeholder="Name" autocomplete="off" />
</div>
</div>
<div class="mt-8 flex justify-end space-x-2">
<%= live_patch("Cancel", to: @return_to, class: "button-base button-outlined-gray") %>
<button
class="button-base button-blue"
type="submit"
disabled={@uploads.cell_image.entries == []}
>
Upload
</button>
</div>
</form>
</div>
"""
end
@impl true
def handle_event("validate", %{"name" => name}, socket) do
{:noreply, assign(socket, name: name)}
end
def handle_event("save", %{"name" => name}, socket) do
%{images_dir: images_dir} = socket.assigns.session
consume_uploaded_entries(socket, :cell_image, fn %{path: path}, entry ->
upload_file = FileSystem.File.local(path)
ext = Path.extname(entry.client_name)
filename = if name == "", do: entry.client_name, else: name <> ext
destination_file = FileSystem.File.resolve(images_dir, filename)
result =
with :ok <- FileSystem.File.copy(upload_file, destination_file) do
{:ok, filename}
end
{:ok, result}
end)
|> case do
[{:ok, filename}] ->
src_path = "images/#{URI.encode(filename, &URI.char_unreserved?/1)}"
{:noreply,
socket
|> push_patch(to: socket.assigns.return_to)
|> push_event("cell_upload", %{cell_id: socket.assigns.cell.id, url: src_path})}
[{:error, message}] ->
{:noreply, assign(socket, error_message: message)}
end
end
end