Update to new interpolation syntax

Includes a fix to a brittle test that failed due to changes in the
number of linebreaks.
This commit is contained in:
Claudio Ortolina
2024-12-02 23:28:11 +00:00
parent 9448e77e23
commit ccefc6e697
16 changed files with 191 additions and 191 deletions
@@ -84,7 +84,7 @@ defmodule MusicLibraryWeb.CoreComponents do
</button>
</div>
<div id={"#{@id}-content"}>
<%= render_slot(@inner_block) %>
{render_slot(@inner_block)}
</div>
</.focus_wrap>
</div>
@@ -129,9 +129,9 @@ defmodule MusicLibraryWeb.CoreComponents do
<p :if={@title} class="flex items-center gap-1.5 text-sm font-semibold leading-6">
<.icon :if={@kind == :info} name="hero-information-circle-mini" class="h-4 w-4" />
<.icon :if={@kind == :error} name="hero-exclamation-circle-mini" class="h-4 w-4" />
<%= @title %>
{@title}
</p>
<p class="mt-2 text-sm leading-5"><%= msg %></p>
<p class="mt-2 text-sm leading-5">{msg}</p>
<button type="button" class="group absolute top-1 right-1 p-2" aria-label={gettext("close")}>
<.icon name="hero-x-mark-solid" class="h-5 w-5 opacity-40 group-hover:opacity-70" />
</button>
@@ -162,7 +162,7 @@ defmodule MusicLibraryWeb.CoreComponents do
phx-connected={hide("#client-error")}
hidden
>
<%= gettext("Attempting to reconnect") %>
{gettext("Attempting to reconnect")}
<.icon name="hero-arrow-path" class="ml-1 h-3 w-3 animate-spin" />
</.flash>
@@ -174,7 +174,7 @@ defmodule MusicLibraryWeb.CoreComponents do
phx-connected={hide("#server-error")}
hidden
>
<%= gettext("Hang in there while we get back on track") %>
{gettext("Hang in there while we get back on track")}
<.icon name="hero-arrow-path" class="ml-1 h-3 w-3 animate-spin" />
</.flash>
</div>
@@ -208,9 +208,9 @@ defmodule MusicLibraryWeb.CoreComponents do
~H"""
<.form :let={f} for={@for} as={@as} {@rest}>
<div class="mt-10 space-y-8 bg-white dark:bg-zinc-800">
<%= render_slot(@inner_block, f) %>
{render_slot(@inner_block, f)}
<div :for={action <- @actions} class="mt-2 flex items-center justify-between gap-6">
<%= render_slot(action, f) %>
{render_slot(action, f)}
</div>
</div>
</.form>
@@ -245,7 +245,7 @@ defmodule MusicLibraryWeb.CoreComponents do
]}
{@rest}
>
<%= render_slot(@inner_block) %>
{render_slot(@inner_block)}
</button>
"""
end
@@ -330,9 +330,9 @@ defmodule MusicLibraryWeb.CoreComponents do
class="rounded border-zinc-300 text-zinc-900 focus:ring-0"
{@rest}
/>
<%= @label %>
{@label}
</label>
<.error :for={msg <- @errors}><%= msg %></.error>
<.error :for={msg <- @errors}>{msg}</.error>
</div>
"""
end
@@ -340,7 +340,7 @@ defmodule MusicLibraryWeb.CoreComponents do
def input(%{type: "select"} = assigns) do
~H"""
<div>
<.label for={@id}><%= @label %></.label>
<.label for={@id}>{@label}</.label>
<select
id={@id}
name={@name}
@@ -358,10 +358,10 @@ defmodule MusicLibraryWeb.CoreComponents do
multiple={@multiple}
{@rest}
>
<option :if={@prompt} value=""><%= @prompt %></option>
<%= Phoenix.HTML.Form.options_for_select(@options, @value) %>
<option :if={@prompt} value="">{@prompt}</option>
{Phoenix.HTML.Form.options_for_select(@options, @value)}
</select>
<.error :for={msg <- @errors}><%= msg %></.error>
<.error :for={msg <- @errors}>{msg}</.error>
</div>
"""
end
@@ -369,7 +369,7 @@ defmodule MusicLibraryWeb.CoreComponents do
def input(%{type: "textarea"} = assigns) do
~H"""
<div>
<.label for={@id}><%= @label %></.label>
<.label for={@id}>{@label}</.label>
<textarea
id={@id}
name={@name}
@@ -380,7 +380,7 @@ defmodule MusicLibraryWeb.CoreComponents do
]}
{@rest}
><%= Phoenix.HTML.Form.normalize_value("textarea", @value) %></textarea>
<.error :for={msg <- @errors}><%= msg %></.error>
<.error :for={msg <- @errors}>{msg}</.error>
</div>
"""
end
@@ -389,7 +389,7 @@ defmodule MusicLibraryWeb.CoreComponents do
def input(assigns) do
~H"""
<div>
<.label for={@id}><%= @label %></.label>
<.label for={@id}>{@label}</.label>
<input
type={@type}
name={@name}
@@ -410,7 +410,7 @@ defmodule MusicLibraryWeb.CoreComponents do
]}
{@rest}
/>
<.error :for={msg <- @errors}><%= msg %></.error>
<.error :for={msg <- @errors}>{msg}</.error>
</div>
"""
end
@@ -424,7 +424,7 @@ defmodule MusicLibraryWeb.CoreComponents do
def label(assigns) do
~H"""
<label for={@for} class="block text-sm font-semibold leading-6 text-zinc-800 dark:text-zinc-400">
<%= render_slot(@inner_block) %>
{render_slot(@inner_block)}
</label>
"""
end
@@ -438,7 +438,7 @@ defmodule MusicLibraryWeb.CoreComponents do
~H"""
<p class="mt-3 flex gap-3 text-sm leading-6 text-rose-600">
<.icon name="hero-exclamation-circle-mini" class="mt-0.5 h-5 w-5 flex-none" />
<%= render_slot(@inner_block) %>
{render_slot(@inner_block)}
</p>
"""
end
@@ -460,13 +460,13 @@ defmodule MusicLibraryWeb.CoreComponents do
]}>
<div class="font-semibold">
<h1 class="text-sm md:text-base lg:text-2xl text-zinc-900">
<%= render_slot(@inner_block) %>
{render_slot(@inner_block)}
</h1>
<h2 :if={@subtitle != []} class="mt-2 text-sm md:text-base text-zinc-600">
<%= render_slot(@subtitle) %>
{render_slot(@subtitle)}
</h2>
</div>
<div class="flex justify-center gap-2 sm:flex-none mt-4 mb-4"><%= render_slot(@actions) %></div>
<div class="flex justify-center gap-2 sm:flex-none mt-4 mb-4">{render_slot(@actions)}</div>
</header>
"""
end
@@ -507,9 +507,9 @@ defmodule MusicLibraryWeb.CoreComponents do
<table class="md:w-full">
<thead class="text-sm text-left leading-6 text-zinc-500">
<tr>
<th :for={col <- @col} class="p-0 pb-4 pr-6 font-normal"><%= col[:label] %></th>
<th :for={col <- @col} class="p-0 pb-4 pr-6 font-normal">{col[:label]}</th>
<th :if={@action != []} class="relative p-0 pb-4">
<span class="sr-only"><%= gettext("Actions") %></span>
<span class="sr-only">{gettext("Actions")}</span>
</th>
</tr>
</thead>
@@ -527,7 +527,7 @@ defmodule MusicLibraryWeb.CoreComponents do
<div class="block py-4 pr-6">
<span class="absolute -inset-y-px right-0 -left-4 sm:rounded-l-xl" />
<span class={["relative", i == 0 && "font-semibold text-zinc-900"]}>
<%= render_slot(col, @row_item.(row)) %>
{render_slot(col, @row_item.(row))}
</span>
</div>
</td>
@@ -538,7 +538,7 @@ defmodule MusicLibraryWeb.CoreComponents do
:for={action <- @action}
class="relative ml-4 max-sm:ml-2 max-sm:text-sm font-semibold leading-6 text-zinc-900 hover:text-zinc-700"
>
<%= render_slot(action, @row_item.(row)) %>
{render_slot(action, @row_item.(row))}
</span>
</div>
</td>
@@ -568,8 +568,8 @@ defmodule MusicLibraryWeb.CoreComponents do
<div class="mt-14">
<dl class="-my-4 divide-y divide-zinc-100">
<div :for={item <- @item} class="flex gap-4 py-4 text-sm leading-6 sm:gap-8">
<dt class="w-1/4 flex-none text-zinc-500"><%= item.title %></dt>
<dd class="text-zinc-700"><%= render_slot(item) %></dd>
<dt class="w-1/4 flex-none text-zinc-500">{item.title}</dt>
<dd class="text-zinc-700">{render_slot(item)}</dd>
</div>
</dl>
</div>
@@ -594,7 +594,7 @@ defmodule MusicLibraryWeb.CoreComponents do
class="text-sm font-semibold leading-6 text-zinc-900 dark:text-zinc-400 hover:text-zinc-700 dark:hover:text-zinc-300"
>
<.icon name="hero-arrow-left-solid" class="h-3 w-3" />
<%= render_slot(@inner_block) %>
{render_slot(@inner_block)}
</.link>
</div>
"""
@@ -4,28 +4,28 @@
<div class="flex">
<div class="flex space-x-4 md:space-x-8">
<.link navigate={~p"/"} class={section_link_classes(assigns[:nav_section], :stats)}>
<%= gettext("Stats") %>
{gettext("Stats")}
</.link>
<.link
navigate={~p"/collection"}
class={section_link_classes(assigns[:nav_section], :records)}
>
<%= gettext("Collection") %>
{gettext("Collection")}
</.link>
<.link
navigate={~p"/wishlist"}
class={section_link_classes(assigns[:nav_section], :wishlist)}
>
<%= gettext("Wishlist") %>
{gettext("Wishlist")}
</.link>
</div>
</div>
<div class="flex space-x-8">
<a class={["max-sm:hidden" | nav_link_classes()]} } href={~p"/dev/dashboard"}>
<%= gettext("Dev dashboard") %>
{gettext("Dev dashboard")}
</a>
<a class={nav_link_classes()} } href={~p"/login"}>
<%= gettext("Logout") %>
{gettext("Logout")}
</a>
</div>
</div>
@@ -34,6 +34,6 @@
<main class="px-4 py-4 max-sm:pb-20 sm:px-6 lg:px-8">
<div class="mx-auto max-w-screen-xl">
<.flash_group flash={@flash} />
<%= @inner_content %>
{@inner_content}
</div>
</main>
@@ -5,7 +5,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="csrf-token" content={get_csrf_token()} />
<.live_title suffix=" · Music Library">
<%= assigns[:page_title] || assigns.conn.request_path %>
{assigns[:page_title] || assigns.conn.request_path}
</.live_title>
<link rel="preconnect" href="https://rsms.me/" />
<link rel="stylesheet" href="https://rsms.me/inter/inter.css" />
@@ -35,7 +35,7 @@
</script>
</head>
<body class="bg-white dark:bg-zinc-900">
<%= @inner_content %>
{@inner_content}
<footer class="mt-8 border-t border-slate-900/10 dark:border-slate-300/10">
<div class="mx-auto max-w-7xl px-6 pb-8 lg:px-8">
<div class="pt-8 flex items-center justify-between">
@@ -55,7 +55,7 @@
</a>
</div>
<p class="text-sm/6 text-zinc-600 dark:text-zinc-400 order-1">
<span><%= gettext("Made by") %></span>
<span>{gettext("Made by")}</span>
<a
class="font-medium text-zinc-500 hover:border-zinc-300 hover:text-zinc-700 dark:text-zinc-300 dark:hover:text-zinc-200"
href="https://claudio-ortolina.org"
@@ -1,6 +1,6 @@
<main class="px-4 py-8 max-sm:pb-20 sm:px-6 lg:px-8">
<div class="mx-auto max-w-5xl">
<.flash_group flash={@flash} />
<%= @inner_content %>
{@inner_content}
</div>
</main>
@@ -32,7 +32,7 @@ defmodule MusicLibraryWeb.Pagination do
"focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-zinc-600"
]}
>
<%= gettext("Previous") %>
{gettext("Previous")}
</.link>
<.link
:if={@page_links.next_page}
@@ -45,7 +45,7 @@ defmodule MusicLibraryWeb.Pagination do
"focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-zinc-600"
]}
>
<%= gettext("Next") %>
{gettext("Next")}
</.link>
</div>
<div class="hidden sm:flex sm:flex-1 sm:items-center sm:justify-items-center sm:justify-center">
@@ -108,7 +108,7 @@ defmodule MusicLibraryWeb.Pagination do
]}
patch={"?" <> encode_query(page: @page_number, page_size: @page_size, query: @query)}
>
<span class="sr-only"><%= gettext("Next") %></span>
<span class="sr-only">{gettext("Next")}</span>
<svg class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
<path
fill-rule="evenodd"
@@ -130,7 +130,7 @@ defmodule MusicLibraryWeb.Pagination do
class="relative inline-flex items-center rounded-l-md px-2 py-2 text-zinc-400 ring-1 ring-inset ring-zinc-300 hover:bg-zinc-50 focus:z-20 focus:outline-offset-0"
patch={"?" <> encode_query(page: @page_number, page_size: @page_size, query: @query)}
>
<span class="sr-only"><%= gettext("Previous") %></span>
<span class="sr-only">{gettext("Previous")}</span>
<svg class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
<path
fill-rule="evenodd"
@@ -158,7 +158,7 @@ defmodule MusicLibraryWeb.Pagination do
defp numbered_link(assigns) when assigns.active do
~H"""
<span class="relative z-10 inline-flex items-center first:rounded-l-md last:rounded-r-md bg-zinc-600 dark:bg-zinc-300 px-4 py-2 text-sm font-semibold text-white dark:text-zinc-700 focus:z-20 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-zinc-600">
<%= @page_number %>
{@page_number}
</span>
"""
end
@@ -169,7 +169,7 @@ defmodule MusicLibraryWeb.Pagination do
class="relative hidden items-center first:rounded-l-md last:rounded-r-md px-4 py-2 text-sm font-semibold text-zinc-900 dark:text-zinc-400 ring-1 ring-inset ring-zinc-300 hover:bg-zinc-300 hover:text-zinc-500 focus:z-20 focus:outline-offset-0 md:inline-flex"
patch={"?" <> encode_query(page: @page_number, page_size: @page_size, query: @query)}
>
<%= @page_number %>
{@page_number}
</.link>
"""
end
@@ -2,13 +2,13 @@
<div class="w-full max-w-sm space-y-10">
<div>
<h2 class="mt-10 text-center text-2xl font-bold leading-9 tracking-tight text-zinc-900 dark:text-zinc-200">
<%= gettext("Welcome to your Music Library") %>
{gettext("Welcome to your Music Library")}
</h2>
</div>
<.form class="space-y-6" for={@form} action={~p"/sessions/create"}>
<div class="relative -space-y-px rounded-md shadow-sm">
<div>
<label for="password" class="sr-only"><%= gettext("Password") %></label>
<label for="password" class="sr-only">{gettext("Password")}</label>
<input
id="password"
name="password"
@@ -41,7 +41,7 @@
"focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-zinc-600"
]}
>
<%= gettext("Login") %>
{gettext("Login")}
</button>
</div>
</.form>
@@ -1,17 +1,17 @@
<div class="mt-4 px-4 sm:px-6 lg:px-8">
<h1 class="mt-1 flex font-semibold text-base lg:text-2xl leading-5 text-zinc-700 dark:text-zinc-300 text-wrap">
<%= @artist.name %>
{@artist.name}
</h1>
<p
:if={artist_info = @artist_info.ok? && @artist_info.result}
class="bio mt-2 text-sm leading-5 text-zinc-500 dark:text-zinc-400"
>
<%= (artist_info.bio || gettext("Biography not available")) |> raw() %>
{(artist_info.bio || gettext("Biography not available")) |> raw()}
</p>
<div :if={@artist_records.collection !== []} class="mt-4">
<h2 class="font-semibold text-base sm:text-lg leading-5 text-zinc-700 dark:text-zinc-300">
<%= gettext("Collection") %>
{gettext("Collection")}
</h2>
<ul
role="list"
@@ -29,19 +29,19 @@
class="absolute inset-0 focus:outline-none"
phx-click={JS.navigate(~p"/collection/#{record}")}
>
<span class="sr-only"><%= gettext("View details") %></span>
<span class="sr-only">{gettext("View details")}</span>
</button>
</div>
<p class="pointer-events-none mt-2 block truncate text-sm font-medium text-zinc-900 dark:text-zinc-300">
<%= record.title %>
{record.title}
</p>
<p class="pointer-events-none block text-sm font-medium text-zinc-500">
<%= Records.Record.format_long_label(record.format) %> · <%= Records.Record.type_long_label(
{Records.Record.format_long_label(record.format)} · {Records.Record.type_long_label(
record.type
) %>
)}
</p>
<p class="pointer-events-none block text-sm font-medium text-zinc-500">
<%= Records.Record.format_release(record.release) %>
{Records.Record.format_release(record.release)}
</p>
</li>
</ul>
@@ -49,7 +49,7 @@
<div :if={@artist_records.wishlist !== []} class="mt-4">
<h2 class="font-semibold text-base sm:text-lg leading-5 text-zinc-700 dark:text-zinc-300">
<%= gettext("Wishlist") %>
{gettext("Wishlist")}
</h2>
<ul
role="list"
@@ -67,19 +67,19 @@
class="absolute inset-0 focus:outline-none"
phx-click={JS.navigate(~p"/wishlist/#{record}")}
>
<span class="sr-only"><%= gettext("View details") %></span>
<span class="sr-only">{gettext("View details")}</span>
</button>
</div>
<p class="pointer-events-none mt-2 block truncate text-sm font-medium text-zinc-900 dark:text-zinc-300">
<%= record.title %>
{record.title}
</p>
<p class="pointer-events-none block text-sm font-medium text-zinc-500">
<%= Records.Record.format_long_label(record.format) %> · <%= Records.Record.type_long_label(
{Records.Record.format_long_label(record.format)} · {Records.Record.type_long_label(
record.type
) %>
)}
</p>
<p class="pointer-events-none block text-sm font-medium text-zinc-500">
<%= Records.Record.format_release(record.release) %>
{Records.Record.format_release(record.release)}
</p>
</li>
</ul>
@@ -14,17 +14,17 @@
/>
</form>
<.link patch={~p"/collection/import"}>
<.button><%= gettext("Import") %></.button>
<.button>{gettext("Import")}</.button>
</.link>
</div>
</header>
<p class="text-right text-sm max-sm:text-xs mt-8 text-zinc-900 dark:text-zinc-400">
<%= gettext(
{gettext(
"Showing <b>%{visible}</b> of <b>%{total}</b> records",
%{visible: Enum.count(@streams.records), total: @record_list_params.total_entries}
)
|> raw() %>
|> raw()}
</p>
</div>
@@ -53,22 +53,22 @@
class="text-zinc-700 hover:text-zinc-500 dark:text-zinc-400 dark:hover:text-zinc-300"
patch={~p"/artists/#{artist.musicbrainz_id}"}
>
<%= artist.name %>
{artist.name}
</.link>
</h1>
<h2 class="mt-1 flex font-semibold text-sm sm:text-base leading-5 text-zinc-700 dark:text-zinc-300 text-wrap">
<%= record.title %>
{record.title}
</h2>
<p class="mt-1 text-xs leading-5 text-zinc-500 dark:text-zinc-400">
<%= Records.Record.format_release(record.release) %>
{Records.Record.format_release(record.release)}
<span class="sm:hidden">
· <%= Records.Record.format_long_label(record.format) %> · <%= Records.Record.type_long_label(
· {Records.Record.format_long_label(record.format)} · {Records.Record.type_long_label(
record.type
) %>
)}
<span :if={Records.Record.child_release_groups_count(record) > 0}>
·
<span class="sr-only">
<%= gettext("Number of included records") %>
{gettext("Number of included records")}
</span>
<span class={[
"inline-flex items-center rounded-full",
@@ -78,7 +78,7 @@
"text-gray-600 dark:text-gray-500",
"ring-gray-500/10 dark:ring-gray-400/20"
]}>
<%= Records.Record.child_release_groups_count(record) %>
{Records.Record.child_release_groups_count(record)}
</span>
</span>
</span>
@@ -88,13 +88,13 @@
<div class="flex shrink-0 items-center gap-x-6">
<div class="hidden sm:flex sm:flex-col sm:items-end">
<p class="text-xs leading-6 text-zinc-900 dark:text-zinc-300">
<%= Records.Record.format_long_label(record.format) %> · <%= Records.Record.type_long_label(
{Records.Record.format_long_label(record.format)} · {Records.Record.type_long_label(
record.type
) %>
)}
<span :if={Records.Record.child_release_groups_count(record) > 0}>
·
<span class="sr-only">
<%= gettext("Number of included records") %>
{gettext("Number of included records")}
</span>
<span class={[
"inline-flex items-center rounded-full",
@@ -104,7 +104,7 @@
"text-gray-600 dark:text-gray-500",
"ring-gray-500/10 dark:ring-gray-400/20"
]}>
<%= Records.Record.child_release_groups_count(record) %>
{Records.Record.child_release_groups_count(record)}
</span>
</span>
</p>
@@ -118,7 +118,7 @@
phx-click={toggle_actions_menu(record.id)}
phx-click-away={close_actions_menu(record.id)}
>
<span class="sr-only"><%= gettext("Open options") %></span>
<span class="sr-only">{gettext("Open options")}</span>
<.icon
name="hero-ellipsis-vertical"
class="-mt-1 h-5 w-5"
@@ -153,7 +153,7 @@
id={"actions-#{record.id}-show"}
navigate={~p"/collection/#{record}"}
>
<%= gettext("Show") %>
{gettext("Show")}
</.link>
<a
href={musicbrainz_url(record)}
@@ -163,7 +163,7 @@
tabindex="-1"
id={"actions-#{record.id}-musicbrainz"}
>
<%= gettext("View on MusicBrainz") %>
{gettext("View on MusicBrainz")}
</a>
<.link
@@ -173,7 +173,7 @@
id={"actions-#{record.id}-edit"}
patch={~p"/collection/#{record}/edit"}
>
<%= gettext("Edit") %>
{gettext("Edit")}
</.link>
<.link
@@ -184,7 +184,7 @@
phx-click={JS.push("delete", value: %{id: record.id}) |> hide("##{id}")}
data-confirm={gettext("Are you sure?")}
>
<%= gettext("Delete") %>
{gettext("Delete")}
</.link>
</.focus_wrap>
</div>
@@ -14,46 +14,46 @@
class="text-zinc-700 hover:text-zinc-500 dark:text-zinc-400 dark:hover:text-zinc-300"
patch={~p"/artists/#{artist.musicbrainz_id}"}
>
<%= artist.name %>
{artist.name}
</.link>
</h1>
<h2 class="mt-1 flex font-semibold text-base sm:text-lg leading-5 text-zinc-700 dark:text-zinc-300 text-wrap">
<%= @record.title %>
{@record.title}
</h2>
<p class="mt-2 text-sm leading-5 text-zinc-500 dark:text-zinc-400">
<%= Records.Record.format_release(@record.release) %> · <%= Records.Record.format_long_label(
{Records.Record.format_release(@record.release)} · {Records.Record.format_long_label(
@record.format
) %> · <%= Records.Record.type_long_label(@record.type) %>
)} · {Records.Record.type_long_label(@record.type)}
</p>
<!-- TODO: extract to a component -->
<nav class="mt-5 isolate inline-flex rounded-md shadow-sm">
<.link patch={~p"/collection/#{@record}/show/edit"} phx-click={JS.push_focus()}>
<.button type="button" class="relative inline-flex items-center rounded-r-none">
<%= gettext("Edit") %>
{gettext("Edit")}
</.button>
</.link>
<.link phx-click={JS.push("refresh_cover", value: %{id: @record.id})}>
<.button type="button" class="relative -ml-px inline-flex items-center rounded-none">
<span class="sr-only"><%= gettext("Refresh") %></span>
<span class="sr-only">{gettext("Refresh")}</span>
<.icon
name="hero-arrow-path"
class="h-4 w-4 mr-1 phx-click-loading:animate-spin"
aria-hidden="true"
data-slot="icon"
/>
<%= gettext("Cover") %>
{gettext("Cover")}
</.button>
</.link>
<.link phx-click={JS.push("refresh_musicbrainz_data", value: %{id: @record.id})}>
<.button type="button" class="relative -ml-px inline-flex items-center rounded-none">
<span class="sr-only"><%= gettext("Refresh") %></span>
<span class="sr-only">{gettext("Refresh")}</span>
<.icon
name="hero-arrow-path"
class="h-4 w-4 mr-1 phx-click-loading:animate-spin"
aria-hidden="true"
data-slot="icon"
/>
<%= gettext("MB Data") %>
{gettext("MB Data")}
</.button>
</.link>
<.link
@@ -64,7 +64,7 @@
type="button"
class="relative -ml-px inline-flex items-center rounded-l-none !text-red-600 hover:!text-red-500 dark:!text-red-700 hover:dark:!text-red-500"
>
<%= gettext("Delete") %>
{gettext("Delete")}
</.button>
</.link>
</nav>
@@ -74,7 +74,7 @@
<dl class="mt-4 divide-y divide-zinc-100 dark:divide-slate-300/30">
<div class="py-2 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-0">
<dt class="text-sm font-medium leading-6 text-zinc-900 dark:text-zinc-400">
<%= gettext("Genres") %>
{gettext("Genres")}
</dt>
<dd class="mt-1 text-sm leading-6 text-zinc-700 dark:text-zinc-300 sm:col-span-2 sm:mt-0">
<.link
@@ -82,23 +82,23 @@
class="mr-2 text-zinc-700 hover:text-zinc-500 dark:text-zinc-400 dark:hover:text-zinc-300"
patch={~p"/collection?#{%{query: ~s(genre:"#{genre}")}}"}
>
<%= genre %>
{genre}
</.link>
</dd>
</div>
<div class="py-2 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-0">
<dt class="text-sm font-medium leading-6 text-zinc-900 dark:text-zinc-400">
<%= gettext("MusicBrainz ID") %>
{gettext("MusicBrainz ID")}
</dt>
<dd class="mt-1 text-sm flex justify-between leading-6 text-zinc-700 dark:text-zinc-300 sm:col-span-2 sm:mt-0">
<a href={musicbrainz_url(@record)}>
<code id={"mb-#{@record.musicbrainz_id}"}><%= @record.musicbrainz_id %></code>
<code id={"mb-#{@record.musicbrainz_id}"}>{@record.musicbrainz_id}</code>
</a>
<button phx-click={
JS.dispatch("music_library:clipcopy", to: "#mb-" <> @record.musicbrainz_id)
|> JS.transition("animate-shake")
}>
<span class="sr-only"><%= gettext("Copy MusicBrainz ID to clipboard") %></span>
<span class="sr-only">{gettext("Copy MusicBrainz ID to clipboard")}</span>
<.icon
name="hero-clipboard-document"
class="-mt-1 h-5 w-5"
@@ -110,10 +110,10 @@
</div>
<div class="py-2 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-0">
<dt class="text-sm font-medium leading-6 text-zinc-900 dark:text-zinc-400">
<%= gettext("Purchased on") %>
{gettext("Purchased on")}
</dt>
<dd class="mt-1 text-sm leading-6 text-zinc-700 dark:text-zinc-300 sm:col-span-2 sm:mt-0">
<%= human_datetime(@record.purchased_at) %>
{human_datetime(@record.purchased_at)}
</dd>
</div>
<div
@@ -121,30 +121,30 @@
class="py-2 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-0"
>
<dt class="text-sm font-medium leading-6 text-zinc-900 dark:text-zinc-400">
<%= gettext("Includes") %>
{gettext("Includes")}
</dt>
<dd class="mt-1 text-sm leading-6 text-zinc-700 dark:text-zinc-300 sm:col-span-2 sm:mt-0">
<ul>
<li :for={child_release_group <- Records.Record.child_release_groups(@record)}>
<%= child_release_group.artists %> - <%= child_release_group.title %>
{child_release_group.artists} - {child_release_group.title}
</li>
</ul>
</dd>
</div>
<div class="py-2 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-0">
<dt class="text-sm font-medium leading-6 text-zinc-900 dark:text-zinc-400">
<%= gettext("Inserted at") %>
{gettext("Inserted at")}
</dt>
<dd class="mt-1 text-sm leading-6 text-zinc-700 dark:text-zinc-300 sm:col-span-2 sm:mt-0">
<%= human_datetime(@record.inserted_at) %>
{human_datetime(@record.inserted_at)}
</dd>
</div>
<div class="py-2 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-0">
<dt class="text-sm font-medium leading-6 text-zinc-900 dark:text-zinc-400">
<%= gettext("Updated at") %>
{gettext("Updated at")}
</dt>
<dd class="mt-1 text-sm leading-6 text-zinc-700 dark:text-zinc-300 sm:col-span-2 sm:mt-0">
<%= human_datetime(@record.updated_at) %>
{human_datetime(@record.updated_at)}
</dd>
</div>
</dl>
@@ -152,13 +152,13 @@
</div>
<!-- TODO: extract to a component -->
<details class="mt-4 px-4 text-zinc-700 hover:text-zinc-500 dark:text-zinc-400 dark:hover:text-zinc-300">
<summary class="text-xs sm:text-sm"><%= gettext("MusicBrainz data") %></summary>
<summary class="text-xs sm:text-sm">{gettext("MusicBrainz data")}</summary>
<pre><code class="text-xs sm:text-sm"><%= Jason.encode!(@record.musicbrainz_data, pretty: true) %></code></pre>
</details>
<div class="mt-4">
<.back navigate={@back_url}>
<%= gettext("Back to records") %>
{gettext("Back to records")}
</.back>
</div>
@@ -17,7 +17,7 @@ defmodule MusicLibraryWeb.RecordLive.FormComponent do
<div>
<header>
<h1 class="text-base font-medium leading-6 text-zinc-700 dark:text-zinc-400">
<%= @title %>
{@title}
</h1>
</header>
@@ -54,16 +54,16 @@ defmodule MusicLibraryWeb.RecordLive.FormComponent do
/>
<div phx-drop-target={@uploads.cover_data.ref}>
<.label for={@uploads.cover_data.ref}>
<%= gettext("Cover art") %>
{gettext("Cover art")}
</.label>
<span
:if={@uploads.cover_data.entries == []}
class="float-right text-zinc-700 dark:text-zinc-400"
>
<%= gettext("No cover selected") %>
{gettext("No cover selected")}
</span>
<%= for entry <- @uploads.cover_data.entries do %>
<span class="float-right text-zinc-700 dark:text-zinc-400"><%= entry.progress %>%</span>
<span class="float-right text-zinc-700 dark:text-zinc-400">{entry.progress}%</span>
<% end %>
<.live_file_input
class="mt-2 block w-full rounded-lg text-zinc-900 dark:text-zinc-200 focus:ring-0 sm:text-sm sm:leading-6"
@@ -71,7 +71,7 @@ defmodule MusicLibraryWeb.RecordLive.FormComponent do
/>
</div>
<:actions>
<.button phx-disable-with={gettext("Saving...")}><%= gettext("Save") %></.button>
<.button phx-disable-with={gettext("Saving...")}>{gettext("Save")}</.button>
</:actions>
</.simple_form>
</div>
@@ -42,7 +42,7 @@ defmodule MusicLibraryWeb.RecordLive.ImportComponent do
:if={@release_groups == []}
class="flex items-center justify-center h-32 text-md text-zinc-500"
>
<%= gettext("No results") %>
{gettext("No results")}
</div>
</div>
"""
@@ -57,15 +57,15 @@ defmodule MusicLibraryWeb.RecordLive.ImportComponent do
<div class="shrink-0 flex items-center justify-between w-full px-4">
<div class="min-w-0 flex-auto">
<h1 class="text-sm leading-6 text-zinc-700 dark:text-zinc-400">
<%= @release_group.artists %>
{@release_group.artists}
</h1>
<h2 class="mt-1 flex font-semibold text-sm sm:text-base leading-5 text-zinc-700 dark:text-zinc-300 text-wrap">
<%= @release_group.title %>
{@release_group.title}
</h2>
<p class="mt-1 text-xs leading-5 text-zinc-500 dark:text-zinc-400">
<%= Records.Record.format_release(@release_group.release) %> · <%= Records.Record.type_long_label(
{Records.Record.format_release(@release_group.release)} · {Records.Record.type_long_label(
@release_group.type
) %>
)}
</p>
</div>
<div class="relative flex-none">
@@ -77,7 +77,7 @@ defmodule MusicLibraryWeb.RecordLive.ImportComponent do
phx-click={toggle_actions_menu(@release_group.id)}
phx-click-away={close_actions_menu(@release_group.id)}
>
<span class="sr-only"><%= gettext("Choose which format to import") %></span>
<span class="sr-only">{gettext("Choose which format to import")}</span>
<.icon name={@icon_name} class="-mt-1 h-5 w-5" aria-hidden="true" data-slot="icon" />
</button>
<!--
@@ -110,7 +110,7 @@ defmodule MusicLibraryWeb.RecordLive.ImportComponent do
JS.push("import", value: %{id: @release_group.id, format: format}, page_loading: true)
}
>
<%= Records.Record.format_long_label(format) %>
{Records.Record.format_long_label(format)}
</.link>
</.focus_wrap>
</div>
@@ -124,7 +124,7 @@ defmodule MusicLibraryWeb.RecordLive.ImportComponent do
defp type_badge(assigns) do
~H"""
<span class="inline-flex items-center rounded-md bg-zinc-50 px-2 py-1 text-xs font-medium text-zinc-600 ring-1 ring-inset ring-zinc-500/10">
<%= @type %>
{@type}
</span>
"""
end
@@ -21,7 +21,7 @@ defmodule MusicLibraryWeb.StatsLive.DataComponents do
alt={@record.title}
/>
<p class="ml-24 truncate text-xs sm:text-sm font-medium text-zinc-500 dark:text-zinc-400">
<%= @title %>
{@title}
</p>
</dt>
<dd class="ml-24 flex items-baseline pb-6 sm:pb-7">
@@ -31,10 +31,10 @@ defmodule MusicLibraryWeb.StatsLive.DataComponents do
class="text-sm md:text-base lg:text-2xl text-zinc-900 hover:text-zinc-500 dark:text-zinc-300 dark:hover:text-zinc-200"
patch={~p"/artists/#{artist.musicbrainz_id}"}
>
<%= artist.name %>
{artist.name}
</.link>
<span class="text-sm md:text-base block text-zinc-600 dark:text-zinc-200">
<%= @record.title %>
{@record.title}
</span>
</p>
</dd>
@@ -51,7 +51,7 @@ defmodule MusicLibraryWeb.StatsLive.DataComponents do
<div class="overflow-hidden rounded-md bg-white dark:bg-zinc-800 px-4 pb-3 pt-5 shadow sm:px-6 sm:pt-6">
<dt>
<p class="truncate text-sm font-medium text-zinc-500 dark:text-zinc-400">
<%= @title %>
{@title}
</p>
</dt>
<dd class="flex items-baseline mt-1 pb-6 sm:pb-7">
@@ -59,7 +59,7 @@ defmodule MusicLibraryWeb.StatsLive.DataComponents do
href={@path}
class="text-2xl font-semibold text-zinc-900 hover:text-zinc-500 dark:text-zinc-300 dark:hover:text-zinc-200"
>
<%= @count %>
{@count}
</a>
</dd>
</div>
@@ -1,6 +1,6 @@
<div>
<h1 class="mt-5 text-base lg:text-2xl text-zinc-900 dark:text-zinc-200 font-semibold">
<%= gettext("Basics") %>
{gettext("Basics")}
</h1>
<dl class="mt-5 grid grid-cols-2 gap-5 sm:grid-cols-5">
<.album_preview
@@ -19,7 +19,7 @@
<div>
<h1 class="mt-5 text-base lg:text-2xl text-zinc-900 dark:text-zinc-200 font-semibold">
<%= gettext("Formats") %>
{gettext("Formats")}
</h1>
<dl class={[
"mt-5 grid divide-zinc-200 dark:divide-slate-300/50 overflow-hidden rounded-md bg-white dark:bg-zinc-800 shadow divide-x",
@@ -27,14 +27,14 @@
]}>
<div :for={{format, count} <- @collection_count_by_format} class="px-2 py-5 sm:px-4">
<dt class="text-sm font-medium text-zinc-500 dark:text-zinc-400 text-center max-sm:text-xs break-keep">
<%= Record.format_long_label(format) %>
{Record.format_long_label(format)}
</dt>
<dd class="mt-1 text-center">
<a
class="text-xl lg:text-2xl font-semibold hover:text-zinc-500 dark:text-zinc-300 dark:hover:text-zinc-200"
href={~p"/collection?query=format:#{format}"}
>
<%= count %>
{count}
</a>
</dd>
</div>
@@ -43,7 +43,7 @@
<div>
<h1 class="mt-5 text-base lg:text-2xl text-zinc-900 dark:text-zinc-200 font-semibold">
<%= gettext("Types") %>
{gettext("Types")}
</h1>
<dl class={[
"mt-5 grid divide-zinc-200 dark:divide-slate-300/50 overflow-hidden rounded-md bg-white dark:bg-zinc-800 shadow divide-x",
@@ -51,14 +51,14 @@
]}>
<div :for={{type, count} <- @collection_count_by_type} class="px-2 py-5 sm:px-4">
<dt class="text-sm font-medium text-zinc-500 dark:text-zinc-400 text-center max-sm:text-xs break-keep">
<%= Record.type_long_label(type) %>
{Record.type_long_label(type)}
</dt>
<dd class="mt-1 text-center">
<a
class="text-xl lg:text-2xl font-semibold hover:text-zinc-500 dark:text-zinc-300 dark:hover:text-zinc-200"
href={~p"/collection?query=type:#{type}"}
>
<%= count %>
{count}
</a>
</dd>
</div>
@@ -68,14 +68,14 @@
<div class="flow-root">
<div class="mt-5 flex justify-between items-center">
<h1 class="text-base lg:text-2xl text-zinc-900 dark:text-zinc-200 font-semibold">
<%= gettext("Scrobble activity") %>
{gettext("Scrobble activity")}
</h1>
<button
type="button"
class="phx-click-loading:animate-spin text-zinc-500 hover:text-zinc-900 dark:text-zinc-400 dark:hover:text-zinc-300"
phx-click={JS.push("refresh_lastfm_feed")}
>
<span class="sr-only"><%= gettext("Refresh LastFm Feed") %></span>
<span class="sr-only">{gettext("Refresh LastFm Feed")}</span>
<.icon name="hero-arrow-path" class="-mt-1 h-5 w-5" aria-hidden="true" data-slot="icon" />
</button>
</div>
@@ -97,19 +97,19 @@
<img class="h-12 w-12 rounded-md shadow" src={track.cover_url} alt={track.title} />
<div>
<p class="font-semibold text-sm block text-zinc-500 dark:text-zinc-400">
<%= track.artist.name %>
{track.artist.name}
</p>
<p class="font-semibold text-sm md:text-base text-zinc-700 dark:text-zinc-300">
<%= track.title %>
{track.title}
</p>
<p class="font-semibold text-sm text-zinc-500 dark:text-zinc-400">
<%= track.album.title %>
{track.album.title}
</p>
<time
datetime={format_scrobbled_at_uts(track.scrobbled_at_uts)}
class="whitespace-nowrap text-right text-xs sm:text-sm text-zinc-500 dark:text-zinc-400"
>
<%= track.scrobbled_at_label %>
{track.scrobbled_at_label}
</time>
</div>
</div>
@@ -125,7 +125,7 @@
"ring-zinc-600/20 dark:ring-zinc-500/20"
]}
>
<%= gettext("No MB ID") %>
{gettext("No MB ID")}
</span>
<span
:if={track.album.musicbrainz_id in @collected_release_ids}
@@ -138,7 +138,7 @@
"ring-green-600/20 dark:ring-green-500/20"
]}
>
<%= gettext("Collected") %>
{gettext("Collected")}
</span>
<span
:if={track.album.musicbrainz_id in @wishlisted_release_ids}
@@ -151,7 +151,7 @@
"ring-yellow-600/20 dark:ring-yellow-400/20"
]}
>
<%= gettext("Wishlisted") %>
{gettext("Wishlisted")}
</span>
<div
@@ -170,7 +170,7 @@
phx-click={toggle_actions_menu(track.scrobbled_at_uts)}
phx-click-away={close_actions_menu(track.scrobbled_at_uts)}
>
<span class="sr-only"><%= gettext("Choose which format to import") %></span>
<span class="sr-only">{gettext("Choose which format to import")}</span>
<.icon name="hero-star" class="-mt-1 h-5 w-5" aria-hidden="true" data-slot="icon" />
</button>
<!--
@@ -206,7 +206,7 @@
)
}
>
<%= Records.Record.format_long_label(format) %>
{Records.Record.format_long_label(format)}
</.link>
</.focus_wrap>
</div>
@@ -14,17 +14,17 @@
/>
</form>
<.link patch={~p"/wishlist/import"}>
<.button><%= gettext("Import") %></.button>
<.button>{gettext("Import")}</.button>
</.link>
</div>
</header>
<p class="text-right text-sm max-sm:text-xs mt-8 text-zinc-900 dark:text-zinc-400">
<%= gettext(
{gettext(
"Showing <b>%{visible}</b> of <b>%{total}</b> records",
%{visible: Enum.count(@streams.records), total: @record_list_params.total_entries}
)
|> raw() %>
|> raw()}
</p>
</div>
@@ -53,22 +53,22 @@
class="text-zinc-700 hover:text-zinc-500 dark:text-zinc-400 dark:hover:text-zinc-300"
patch={~p"/artists/#{artist.musicbrainz_id}"}
>
<%= artist.name %>
{artist.name}
</.link>
</h1>
<h2 class="mt-1 flex font-semibold text-sm sm:text-base leading-5 text-zinc-700 dark:text-zinc-300 text-wrap">
<%= record.title %>
{record.title}
</h2>
<p class="mt-1 text-xs leading-5 text-zinc-500 dark:text-zinc-400">
<%= Records.Record.format_release(record.release) %>
{Records.Record.format_release(record.release)}
<span class="sm:hidden">
· <%= Records.Record.format_long_label(record.format) %> · <%= Records.Record.type_long_label(
· {Records.Record.format_long_label(record.format)} · {Records.Record.type_long_label(
record.type
) %>
)}
<span :if={Records.Record.child_release_groups_count(record) > 0}>
·
<span class="sr-only">
<%= gettext("Number of included records") %>
{gettext("Number of included records")}
</span>
<span class={[
"inline-flex items-center rounded-full",
@@ -78,7 +78,7 @@
"text-gray-600 dark:text-gray-500",
"ring-gray-500/10 dark:ring-gray-400/20"
]}>
<%= Records.Record.child_release_groups_count(record) %>
{Records.Record.child_release_groups_count(record)}
</span>
</span>
</span>
@@ -88,13 +88,13 @@
<div class="flex shrink-0 items-center gap-x-6">
<div class="hidden sm:flex sm:flex-col sm:items-end">
<p class="text-xs leading-6 text-zinc-900 dark:text-zinc-300">
<%= Records.Record.format_long_label(record.format) %> · <%= Records.Record.type_long_label(
{Records.Record.format_long_label(record.format)} · {Records.Record.type_long_label(
record.type
) %>
)}
<span :if={Records.Record.child_release_groups_count(record) > 0}>
·
<span class="sr-only">
<%= gettext("Number of included records") %>
{gettext("Number of included records")}
</span>
<span class={[
"inline-flex items-center rounded-full",
@@ -104,7 +104,7 @@
"text-gray-600 dark:text-gray-500",
"ring-gray-500/10 dark:ring-gray-400/20"
]}>
<%= Records.Record.child_release_groups_count(record) %>
{Records.Record.child_release_groups_count(record)}
</span>
</span>
</p>
@@ -118,7 +118,7 @@
phx-click={toggle_actions_menu(record.id)}
phx-click-away={close_actions_menu(record.id)}
>
<span class="sr-only"><%= gettext("Open options") %></span>
<span class="sr-only">{gettext("Open options")}</span>
<.icon
name="hero-ellipsis-vertical"
class="-mt-1 h-5 w-5"
@@ -153,7 +153,7 @@
id={"actions-#{record.id}-show"}
navigate={~p"/wishlist/#{record}"}
>
<%= gettext("Show") %>
{gettext("Show")}
</.link>
<a
href={musicbrainz_url(record)}
@@ -163,7 +163,7 @@
tabindex="-1"
id={"actions-#{record.id}-musicbrainz"}
>
<%= gettext("View on MusicBrainz") %>
{gettext("View on MusicBrainz")}
</a>
<.link
@@ -173,7 +173,7 @@
id={"actions-#{record.id}-edit"}
patch={~p"/wishlist/#{record}/edit"}
>
<%= gettext("Edit") %>
{gettext("Edit")}
</.link>
<.link
@@ -183,7 +183,7 @@
id={"actions-#{record.id}-purchase"}
phx-click={JS.push("purchase", value: %{id: record.id})}
>
<%= gettext("Purchase") %>
{gettext("Purchase")}
</.link>
<.link
@@ -194,7 +194,7 @@
phx-click={JS.push("delete", value: %{id: record.id}) |> hide("##{id}")}
data-confirm={gettext("Are you sure?")}
>
<%= gettext("Delete") %>
{gettext("Delete")}
</.link>
</.focus_wrap>
</div>
@@ -14,46 +14,46 @@
class="text-zinc-700 hover:text-zinc-500 dark:text-zinc-400 dark:hover:text-zinc-300"
patch={~p"/artists/#{artist.musicbrainz_id}"}
>
<%= artist.name %>
{artist.name}
</.link>
</h1>
<h2 class="mt-1 flex font-semibold text-base sm:text-lg leading-5 text-zinc-700 dark:text-zinc-300 text-wrap">
<%= @record.title %>
{@record.title}
</h2>
<p class="mt-2 text-sm leading-5 text-zinc-500 dark:text-zinc-400">
<%= Records.Record.format_release(@record.release) %> · <%= Records.Record.format_long_label(
{Records.Record.format_release(@record.release)} · {Records.Record.format_long_label(
@record.format
) %> · <%= Records.Record.type_long_label(@record.type) %>
)} · {Records.Record.type_long_label(@record.type)}
</p>
<!-- TODO: extract to a component -->
<nav class="mt-5 isolate inline-flex rounded-md shadow-sm">
<.link patch={~p"/wishlist/#{@record}/show/edit"} phx-click={JS.push_focus()}>
<.button type="button" class="relative inline-flex items-center rounded-r-none">
<%= gettext("Edit") %>
{gettext("Edit")}
</.button>
</.link>
<.link phx-click={JS.push("refresh_cover", value: %{id: @record.id})}>
<.button type="button" class="relative -ml-px inline-flex items-center rounded-none">
<span class="sr-only"><%= gettext("Refresh") %></span>
<span class="sr-only">{gettext("Refresh")}</span>
<.icon
name="hero-arrow-path"
class="h-4 w-4 mr-1 phx-click-loading:animate-spin"
aria-hidden="true"
data-slot="icon"
/>
<%= gettext("Cover") %>
{gettext("Cover")}
</.button>
</.link>
<.link phx-click={JS.push("refresh_musicbrainz_data", value: %{id: @record.id})}>
<.button type="button" class="relative -ml-px inline-flex items-center rounded-none">
<span class="sr-only"><%= gettext("Refresh") %></span>
<span class="sr-only">{gettext("Refresh")}</span>
<.icon
name="hero-arrow-path"
class="h-4 w-4 mr-1 phx-click-loading:animate-spin"
aria-hidden="true"
data-slot="icon"
/>
<%= gettext("MB Data") %>
{gettext("MB Data")}
</.button>
</.link>
<.link
@@ -64,7 +64,7 @@
type="button"
class="relative -ml-px inline-flex items-center rounded-l-none !text-red-600 hover:!text-red-500 dark:!text-red-700 hover:dark:!text-red-500"
>
<%= gettext("Delete") %>
{gettext("Delete")}
</.button>
</.link>
</nav>
@@ -75,7 +75,7 @@
<dl class="mt-4 divide-y divide-zinc-100 dark:divide-slate-300/30">
<div class="py-2 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-0">
<dt class="text-sm font-medium leading-6 text-zinc-900 dark:text-zinc-400">
<%= gettext("Genres") %>
{gettext("Genres")}
</dt>
<dd class="mt-1 text-sm leading-6 text-zinc-700 dark:text-zinc-300 sm:col-span-2 sm:mt-0">
<.link
@@ -83,23 +83,23 @@
class="mr-2 text-zinc-700 hover:text-zinc-500 dark:text-zinc-400 dark:hover:text-zinc-300"
patch={~p"/wishlist?#{%{query: ~s(genre:"#{genre}")}}"}
>
<%= genre %>
{genre}
</.link>
</dd>
</div>
<div class="py-2 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-0">
<dt class="text-sm font-medium leading-6 text-zinc-900 dark:text-zinc-400">
<%= gettext("MusicBrainz ID") %>
{gettext("MusicBrainz ID")}
</dt>
<dd class="mt-1 text-sm flex justify-between leading-6 text-zinc-700 dark:text-zinc-300 sm:col-span-2 sm:mt-0">
<a href={musicbrainz_url(@record)}>
<code id={"mb-#{@record.musicbrainz_id}"}><%= @record.musicbrainz_id %></code>
<code id={"mb-#{@record.musicbrainz_id}"}>{@record.musicbrainz_id}</code>
</a>
<button phx-click={
JS.dispatch("music_library:clipcopy", to: "#mb-" <> @record.musicbrainz_id)
|> JS.transition("animate-shake")
}>
<span class="sr-only"><%= gettext("Copy MusicBrainz ID to clipboard") %></span>
<span class="sr-only">{gettext("Copy MusicBrainz ID to clipboard")}</span>
<.icon
name="hero-clipboard-document"
class="-mt-1 h-5 w-5"
@@ -114,30 +114,30 @@
class="py-2 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-0"
>
<dt class="text-sm font-medium leading-6 text-zinc-900 dark:text-zinc-400">
<%= gettext("Includes") %>
{gettext("Includes")}
</dt>
<dd class="mt-1 text-sm leading-6 text-zinc-700 dark:text-zinc-300 sm:col-span-2 sm:mt-0">
<ul>
<li :for={child_release_group <- Records.Record.child_release_groups(@record)}>
<%= child_release_group.artists %> - <%= child_release_group.title %>
{child_release_group.artists} - {child_release_group.title}
</li>
</ul>
</dd>
</div>
<div class="py-2 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-0">
<dt class="text-sm font-medium leading-6 text-zinc-900 dark:text-zinc-400">
<%= gettext("Inserted at") %>
{gettext("Inserted at")}
</dt>
<dd class="mt-1 text-sm leading-6 text-zinc-700 dark:text-zinc-300 sm:col-span-2 sm:mt-0">
<%= human_datetime(@record.inserted_at) %>
{human_datetime(@record.inserted_at)}
</dd>
</div>
<div class="py-2 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-0">
<dt class="text-sm font-medium leading-6 text-zinc-900 dark:text-zinc-400">
<%= gettext("Updated at") %>
{gettext("Updated at")}
</dt>
<dd class="mt-1 text-sm leading-6 text-zinc-700 dark:text-zinc-300 sm:col-span-2 sm:mt-0">
<%= human_datetime(@record.updated_at) %>
{human_datetime(@record.updated_at)}
</dd>
</div>
</dl>
@@ -145,13 +145,13 @@
</div>
<!-- TODO: extract to a component -->
<details class="mt-4 px-4 text-zinc-700 hover:text-zinc-500 dark:text-zinc-400 dark:hover:text-zinc-300">
<summary class="text-xs sm:text-sm"><%= gettext("MusicBrainz data") %></summary>
<summary class="text-xs sm:text-sm">{gettext("MusicBrainz data")}</summary>
<pre><code class="text-xs sm:text-sm"><%= Jason.encode!(@record.musicbrainz_data, pretty: true) %></code></pre>
</details>
<div class="mt-4">
<.back navigate={@back_url}>
<%= gettext("Back to wishlist") %>
{gettext("Back to wishlist")}
</.back>
</div>
@@ -30,22 +30,22 @@ defmodule MusicLibraryWeb.StatsLive.IndexTest do
conn: conn,
collection: collection
} do
{:ok, _stats_live, html} = live(conn, "/")
{:ok, stats_live, html} = live(conn, "/")
assert html =~ collection |> length() |> Integer.to_string()
collection
|> Enum.frequencies_by(& &1.format)
|> Enum.each(fn {format, count} ->
assert html =~ "\n#{count}\n"
assert html =~ "\n#{Record.format_long_label(format)}\n"
assert has_element?(stats_live, "a", to_string(count))
assert has_element?(stats_live, "dt", Record.format_long_label(format))
end)
collection
|> Enum.frequencies_by(& &1.type)
|> Enum.each(fn {type, count} ->
assert html =~ "\n#{count}\n"
assert html =~ "\n#{Record.type_long_label(type)}\n"
assert has_element?(stats_live, "a", to_string(count))
assert has_element?(stats_live, "dt", Record.type_long_label(type))
end)
end