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("Create Scrobble Rule")}

{gettext("Search your records to map \"%{album_title}\" to a release.", album_title: @album_title )}

<.input type="search" size="sm" id="rule-picker-search-input" name={:query} value={@query} placeholder={gettext("Search")} phx-debounce="500" autocomplete="off" autofocus />

{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