diff --git a/lib/music_brainz/release.ex b/lib/music_brainz/release.ex index c96bfa6c..8cec9692 100644 --- a/lib/music_brainz/release.ex +++ b/lib/music_brainz/release.ex @@ -41,10 +41,21 @@ defmodule MusicBrainz.Release do Enum.count(release.media) end + def get_medium(release, medium_number) do + Enum.find(release.media, fn m -> m.number == medium_number end) + end + def medium_duration(medium) do Enum.sum_by(medium.tracks, fn track -> track.length || 0 end) end + def medium_tracks(release, medium_number) do + case Enum.find(release.media, fn m -> m.number == medium_number end) do + nil -> [] + medium -> medium.tracks + end + end + def release_duration(release) do Enum.sum_by(release.media, fn medium -> medium_duration(medium) end) end diff --git a/lib/music_library_web/components/release.ex b/lib/music_library_web/components/release.ex index 2e48d103..bbeb7a83 100644 --- a/lib/music_library_web/components/release.ex +++ b/lib/music_library_web/components/release.ex @@ -47,7 +47,24 @@ defmodule MusicLibraryWeb.Components.Release do class="min-w-xs sm:min-w-sm" >
-

{gettext("Tracks")}

+

+ + {gettext("Tracks")} +

<.button :if={@can_scrobble? && @release_with_tracks.ok?} size="sm" @@ -118,6 +135,16 @@ defmodule MusicLibraryWeb.Components.Release do class="flex justify-between items-center gap-4" >

+ {medium_title(@medium)}

<.button @@ -282,6 +309,27 @@ defmodule MusicLibraryWeb.Components.Release do {:noreply, assign(socket, :selected_tracks, updated_tracks)} end + def handle_event("toggle_medium", %{"medium-number" => number}, socket) do + number = String.to_integer(number) + selected_tracks = socket.assigns.selected_tracks + release_with_tracks = socket.assigns.release_with_tracks.result + + medium_tracks = + release_with_tracks + |> Release.medium_tracks(number) + |> Enum.map(& &1.id) + |> MapSet.new() + + updated_tracks = + if MapSet.subset?(medium_tracks, selected_tracks) do + MapSet.difference(selected_tracks, medium_tracks) + else + MapSet.union(selected_tracks, medium_tracks) + end + + {:noreply, assign(socket, :selected_tracks, updated_tracks)} + end + def handle_event("scrobble_selected_tracks", _params, socket) when release_loaded?(socket.assigns) do release_with_tracks = socket.assigns.release_with_tracks.result @@ -321,6 +369,11 @@ defmodule MusicLibraryWeb.Components.Release do {:noreply, socket |> put_toast(:error, gettext("Error scrobbling selected tracks"))} end + defp medium_selected?(medium, selected_tracks) do + medium_track_ids = medium.tracks |> Enum.map(& &1.id) |> MapSet.new() + MapSet.subset?(medium_track_ids, selected_tracks) + end + def scrobble_button_label(selected_tracks) do if MapSet.size(selected_tracks) > 0 do gettext("Scrobble selected tracks")