diff --git a/lib/last_fm/artist.ex b/lib/last_fm/artist.ex
index d707bcb2..abdca4e9 100644
--- a/lib/last_fm/artist.ex
+++ b/lib/last_fm/artist.ex
@@ -11,7 +11,8 @@ defmodule LastFm.Artist do
image: String.t(),
play_count: non_neg_integer(),
on_tour: boolean(),
- base_url: String.t()
+ base_url: String.t(),
+ image_data_hash: String.t() | nil
}
embedded_schema do
@@ -23,6 +24,7 @@ defmodule LastFm.Artist do
field :play_count, :integer, default: 0
field :on_tour, :boolean, default: false
field :base_url, :string
+ field :image_data_hash, :string
end
def from_api_response(api_response) do
diff --git a/lib/music_library/artists.ex b/lib/music_library/artists.ex
index 5eb4d6a3..cd1cd388 100644
--- a/lib/music_library/artists.ex
+++ b/lib/music_library/artists.ex
@@ -56,6 +56,19 @@ defmodule MusicLibrary.Artists do
q |> Repo.all()
end
+ def get_image_hashes(lastfm_artists) do
+ musicbrainz_ids = Enum.map(lastfm_artists, & &1.musicbrainz_id)
+
+ q =
+ from ai in ArtistInfo,
+ where: ai.id in ^musicbrainz_ids,
+ select: {ai.id, ai.image_data_hash}
+
+ q
+ |> Repo.all()
+ |> Enum.into(%{})
+ end
+
def exists?(artist_id) do
q =
from ar in ArtistRecord,
diff --git a/lib/music_library/search.ex b/lib/music_library/search.ex
index 4e47046e..9f8c8a13 100644
--- a/lib/music_library/search.ex
+++ b/lib/music_library/search.ex
@@ -10,6 +10,7 @@ defmodule MusicLibrary.Search do
import Ecto.Query, warn: false
+ alias MusicLibrary.Artists.ArtistInfo
alias MusicLibrary.Records.ArtistRecord
alias MusicLibrary.{Collection, Repo, Wishlist}
@@ -64,10 +65,12 @@ defmodule MusicLibrary.Search do
q =
from ar in ArtistRecord,
+ join: ai in ArtistInfo,
+ on: ar.musicbrainz_id == ai.id,
where:
fragment("lower(unaccent(artist ->> '$.name')) LIKE ?", ^"%#{normalized_query}%"),
group_by: ar.musicbrainz_id,
- select: ar.artist,
+ select: %{artist: ar.artist, image_data_hash: ai.image_data_hash},
limit: ^limit,
order_by: fragment("artist ->> '$.name'")
diff --git a/lib/music_library_web/components/search_components.ex b/lib/music_library_web/components/search_components.ex
index dc2fb4f7..4583c288 100644
--- a/lib/music_library_web/components/search_components.ex
+++ b/lib/music_library_web/components/search_components.ex
@@ -7,6 +7,7 @@ defmodule MusicLibraryWeb.SearchComponents do
import MusicLibraryWeb.RecordComponents, only: [format_label: 1, type_label: 1, record_cover: 1]
+ alias MusicLibrary.Assets.Transform
alias MusicLibrary.Records.Record
@doc """
@@ -63,6 +64,7 @@ defmodule MusicLibraryWeb.SearchComponents do
<.search_result_artist artist={artist} />
"""
attr :artist, :map, required: true
+ attr :image_data_hash, :string, required: false
attr :rest, :global, include: ~w(phx-click phx-value-id)
def search_result_artist(assigns) do
@@ -78,7 +80,7 @@ defmodule MusicLibraryWeb.SearchComponents do

~p"/images/cover-not-found.png" <> "';"}
/>
@@ -96,6 +98,14 @@ defmodule MusicLibraryWeb.SearchComponents do
"""
end
+ defp artist_image_path(image_data_hash) do
+ payload =
+ %Transform{hash: image_data_hash, width: 96}
+ |> Transform.encode!()
+
+ ~p"/assets/#{payload}"
+ end
+
@doc """
Renders a search result group with a title and items.
diff --git a/lib/music_library_web/live/artist_live/form_component.ex b/lib/music_library_web/live/artist_live/form_component.ex
index e4b85f9a..b6cbc999 100644
--- a/lib/music_library_web/live/artist_live/form_component.ex
+++ b/lib/music_library_web/live/artist_live/form_component.ex
@@ -2,6 +2,7 @@ defmodule MusicLibraryWeb.ArtistLive.FormComponent do
use MusicLibraryWeb, :live_component
alias MusicLibrary.Artists
+ alias MusicLibrary.Assets.Transform
alias Vix.Vips.Image
@impl true
@@ -46,7 +47,7 @@ defmodule MusicLibraryWeb.ArtistLive.FormComponent do
:if={@uploads.image_data.entries == []}
class="rounded-lg mx-auto w-full"
alt={@artist.name}
- src={~p"/artists/#{@artist_info.id}/image?vsn=#{@artist_info.image_data_hash || ""}"}
+ src={artist_image_path(@artist_info)}
/>
<.live_img_preview
:for={entry <- @uploads.image_data.entries}
@@ -154,4 +155,12 @@ defmodule MusicLibraryWeb.ArtistLive.FormComponent do
end
defp notify_parent(msg), do: send(self(), {__MODULE__, msg})
+
+ defp artist_image_path(artist_info) do
+ payload =
+ %Transform{hash: artist_info.image_hash, width: 96}
+ |> Transform.encode!()
+
+ ~p"/assets/#{payload}"
+ end
end
diff --git a/lib/music_library_web/live/artist_live/show.ex b/lib/music_library_web/live/artist_live/show.ex
index 9fc57504..4d890914 100644
--- a/lib/music_library_web/live/artist_live/show.ex
+++ b/lib/music_library_web/live/artist_live/show.ex
@@ -6,6 +6,7 @@ defmodule MusicLibraryWeb.ArtistLive.Show do
alias MusicLibrary.Artists.ArtistInfo
alias MusicLibrary.{Artists, Records}
+ alias(MusicLibrary.Assets.Transform)
attr :country, :map, required: true
@@ -63,7 +64,7 @@ defmodule MusicLibraryWeb.ArtistLive.Show do

~p"/images/cover-not-found.png" <> "';"}
@@ -212,6 +213,13 @@ defmodule MusicLibraryWeb.ArtistLive.Show do
end)
|> assign_async(:similar_artists, fn ->
with {:ok, similar_artists} <- Artists.get_similar_artists(artist) do
+ artist_image_hashes = Artists.get_image_hashes(similar_artists)
+
+ similar_artists =
+ Enum.map(similar_artists, fn artist ->
+ %{artist | image_data_hash: Map.get(artist_image_hashes, artist.musicbrainz_id)}
+ end)
+
{:ok, %{similar_artists: similar_artists}}
end
end)
@@ -354,4 +362,20 @@ defmodule MusicLibraryWeb.ArtistLive.Show do
attributes: [class: "mt-2 text-sm/7"]
)
end
+
+ defp artist_image_path(artist_info) do
+ payload =
+ %Transform{hash: artist_info.image_data_hash}
+ |> Transform.encode!()
+
+ ~p"/assets/#{payload}"
+ end
+
+ defp artist_thumb_path(artist_info) do
+ payload =
+ %Transform{hash: artist_info.image_data_hash, width: 300}
+ |> Transform.encode!()
+
+ ~p"/assets/#{payload}"
+ end
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 5048799b..a5f592e0 100644
--- a/lib/music_library_web/live/artist_live/show.html.heex
+++ b/lib/music_library_web/live/artist_live/show.html.heex
@@ -106,7 +106,7 @@

~p"/images/cover-not-found.png" <> "';"}
/>
diff --git a/lib/music_library_web/live/universal_search_live/index.html.heex b/lib/music_library_web/live/universal_search_live/index.html.heex
index 7774daba..27ed5089 100644
--- a/lib/music_library_web/live/universal_search_live/index.html.heex
+++ b/lib/music_library_web/live/universal_search_live/index.html.heex
@@ -91,8 +91,9 @@
class="border-t border-zinc-200 dark:border-zinc-700"
>
<.search_result_artist
- :for={artist <- @search_results.artists}
+ :for={%{artist: artist, image_data_hash: image_data_hash} <- @search_results.artists}
artist={artist}
+ image_data_hash={image_data_hash}
phx-click="navigate_to_artist"
phx-value-id={artist.musicbrainz_id}
/>
diff --git a/lib/music_library_web/router.ex b/lib/music_library_web/router.ex
index f8c3d4b2..390543c5 100644
--- a/lib/music_library_web/router.ex
+++ b/lib/music_library_web/router.ex
@@ -37,7 +37,6 @@ defmodule MusicLibraryWeb.Router do
get "/backup", ArchiveController, :backup
get "/assets/:transform_payload", AssetController, :show
- get "/artists/:musicbrainz_id/image", ArtistController, :image
live_session :default,
on_mount: [MusicLibraryWeb.Hooks.StaticAssets, MusicLibraryWeb.Hooks.GetTimezone] do