diff --git a/lib/music_library/listening_stats.ex b/lib/music_library/listening_stats.ex index 36bd0e40..6e4f7199 100644 --- a/lib/music_library/listening_stats.ex +++ b/lib/music_library/listening_stats.ex @@ -123,12 +123,9 @@ defmodule MusicLibrary.ListeningStats do recent_tracks |> Enum.map(fn %{track: track, artist_id: artist_id, matching_records: matching_records} = rt -> - parsed = parse_matching_records(matching_records) - rt |> Map.put(:track, polyfill_track(track, timezone, artist_id)) - |> Map.put(:matching_records, parsed) - |> derive_legacy_record_ids(parsed) + |> Map.put(:matching_records, parse_matching_records(matching_records)) end) recent_albums = @@ -200,11 +197,7 @@ defmodule MusicLibrary.ListeningStats do from(t in ordered_query, limit: ^page_size, offset: ^offset) |> Repo.all() |> Enum.map(fn result -> - parsed = parse_matching_records(result.matching_records) - - result - |> Map.put(:matching_records, parsed) - |> derive_legacy_record_ids(parsed) + %{result | matching_records: parse_matching_records(result.matching_records)} end) end @@ -624,16 +617,4 @@ defmodule MusicLibrary.ListeningStats do {:ok, dt, _offset} = DateTime.from_iso8601(dt_string) dt end - - # Temporary bridge: derive collected_record_id and wishlisted_record_id from - # matching_records so existing LiveView templates keep working until they are - # migrated to use matching_records directly. - defp derive_legacy_record_ids(result, matching_records) do - collected = Enum.find(matching_records, &(&1.purchased_at != nil)) - wishlisted = Enum.find(matching_records, &is_nil(&1.purchased_at)) - - result - |> Map.put(:collected_record_id, collected && collected.id) - |> Map.put(:wishlisted_record_id, wishlisted && wishlisted.id) - end end diff --git a/lib/music_library_web/live/scrobbled_tracks_live/index.ex b/lib/music_library_web/live/scrobbled_tracks_live/index.ex index 0da5461d..7370dc53 100644 --- a/lib/music_library_web/live/scrobbled_tracks_live/index.ex +++ b/lib/music_library_web/live/scrobbled_tracks_live/index.ex @@ -107,8 +107,7 @@ defmodule MusicLibraryWeb.ScrobbledTracksLive.Index do %{ track: track, artist_id: artist_id, - collected_record_id: collected_record_id, - wishlisted_record_id: wishlisted_record_id, + matching_records: matching_records, cover_hash: cover_hash }} <- @streams.tracks } @@ -147,16 +146,13 @@ defmodule MusicLibraryWeb.ScrobbledTracksLive.Index do
<.record_status_badges + id={"status-#{track.scrobbled_at_uts}"} musicbrainz_id={track.album.musicbrainz_id} - collected_record_id={collected_record_id} - wishlisted_record_id={wishlisted_record_id} + matching_records={matching_records} /> <.import_format_dropdown - :if={ - track.album.musicbrainz_id !== "" and !collected_record_id and - !wishlisted_record_id - } + :if={track.album.musicbrainz_id !== "" and matching_records == []} id={"actions-#{track.scrobbled_at_uts}-tracks"} musicbrainz_id={track.album.musicbrainz_id} /> diff --git a/lib/music_library_web/live/stats_live/index.ex b/lib/music_library_web/live/stats_live/index.ex index 24e13736..f3e399eb 100644 --- a/lib/music_library_web/live/stats_live/index.ex +++ b/lib/music_library_web/live/stats_live/index.ex @@ -266,8 +266,7 @@ defmodule MusicLibraryWeb.StatsLive.Index do %{ album: album, artist_id: artist_id, - collected_record_id: collected_record_id, - wishlisted_record_id: wishlisted_record_id, + matching_records: matching_records, cover_hash: cover_hash }} <- @streams.recent_albums } @@ -316,16 +315,13 @@ defmodule MusicLibraryWeb.StatsLive.Index do
<.record_status_badges + id={"status-#{album.scrobbled_at_uts}-albums"} musicbrainz_id={album.metadata.musicbrainz_id} - collected_record_id={collected_record_id} - wishlisted_record_id={wishlisted_record_id} + matching_records={matching_records} /> <.import_format_dropdown - :if={ - album.metadata.musicbrainz_id !== "" and !collected_record_id and - !wishlisted_record_id - } + :if={album.metadata.musicbrainz_id !== "" and matching_records == []} id={"actions-#{album.scrobbled_at_uts}-albums"} musicbrainz_id={album.metadata.musicbrainz_id} /> @@ -347,8 +343,7 @@ defmodule MusicLibraryWeb.StatsLive.Index do %{ track: track, artist_id: artist_id, - collected_record_id: collected_record_id, - wishlisted_record_id: wishlisted_record_id, + matching_records: matching_records, cover_hash: cover_hash }} <- @streams.recent_tracks } @@ -400,16 +395,13 @@ defmodule MusicLibraryWeb.StatsLive.Index do <.record_status_badges + id={"status-#{track.scrobbled_at_uts}-tracks"} musicbrainz_id={track.album.musicbrainz_id} - collected_record_id={collected_record_id} - wishlisted_record_id={wishlisted_record_id} + matching_records={matching_records} /> <.import_format_dropdown - :if={ - track.album.musicbrainz_id !== "" and !collected_record_id and - !wishlisted_record_id - } + :if={track.album.musicbrainz_id !== "" and matching_records == []} id={"actions-#{track.scrobbled_at_uts}-tracks"} musicbrainz_id={track.album.musicbrainz_id} /> diff --git a/lib/music_library_web/live/stats_live/top_albums.ex b/lib/music_library_web/live/stats_live/top_albums.ex index 668e5484..bc108b40 100644 --- a/lib/music_library_web/live/stats_live/top_albums.ex +++ b/lib/music_library_web/live/stats_live/top_albums.ex @@ -1,8 +1,11 @@ defmodule MusicLibraryWeb.StatsLive.TopAlbums do use MusicLibraryWeb, :html + import MusicLibraryWeb.RecordComponents, only: [format_label: 1, type_label: 1] + alias MusicLibrary.Assets.Transform alias MusicLibrary.ListeningStats + alias MusicLibrary.Records alias MusicLibraryWeb.StatsLive.TopByPeriod attr :id, :string, required: true @@ -25,7 +28,7 @@ defmodule MusicLibraryWeb.StatsLive.TopAlbums do phx-click={navigate_to_record(album)} class={[ "flex items-center space-x-3 p-2", - (album.collected_record_id || album.wishlisted_record_id) && + navigable?(album) && "cursor-pointer hover:bg-zinc-100 dark:hover:bg-zinc-700" ]} > @@ -45,46 +48,121 @@ defmodule MusicLibraryWeb.StatsLive.TopAlbums do {album.album_title}

- <.badge :if={album.album_musicbrainz_id == ""}> - {album.play_count} - - <.badge :if={ - album.album_musicbrainz_id !== "" and !album.collected_record_id and - !album.wishlisted_record_id - }> - {album.play_count} - - <.badge - :if={album.collected_record_id} - color="success" - > - {album.play_count} - - <.badge - :if={album.wishlisted_record_id} - color="warning" - > - {album.play_count} - + <.top_album_badge album={album} /> """ end - defp navigate_to_record(album) do - cond do - album.collected_record_id -> - JS.navigate(~p"/collection/#{album.collected_record_id}") + attr :album, :map, required: true - album.wishlisted_record_id -> - JS.navigate(~p"/wishlist/#{album.wishlisted_record_id}") + defp top_album_badge(assigns) do + assigns = + assigns + |> assign(:status, badge_status(assigns.album.matching_records)) + |> assign(:count, length(assigns.album.matching_records)) - true -> - nil + ~H""" + <%= case {@count, @status} do %> + <% {0, _} -> %> + <.badge>{@album.play_count} + <% {1, :collected} -> %> + <.badge color="success">{@album.play_count} + <% {1, :wishlisted} -> %> + <.badge color="warning">{@album.play_count} + <% {_, status} -> %> + <.dropdown + id={"top-album-#{@album.album_musicbrainz_id}"} + placement="bottom-end" + > + <:toggle> + + {@album.play_count} + + + <.top_album_dropdown_link + :for={record <- @album.matching_records} + record={record} + /> + + <% end %> + """ + end + + attr :record, :map, required: true + + defp top_album_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 navigate_to_record(%{matching_records: [record]}) do + if record.purchased_at do + JS.navigate(~p"/collection/#{record.id}") + else + JS.navigate(~p"/wishlist/#{record.id}") end end + defp navigate_to_record(_album), do: nil + + defp navigable?(%{matching_records: [_]}), do: true + defp navigable?(_), do: false + + 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 play_count_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 play_count_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 play_count_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" + defp cover_url(album) when is_nil(album.cover_hash) do album.cover_url end diff --git a/priv/gettext/default.pot b/priv/gettext/default.pot index 20ba0f96..d12031c8 100644 --- a/priv/gettext/default.pot +++ b/priv/gettext/default.pot @@ -2424,11 +2424,13 @@ msgid "Chat" msgstr "" #: lib/music_library_web/components/scrobble_components.ex +#: lib/music_library_web/live/stats_live/top_albums.ex #, elixir-autogen, elixir-format msgid "C" msgstr "" #: lib/music_library_web/components/scrobble_components.ex +#: lib/music_library_web/live/stats_live/top_albums.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 0f80d4ba..8d59b5c7 100644 --- a/priv/gettext/en/LC_MESSAGES/default.po +++ b/priv/gettext/en/LC_MESSAGES/default.po @@ -2424,11 +2424,13 @@ msgid "Chat" msgstr "" #: lib/music_library_web/components/scrobble_components.ex +#: lib/music_library_web/live/stats_live/top_albums.ex #, elixir-autogen, elixir-format, fuzzy msgid "C" msgstr "" #: lib/music_library_web/components/scrobble_components.ex +#: lib/music_library_web/live/stats_live/top_albums.ex #, elixir-autogen, elixir-format msgid "W" msgstr ""