Can print an individual medium tracklist
This commit is contained in:
@@ -16,19 +16,28 @@ defmodule MusicLibrary.Records.TracklistPdf do
|
||||
@spec generate(MusicLibrary.Records.Record.t(), Release.t()) ::
|
||||
{:ok, binary()} | {:error, term()}
|
||||
def generate(record, release) do
|
||||
markup = build_markup(record, release)
|
||||
markup = build_markup(record, release.media)
|
||||
Typst.render_to_pdf(markup)
|
||||
end
|
||||
|
||||
defp build_markup(record, release) do
|
||||
media_count = Release.media_count(release)
|
||||
track_count = Enum.sum(Enum.map(release.media, &length(&1.tracks)))
|
||||
@spec generate_medium(MusicLibrary.Records.Record.t(), Release.t(), integer()) ::
|
||||
{:ok, binary()} | {:error, term()}
|
||||
def generate_medium(record, release, medium_number) do
|
||||
case Release.get_medium(release, medium_number) do
|
||||
nil -> {:error, :medium_not_found}
|
||||
medium -> generate(record, %{release | media: [medium]})
|
||||
end
|
||||
end
|
||||
|
||||
defp build_markup(record, media) do
|
||||
media_count = length(media)
|
||||
track_count = Enum.sum(Enum.map(media, &length(&1.tracks)))
|
||||
header_count = if media_count > 1, do: media_count, else: 0
|
||||
total_items = track_count + header_count
|
||||
|
||||
{columns, font_size, show_duration} = layout_params(total_items, media_count)
|
||||
|
||||
content = build_media(release, media_count, font_size, show_duration)
|
||||
content = build_media(media, media_count, font_size, show_duration)
|
||||
|
||||
"""
|
||||
#set page(width: 120mm, height: 120mm, margin: 5mm, background: rect(width: 100%, height: 100%, stroke: 0.5pt + black))
|
||||
@@ -56,8 +65,8 @@ defmodule MusicLibrary.Records.TracklistPdf do
|
||||
"""
|
||||
end
|
||||
|
||||
defp build_media(release, media_count, font_size, show_duration) do
|
||||
release.media
|
||||
defp build_media(media, media_count, font_size, show_duration) do
|
||||
media
|
||||
|> Enum.map_join("\n", fn medium ->
|
||||
build_medium(medium, media_count, font_size, show_duration)
|
||||
end)
|
||||
|
||||
@@ -136,6 +136,7 @@ defmodule MusicLibraryWeb.Components.Release do
|
||||
media_count={MusicBrainz.Release.media_count(release_with_tracks)}
|
||||
selected_tracks={@selected_tracks}
|
||||
myself={@myself}
|
||||
record={@record}
|
||||
/>
|
||||
</.async_result>
|
||||
</div>
|
||||
@@ -151,6 +152,7 @@ defmodule MusicLibraryWeb.Components.Release do
|
||||
attr :already_scrobbled, :boolean, required: true
|
||||
attr :selected_tracks, :any, required: true
|
||||
attr :myself, :any, required: true
|
||||
attr :record, :any, default: nil
|
||||
|
||||
def medium(assigns) do
|
||||
~H"""
|
||||
@@ -174,17 +176,29 @@ defmodule MusicLibraryWeb.Components.Release do
|
||||
{@medium.format}
|
||||
</.badge>
|
||||
</label>
|
||||
<.button
|
||||
:if={@can_scrobble?}
|
||||
size="sm"
|
||||
disabled={@already_scrobbled || MapSet.size(@selected_tracks) > 0}
|
||||
phx-click="scrobble_medium"
|
||||
phx-value-number={@medium.number}
|
||||
phx-target={@myself}
|
||||
phx-disable-with={gettext("Scrobbling...")}
|
||||
>
|
||||
{medium_scrobble_label(@medium.format)}
|
||||
</.button>
|
||||
<div class="flex items-center gap-2">
|
||||
<.button
|
||||
:if={@record}
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
phx-click="print_medium_tracklist"
|
||||
phx-value-medium-number={@medium.number}
|
||||
phx-target={@myself}
|
||||
>
|
||||
<.icon name="hero-printer" class="h-4 w-4" />
|
||||
</.button>
|
||||
<.button
|
||||
:if={@can_scrobble?}
|
||||
size="sm"
|
||||
disabled={@already_scrobbled || MapSet.size(@selected_tracks) > 0}
|
||||
phx-click="scrobble_medium"
|
||||
phx-value-number={@medium.number}
|
||||
phx-target={@myself}
|
||||
phx-disable-with={gettext("Scrobbling...")}
|
||||
>
|
||||
{medium_scrobble_label(@medium.format)}
|
||||
</.button>
|
||||
</div>
|
||||
</div>
|
||||
<.track_list
|
||||
medium_number={@medium.number}
|
||||
@@ -431,6 +445,40 @@ defmodule MusicLibraryWeb.Components.Release do
|
||||
{:noreply, socket}
|
||||
end
|
||||
|
||||
def handle_event("print_medium_tracklist", %{"medium-number" => number}, socket)
|
||||
when release_loaded?(socket.assigns) do
|
||||
release = socket.assigns.release_with_tracks.result
|
||||
record = socket.assigns.record
|
||||
{number, ""} = Integer.parse(number)
|
||||
|
||||
case TracklistPdf.generate_medium(record, release, number) do
|
||||
{:ok, pdf_binary} ->
|
||||
filename = "#{record.title} - Disc #{number} - Tracklist.pdf"
|
||||
|
||||
{:noreply,
|
||||
push_event(socket, "music_library:download", %{
|
||||
data: Base.encode64(pdf_binary),
|
||||
filename: filename,
|
||||
content_type: "application/pdf"
|
||||
})}
|
||||
|
||||
{:error, reason} ->
|
||||
Logger.error("Error generating medium tracklist PDF: #{inspect(reason)}")
|
||||
|
||||
put_toast!(
|
||||
:error,
|
||||
gettext("Error generating tracklist PDF") <>
|
||||
": " <> ErrorMessages.friendly_message(reason)
|
||||
)
|
||||
|
||||
{:noreply, socket}
|
||||
end
|
||||
end
|
||||
|
||||
def handle_event("print_medium_tracklist", _params, socket) do
|
||||
{:noreply, socket}
|
||||
end
|
||||
|
||||
def handle_event("load_release_tracks", _params, socket) do
|
||||
selected_release_id = socket.assigns.record.selected_release_id
|
||||
|
||||
|
||||
Reference in New Issue
Block a user