Skip to content

Instantly share code, notes, and snippets.

@onixus74
Forked from goofansu/app.js
Last active May 29, 2022 01:32
Show Gist options
  • Save onixus74/dd1337b3532d142bcce18421f6ab1b39 to your computer and use it in GitHub Desktop.
Save onixus74/dd1337b3532d142bcce18421f6ab1b39 to your computer and use it in GitHub Desktop.

Revisions

  1. onixus74 renamed this gist May 29, 2022. 1 changed file with 0 additions and 0 deletions.
  2. onixus74 revised this gist May 29, 2022. No changes.
  3. onixus74 revised this gist May 29, 2022. No changes.
  4. onixus74 renamed this gist May 29, 2022. 1 changed file with 0 additions and 0 deletions.
  5. onixus74 renamed this gist May 29, 2022. 1 changed file with 0 additions and 0 deletions.
  6. onixus74 renamed this gist May 29, 2022. 1 changed file with 0 additions and 0 deletions.
  7. onixus74 renamed this gist May 29, 2022. 1 changed file with 0 additions and 0 deletions.
  8. onixus74 revised this gist May 29, 2022. 1 changed file with 1 addition and 0 deletions.
    1 change: 1 addition & 0 deletions Liveview upload s3.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1 @@
    LiveView upload directly to AWS China S3
  9. @goofansu goofansu revised this gist Oct 27, 2020. 1 changed file with 3 additions and 3 deletions.
    6 changes: 3 additions & 3 deletions page_live.html.leex
    Original file line number Diff line number Diff line change
    @@ -9,11 +9,11 @@
    <%= live_img_preview entry, width: 64 %>
    <div>
    <div>
    <span class="text-3xl font-bold"><%= entry.client_name %></span>
    <span class="text-3xl font-bold"><%= entry.client_name %></span>
    </div>
    <div>
    <progress max="100" value="<%= entry.progress %>" class="mt-2"></progress>
    <%= entry.progress %>%
    <progress max="100" value="<%= entry.progress %>" class="mt-2"></progress>
    <%= entry.progress %>%
    </div>
    <button phx-click="cancel-upload" phx-value-ref="<%= entry.ref %>">cancel</button>
    </div>
  10. @goofansu goofansu revised this gist Oct 27, 2020. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions page_live.html.leex
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,4 @@
    <div class="bg-gray-100 p-4 sm:p-6" phx-drop-target="<%= @uploads.avatar.ref %>">
    <div class="bg-gray-100 p-6" phx-drop-target="<%= @uploads.avatar.ref %>">
    <%= for {_ref, err} <- @uploads.avatar.errors do %>
    <p class="alert alert-danger"><%= Phoenix.Naming.humanize(err) %></p>
    <% end %>
    @@ -15,7 +15,7 @@
    <progress max="100" value="<%= entry.progress %>" class="mt-2"></progress>
    <%= entry.progress %>%
    </div>
    <button phx-click="cancel-upload" phx-value-ref="<%= entry.ref %>" class="align-text-baseline">cancel</button>
    <button phx-click="cancel-upload" phx-value-ref="<%= entry.ref %>">cancel</button>
    </div>
    </div>
    <% end %>
  11. @goofansu goofansu revised this gist Oct 27, 2020. 1 changed file with 28 additions and 27 deletions.
    55 changes: 28 additions & 27 deletions page_live.html.leex
    Original file line number Diff line number Diff line change
    @@ -1,33 +1,34 @@
    <div phx-drop-target="<%= @uploads.avatar.ref %>">
    <%= for {_ref, err} <- @uploads.avatar.errors do %>
    <p class="alert alert-danger"><%= Phoenix.Naming.humanize(err) %></p>
    <% end %>
    <div class="bg-gray-100 p-4 sm:p-6" phx-drop-target="<%= @uploads.avatar.ref %>">
    <%= for {_ref, err} <- @uploads.avatar.errors do %>
    <p class="alert alert-danger"><%= Phoenix.Naming.humanize(err) %></p>
    <% end %>

    <div class="grid grid-cols-2 gap-4">
    <%= for entry <- @uploads.avatar.entries do %>
    <div class="flex items-center space-x-4 p-4">
    <%= live_img_preview entry, width: 64 %>
    <div>
    <div>
    <span class="text-3xl font-bold"><%= entry.client_name %></span>
    <div class="grid grid-cols-2 gap-4">
    <%= for entry <- @uploads.avatar.entries do %>
    <div class="flex items-center space-x-4 p-4">
    <%= live_img_preview entry, width: 64 %>
    <div>
    <div>
    <span class="text-3xl font-bold"><%= entry.client_name %></span>
    </div>
    <div>
    <progress max="100" value="<%= entry.progress %>" class="mt-2"></progress>
    <%= entry.progress %>%
    </div>
    <button phx-click="cancel-upload" phx-value-ref="<%= entry.ref %>" class="align-text-baseline">cancel</button>
    </div>
    </div>
    <div>
    <progress max="100" value="<%= entry.progress %>" class="mt-2"></progress>
    <%= entry.progress %>%
    </div>
    <button phx-click="cancel-upload" phx-value-ref="<%= entry.ref %>" class="align-text-baseline">cancel</button>
    </div>
    <% end %>
    </div>
    <% end %>
    </div>

    <form class="mt-6" phx-change="validate" phx-submit="save">
    <%= live_file_input @uploads.avatar %>
    <button type="submit">upload <%= Enum.count(@uploads.avatar.entries) %> files</button>
    </form>
    <form class="mt-6" phx-change="validate" phx-submit="save">
    <%= live_file_input @uploads.avatar %>
    <button type="submit">upload <%= Enum.count(@uploads.avatar.entries) %> files</button>
    </form>

    <div class="grid grid-cols-6 gap-x-4">
    <%= for url <- @uploaded_files do %>
    <img src="<%= url %>" class="object-cover h-48" />
    <% end %>
    <div class="grid grid-cols-6 gap-x-4">
    <%= for url <- @uploaded_files do %>
    <img src="<%= url %>" class="object-cover h-48" />
    <% end %>
    </div>
    </div>
  12. @goofansu goofansu revised this gist Oct 26, 2020. 1 changed file with 21 additions and 21 deletions.
    42 changes: 21 additions & 21 deletions mix.exs
    Original file line number Diff line number Diff line change
    @@ -1,21 +1,21 @@
    defp deps do
    [
    {:phoenix, github: "phoenixframework/phoenix", branch: "master", override: true},
    {:phoenix_ecto, "~> 4.0"},
    {:phoenix_live_view, github: "phoenixframework/phoenix_live_view", branch: "cm-uploads-merge", override: true},
    {:floki, ">= 0.27.0", only: :test},
    {:phoenix_html, "~> 2.11"},
    {:phoenix_live_reload, "~> 1.2", only: :dev},
    {:phoenix_live_dashboard, "~> 0.3 or ~> 0.2.9"},
    {:telemetry_metrics, "~> 0.4"},
    {:telemetry_poller, "~> 0.4"},
    {:gettext, "~> 0.11"},
    {:brightu, in_umbrella: true},
    {:jason, "~> 1.0"},
    {:plug_cowboy, "~> 2.0"},
    {:ranch, "~> 1.7.1"},
    {:ex_aws, "~> 2.1"},
    {:ex_aws_s3, "~> 2.0"},
    {:sweet_xml, "~> 0.6"}
    ]
    end
    defp deps do
    [
    {:phoenix, github: "phoenixframework/phoenix", branch: "master", override: true},
    {:phoenix_ecto, "~> 4.0"},
    {:phoenix_live_view, github: "phoenixframework/phoenix_live_view", branch: "cm-uploads-merge", override: true},
    {:floki, ">= 0.27.0", only: :test},
    {:phoenix_html, "~> 2.11"},
    {:phoenix_live_reload, "~> 1.2", only: :dev},
    {:phoenix_live_dashboard, "~> 0.3 or ~> 0.2.9"},
    {:telemetry_metrics, "~> 0.4"},
    {:telemetry_poller, "~> 0.4"},
    {:gettext, "~> 0.11"},
    {:brightu, in_umbrella: true},
    {:jason, "~> 1.0"},
    {:plug_cowboy, "~> 2.0"},
    {:ranch, "~> 1.7.1"},
    {:ex_aws, "~> 2.1"},
    {:ex_aws_s3, "~> 2.0"},
    {:sweet_xml, "~> 0.6"}
    ]
    end
  13. @goofansu goofansu revised this gist Oct 26, 2020. 1 changed file with 21 additions and 0 deletions.
    21 changes: 21 additions & 0 deletions mix.exs
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,21 @@
    defp deps do
    [
    {:phoenix, github: "phoenixframework/phoenix", branch: "master", override: true},
    {:phoenix_ecto, "~> 4.0"},
    {:phoenix_live_view, github: "phoenixframework/phoenix_live_view", branch: "cm-uploads-merge", override: true},
    {:floki, ">= 0.27.0", only: :test},
    {:phoenix_html, "~> 2.11"},
    {:phoenix_live_reload, "~> 1.2", only: :dev},
    {:phoenix_live_dashboard, "~> 0.3 or ~> 0.2.9"},
    {:telemetry_metrics, "~> 0.4"},
    {:telemetry_poller, "~> 0.4"},
    {:gettext, "~> 0.11"},
    {:brightu, in_umbrella: true},
    {:jason, "~> 1.0"},
    {:plug_cowboy, "~> 2.0"},
    {:ranch, "~> 1.7.1"},
    {:ex_aws, "~> 2.1"},
    {:ex_aws_s3, "~> 2.0"},
    {:sweet_xml, "~> 0.6"}
    ]
    end
  14. @goofansu goofansu created this gist Oct 26, 2020.
    24 changes: 24 additions & 0 deletions app.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,24 @@
    let Uploaders = {}

    Uploaders.S3 = function (entries, onViewError) {
    entries.forEach(entry => {
    let xhr = new XMLHttpRequest()
    onViewError(() => xhr.abort())
    xhr.onload = () => (xhr.status === 200 ? entry.done() : entry.error())
    xhr.onerror = () => entry.error()
    xhr.upload.addEventListener("progress", event => {
    if (event.lengthComputable) {
    let percent = Math.round((event.loaded / event.total) * 100)
    entry.progress(percent)
    }
    })

    xhr.open("PUT", entry.meta.url, true)
    xhr.send(entry.file)
    })
    }

    let liveSocket = new LiveSocket("/live", Socket, {
    uploaders: Uploaders,
    params: {_csrf_token: csrfToken},
    })
    4 changes: 4 additions & 0 deletions config.exs
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,4 @@
    config :ex_aws,
    access_key_id: [{:system, "AWS_ACCESS_KEY_ID"}, :instance_role],
    secret_access_key: [{:system, "AWS_SECRET_ACCESS_KEY"}, :instance_role],
    region: {:system, "AWS_REGION"}
    47 changes: 47 additions & 0 deletions page_live.ex
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,47 @@
    @impl true
    def mount(_params, _session, socket) do
    {:ok,
    socket
    |> assign(:uploaded_files, [])
    |> allow_upload(:avatar,
    accept: ~w(.jpg .jpeg .png),
    max_entries: 10,
    max_file_size: 50_000,
    external: &presign_upload/2
    )}
    end

    defp presign_upload(entry, socket) do
    bucket = "phx-upload-example"
    key = "public/#{entry.client_name}"

    {:ok, presigned_url} = ExAws.Config.new(:s3) |> ExAws.S3.presigned_url(:put, bucket, key)
    meta = %{uploader: "S3", bucket: bucket, key: key, url: presigned_url}
    {:ok, meta, socket}
    end
    @impl true
    def handle_event("validate", _params, socket) do
    {:noreply, socket}
    end

    @impl true
    def handle_event("cancel-upload", %{"ref" => ref}, socket) do
    {:noreply, cancel_upload(socket, :avatar, ref)}
    end

    @impl true
    def handle_event("save", _params, socket) do
    uploaded_files =
    consume_uploaded_entries(socket, :avatar, fn %{} = meta, _entry ->
    {:ok, presigned_url} =
    ExAws.Config.new(:s3)
    |> ExAws.S3.presigned_url(:get, meta.bucket, meta.key, expires_in: 86_400)

    presigned_url
    end)

    {:noreply,
    socket
    |> put_flash(:info, "#{length(uploaded_files)} file(s) uploaded")
    |> update(:uploaded_files, &(&1 ++ uploaded_files))}
    end
    33 changes: 33 additions & 0 deletions page_live.html.leex
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,33 @@
    <div phx-drop-target="<%= @uploads.avatar.ref %>">
    <%= for {_ref, err} <- @uploads.avatar.errors do %>
    <p class="alert alert-danger"><%= Phoenix.Naming.humanize(err) %></p>
    <% end %>

    <div class="grid grid-cols-2 gap-4">
    <%= for entry <- @uploads.avatar.entries do %>
    <div class="flex items-center space-x-4 p-4">
    <%= live_img_preview entry, width: 64 %>
    <div>
    <div>
    <span class="text-3xl font-bold"><%= entry.client_name %></span>
    </div>
    <div>
    <progress max="100" value="<%= entry.progress %>" class="mt-2"></progress>
    <%= entry.progress %>%
    </div>
    <button phx-click="cancel-upload" phx-value-ref="<%= entry.ref %>" class="align-text-baseline">cancel</button>
    </div>
    </div>
    <% end %>
    </div>

    <form class="mt-6" phx-change="validate" phx-submit="save">
    <%= live_file_input @uploads.avatar %>
    <button type="submit">upload <%= Enum.count(@uploads.avatar.entries) %> files</button>
    </form>

    <div class="grid grid-cols-6 gap-x-4">
    <%= for url <- @uploaded_files do %>
    <img src="<%= url %>" class="object-cover h-48" />
    <% end %>
    </div>