diff --git a/lib/music_library/chats.ex b/lib/music_library/chats.ex
index 2cb3224c..c3eb68cd 100644
--- a/lib/music_library/chats.ex
+++ b/lib/music_library/chats.ex
@@ -25,6 +25,14 @@ defmodule MusicLibrary.Chats do
|> Repo.all()
end
+ @spec count_chats(atom(), String.t()) :: non_neg_integer()
+ def count_chats(entity, musicbrainz_id) do
+ from(c in Chat,
+ where: c.entity == ^entity and c.musicbrainz_id == ^musicbrainz_id
+ )
+ |> Repo.aggregate(:count)
+ end
+
@spec has_any_chats?(atom(), String.t()) :: boolean()
def has_any_chats?(entity, musicbrainz_id) do
from(c in Chat,
diff --git a/lib/music_library_web/components/chat.ex b/lib/music_library_web/components/chat.ex
index d1e758fc..6dd1b3ee 100644
--- a/lib/music_library_web/components/chat.ex
+++ b/lib/music_library_web/components/chat.ex
@@ -336,6 +336,7 @@ defmodule MusicLibraryWeb.Components.Chat do
def handle_event("delete_chat", %{"id" => id}, socket) do
chat = Chats.get_chat!(id)
{:ok, _} = Chats.delete_chat(chat)
+ send(self(), {__MODULE__, :chats_changed})
chats = Chats.list_chats(socket.assigns.entity, socket.assigns.musicbrainz_id)
@@ -418,6 +419,7 @@ defmodule MusicLibraryWeb.Components.Chat do
%{role: user_message.role, content: user_message.content}
)
+ send(self(), {__MODULE__, :chats_changed})
chat
chat ->
diff --git a/lib/music_library_web/live/artist_live/show.ex b/lib/music_library_web/live/artist_live/show.ex
index 4c96c630..88c4e4ed 100644
--- a/lib/music_library_web/live/artist_live/show.ex
+++ b/lib/music_library_web/live/artist_live/show.ex
@@ -4,7 +4,7 @@ defmodule MusicLibraryWeb.ArtistLive.Show do
import MusicLibraryWeb.RecordComponents,
only: [record_grid: 1, country_label: 1, artist_image: 1]
- alias MusicLibrary.{Artists, Records}
+ alias MusicLibrary.{Artists, Chats, Records}
alias MusicLibrary.Artists.ArtistInfo
alias MusicLibraryWeb.ErrorMessages
@@ -120,6 +120,7 @@ defmodule MusicLibraryWeb.ArtistLive.Show do
aria-hidden="true"
data-slot="icon"
/>
+ 0} class="text-xs font-medium">{@chat_count}
<.button
variant="soft"
@@ -646,6 +647,16 @@ defmodule MusicLibraryWeb.ArtistLive.Show do
|> put_toast(:info, gettext("Record deleted"))}
end
+ @impl true
+ def handle_info({MusicLibraryWeb.Components.Chat, :chats_changed}, socket) do
+ {:noreply,
+ assign(
+ socket,
+ :chat_count,
+ Chats.count_chats(:artist, socket.assigns.artist.musicbrainz_id)
+ )}
+ end
+
defp apply_action(socket, :show, %{"musicbrainz_id" => musicbrainz_id}) do
artist = Artists.get_artist!(musicbrainz_id)
artist_info = Artists.get_artist_info!(musicbrainz_id)
@@ -655,6 +666,7 @@ defmodule MusicLibraryWeb.ArtistLive.Show do
|> assign(:current_section, :artists)
|> assign(:artist, artist)
|> assign(:artist_info, artist_info)
+ |> assign(:chat_count, Chats.count_chats(:artist, musicbrainz_id))
|> assign(:biography, build_biography(artist_info))
|> assign(:external_links, ArtistInfo.external_links(artist_info))
|> assign(:country, ArtistInfo.country(artist_info))
diff --git a/lib/music_library_web/live/collection_live/show.ex b/lib/music_library_web/live/collection_live/show.ex
index 8742ba59..33bbffef 100644
--- a/lib/music_library_web/live/collection_live/show.ex
+++ b/lib/music_library_web/live/collection_live/show.ex
@@ -20,7 +20,7 @@ defmodule MusicLibraryWeb.CollectionLive.Show do
release_summary: 1
]
- alias MusicLibrary.{ListeningStats, Records, RecordSets, ScrobbleActivity}
+ alias MusicLibrary.{Chats, ListeningStats, Records, RecordSets, ScrobbleActivity}
alias MusicLibrary.Records.Similarity
alias MusicLibraryWeb.ErrorMessages
alias Phoenix.LiveView.JS
@@ -70,6 +70,7 @@ defmodule MusicLibraryWeb.CollectionLive.Show do
aria-hidden="true"
data-slot="icon"
/>
+ 0} class="text-xs font-medium">{@chat_count}
<.button
:if={@record.selected_release_id}
@@ -354,6 +355,7 @@ defmodule MusicLibraryWeb.CollectionLive.Show do
|> assign(:last_listened_track, last_listened_track)
|> assign(:play_count, play_count)
|> assign(:record_sets, record_sets)
+ |> assign(:chat_count, Chats.count_chats(:record, record.musicbrainz_id))
|> assign_embedding_text()
|> assign_similar_records()}
end
@@ -511,6 +513,11 @@ defmodule MusicLibraryWeb.CollectionLive.Show do
|> assign_embedding_text()}
end
+ def handle_info({MusicLibraryWeb.Components.Chat, :chats_changed}, socket) do
+ {:noreply,
+ assign(socket, :chat_count, Chats.count_chats(:record, socket.assigns.record.musicbrainz_id))}
+ end
+
@impl true
def handle_info({:update, record}, socket) do
{:noreply,
diff --git a/lib/music_library_web/live/wishlist_live/show.ex b/lib/music_library_web/live/wishlist_live/show.ex
index 9bb0e13b..7f952ec2 100644
--- a/lib/music_library_web/live/wishlist_live/show.ex
+++ b/lib/music_library_web/live/wishlist_live/show.ex
@@ -16,6 +16,7 @@ defmodule MusicLibraryWeb.WishlistLive.Show do
release_summary: 1
]
+ alias MusicLibrary.Chats
alias MusicLibrary.OnlineStoreTemplates
alias MusicLibrary.{Records, RecordSets}
alias MusicLibrary.Records.Similarity
@@ -51,6 +52,7 @@ defmodule MusicLibraryWeb.WishlistLive.Show do
aria-hidden="true"
data-slot="icon"
/>
+ 0} class="text-xs font-medium">{@chat_count}
<.dropdown id={"actions-#{@record.id}"} placement="bottom-end">
<:toggle>
@@ -304,6 +306,7 @@ defmodule MusicLibraryWeb.WishlistLive.Show do
|> assign(:record, record)
|> assign(:online_store_templates, online_store_templates)
|> assign(:record_sets, record_sets)
+ |> assign(:chat_count, Chats.count_chats(:record, record.musicbrainz_id))
|> assign_embedding_text()}
end
@@ -418,6 +421,11 @@ defmodule MusicLibraryWeb.WishlistLive.Show do
|> assign_embedding_text()}
end
+ def handle_info({MusicLibraryWeb.Components.Chat, :chats_changed}, socket) do
+ {:noreply,
+ assign(socket, :chat_count, Chats.count_chats(:record, socket.assigns.record.musicbrainz_id))}
+ end
+
@impl true
def handle_info({:update, record}, socket) do
{:noreply,
diff --git a/test/music_library/chats_test.exs b/test/music_library/chats_test.exs
index f9159f00..01117f96 100644
--- a/test/music_library/chats_test.exs
+++ b/test/music_library/chats_test.exs
@@ -16,6 +16,35 @@ defmodule MusicLibrary.ChatsTest do
%{chat: chat}
end
+ describe "count_chats/2" do
+ test "returns 0 when no chats exist" do
+ assert Chats.count_chats(:record, Ecto.UUID.generate()) == 0
+ end
+
+ test "returns the number of chats for an entity" do
+ Chats.create_chat_with_message(
+ %{entity: :record, musicbrainz_id: @musicbrainz_id},
+ %{role: "user", content: "First chat"}
+ )
+
+ Chats.create_chat_with_message(
+ %{entity: :record, musicbrainz_id: @musicbrainz_id},
+ %{role: "user", content: "Second chat"}
+ )
+
+ assert Chats.count_chats(:record, @musicbrainz_id) == 2
+ end
+
+ test "does not count chats for different entity" do
+ Chats.create_chat_with_message(
+ %{entity: :record, musicbrainz_id: @musicbrainz_id},
+ %{role: "user", content: "A chat"}
+ )
+
+ assert Chats.count_chats(:artist, @musicbrainz_id) == 0
+ end
+ end
+
describe "list_chats/2" do
setup [:create_chat]