defmodule MusicLibraryWeb.ScrobbleRulePicker do
@moduledoc false
use MusicLibraryWeb, :live_component
require Logger
alias MusicLibrary.Collection
alias MusicLibrary.Records.Record
alias MusicLibrary.ScrobbleRules
alias MusicLibrary.Wishlist
import MusicLibraryWeb.RecordComponents,
only: [format_label: 1, type_label: 1, release_status_tooltip: 1]
@impl true
def render(assigns) do
~H"""
{gettext("No records found")}
{gettext("Collected")}
<.record_result
:for={record <- @collected_results}
record={record}
myself={@myself}
/>
{gettext("Wishlisted")}
<.record_result
:for={record <- @wishlisted_results}
record={record}
myself={@myself}
/>
"""
end
defp record_result(assigns) do
~H"""
{@record.title}
{Record.artist_names(@record)}
<.release_status_tooltip record={@record} />
{Record.format_release_date(@record.release_date)} · {format_label(@record.format)} · {type_label(
@record.type
)}
<.icon
name="hero-link"
class="size-5 text-zinc-400 hover:text-zinc-600 dark:hover:text-zinc-300"
aria-hidden="true"
data-slot="icon"
/>
"""
end
@impl true
def update(assigns, socket) do
{:ok,
socket
|> assign(assigns)
|> assign_new(:query, fn -> "" end)
|> assign_new(:collected_results, fn -> [] end)
|> assign_new(:wishlisted_results, fn -> [] end)}
end
@impl true
def handle_event("search", %{"query" => query}, socket) do
{collected, wishlisted} =
if String.trim(query) == "" do
{[], []}
else
collected =
query
|> Collection.search_records(limit: 20)
|> Enum.filter(&has_selected_release?/1)
wishlisted =
query
|> Wishlist.search_records(limit: 20)
|> Enum.filter(&has_selected_release?/1)
{collected, wishlisted}
end
{:noreply,
socket
|> assign(:query, query)
|> assign(:collected_results, collected)
|> assign(:wishlisted_results, wishlisted)}
end
@impl true
def handle_event(
"select_record",
%{"record-id" => _record_id, "selected-release-id" => selected_release_id},
socket
) do
album_title = socket.assigns.album_title
case ScrobbleRules.create_scrobble_rule(%{
type: :album,
match_value: album_title,
target_musicbrainz_id: selected_release_id
}) do
{:ok, rule} ->
case ScrobbleRules.apply_rule(rule) do
{:ok, _count} -> :ok
{:error, reason} -> Logger.warning("Failed to apply scrobble rule: #{inspect(reason)}")
end
notify_parent({:rule_created, rule})
put_toast!(:info, gettext("Scrobble rule created"))
{:noreply, socket}
{:error, %Ecto.Changeset{} = changeset} ->
message =
if Keyword.has_key?(changeset.errors, :match_value) do
gettext("A rule for this album already exists")
else
gettext("Could not create scrobble rule")
end
put_toast!(:error, message)
{:noreply, socket}
end
end
defp has_selected_release?(record) do
record.selected_release_id not in [nil, ""]
end
defp notify_parent(msg), do: send(self(), {__MODULE__, msg})
end