diff --git a/lib/music_library_web/live/collection_live/show.ex b/lib/music_library_web/live/collection_live/show.ex index 28f1a7b6..a348c356 100644 --- a/lib/music_library_web/live/collection_live/show.ex +++ b/lib/music_library_web/live/collection_live/show.ex @@ -23,6 +23,7 @@ defmodule MusicLibraryWeb.CollectionLive.Show do alias MusicLibrary.{Chats, ListeningStats, Records, RecordSets, ScrobbleActivity} alias MusicLibrary.Records.Similarity alias MusicLibraryWeb.ErrorMessages + alias MusicLibraryWeb.LiveHelpers.RecordActions alias Phoenix.LiveView.JS alias MusicBrainz @@ -356,7 +357,7 @@ defmodule MusicLibraryWeb.CollectionLive.Show do |> assign(:play_count, play_count) |> assign(:record_sets, record_sets) |> assign(:chat_count, Chats.count_chats(:record, record.musicbrainz_id)) - |> assign_embedding_text() + |> RecordActions.assign_embedding_text() |> assign_similar_records()} end @@ -368,83 +369,19 @@ defmodule MusicLibraryWeb.CollectionLive.Show do end def handle_event("refresh_musicbrainz_data", _params, socket) do - record = socket.assigns.record - - case Records.refresh_musicbrainz_data(record) do - {:ok, updated_record} -> - {:noreply, - socket - |> put_toast(:info, gettext("MusicBrainz data refreshed successfully")) - |> assign(:record, updated_record)} - - {:error, reason} -> - {:noreply, - socket - |> put_toast( - :error, - gettext("Error refreshing MusicBrainz data") <> - ": " <> ErrorMessages.friendly_message(reason) - )} - end + RecordActions.refresh_musicbrainz_data(socket) end def handle_event("populate_genres", _params, socket) do - record = socket.assigns.record - - case Records.populate_genres_async(record) do - {:ok, _worker} -> - {:noreply, - socket - |> put_toast(:info, gettext("In progress - record will update automatically"))} - - {:error, reason} -> - {:noreply, - socket - |> put_toast( - :error, - gettext("Error") <> ": " <> ErrorMessages.friendly_message(reason) - )} - end + RecordActions.populate_genres(socket) end def handle_event("refresh_cover", _params, socket) do - record = socket.assigns.record - - case Records.refresh_cover(record) do - {:ok, record} -> - {:noreply, - socket - |> assign(:record, record) - |> put_toast(:info, gettext("Cover refreshed successfully"))} - - {:error, reason} -> - {:noreply, - socket - |> put_toast( - :error, - gettext("Error refreshing cover") <> ": " <> ErrorMessages.friendly_message(reason) - )} - end + RecordActions.refresh_cover(socket) end def handle_event("extract_colors", _params, socket) do - record = socket.assigns.record - - case Records.extract_colors(record) do - {:ok, updated_record} -> - {:noreply, - socket - |> assign(:record, updated_record) - |> put_toast(:info, gettext("Colors extracted"))} - - {:error, reason} -> - {:noreply, - socket - |> put_toast( - :error, - gettext("Error extracting colors") <> ": " <> ErrorMessages.friendly_message(reason) - )} - end + RecordActions.extract_colors(socket) end def handle_event("regenerate_embeddings", _params, socket) do @@ -510,22 +447,19 @@ defmodule MusicLibraryWeb.CollectionLive.Show do socket |> assign(:record, record) |> assign_similar_records() - |> assign_embedding_text()} + |> RecordActions.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))} + RecordActions.handle_chats_changed(socket) end @impl true def handle_info({:update, record}, socket) do {:noreply, socket - |> put_toast(:info, gettext("Record updated in the background")) - |> assign(:record, record) - |> assign_similar_records() - |> assign_embedding_text()} + |> RecordActions.handle_record_updated(record) + |> assign_similar_records()} end defp page_title(action, record) do @@ -598,14 +532,4 @@ defmodule MusicLibraryWeb.CollectionLive.Show do assign(socket, :similar_records, similar_records) end - - defp assign_embedding_text(socket) do - case Similarity.get_embedding_text(socket.assigns.record.id) do - {:ok, text} -> - assign(socket, :embedding_text, text) - - {:error, _reason} -> - assign(socket, :embedding_text, gettext("Not available")) - end - end end diff --git a/lib/music_library_web/live/wishlist_live/show.ex b/lib/music_library_web/live/wishlist_live/show.ex index 8bccd9a5..6aadc04f 100644 --- a/lib/music_library_web/live/wishlist_live/show.ex +++ b/lib/music_library_web/live/wishlist_live/show.ex @@ -19,8 +19,7 @@ defmodule MusicLibraryWeb.WishlistLive.Show do alias MusicLibrary.Chats alias MusicLibrary.OnlineStoreTemplates alias MusicLibrary.{Records, RecordSets} - alias MusicLibrary.Records.Similarity - alias MusicLibraryWeb.ErrorMessages + alias MusicLibraryWeb.LiveHelpers.RecordActions @impl true def render(assigns) do @@ -307,7 +306,7 @@ defmodule MusicLibraryWeb.WishlistLive.Show do |> 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()} + |> RecordActions.assign_embedding_text()} end @impl true @@ -318,63 +317,15 @@ defmodule MusicLibraryWeb.WishlistLive.Show do end def handle_event("refresh_musicbrainz_data", _params, socket) do - record = socket.assigns.record - - case Records.refresh_musicbrainz_data(record) do - {:ok, updated_record} -> - {:noreply, - socket - |> put_toast(:info, gettext("MusicBrainz data refreshed successfully")) - |> assign(:record, updated_record)} - - {:error, reason} -> - {:noreply, - socket - |> put_toast( - :error, - gettext("Error refreshing MusicBrainz data") <> - ": " <> ErrorMessages.friendly_message(reason) - )} - end + RecordActions.refresh_musicbrainz_data(socket) end def handle_event("refresh_cover", _params, socket) do - record = socket.assigns.record - - case Records.refresh_cover(record) do - {:ok, updated_record} -> - {:noreply, - socket - |> put_toast(:info, gettext("Cover refreshed successfully")) - |> assign(:record, updated_record)} - - {:error, reason} -> - {:noreply, - socket - |> put_toast( - :error, - gettext("Error refreshing cover") <> ": " <> ErrorMessages.friendly_message(reason) - )} - end + RecordActions.refresh_cover(socket) end def handle_event("populate_genres", _params, socket) do - record = socket.assigns.record - - case Records.populate_genres_async(record) do - {:ok, _worker} -> - {:noreply, - socket - |> put_toast(:info, gettext("In progress - record will update automatically"))} - - {:error, reason} -> - {:noreply, - socket - |> put_toast( - :error, - gettext("Error") <> ": " <> ErrorMessages.friendly_message(reason) - )} - end + RecordActions.populate_genres(socket) end def handle_event("add-to-collection", _params, socket) do @@ -394,23 +345,7 @@ defmodule MusicLibraryWeb.WishlistLive.Show do end def handle_event("extract_colors", _params, socket) do - record = socket.assigns.record - - case Records.extract_colors(record) do - {:ok, updated_record} -> - {:noreply, - socket - |> assign(:record, updated_record) - |> put_toast(:info, gettext("Colors extracted"))} - - {:error, reason} -> - {:noreply, - socket - |> put_toast( - :error, - gettext("Error extracting colors") <> ": " <> ErrorMessages.friendly_message(reason) - )} - end + RecordActions.extract_colors(socket) end @impl true @@ -418,21 +353,16 @@ defmodule MusicLibraryWeb.WishlistLive.Show do {:noreply, socket |> assign(:record, record) - |> assign_embedding_text()} + |> RecordActions.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))} + RecordActions.handle_chats_changed(socket) end @impl true def handle_info({:update, record}, socket) do - {:noreply, - socket - |> put_toast(:info, gettext("Record updated in the background")) - |> assign(:record, record) - |> assign_embedding_text()} + {:noreply, RecordActions.handle_record_updated(socket, record)} end defp page_title(action, record) do @@ -452,11 +382,4 @@ defmodule MusicLibraryWeb.WishlistLive.Show do defp title_segment(:show), do: gettext("Details") defp title_segment(:edit), do: gettext("Edit") - - defp assign_embedding_text(socket) do - case Similarity.get_embedding_text(socket.assigns.record.id) do - {:ok, text} -> assign(socket, :embedding_text, text) - {:error, _reason} -> assign(socket, :embedding_text, gettext("Not available")) - end - end end diff --git a/lib/music_library_web/live_helpers/record_actions.ex b/lib/music_library_web/live_helpers/record_actions.ex new file mode 100644 index 00000000..ce66f19d --- /dev/null +++ b/lib/music_library_web/live_helpers/record_actions.ex @@ -0,0 +1,122 @@ +defmodule MusicLibraryWeb.LiveHelpers.RecordActions do + @moduledoc """ + Shared record action handlers for CollectionLive.Show and WishlistLive.Show. + + Each function takes a socket (with a `:record` assign), performs the + operation, and returns `{:noreply, socket}` — ready to be returned + directly from a `handle_event/3` callback. + """ + + import LiveToast, only: [put_toast: 3] + import Phoenix.Component, only: [assign: 3] + + use Gettext, backend: MusicLibraryWeb.Gettext + + alias MusicLibrary.Chats + alias MusicLibrary.Records + alias MusicLibrary.Records.Similarity + alias MusicLibraryWeb.ErrorMessages + + def refresh_musicbrainz_data(socket) do + record = socket.assigns.record + + case Records.refresh_musicbrainz_data(record) do + {:ok, updated_record} -> + {:noreply, + socket + |> put_toast(:info, gettext("MusicBrainz data refreshed successfully")) + |> assign(:record, updated_record)} + + {:error, reason} -> + {:noreply, + socket + |> put_toast( + :error, + gettext("Error refreshing MusicBrainz data") <> + ": " <> ErrorMessages.friendly_message(reason) + )} + end + end + + def refresh_cover(socket) do + record = socket.assigns.record + + case Records.refresh_cover(record) do + {:ok, updated_record} -> + {:noreply, + socket + |> put_toast(:info, gettext("Cover refreshed successfully")) + |> assign(:record, updated_record)} + + {:error, reason} -> + {:noreply, + socket + |> put_toast( + :error, + gettext("Error refreshing cover") <> ": " <> ErrorMessages.friendly_message(reason) + )} + end + end + + def populate_genres(socket) do + record = socket.assigns.record + + case Records.populate_genres_async(record) do + {:ok, _worker} -> + {:noreply, + socket + |> put_toast(:info, gettext("In progress - record will update automatically"))} + + {:error, reason} -> + {:noreply, + socket + |> put_toast( + :error, + gettext("Error") <> ": " <> ErrorMessages.friendly_message(reason) + )} + end + end + + def extract_colors(socket) do + record = socket.assigns.record + + case Records.extract_colors(record) do + {:ok, updated_record} -> + {:noreply, + socket + |> assign(:record, updated_record) + |> put_toast(:info, gettext("Colors extracted"))} + + {:error, reason} -> + {:noreply, + socket + |> put_toast( + :error, + gettext("Error extracting colors") <> ": " <> ErrorMessages.friendly_message(reason) + )} + end + end + + def handle_chats_changed(socket) do + {:noreply, + assign(socket, :chat_count, Chats.count_chats(:record, socket.assigns.record.musicbrainz_id))} + end + + @doc """ + Handles a background record update. Returns the updated socket (not wrapped + in `{:noreply, ...}`) so the caller can pipe additional assigns. + """ + def handle_record_updated(socket, record) do + socket + |> put_toast(:info, gettext("Record updated in the background")) + |> assign(:record, record) + |> assign_embedding_text() + end + + def assign_embedding_text(socket) do + case Similarity.get_embedding_text(socket.assigns.record.id) do + {:ok, text} -> assign(socket, :embedding_text, text) + {:error, _reason} -> assign(socket, :embedding_text, gettext("Not available")) + end + end +end diff --git a/priv/gettext/default.pot b/priv/gettext/default.pot index 0ba488b0..635e026d 100644 --- a/priv/gettext/default.pot +++ b/priv/gettext/default.pot @@ -252,14 +252,12 @@ msgstr "" msgid "Includes" msgstr "" -#: lib/music_library_web/live/collection_live/show.ex -#: lib/music_library_web/live/wishlist_live/show.ex +#: lib/music_library_web/live_helpers/record_actions.ex #, elixir-autogen, elixir-format msgid "Error refreshing MusicBrainz data" msgstr "" -#: lib/music_library_web/live/collection_live/show.ex -#: lib/music_library_web/live/wishlist_live/show.ex +#: lib/music_library_web/live_helpers/record_actions.ex #, elixir-autogen, elixir-format msgid "MusicBrainz data refreshed successfully" msgstr "" @@ -269,14 +267,12 @@ msgstr "" msgid "Refresh LastFm Feed" msgstr "" -#: lib/music_library_web/live/collection_live/show.ex -#: lib/music_library_web/live/wishlist_live/show.ex +#: lib/music_library_web/live_helpers/record_actions.ex #, elixir-autogen, elixir-format msgid "Cover refreshed successfully" msgstr "" -#: lib/music_library_web/live/collection_live/show.ex -#: lib/music_library_web/live/wishlist_live/show.ex +#: lib/music_library_web/live_helpers/record_actions.ex #, elixir-autogen, elixir-format msgid "Error refreshing cover" msgstr "" @@ -611,8 +607,7 @@ msgstr "" msgid "Meta" msgstr "" -#: lib/music_library_web/live/collection_live/show.ex -#: lib/music_library_web/live/wishlist_live/show.ex +#: lib/music_library_web/live_helpers/record_actions.ex #, elixir-autogen, elixir-format msgid "Record updated in the background" msgstr "" @@ -807,13 +802,13 @@ msgid "Last listened at" msgstr "" #: lib/music_library_web/live/collection_live/show.ex -#: lib/music_library_web/live/wishlist_live/show.ex +#: lib/music_library_web/live_helpers/record_actions.ex #, elixir-autogen, elixir-format msgid "Error" msgstr "" #: lib/music_library_web/live/collection_live/show.ex -#: lib/music_library_web/live/wishlist_live/show.ex +#: lib/music_library_web/live_helpers/record_actions.ex #, elixir-autogen, elixir-format msgid "In progress - record will update automatically" msgstr "" @@ -1553,8 +1548,7 @@ msgstr "" msgid "Running optimize..." msgstr "" -#: lib/music_library_web/live/collection_live/show.ex -#: lib/music_library_web/live/wishlist_live/show.ex +#: lib/music_library_web/live_helpers/record_actions.ex #, elixir-autogen, elixir-format msgid "Not available" msgstr "" @@ -1998,14 +1992,12 @@ msgstr "" msgid "Failed to store cover image" msgstr "" -#: lib/music_library_web/live/collection_live/show.ex -#: lib/music_library_web/live/wishlist_live/show.ex +#: lib/music_library_web/live_helpers/record_actions.ex #, elixir-autogen, elixir-format msgid "Colors extracted" msgstr "" -#: lib/music_library_web/live/collection_live/show.ex -#: lib/music_library_web/live/wishlist_live/show.ex +#: lib/music_library_web/live_helpers/record_actions.ex #, elixir-autogen, elixir-format msgid "Error extracting colors" msgstr "" diff --git a/priv/gettext/en/LC_MESSAGES/default.po b/priv/gettext/en/LC_MESSAGES/default.po index 297217fd..0f0ee26a 100644 --- a/priv/gettext/en/LC_MESSAGES/default.po +++ b/priv/gettext/en/LC_MESSAGES/default.po @@ -252,14 +252,12 @@ msgstr "" msgid "Includes" msgstr "" -#: lib/music_library_web/live/collection_live/show.ex -#: lib/music_library_web/live/wishlist_live/show.ex +#: lib/music_library_web/live_helpers/record_actions.ex #, elixir-autogen, elixir-format msgid "Error refreshing MusicBrainz data" msgstr "" -#: lib/music_library_web/live/collection_live/show.ex -#: lib/music_library_web/live/wishlist_live/show.ex +#: lib/music_library_web/live_helpers/record_actions.ex #, elixir-autogen, elixir-format msgid "MusicBrainz data refreshed successfully" msgstr "" @@ -269,14 +267,12 @@ msgstr "" msgid "Refresh LastFm Feed" msgstr "" -#: lib/music_library_web/live/collection_live/show.ex -#: lib/music_library_web/live/wishlist_live/show.ex +#: lib/music_library_web/live_helpers/record_actions.ex #, elixir-autogen, elixir-format msgid "Cover refreshed successfully" msgstr "" -#: lib/music_library_web/live/collection_live/show.ex -#: lib/music_library_web/live/wishlist_live/show.ex +#: lib/music_library_web/live_helpers/record_actions.ex #, elixir-autogen, elixir-format msgid "Error refreshing cover" msgstr "" @@ -611,8 +607,7 @@ msgstr "" msgid "Meta" msgstr "" -#: lib/music_library_web/live/collection_live/show.ex -#: lib/music_library_web/live/wishlist_live/show.ex +#: lib/music_library_web/live_helpers/record_actions.ex #, elixir-autogen, elixir-format msgid "Record updated in the background" msgstr "" @@ -807,13 +802,13 @@ msgid "Last listened at" msgstr "" #: lib/music_library_web/live/collection_live/show.ex -#: lib/music_library_web/live/wishlist_live/show.ex +#: lib/music_library_web/live_helpers/record_actions.ex #, elixir-autogen, elixir-format, fuzzy msgid "Error" msgstr "" #: lib/music_library_web/live/collection_live/show.ex -#: lib/music_library_web/live/wishlist_live/show.ex +#: lib/music_library_web/live_helpers/record_actions.ex #, elixir-autogen, elixir-format msgid "In progress - record will update automatically" msgstr "" @@ -1553,8 +1548,7 @@ msgstr "" msgid "Running optimize..." msgstr "" -#: lib/music_library_web/live/collection_live/show.ex -#: lib/music_library_web/live/wishlist_live/show.ex +#: lib/music_library_web/live_helpers/record_actions.ex #, elixir-autogen, elixir-format, fuzzy msgid "Not available" msgstr "" @@ -1998,14 +1992,12 @@ msgstr "" msgid "Failed to store cover image" msgstr "" -#: lib/music_library_web/live/collection_live/show.ex -#: lib/music_library_web/live/wishlist_live/show.ex +#: lib/music_library_web/live_helpers/record_actions.ex #, elixir-autogen, elixir-format msgid "Colors extracted" msgstr "" -#: lib/music_library_web/live/collection_live/show.ex -#: lib/music_library_web/live/wishlist_live/show.ex +#: lib/music_library_web/live_helpers/record_actions.ex #, elixir-autogen, elixir-format msgid "Error extracting colors" msgstr ""