Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
146 changes: 146 additions & 0 deletions lib/phoenix_kit_web/helpers/media_selector_helper.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
defmodule PhoenixKitWeb.Helpers.MediaSelectorHelper do
@moduledoc """
Helper functions for integrating the media selector component.

Provides convenience functions to generate media selector URLs,
parse returned selections, and handle media selector integration
from any LiveView or controller.

## Examples

# In a LiveView template
<.link navigate={MediaSelectorHelper.media_selector_url(@current_path, mode: :single)}>
Select Featured Image
</.link>

# In handle_params to receive selection
def handle_params(params, _uri, socket) do
case MediaSelectorHelper.parse_selected_media(params) do
{:ok, [file_id]} ->
socket
|> assign(:featured_image_id, file_id)
|> put_flash(:info, "Image selected!")

{:ok, file_ids} ->
socket
|> assign(:gallery_ids, file_ids)
|> put_flash(:info, "\#{length(file_ids)} images selected!")

:none ->
socket
end
end
"""

alias PhoenixKit.Utils.Routes

@doc """
Generates a URL to the media selector page.

## Parameters

- `return_to` - The URL to return to after selection (required)
- `opts` - Keyword list of options:
- `:mode` - Selection mode: `:single` or `:multiple` (default: `:single`)
- `:filter` - File type filter: `:image`, `:video`, or `:all` (default: `:all`)
- `:selected` - List of pre-selected file IDs (optional)

## Examples

# Single image selection
media_selector_url("/admin/blog/edit", mode: :single, filter: :image)
#=> "/admin/media/selector?return_to=%2Fadmin%2Fblog%2Fedit&mode=single&filter=image"

# Multiple selection with pre-selected files
media_selector_url("/admin/gallery", mode: :multiple, selected: ["id1", "id2"])
#=> "/admin/media/selector?return_to=%2Fadmin%2Fgallery&mode=multiple&selected=id1%2Cid2"

"""
def media_selector_url(return_to, opts \\ []) do
mode = Keyword.get(opts, :mode, :single)
filter = Keyword.get(opts, :filter, :all)
selected = Keyword.get(opts, :selected, [])

base_url = Routes.path("/admin/media/selector")
params = build_query_params(return_to, mode, filter, selected)

"#{base_url}?#{params}"
end

@doc """
Parses the selected media from LiveView params.

Returns `{:ok, [file_ids]}` if media was selected, or `:none` if no selection.

## Examples

parse_selected_media(%{"selected_media" => "id1,id2,id3"})
#=> {:ok, ["id1", "id2", "id3"]}

parse_selected_media(%{"selected_media" => "single-id"})
#=> {:ok, ["single-id"]}

parse_selected_media(%{})
#=> :none

"""
def parse_selected_media(%{"selected_media" => selected_media})
when is_binary(selected_media) do
file_ids =
selected_media
|> String.split(",")
|> Enum.map(&String.trim/1)
|> Enum.reject(&(&1 == ""))

case file_ids do
[] -> :none
ids -> {:ok, ids}
end
end

def parse_selected_media(_params), do: :none

@doc """
Extracts the first file ID from selected media.

Useful for single-selection scenarios where you only need one file ID.

## Examples

get_first_selected(%{"selected_media" => "id1,id2,id3"})
#=> {:ok, "id1"}

get_first_selected(%{"selected_media" => "single-id"})
#=> {:ok, "single-id"}

get_first_selected(%{})
#=> :none

"""
def get_first_selected(params) do
case parse_selected_media(params) do
{:ok, [first_id | _]} -> {:ok, first_id}
:none -> :none
end
end

# Private Functions

defp build_query_params(return_to, mode, filter, selected) do
params = [
{"return_to", return_to},
{"mode", to_string(mode)},
{"filter", to_string(filter)}
]

params =
if Enum.any?(selected) do
selected_string = Enum.join(selected, ",")
params ++ [{"selected", selected_string}]
else
params
end

URI.encode_query(params)
end
end
2 changes: 2 additions & 0 deletions lib/phoenix_kit_web/integration.ex
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,7 @@ defmodule PhoenixKitWeb.Integration do
live "/admin/users/sessions", Live.Users.Sessions, :index
live "/admin/users/media", Live.Users.Media, :index
live "/admin/users/media/:file_id", Live.Users.MediaDetail, :show
live "/admin/media/selector", Live.Users.MediaSelector, :index
live "/admin/settings", Live.Settings, :index
live "/admin/settings/users", Live.Settings.Users, :index
live "/admin/modules", Live.Modules, :index
Expand Down Expand Up @@ -417,6 +418,7 @@ defmodule PhoenixKitWeb.Integration do
live "/admin/users/sessions", Live.Users.Sessions, :index
live "/admin/users/media", Live.Users.Media, :index
live "/admin/users/media/:file_id", Live.Users.MediaDetail, :show
live "/admin/media/selector", Live.Users.MediaSelector, :index
live "/admin/settings", Live.Settings, :index
live "/admin/settings/users", Live.Settings.Users, :index
live "/admin/modules", Live.Modules, :index
Expand Down
Loading
Loading