I am using LiveView with external uploads. If the socket is reconnected for some reason, the uploads are lost. Is there a way to preserve them? At least those that are done uploading?
This is the best I could do so far:
In the template:
<input
type="hidden"
name="post[completed_media]"
value={completed_media(@current_user, @form, @uploads.media, @cancelled, :completed_media)}
/>
In the live view:
def handle_event("cancel-upload", %{"uuid" => uuid}, socket) do
upload_config = Map.fetch!(socket.assigns[:uploads] || %{}, :media)
entry = Enum.find(upload_config.entries, &(&1.uuid === uuid))
socket =
case entry do
nil -> socket
entry -> socket |> cancel_upload(:media, entry.ref)
end
|> update(:cancelled, &[uuid | &1])
|> push_event("resume_upload", %{id: socket.assigns.uploads.media.ref})
{:noreply, socket}
end
defp completed_media(user, form, uploads, cancelled, input_name) do
token = Phoenix.HTML.Form.input_value(form, input_name) || ""
current_list =
with {:ok, list} <- Phoenix.Token.verify(SmtWeb.Endpoint, "#{user.id}", token) do
list
|> Enum.filter(fn {uuid, _} -> !Enum.any?(cancelled, &(&1 == uuid)) end)
|> Map.new()
else
_ -> %{}
end
updated =
uploads.entries
|> Enum.filter(& &1.done?)
|> Enum.reduce(current_list, fn entry, cur ->
Map.put_new(cur, entry.uuid, upload_url(entry))
end)
Phoenix.Token.sign(SmtWeb.Endpoint, "#{user.id}", updated)
end
I allow only images to be uploaded, so I can use the values in completed_media
to render already uploaded images in case of reconnect, and have the list of completed files URLs in save action
HI! Do you thing this can be an issue or request? Seems a little weird all state is persisted but uploads not. I’ll put this on GitHub. Let see what they say
HI again!. I found this issue in GitHub. File input cleared upon reconnection · Issue #3323 · phoenixframework/phoenix_live_view · GitHub
They say it is hard to keep this files state
State can recovered from the form inputs on reconnection, not sure why exactly that is not possible for files, but that’s how it is