Display tracks for records with a selected release
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
defmodule MusicBrainz.Release do
|
||||
@enforce_keys [:id, :date, :barcode, :media]
|
||||
defstruct [:id, :date, :barcode, :media]
|
||||
|
||||
defmodule Medium do
|
||||
@enforce_keys [:format, :number, :track_count, :tracks]
|
||||
defstruct [:format, :number, :track_count, :tracks]
|
||||
end
|
||||
|
||||
defmodule Track do
|
||||
@enforce_keys [:id, :title, :length, :number, :position]
|
||||
defstruct [:id, :title, :length, :number, :position]
|
||||
end
|
||||
|
||||
def media_count(release) do
|
||||
Enum.count(release.media)
|
||||
end
|
||||
|
||||
def from_api_response(r) do
|
||||
%__MODULE__{
|
||||
id: r["id"],
|
||||
date: r["date"],
|
||||
barcode: r["barcode"],
|
||||
media: parse_media(r["media"])
|
||||
}
|
||||
end
|
||||
|
||||
defp parse_media(media) do
|
||||
Enum.map(media, fn m ->
|
||||
%Medium{
|
||||
format: m["format"],
|
||||
number: m["position"],
|
||||
track_count: m["track-count"],
|
||||
tracks: parse_tracks(m["tracks"])
|
||||
}
|
||||
end)
|
||||
end
|
||||
|
||||
defp parse_tracks(tracks) do
|
||||
Enum.map(tracks, fn t ->
|
||||
%Track{
|
||||
id: t["id"],
|
||||
title: t["title"],
|
||||
length: t["length"],
|
||||
number: t["number"],
|
||||
position: t["position"]
|
||||
}
|
||||
end)
|
||||
end
|
||||
end
|
||||
@@ -33,6 +33,18 @@ defmodule MusicLibraryWeb.CollectionLive.Show do
|
||||
def handle_params(%{"id" => id}, _, socket) do
|
||||
record = Records.get_record!(id)
|
||||
|
||||
socket =
|
||||
if record.selected_release_id do
|
||||
socket
|
||||
|> assign_async(:release_with_tracks, fn ->
|
||||
with {:ok, release} <- MusicBrainz.get_release(record.selected_release_id) do
|
||||
{:ok, %{release_with_tracks: MusicBrainz.Release.from_api_response(release)}}
|
||||
end
|
||||
end)
|
||||
else
|
||||
socket
|
||||
end
|
||||
|
||||
{:noreply,
|
||||
socket
|
||||
|> assign(:nav_section, :records)
|
||||
|
||||
@@ -216,8 +216,21 @@
|
||||
<dt class="text-xs md:text-sm font-medium leading-6 text-zinc-900 dark:text-zinc-400">
|
||||
{gettext("Collected release")}
|
||||
</dt>
|
||||
<dd class="mt-1 text-xs md:text-sm leading-6 text-zinc-700 dark:text-zinc-300 sm:col-span-2 sm:mt-0">
|
||||
{selected_release_label(@record)}
|
||||
<dd class="mt-1 text-xs md:text-sm flex justify-between leading-6 text-zinc-700 dark:text-zinc-300 sm:col-span-2 sm:mt-0">
|
||||
<span>{selected_release_label(@record)}</span>
|
||||
|
||||
<button
|
||||
:if={@record.selected_release_id}
|
||||
phx-click={Fluxon.open_dialog("tracks-sheet")}
|
||||
>
|
||||
<span class="sr-only">{gettext("Show Tracks")}</span>
|
||||
<.icon
|
||||
name="hero-numbered-list"
|
||||
class="-mt-1 h-5 w-5"
|
||||
aria-hidden="true"
|
||||
data-slot="icon"
|
||||
/>
|
||||
</button>
|
||||
</dd>
|
||||
</div>
|
||||
<div
|
||||
@@ -261,6 +274,51 @@
|
||||
<pre><code class="text-xs sm:text-sm"><%= Jason.encode!(@record.musicbrainz_data, pretty: true) %></code></pre>
|
||||
</details>
|
||||
|
||||
<Fluxon.Components.Sheet.sheet
|
||||
:if={@record.selected_release_id}
|
||||
id="tracks-sheet"
|
||||
placement="right"
|
||||
open
|
||||
>
|
||||
<h3 class="text-lg font-semibold mb-4">{gettext("Tracks")}</h3>
|
||||
|
||||
<div class="space-y-4">
|
||||
<.async_result :let={release_with_tracks} assign={@release_with_tracks}>
|
||||
<:loading>
|
||||
<span class="sr-only">{gettext("Loading release with tracks")}</span>
|
||||
<Fluxon.Components.Loading.loading />
|
||||
</:loading>
|
||||
<:failed :let={_failure}>
|
||||
<div class="mt-4 text-sm leading-5 text-zinc-500 dark:text-zinc-400">
|
||||
<.icon
|
||||
name="hero-exclamation-triangle"
|
||||
class="-mt-1 mr-1 h-5 w-5"
|
||||
aria-hidden="true"
|
||||
data-slot="icon"
|
||||
/>
|
||||
{gettext("Error loading tracks")}
|
||||
</div>
|
||||
</:failed>
|
||||
<div :for={medium <- release_with_tracks.media} class="space-y-4">
|
||||
<h4
|
||||
:if={MusicBrainz.Release.media_count(release_with_tracks) > 1}
|
||||
class="text-sm font-semibold"
|
||||
>
|
||||
{medium.number}
|
||||
</h4>
|
||||
<ul class="list-disc pl-6">
|
||||
<li
|
||||
:for={track <- medium.tracks}
|
||||
class="text-sm leading-5 text-zinc-700 dark:text-zinc-300"
|
||||
>
|
||||
{track.position} - {track.title}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</.async_result>
|
||||
</div>
|
||||
</Fluxon.Components.Sheet.sheet>
|
||||
|
||||
<.modal
|
||||
:if={@live_action == :edit}
|
||||
id="record-modal"
|
||||
|
||||
Reference in New Issue
Block a user