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:
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user