From c67d11da0cc93b95ef52a0e54b7123acec1fc218 Mon Sep 17 00:00:00 2001 From: Claudio Ortolina Date: Sun, 23 Feb 2025 16:56:52 +0000 Subject: [PATCH] Show similar artists in artist page Styling to be defined - only links for now. --- lib/last_fm/api_impl.ex | 2 +- lib/music_library/artists.ex | 15 ++++ .../live/artist_live/show.ex | 5 ++ .../live/artist_live/show.html.heex | 84 +++++++++++++------ priv/gettext/default.pot | 27 ++++-- .../live/artist_live/show_test.exs | 15 ++++ 6 files changed, 116 insertions(+), 32 deletions(-) diff --git a/lib/last_fm/api_impl.ex b/lib/last_fm/api_impl.ex index aea5dbe6..7695b69b 100644 --- a/lib/last_fm/api_impl.ex +++ b/lib/last_fm/api_impl.ex @@ -100,7 +100,7 @@ defmodule LastFm.APIImpl do method: "artist.getSimilar", api_key: config.api_key, format: "json", - limit: 50 + limit: 100 ] options = Keyword.merge(base_options, options) diff --git a/lib/music_library/artists.ex b/lib/music_library/artists.ex index ab6486b6..a620f2a1 100644 --- a/lib/music_library/artists.ex +++ b/lib/music_library/artists.ex @@ -14,6 +14,21 @@ defmodule MusicLibrary.Artists do Repo.one!(q) end + def get_similar_artists(artist) do + case LastFm.get_similar_artists(artist.musicbrainz_id, artist.name) do + {:ok, artists} -> + all_artist_ids = get_all_artist_ids() + + {:ok, + Enum.filter(artists, fn a -> + MapSet.member?(all_artist_ids, a.musicbrainz_id) + end)} + + error -> + error + end + end + def get_all_artist_ids do q = from ar in ArtistRecord, distinct: true, select: ar.musicbrainz_id diff --git a/lib/music_library_web/live/artist_live/show.ex b/lib/music_library_web/live/artist_live/show.ex index 8d888919..663b73da 100644 --- a/lib/music_library_web/live/artist_live/show.ex +++ b/lib/music_library_web/live/artist_live/show.ex @@ -31,6 +31,11 @@ defmodule MusicLibraryWeb.ArtistLive.Show do {:ok, %{artist_info: artist_info}} end end) + |> assign_async(:similar_artists, fn -> + with {:ok, similar_artists} <- Artists.get_similar_artists(artist) do + {:ok, %{similar_artists: similar_artists}} + end + end) |> assign(:page_title, page_title(socket.assigns.live_action, artist))} end diff --git a/lib/music_library_web/live/artist_live/show.html.heex b/lib/music_library_web/live/artist_live/show.html.heex index dce72ec9..2a493ac3 100644 --- a/lib/music_library_web/live/artist_live/show.html.heex +++ b/lib/music_library_web/live/artist_live/show.html.heex @@ -36,31 +36,65 @@ - <.async_result :let={artist_info} assign={@artist_info}> - <:loading> -
- {gettext("Loading biography")} -
- - <:failed :let={_failure}> -
- <.icon - name="hero-exclamation-triangle" - class="-mt-1 mr-1 h-5 w-5" - aria-hidden="true" - data-slot="icon" - /> - {gettext("Error loading biography")} -
- -
- {gettext("Biography")} - {render_bio(@artist_info.result.bio)} -
- +
+ <.async_result :let={artist_info} assign={@artist_info}> + <:loading> +
+ {gettext("Loading biography")} +
+ + <:failed :let={_failure}> +
+ <.icon + name="hero-exclamation-triangle" + class="-mt-1 mr-1 h-5 w-5" + aria-hidden="true" + data-slot="icon" + /> + {gettext("Error loading biography")} +
+ +
+ {gettext("Biography")} + {render_bio(@artist_info.result.bio)} +
+ + + <.async_result :let={similar_artists} assign={@similar_artists}> + <:loading> +
+ {gettext("Loading similar artists")} +
+ + <:failed :let={_failure}> +
+ <.icon + name="hero-exclamation-triangle" + class="-mt-1 mr-1 h-5 w-5" + aria-hidden="true" + data-slot="icon" + /> + {gettext("Error loading similar artists")} +
+ +
+ {gettext("Similar artists")} + <.link + :for={artist <- similar_artists} + class="text-zinc-700 hover:text-zinc-500 dark:text-zinc-400 dark:hover:text-zinc-300" + patch={~p"/artists/#{artist.musicbrainz_id}"} + > + {artist.name} + +
+ +
<.record_grid :if={@collection_records_count > 0} diff --git a/priv/gettext/default.pot b/priv/gettext/default.pot index 47ac46dc..1893759a 100644 --- a/priv/gettext/default.pot +++ b/priv/gettext/default.pot @@ -30,7 +30,7 @@ msgid "Choose a value" msgstr "" #: lib/music_library_web/components/layouts/app.html.heex:14 -#: lib/music_library_web/live/artist_live/show.html.heex:67 +#: lib/music_library_web/live/artist_live/show.html.heex:101 #: lib/music_library_web/live/collection_live/index.ex:157 #: lib/music_library_web/live/collection_live/show.ex:117 #: lib/music_library_web/live/collection_live/show.ex:134 @@ -302,7 +302,7 @@ msgid "Welcome to your Music Library" msgstr "" #: lib/music_library_web/components/layouts/app.html.heex:20 -#: lib/music_library_web/live/artist_live/show.html.heex:76 +#: lib/music_library_web/live/artist_live/show.html.heex:110 #: lib/music_library_web/live/wishlist_live/index.ex:159 #: lib/music_library_web/live/wishlist_live/show.ex:137 #, elixir-autogen, elixir-format @@ -405,7 +405,7 @@ msgstr "" msgid "No MB ID" msgstr "" -#: lib/music_library_web/live/artist_live/show.ex:42 +#: lib/music_library_web/live/artist_live/show.ex:47 #: lib/music_library_web/live/collection_live/show.ex:115 #, elixir-autogen, elixir-format msgid "Details" @@ -436,12 +436,12 @@ msgstr "" msgid "View details" msgstr "" -#: lib/music_library_web/live/artist_live/show.html.heex:60 +#: lib/music_library_web/live/artist_live/show.html.heex:61 #, elixir-autogen, elixir-format msgid "Biography" msgstr "" -#: lib/music_library_web/live/artist_live/show.html.heex:42 +#: lib/music_library_web/live/artist_live/show.html.heex:43 #, elixir-autogen, elixir-format msgid "Loading biography" msgstr "" @@ -486,7 +486,7 @@ msgstr "" msgid "Records" msgstr "" -#: lib/music_library_web/live/artist_live/show.html.heex:53 +#: lib/music_library_web/live/artist_live/show.html.heex:54 #, elixir-autogen, elixir-format msgid "Error loading biography" msgstr "" @@ -671,3 +671,18 @@ msgstr "" #, elixir-autogen, elixir-format msgid "New" msgstr "" + +#: lib/music_library_web/live/artist_live/show.html.heex:80 +#, elixir-autogen, elixir-format +msgid "Error loading similar artists" +msgstr "" + +#: lib/music_library_web/live/artist_live/show.html.heex:69 +#, elixir-autogen, elixir-format +msgid "Loading similar artists" +msgstr "" + +#: lib/music_library_web/live/artist_live/show.html.heex:87 +#, elixir-autogen, elixir-format +msgid "Similar artists" +msgstr "" diff --git a/test/music_library_web/live/artist_live/show_test.exs b/test/music_library_web/live/artist_live/show_test.exs index 0139b24b..ec0c5157 100644 --- a/test/music_library_web/live/artist_live/show_test.exs +++ b/test/music_library_web/live/artist_live/show_test.exs @@ -32,6 +32,11 @@ defmodule MusicLibraryWeb.ArtistLive.ShowTest do {:ok, get_info()} end) + expect(APIMock, :get_similar_artists, fn {:musicbrainz_id, ^artist_musicbrainz_id}, + _config -> + {:ok, []} + end) + conn |> visit(~p"/artists/#{artist_musicbrainz_id}") |> unwrap(&render_async/1) @@ -48,6 +53,11 @@ defmodule MusicLibraryWeb.ArtistLive.ShowTest do {:error, :timeout} end) + expect(APIMock, :get_similar_artists, fn {:musicbrainz_id, ^artist_musicbrainz_id}, + _config -> + {:ok, []} + end) + conn |> visit(~p"/artists/#{artist_musicbrainz_id}") |> unwrap(&render_async/1) @@ -76,6 +86,11 @@ defmodule MusicLibraryWeb.ArtistLive.ShowTest do {:error, :timeout} end) + expect(APIMock, :get_similar_artists, fn {:musicbrainz_id, ^artist_musicbrainz_id}, + _config -> + {:ok, []} + end) + conn |> visit(~p"/artists/#{artist_musicbrainz_id}") |> unwrap(&render_async/1)