LiveView Uploads: single file, allow to change it before actual upload

Hey lovely people!

I’m building a very simple uploader, single image file, auto_upload: false, straight to S3.

Now, I want my UI to allow that when people already selected an image that hasn’t been uploaded yet, change their mind and select another one. So: select an image (live_file_input), a preview pops up (live_img_preview), click again to select another one as a replacement, etc.

Here is where I find the current behavior a bit weird (aka I most likely don’t understand it enough): Even though I set max_entries: 1, the next upload gets added to the list of entries (again, I don’t add them all at once, just one by one) and I will then be, of course, greeted with a too many entries error.

I fixed this for now with giving the live_img_preview always just the last entry:
live_img_preview List.last(@uploads.icon.entries) :see_no_evil:
and on my validation event, clean up the upload config (work in progress):

  def handle_event("validate", %{"menu_item" => menu_item_params} = _params, socket) do
    new_upload_config = socket.assigns.uploads |> Map.fetch!(:icon) |> clean_uploads()
    new_uploads = Map.update!(socket.assigns.uploads, :icon, fn _ -> new_upload_config end)

    changeset =
      |> Project.change_menu_item(menu_item_params)

    socket = socket |> assign(changeset: changeset, uploads: new_uploads)

    {:noreply, socket}

  defp clean_uploads(%UploadConfig{entries: [entry_to_drop | [_ | _]]} = upload_config) do
    |> UploadConfig.drop_entry(entry_to_drop)

  defp clean_uploads(upload_config), do: upload_config

I mean, it works, but that cleanup thing feels super weird to me, and I have a feeling that I was missing something here… What do you guys think?

Thanks a lot! :pray::slightly_smiling_face: