defmodule LivebookWeb.Output.ImageInputComponent do
use LivebookWeb, :live_component
@impl true
def mount(socket) do
{:ok,
socket
|> assign(value: nil, value: nil, image_url: nil)
|> allow_upload(:file,
accept: :any,
max_entries: 1,
max_file_size: 100_000_000_000,
progress: &handle_progress/3,
auto_upload: true
)}
end
@impl true
def update(assigns, socket) do
{value, assigns} = Map.pop!(assigns, :value)
socket = assign(socket, assigns)
socket =
cond do
value == socket.assigns.value ->
socket
value == nil ->
assign(socket, value: value, image_url: nil)
true ->
assign(socket, value: value, image_url: image_url(socket.assigns.input_id))
end
{:ok, socket}
end
defp image_url(input_id) do
# For the client-side image preview, we serve the original binary
# value from a separate endpoint. To do that, we encode information
# in a token and then the controller fetches input value from the
# LV. This is especially important for client-specific inputs in
# forms.
token = LivebookWeb.SessionHelpers.generate_input_token(self(), input_id)
~p"/public/sessions/image-input/#{token}"
end
@impl true
def render(assigns) do
~H"""
Drag an image file
<.menu id={"#{@id}-camera-select-menu"} position={:bottom_left}>
<:toggle>
<.button color="gray" data-btn-open-camera>
<.remix_icon icon="camera-line" />
Open camera