Show country flag for artist

This commit is contained in:
Claudio Ortolina
2025-04-29 09:58:06 +01:00
parent 91a00fab94
commit f1dd45e438
10 changed files with 79 additions and 7 deletions
+8 -6
View File
@@ -51,24 +51,20 @@ defmodule MusicLibrary.Artists do
if discogs_id = MusicBrainz.Artist.get_discogs_id(musicbrainz_artist) do if discogs_id = MusicBrainz.Artist.get_discogs_id(musicbrainz_artist) do
case Discogs.get_artist(discogs_id) do case Discogs.get_artist(discogs_id) do
{:ok, discogs_artist} -> {:ok, discogs_artist} ->
%ArtistInfo{} create_artist_info(%{
|> ArtistInfo.changeset(%{
id: musicbrainz_artist.id, id: musicbrainz_artist.id,
musicbrainz_data: musicbrainz_artist.musicbrainz_data, musicbrainz_data: musicbrainz_artist.musicbrainz_data,
discogs_data: discogs_artist discogs_data: discogs_artist
}) })
|> Repo.insert(on_conflict: {:replace, [:musicbrainz_data, :discogs_data]})
error -> error ->
error error
end end
else else
%ArtistInfo{} create_artist_info(%{
|> ArtistInfo.changeset(%{
id: musicbrainz_artist.id, id: musicbrainz_artist.id,
musicbrainz_data: musicbrainz_artist.musicbrainz_data musicbrainz_data: musicbrainz_artist.musicbrainz_data
}) })
|> Repo.insert(on_conflict: {:replace, [:musicbrainz_data, :discogs_data]})
end end
error -> error ->
@@ -76,6 +72,12 @@ defmodule MusicLibrary.Artists do
end end
end end
def create_artist_info(attrs) do
%ArtistInfo{}
|> ArtistInfo.changeset(attrs)
|> Repo.insert(on_conflict: {:replace, [:musicbrainz_data, :discogs_data]})
end
def get_artist_info!(artist_id) do def get_artist_info!(artist_id) do
Repo.get!(ArtistInfo, artist_id) Repo.get!(ArtistInfo, artist_id)
end end
+6
View File
@@ -28,6 +28,12 @@ defmodule MusicLibrary.Records.ArtistInfo do
|> generate_image_hash() |> generate_image_hash()
end end
def country(artist_info) do
%{"area" => area} = artist_info.musicbrainz_data
[country_code | _rest] = area["iso-3166-1-codes"]
%{name: area["name"], code: country_code}
end
def generate_image_hash(%__MODULE__{image_data: image_data} = artist_info) do def generate_image_hash(%__MODULE__{image_data: image_data} = artist_info) do
change(artist_info, image_data_hash: Cover.hash(image_data)) change(artist_info, image_data_hash: Cover.hash(image_data))
end end
@@ -2,8 +2,18 @@ defmodule MusicLibraryWeb.ArtistLive.Show do
use MusicLibraryWeb, :live_view use MusicLibraryWeb, :live_view
alias MusicLibrary.{Artists, Records} alias MusicLibrary.{Artists, Records}
alias MusicLibrary.Records.ArtistInfo
import MusicLibraryWeb.RecordComponents, only: [record_grid: 1] import MusicLibraryWeb.RecordComponents, only: [record_grid: 1]
attr :country, :map, required: true
def country_flag(assigns) do
~H"""
<span>{Flagmojis.by_iso(@country.code).emoji}</span>
<span class="sr-only">{@country.name}</span>
"""
end
@impl true @impl true
def mount(_params, _session, socket) do def mount(_params, _session, socket) do
{:ok, socket} {:ok, socket}
@@ -45,6 +55,7 @@ defmodule MusicLibraryWeb.ArtistLive.Show do
defp apply_action(socket, :show, %{"musicbrainz_id" => musicbrainz_id}) do defp apply_action(socket, :show, %{"musicbrainz_id" => musicbrainz_id}) do
artist = Artists.get_artist!(musicbrainz_id) artist = Artists.get_artist!(musicbrainz_id)
artist_info = Artists.get_artist_info!(musicbrainz_id)
%{collection: collection_records, wishlist: wishlist_records} = %{collection: collection_records, wishlist: wishlist_records} =
musicbrainz_id musicbrainz_id
@@ -54,6 +65,7 @@ defmodule MusicLibraryWeb.ArtistLive.Show do
socket socket
|> assign(:nav_section, :artists) |> assign(:nav_section, :artists)
|> assign(:artist, artist) |> assign(:artist, artist)
|> assign(:country, ArtistInfo.country(artist_info))
|> stream(:collection_records, collection_records, reset: true) |> stream(:collection_records, collection_records, reset: true)
|> stream(:wishlist_records, wishlist_records, reset: true) |> stream(:wishlist_records, wishlist_records, reset: true)
|> assign(:collection_records_count, Enum.count(collection_records)) |> assign(:collection_records_count, Enum.count(collection_records))
@@ -2,6 +2,7 @@
<header class="mt-1 gap-1"> <header class="mt-1 gap-1">
<h1 class="font-semibold text-2xl leading-5 text-zinc-700 dark:text-zinc-300 text-wrap"> <h1 class="font-semibold text-2xl leading-5 text-zinc-700 dark:text-zinc-300 text-wrap">
{@artist.name} {@artist.name}
<.country_flag country={@country} />
</h1> </h1>
<div class="mt-4 flex items-center justify-between"> <div class="mt-4 flex items-center justify-between">
+1
View File
@@ -63,6 +63,7 @@ defmodule MusicLibrary.MixProject do
compile: false, compile: false,
depth: 1}, depth: 1},
{:fluxon, "~> 1.1.0", repo: :fluxon}, {:fluxon, "~> 1.1.0", repo: :fluxon},
{:flagmojis, "~> 1.0"},
# Dev tooling # Dev tooling
{:phoenix_live_reload, "~> 1.2", only: :dev}, {:phoenix_live_reload, "~> 1.2", only: :dev},
+1
View File
@@ -20,6 +20,7 @@
"fast_html": {:hex, :fast_html, "2.4.1", "73142526cee294b0ec8cf122483f32c861e4a9d988c60cd04f63ce7fd9e5a620", [:make, :mix], [{:elixir_make, "~> 0.4", [hex: :elixir_make, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 1.1", [hex: :nimble_pool, repo: "hexpm", optional: false]}], "hexpm", "767a63ecc941d3fc0e0e9609ded1a5e798398e5b1bf4d2f47bcb5992a86b32cf"}, "fast_html": {:hex, :fast_html, "2.4.1", "73142526cee294b0ec8cf122483f32c861e4a9d988c60cd04f63ce7fd9e5a620", [:make, :mix], [{:elixir_make, "~> 0.4", [hex: :elixir_make, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 1.1", [hex: :nimble_pool, repo: "hexpm", optional: false]}], "hexpm", "767a63ecc941d3fc0e0e9609ded1a5e798398e5b1bf4d2f47bcb5992a86b32cf"},
"file_system": {:hex, :file_system, "1.1.0", "08d232062284546c6c34426997dd7ef6ec9f8bbd090eb91780283c9016840e8f", [:mix], [], "hexpm", "bfcf81244f416871f2a2e15c1b515287faa5db9c6bcf290222206d120b3d43f6"}, "file_system": {:hex, :file_system, "1.1.0", "08d232062284546c6c34426997dd7ef6ec9f8bbd090eb91780283c9016840e8f", [:mix], [], "hexpm", "bfcf81244f416871f2a2e15c1b515287faa5db9c6bcf290222206d120b3d43f6"},
"finch": {:hex, :finch, "0.19.0", "c644641491ea854fc5c1bbaef36bfc764e3f08e7185e1f084e35e0672241b76d", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.6.2 or ~> 1.7", [hex: :mint, repo: "hexpm", optional: false]}, {:nimble_options, "~> 0.4 or ~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 1.1", [hex: :nimble_pool, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "fc5324ce209125d1e2fa0fcd2634601c52a787aff1cd33ee833664a5af4ea2b6"}, "finch": {:hex, :finch, "0.19.0", "c644641491ea854fc5c1bbaef36bfc764e3f08e7185e1f084e35e0672241b76d", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.6.2 or ~> 1.7", [hex: :mint, repo: "hexpm", optional: false]}, {:nimble_options, "~> 0.4 or ~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 1.1", [hex: :nimble_pool, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "fc5324ce209125d1e2fa0fcd2634601c52a787aff1cd33ee833664a5af4ea2b6"},
"flagmojis": {:hex, :flagmojis, "1.0.0", "d2b411d9d2c150180103a4d605ee394cabc23c2b6ddf7a0011a9a55a23575281", [:mix], [], "hexpm", "9d9916575cf9dcbe6f0199b410994bec9d19d47971f70089eb7f210f823cd293"},
"floki": {:hex, :floki, "0.37.1", "d7aaee758c8a5b4a7495799a4260754fec5530d95b9c383c03b27359dea117cf", [:mix], [], "hexpm", "673d040cb594d31318d514590246b6dd587ed341d3b67e17c1c0eb8ce7ca6f04"}, "floki": {:hex, :floki, "0.37.1", "d7aaee758c8a5b4a7495799a4260754fec5530d95b9c383c03b27359dea117cf", [:mix], [], "hexpm", "673d040cb594d31318d514590246b6dd587ed341d3b67e17c1c0eb8ce7ca6f04"},
"fluxon": {:hex, :fluxon, "1.1.1", "79195863f5d62362cb296c6fe8c5ec739f0766f90a4e5d2fda7665d492f575b5", [:mix], [{:phoenix_live_view, ">= 1.0.0", [hex: :phoenix_live_view, repo: "hexpm", optional: false]}], "fluxon", "b49d4a8688a32650f90c363fc8f5cedae36d1d4be023b380068bde1a3043b9ce"}, "fluxon": {:hex, :fluxon, "1.1.1", "79195863f5d62362cb296c6fe8c5ec739f0766f90a4e5d2fda7665d492f575b5", [:mix], [{:phoenix_live_view, ">= 1.0.0", [hex: :phoenix_live_view, repo: "hexpm", optional: false]}], "fluxon", "b49d4a8688a32650f90c363fc8f5cedae36d1d4be023b380068bde1a3043b9ce"},
"gettext": {:hex, :gettext, "0.26.2", "5978aa7b21fada6deabf1f6341ddba50bc69c999e812211903b169799208f2a8", [:mix], [{:expo, "~> 0.5.1 or ~> 1.0", [hex: :expo, repo: "hexpm", optional: false]}], "hexpm", "aa978504bcf76511efdc22d580ba08e2279caab1066b76bb9aa81c4a1e0a32a5"}, "gettext": {:hex, :gettext, "0.26.2", "5978aa7b21fada6deabf1f6341ddba50bc69c999e812211903b169799208f2a8", [:mix], [{:expo, "~> 0.5.1 or ~> 1.0", [hex: :expo, repo: "hexpm", optional: false]}], "hexpm", "aa978504bcf76511efdc22d580ba08e2279caab1066b76bb9aa81c4a1e0a32a5"},
@@ -13,7 +13,13 @@ defmodule MusicLibraryWeb.ArtistLive.ShowTest do
[artist] = collection_record.artists [artist] = collection_record.artists
%{collection_record: collection_record, artist_musicbrainz_id: artist.musicbrainz_id} artist_info = artist_info(artist.musicbrainz_id)
%{
collection_record: collection_record,
artist_musicbrainz_id: artist.musicbrainz_id,
artist_info: artist_info
}
end end
describe "Show artist" do describe "Show artist" do
@@ -64,6 +70,27 @@ defmodule MusicLibraryWeb.ArtistLive.ShowTest do
|> assert_has("div", text: "Error loading biography") |> assert_has("div", text: "Error loading biography")
end end
test "it shows the artist country", %{
conn: conn,
artist_musicbrainz_id: artist_musicbrainz_id
} do
Req.Test.stub(LastFm.API, fn conn ->
case Map.get(conn.params, "method") do
"artist.getInfo" ->
Req.Test.json(conn, Fixtures.Artist.get_info())
"artist.getSimilar" ->
Req.Test.json(conn, Fixtures.Artist.get_similar_artists())
end
end)
conn
|> visit(~p"/artists/#{artist_musicbrainz_id}")
|> unwrap(&render_async/1)
|> assert_has("span", text: "United Kingdom")
|> assert_has("span", text: "🇬🇧")
end
test "it shows records from the collection and the wishlist", %{ test "it shows records from the collection and the wishlist", %{
conn: conn, conn: conn,
collection_record: collection_record, collection_record: collection_record,
+7
View File
@@ -6,4 +6,11 @@ defmodule Discogs.Fixtures.Artist do
|> File.read!() |> File.read!()
|> JSON.decode!() |> JSON.decode!()
end end
def image_data do
Path.join([@fixtures_folder, "steven wilson.jpeg"])
|> File.read!()
end
def image_width, do: 225
end end
Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

@@ -75,6 +75,21 @@ defmodule MusicLibrary.Fixtures.Records do
record record
end end
def artist_info(musicbrainz_id, attrs \\ %{}) do
{:ok, artist_info} =
attrs
|> Enum.into(%{
id: musicbrainz_id,
musicbrainz_data: MusicBrainz.Fixtures.Artist.get_artist(),
discogs_data: Discogs.Fixtures.Artist.get_artist(),
image_data: Discogs.Fixtures.Artist.image_data(),
image_width: Discogs.Fixtures.Artist.image_width()
})
|> MusicLibrary.Artists.create_artist_info()
artist_info
end
def record_with_artist(artist_name, record_attrs \\ %{}) do def record_with_artist(artist_name, record_attrs \\ %{}) do
record_attrs record_attrs
|> Map.put(:artists, [artist_attrs(artist_name)]) |> Map.put(:artists, [artist_attrs(artist_name)])