Skip to content

Commit

Permalink
feat: live_video_preview
Browse files Browse the repository at this point in the history
  • Loading branch information
drumusician committed Jan 24, 2023
1 parent 35de681 commit 8e6adbc
Show file tree
Hide file tree
Showing 3 changed files with 119 additions and 0 deletions.
15 changes: 15 additions & 0 deletions assets/js/phoenix_live_view/hooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,21 @@ let Hooks = {
URL.revokeObjectURL(this.url)
}
},
// Currently this is exactly the same as the LiveImgPreview, but I wanted to add this
// so possibly this can have functionality specific to videos in the future.
LiveVideoPreview: {
mounted(){
this.ref = this.el.getAttribute("data-phx-entry-ref")
this.inputEl = document.getElementById(this.el.getAttribute(PHX_UPLOAD_REF))
LiveUploader.getEntryDataURL(this.inputEl, this.ref, url => {
this.url = url
this.el.src = url
})
},
destroyed(){
URL.revokeObjectURL(this.url)
}
},
FocusWrap: {
mounted(){
this.focusStart = this.el.firstElementChild
Expand Down
40 changes: 40 additions & 0 deletions lib/phoenix_component.ex
Original file line number Diff line number Diff line change
Expand Up @@ -2582,6 +2582,46 @@ defmodule Phoenix.Component do
raise ArgumentError, "missing required :entry attribute to <.live_img_preview/>"
end

@doc """
Generates a video preview on the client for a selected file.
## Examples
```heex
<%= for entry <- @uploads.avatar.entries do %>
<.live_video_preview entry={entry} width="400" />
<% end %>
```
"""
@doc type: :component
def live_video_preview(assigns)

# attr :entry, Phoenix.LiveView.UploadEntry, required: true
# attr :rest, :global
def live_video_preview(%{entry: %Phoenix.LiveView.UploadEntry{ref: ref} = entry} = assigns) do
rest =
assigns
|> assigns_to_attributes([:entry])
|> Keyword.put_new_lazy(:id, fn -> "phx-preview-#{ref}" end)

assigns = assign(assigns, entry: entry, ref: ref, rest: rest)

~H"""
<video
controls
data-phx-upload-ref={@entry.upload_ref}
data-phx-entry-ref={@ref}
data-phx-hook="Phoenix.LiveVideoPreview"
data-phx-update="ignore"
{@rest}
/>
"""
end

def live_video_preview(_assigns) do
raise ArgumentError, "missing required :entry attribute to <.live_video_preview/>"
end

@doc """
Intersperses separator slot between an enumerable.
Expand Down
64 changes: 64 additions & 0 deletions test/phoenix_component/components_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -479,6 +479,70 @@ defmodule Phoenix.LiveView.ComponentsTest do
end
end

describe "live_img_preview/1" do
test "basic usage" do
entry = %Phoenix.LiveView.UploadEntry{
progress: 100,
preflighted?: true,
upload_config: :poster_imgix_src,
upload_ref: "phx-Fz1Xjn4seffww0vC",
ref: "1",
uuid: "898e29b9-1724-4b5f-b42f-2389b85bb9f4",
valid?: true,
done?: true,
cancelled?: false,
client_name: "an_image.jpg",
client_relative_path: "",
client_size: 2065187,
client_type: "image/jpeg",
client_last_modified: 1646642130571
}
assigns = %{entry: entry}

assert render(~H|<.live_img_preview entry={@entry}/>|) == ~s|<img data-phx-upload-ref="phx-Fz1Xjn4seffww0vC" data-phx-entry-ref="1" data-phx-hook="Phoenix.LiveImgPreview" data-phx-update="ignore" id="phx-preview-1">|
end

test "requires an entry to be given" do
assigns = %{}

assert_raise ArgumentError, "missing required :entry attribute to <.live_img_preview/>", fn ->
render(~H|<.live_img_preview />|)
end
end
end

describe "live_video_preview/1" do
test "basic usage" do
entry = %Phoenix.LiveView.UploadEntry{
progress: 100,
preflighted?: true,
upload_config: :some_field,
upload_ref: "phx-Fz1Xjn4tLhvww0xC",
ref: "0",
uuid: "e3ae39ee-8251-4e24-9655-d1574adef682",
valid?: true,
done?: true,
cancelled?: false,
client_name: "a_video.mp4",
client_relative_path: "",
client_size: 17116709,
client_type: "video/mp4",
client_last_modified: 1671742709575
}
assigns = %{entry: entry}

assert render(~H|<.live_video_preview entry={@entry}/>|) == ~s|<video controls data-phx-upload-ref="phx-Fz1Xjn4tLhvww0xC" data-phx-entry-ref="0" data-phx-hook="Phoenix.LiveImgPreview" data-phx-update="ignore" id="phx-preview-0"></video>|
end

test "requires an entry to be given" do
assigns = %{}

assert_raise ArgumentError, "missing required :entry attribute to <.live_video_preview/>", fn ->
render(~H|<.live_video_preview />|)
end
end
end

describe "intersperse" do
test "generates form with no options" do
assigns = %{}
Expand Down

0 comments on commit 8e6adbc

Please sign in to comment.