PhxMediaLibrary.MediaLive (PhxMediaLibrary v0.6.1)

Copy Markdown View Source

A self-contained LiveComponent for media uploads and gallery display.

MediaLive eliminates all upload boilerplate. Drop it into any LiveView and get drag-and-drop uploads, live previews, progress bars, a media gallery with delete support, and automatic persistence via PhxMediaLibrary — all in a single line of template code.

Quick Start

<.live_component
  module={PhxMediaLibrary.MediaLive}
  id="post-images"
  model={@post}
  collection={:images}
/>

That's it. No use PhxMediaLibrary.LiveUpload, no handle_event clauses, no allow_upload, no consume_media. The component handles everything.

Options

<.live_component
  module={PhxMediaLibrary.MediaLive}
  id="album-photos"
  model={@album}
  collection={:photos}
  max_file_size={20_000_000}
  max_entries={20}
  responsive={true}
  upload_label="Drop photos here"
  upload_sublabel="JPG, PNG, WebP, GIF up to 20MB"
  compact={false}
  columns={4}
  conversion={:thumb}
  show_gallery={true}
/>

Parent Notifications

The component notifies the parent LiveView via send/2 so you can react to uploads and deletions (update counters, refresh related data, etc.):

def handle_info({PhxMediaLibrary.MediaLive, {:uploaded, :photos, media_items}}, socket) do
  {:noreply, assign(socket, :photo_count, socket.assigns.photo_count + length(media_items))}
end

def handle_info({PhxMediaLibrary.MediaLive, {:deleted, :photos, _media}}, socket) do
  {:noreply, assign(socket, :photo_count, max(0, socket.assigns.photo_count - 1))}
end

You can safely ignore these messages if you don't need them.

How It Works

Internally the component:

  1. Calls allow_upload/3 with collection-aware defaults (accept types, max entries, max file size) derived from your schema's collection config.
  2. Renders a single <.form> containing a <.live_file_input>, drop zone, entry previews with progress bars, and a submit button.
  3. On submit, calls consume_uploaded_entries/3 and persists each file via PhxMediaLibrary.add/2 |> to_collection/2.
  4. Streams existing + newly uploaded media into a gallery grid with delete-on-hover support.

Because the component owns its own <.form>, there is no nested-form problem. The upload binary transfer and consumption work correctly.