Extract RecordHelpers

Closes #123
This commit is contained in:
Claudio Ortolina
2026-03-22 09:21:00 +00:00
parent 72a189c58a
commit ca228db598
5 changed files with 161 additions and 208 deletions
@@ -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
@@ -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
@@ -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