diff --git a/lib/music_library_web/components/release_component.ex b/lib/music_library_web/components/release_component.ex new file mode 100644 index 00000000..eb31132f --- /dev/null +++ b/lib/music_library_web/components/release_component.ex @@ -0,0 +1,156 @@ +defmodule MusicLibraryWeb.ReleaseComponent do + use MusicLibraryWeb, :live_component + use Gettext, backend: MusicLibraryWeb.Gettext + + import MusicLibraryWeb.RecordComponents, + only: [ + format_duration: 1 + ] + + alias MusicLibrary.ScrobbleActivity + + @impl true + def mount(socket) do + {:ok, + socket + |> assign(:can_scrobble?, ScrobbleActivity.can_scrobble?()) + |> assign(:release_with_tracks, nil)} + end + + @impl true + def render(assigns) do + ~H""" +
+ +
+

{gettext("Tracks")}

+ + {gettext("Scrobble to Last.fm")} + + + {gettext("Connect your Last.fm account")} + +
+ +
+ <.async_result :let={release_with_tracks} assign={@release_with_tracks}> + <:loading> + {gettext("Loading release with tracks")} + + + <:failed :let={_failure}> +
+ <.icon + name="hero-exclamation-triangle" + class="-mt-1 mr-1 h-5 w-5" + aria-hidden="true" + data-slot="icon" + /> + {gettext("Error loading tracks")} +
+ +
+

1} + class="text-sm font-semibold text-zinc-700 dark:text-zinc-300" + > + {medium_title(medium)} +

+
    +
  • +
    + {track.position} + {track.title} + + {track.length && format_duration(track.length)} + +
    +
    + + + {Enum.map_join(track.artists, ", ", fn artist -> artist.name end)} + +
    +
  • +
+ +

+ {medium_duration(medium)} +

+
+ +
+
+
+ """ + end + + @impl true + def handle_event("load_release_with_tracks", _params, socket) do + selected_release_id = socket.assigns.record.selected_release_id + + {:noreply, + socket + |> assign_async(:release_with_tracks, fn -> + with {:ok, release} <- MusicBrainz.get_release(selected_release_id) do + {:ok, %{release_with_tracks: MusicBrainz.Release.from_api_response(release)}} + end + end)} + end + + def handle_event("scrobble_release", _params, socket) do + release_with_tracks_async_result = + socket.assigns.release_with_tracks + + if release_with_tracks = + release_with_tracks_async_result && release_with_tracks_async_result.result do + case ScrobbleActivity.scrobble(release_with_tracks, finished_at: DateTime.utc_now()) do + {:ok, _} -> + {:noreply, + socket + |> put_flash(:info, gettext("Release scrobbled successfully"))} + + {:error, reason} -> + {:noreply, + socket + |> put_flash( + :error, + gettext("Error scrobbling release") <> "," <> inspect(reason) + )} + end + end + end + + defp medium_duration(medium) do + medium + |> MusicBrainz.Release.medium_duration() + |> format_duration() + end + + defp medium_title(medium) do + if medium.title !== "" do + medium.title + else + gettext("Disc %{no}", %{no: medium.number}) + end + end +end diff --git a/lib/music_library_web/live/collection_live/show.ex b/lib/music_library_web/live/collection_live/show.ex index 1a3468f2..2255c347 100644 --- a/lib/music_library_web/live/collection_live/show.ex +++ b/lib/music_library_web/live/collection_live/show.ex @@ -7,8 +7,7 @@ defmodule MusicLibraryWeb.CollectionLive.Show do close_actions_menu: 1, format_label: 1, type_label: 1, - selected_release_label: 1, - format_duration: 1 + selected_release_label: 1 ] alias MusicLibrary.{Records, ScrobbleActivity} @@ -119,41 +118,6 @@ defmodule MusicLibraryWeb.CollectionLive.Show do end end - def handle_event("load_release_with_tracks", _params, socket) do - selected_release_id = socket.assigns.record.selected_release_id - - {:noreply, - socket - |> assign_async(:release_with_tracks, fn -> - with {:ok, release} <- MusicBrainz.get_release(selected_release_id) do - {:ok, %{release_with_tracks: MusicBrainz.Release.from_api_response(release)}} - end - end)} - end - - def handle_event("scrobble_release", _params, socket) do - release_with_tracks_async_result = - socket.assigns.release_with_tracks - - if release_with_tracks = - release_with_tracks_async_result && release_with_tracks_async_result.result do - case ScrobbleActivity.scrobble(release_with_tracks, finished_at: DateTime.utc_now()) do - {:ok, _} -> - {:noreply, - socket - |> put_flash(:info, gettext("Release scrobbled successfully"))} - - {:error, reason} -> - {:noreply, - socket - |> put_flash( - :error, - gettext("Error scrobbling release") <> "," <> inspect(reason) - )} - end - end - end - @impl true def handle_info({MusicLibraryWeb.FormComponent, {:saved, record}}, socket) do {:noreply, assign(socket, :record, record)} @@ -199,18 +163,4 @@ defmodule MusicLibraryWeb.CollectionLive.Show do defp title_segment(:show), do: gettext("Show") defp title_segment(:edit), do: gettext("Edit") - - defp medium_duration(medium) do - medium - |> MusicBrainz.Release.medium_duration() - |> format_duration() - end - - defp medium_title(medium) do - if medium.title !== "" do - medium.title - else - gettext("Disc %{no}", %{no: medium.number}) - end - end end diff --git a/lib/music_library_web/live/collection_live/show.html.heex b/lib/music_library_web/live/collection_live/show.html.heex index 91083a78..08d96fc4 100644 --- a/lib/music_library_web/live/collection_live/show.html.heex +++ b/lib/music_library_web/live/collection_live/show.html.heex @@ -221,7 +221,7 @@