From 9ef918a621caf8ca9febdeb00cc067e82ffbfb27 Mon Sep 17 00:00:00 2001 From: Claudio Ortolina Date: Tue, 14 Apr 2026 16:10:57 +0100 Subject: [PATCH] Update record_status_badges with matching_records and dropdown --- .../components/scrobble_components.ex | 110 ++++++++++++++++-- priv/gettext/default.pot | 11 ++ priv/gettext/en/LC_MESSAGES/default.po | 11 ++ 3 files changed, 123 insertions(+), 9 deletions(-) diff --git a/lib/music_library_web/components/scrobble_components.ex b/lib/music_library_web/components/scrobble_components.ex index 5ac722cf..3b040af8 100644 --- a/lib/music_library_web/components/scrobble_components.ex +++ b/lib/music_library_web/components/scrobble_components.ex @@ -8,7 +8,7 @@ defmodule MusicLibraryWeb.ScrobbleComponents do use MusicLibraryWeb, :html - import MusicLibraryWeb.RecordComponents, only: [format_label: 1] + import MusicLibraryWeb.RecordComponents, only: [format_label: 1, type_label: 1] def refresh_scrobbles_button(assigns) do ~H""" @@ -96,26 +96,118 @@ defmodule MusicLibraryWeb.ScrobbleComponents do """ end + attr :id, :string, required: true attr :musicbrainz_id, :string, required: true - attr :collected_record_id, :string, default: nil - attr :wishlisted_record_id, :string, default: nil + attr :matching_records, :list, default: [] def record_status_badges(assigns) do + assigns = + assigns + |> assign(:record_count, length(assigns.matching_records)) + |> assign(:status, badge_status(assigns.matching_records)) + ~H"""
<.badge :if={@musicbrainz_id == ""}> {gettext("No MB ID")} - <.link :if={@collected_record_id} navigate={~p"/collection/#{@collected_record_id}"}> - <.badge color="success">{gettext("Collected")} - - <.link :if={@wishlisted_record_id} navigate={~p"/wishlist/#{@wishlisted_record_id}"}> - <.badge color="warning">{gettext("Wishlisted")} - + + <%= case {@record_count, @status} do %> + <% {0, _} -> %> + <% {1, :collected} -> %> + <.link navigate={~p"/collection/#{hd(@matching_records).id}"}> + <.badge color="success">{gettext("Collected")} + + <% {1, :wishlisted} -> %> + <.link navigate={~p"/wishlist/#{hd(@matching_records).id}"}> + <.badge color="warning">{gettext("Wishlisted")} + + <% {_, status} -> %> + <.dropdown id={@id} placement="bottom-end"> + <:toggle> + <.record_group_badge status={status} count={@record_count} /> + + <.record_dropdown_link + :for={record <- @matching_records} + record={record} + /> + + <% end %>
""" end + attr :status, :atom, required: true, values: [:collected, :wishlisted, :mixed] + attr :count, :integer, required: true + + defp record_group_badge(assigns) do + ~H""" + + {ngettext("1 record", "%{count} records", @count)} + + """ + end + + attr :record, :map, required: true + + defp record_dropdown_link(assigns) do + path = + if assigns.record.purchased_at, + do: ~p"/collection/#{assigns.record.id}", + else: ~p"/wishlist/#{assigns.record.id}" + + assigns = assign(assigns, :path, path) + + ~H""" + <.dropdown_link navigate={@path}> + + <.badge :if={@record.purchased_at} color="success" size="sm"> + {gettext("C")} + + <.badge :if={!@record.purchased_at} color="warning" size="sm"> + {gettext("W")} + + + {format_label(String.to_existing_atom(@record.format))} · {type_label( + String.to_existing_atom(@record.type) + )} + + · {Records.Record.format_as_date(@record.purchased_at)} + + + + + """ + end + + defp badge_status([]), do: nil + + defp badge_status(records) do + all_collected = Enum.all?(records, & &1.purchased_at) + all_wishlisted = Enum.all?(records, &is_nil(&1.purchased_at)) + + cond do + all_collected -> :collected + all_wishlisted -> :wishlisted + true -> :mixed + end + end + + defp badge_classes(:collected), + do: + "bg-emerald-50 text-emerald-700 ring-1 ring-emerald-600/20 dark:bg-emerald-400/10 dark:text-emerald-400 dark:ring-emerald-400/20" + + defp badge_classes(:wishlisted), + do: + "bg-yellow-50 text-yellow-800 ring-1 ring-yellow-600/20 dark:bg-yellow-400/10 dark:text-yellow-500 dark:ring-yellow-400/20" + + defp badge_classes(:mixed), + do: + "bg-yellow-50 text-emerald-700 ring-1 ring-emerald-600/40 dark:bg-yellow-400/10 dark:text-emerald-400 dark:ring-emerald-400/40" + attr :id, :string, required: true attr :musicbrainz_id, :string, required: true diff --git a/priv/gettext/default.pot b/priv/gettext/default.pot index 815fd4a3..20ba0f96 100644 --- a/priv/gettext/default.pot +++ b/priv/gettext/default.pot @@ -331,6 +331,7 @@ msgid "A->Z" msgstr "" #: lib/music_library_web/components/record_components.ex +#: lib/music_library_web/components/scrobble_components.ex #, elixir-autogen, elixir-format msgid "1 record" msgid_plural "%{count} records" @@ -2421,3 +2422,13 @@ msgstr "" #, elixir-autogen, elixir-format msgid "Chat" msgstr "" + +#: lib/music_library_web/components/scrobble_components.ex +#, elixir-autogen, elixir-format +msgid "C" +msgstr "" + +#: lib/music_library_web/components/scrobble_components.ex +#, elixir-autogen, elixir-format +msgid "W" +msgstr "" diff --git a/priv/gettext/en/LC_MESSAGES/default.po b/priv/gettext/en/LC_MESSAGES/default.po index 25ce2a5f..0f80d4ba 100644 --- a/priv/gettext/en/LC_MESSAGES/default.po +++ b/priv/gettext/en/LC_MESSAGES/default.po @@ -331,6 +331,7 @@ msgid "A->Z" msgstr "" #: lib/music_library_web/components/record_components.ex +#: lib/music_library_web/components/scrobble_components.ex #, elixir-autogen, elixir-format msgid "1 record" msgid_plural "%{count} records" @@ -2421,3 +2422,13 @@ msgstr "" #, elixir-autogen, elixir-format msgid "Chat" msgstr "" + +#: lib/music_library_web/components/scrobble_components.ex +#, elixir-autogen, elixir-format, fuzzy +msgid "C" +msgstr "" + +#: lib/music_library_web/components/scrobble_components.ex +#, elixir-autogen, elixir-format +msgid "W" +msgstr ""