Add canonical_tailwind to get correct formatting for tailwind classes
This commit is contained in:
@@ -2,6 +2,8 @@
|
|||||||
import_deps: [:error_tracker, :ecto, :ecto_sql, :oban, :oban_web, :phoenix, :phoenix_live_view],
|
import_deps: [:error_tracker, :ecto, :ecto_sql, :oban, :oban_web, :phoenix, :phoenix_live_view],
|
||||||
subdirectories: ["priv/*/migrations"],
|
subdirectories: ["priv/*/migrations"],
|
||||||
plugins: [Phoenix.LiveView.HTMLFormatter, Quokka],
|
plugins: [Phoenix.LiveView.HTMLFormatter, Quokka],
|
||||||
|
attribute_formatters: %{class: CanonicalTailwind},
|
||||||
|
canonical_tailwind: [pool_size: 2],
|
||||||
inputs: ["*.{heex,ex,exs}", "{config,lib,test}/**/*.{heex,ex,exs}", "priv/*/seeds.exs"],
|
inputs: ["*.{heex,ex,exs}", "{config,lib,test}/**/*.{heex,ex,exs}", "priv/*/seeds.exs"],
|
||||||
quokka: [
|
quokka: [
|
||||||
only: [
|
only: [
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ defmodule MusicLibraryWeb.Components.AddRecord do
|
|||||||
<div
|
<div
|
||||||
:if={@release_groups_count == 0}
|
:if={@release_groups_count == 0}
|
||||||
id="release-groups-empty"
|
id="release-groups-empty"
|
||||||
class="flex items-center justify-center h-32 md:h-64 text-md text-zinc-500"
|
class="text-md flex h-32 items-center justify-center text-zinc-500 md:h-64"
|
||||||
>
|
>
|
||||||
{gettext("No results")}
|
{gettext("No results")}
|
||||||
</div>
|
</div>
|
||||||
@@ -72,21 +72,21 @@ defmodule MusicLibraryWeb.Components.AddRecord do
|
|||||||
defp result(assigns) do
|
defp result(assigns) do
|
||||||
~H"""
|
~H"""
|
||||||
<li id={@id} class="flex justify-between gap-x-6 py-5 hover:bg-zinc-50 dark:hover:bg-zinc-700">
|
<li id={@id} class="flex justify-between gap-x-6 py-5 hover:bg-zinc-50 dark:hover:bg-zinc-700">
|
||||||
<div class="shrink-0 flex items-center justify-between w-full px-4">
|
<div class="flex w-full shrink-0 items-center justify-between px-4">
|
||||||
<img
|
<img
|
||||||
class="w-20 flex-none rounded-lg mr-4"
|
class="mr-4 w-20 flex-none rounded-lg"
|
||||||
alt={@release_group.title}
|
alt={@release_group.title}
|
||||||
src={ReleaseGroupSearchResult.thumb_url(@release_group)}
|
src={ReleaseGroupSearchResult.thumb_url(@release_group)}
|
||||||
onerror={"this.src = '" <> ~p"/images/cover-not-found.png" <> "';"}
|
onerror={"this.src = '" <> ~p"/images/cover-not-found.png" <> "';"}
|
||||||
/>
|
/>
|
||||||
<div class="min-w-0 flex-auto">
|
<div class="min-w-0 flex-auto">
|
||||||
<h1 class="truncate text-sm leading-6 text-zinc-700 dark:text-zinc-400">
|
<h1 class="truncate text-sm/6 text-zinc-700 dark:text-zinc-400">
|
||||||
{@release_group.artists}
|
{@release_group.artists}
|
||||||
</h1>
|
</h1>
|
||||||
<h2 class="truncate mt-1 flex font-semibold text-sm sm:text-base leading-5 text-zinc-700 dark:text-zinc-300 text-wrap">
|
<h2 class="mt-1 flex truncate text-sm/5 font-semibold text-wrap text-zinc-700 sm:text-base dark:text-zinc-300">
|
||||||
{@release_group.title}
|
{@release_group.title}
|
||||||
</h2>
|
</h2>
|
||||||
<p class="mt-1 text-xs leading-5 text-zinc-500 dark:text-zinc-400">
|
<p class="mt-1 text-xs/5 text-zinc-500 dark:text-zinc-400">
|
||||||
{Records.Record.format_release_date(@release_group.release_date)} · {type_label(
|
{Records.Record.format_release_date(@release_group.release_date)} · {type_label(
|
||||||
@release_group.type
|
@release_group.type
|
||||||
)}
|
)}
|
||||||
@@ -98,7 +98,7 @@ defmodule MusicLibraryWeb.Components.AddRecord do
|
|||||||
<span class="sr-only">{gettext("Choose which format to import")}</span>
|
<span class="sr-only">{gettext("Choose which format to import")}</span>
|
||||||
<.icon
|
<.icon
|
||||||
name="hero-plus"
|
name="hero-plus"
|
||||||
class="h-5 w-5 text-zinc-500 dark:text-zinc-400 cursor-pointer"
|
class="size-5 cursor-pointer text-zinc-500 dark:text-zinc-400"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
data-slot="icon"
|
data-slot="icon"
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -22,16 +22,16 @@ defmodule MusicLibraryWeb.Components.BarcodeScanner do
|
|||||||
~H"""
|
~H"""
|
||||||
<div class="min-w-72" id="barcode-scanner" phx-hook=".BarcodeScanner" phx-target={@myself}>
|
<div class="min-w-72" id="barcode-scanner" phx-hook=".BarcodeScanner" phx-target={@myself}>
|
||||||
<header>
|
<header>
|
||||||
<h1 class="text-sm font-medium leading-6 text-zinc-700 dark:text-zinc-400">
|
<h1 class="text-sm/6 font-medium text-zinc-700 dark:text-zinc-400">
|
||||||
{gettext("Scan one or more barcodes")}
|
{gettext("Scan one or more barcodes")}
|
||||||
</h1>
|
</h1>
|
||||||
</header>
|
</header>
|
||||||
<div class="mt-4">
|
<div class="mt-4">
|
||||||
<.camera_button camera={@camera} />
|
<.camera_button camera={@camera} />
|
||||||
<video :if={!(@camera == :denied)} class="w-full hidden h-96" id="camera-preview" playsinline />
|
<video :if={!(@camera == :denied)} class="hidden h-96 w-full" id="camera-preview" playsinline />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ul class="divide-y divide-zinc-100 dark:divide-slate-300/30 mt-5">
|
<ul class="mt-5 divide-y divide-zinc-100 dark:divide-slate-300/30">
|
||||||
<li
|
<li
|
||||||
:for={scan_result <- @scan_results}
|
:for={scan_result <- @scan_results}
|
||||||
id={scan_result.number}
|
id={scan_result.number}
|
||||||
@@ -141,7 +141,7 @@ defmodule MusicLibraryWeb.Components.BarcodeScanner do
|
|||||||
|> JS.dispatch("camera_request", to: "#barcode-scanner")
|
|> JS.dispatch("camera_request", to: "#barcode-scanner")
|
||||||
|> JS.hide(to: "#camera-button")
|
|> JS.hide(to: "#camera-button")
|
||||||
}
|
}
|
||||||
class="relative block w-full h-96 rounded-lg border-2 border-dashed border-zinc-300 p-12 text-center hover:border-zinc-400 outline-hidden"
|
class="relative block h-96 w-full rounded-lg border-2 border-dashed border-zinc-300 p-12 text-center outline-hidden hover:border-zinc-400"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
class="mx-auto size-12 text-zinc-400"
|
class="mx-auto size-12 text-zinc-400"
|
||||||
@@ -316,11 +316,11 @@ defmodule MusicLibraryWeb.Components.BarcodeScanner do
|
|||||||
|
|
||||||
defp barcode_not_found(assigns) do
|
defp barcode_not_found(assigns) do
|
||||||
~H"""
|
~H"""
|
||||||
<div class="w-full bg-red-50 dark:bg-red-950 p-4">
|
<div class="w-full bg-red-50 p-4 dark:bg-red-950">
|
||||||
<h1 class="text-sm leading-6 text-zinc-700 dark:text-zinc-400">
|
<h1 class="text-sm/6 text-zinc-700 dark:text-zinc-400">
|
||||||
{gettext("Barcode not found")}
|
{gettext("Barcode not found")}
|
||||||
</h1>
|
</h1>
|
||||||
<h2 class="mt-1 flex font-semibold text-sm sm:text-base leading-5 text-zinc-700 dark:text-zinc-300 text-wrap">
|
<h2 class="mt-1 flex text-sm/5 font-semibold text-wrap text-zinc-700 sm:text-base dark:text-zinc-300">
|
||||||
{@number}
|
{@number}
|
||||||
</h2>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
@@ -333,21 +333,21 @@ defmodule MusicLibraryWeb.Components.BarcodeScanner do
|
|||||||
|
|
||||||
defp release(assigns) do
|
defp release(assigns) do
|
||||||
~H"""
|
~H"""
|
||||||
<div class="flex items-center justify-between w-full">
|
<div class="flex w-full items-center justify-between">
|
||||||
<img
|
<img
|
||||||
class="w-16 md:w-20 flex-none rounded-lg mr-4"
|
class="mr-4 w-16 flex-none rounded-lg md:w-20"
|
||||||
alt={@release.release_group.title}
|
alt={@release.release_group.title}
|
||||||
src={ReleaseGroupSearchResult.thumb_url(@release.release_group)}
|
src={ReleaseGroupSearchResult.thumb_url(@release.release_group)}
|
||||||
onerror={"this.src = '" <> ~p"/images/cover-not-found.png" <> "';"}
|
onerror={"this.src = '" <> ~p"/images/cover-not-found.png" <> "';"}
|
||||||
/>
|
/>
|
||||||
<div class="min-w-0 flex-auto">
|
<div class="min-w-0 flex-auto">
|
||||||
<h1 class="text-sm leading-6 text-zinc-700 dark:text-zinc-400">
|
<h1 class="text-sm/6 text-zinc-700 dark:text-zinc-400">
|
||||||
{@release.artists}
|
{@release.artists}
|
||||||
</h1>
|
</h1>
|
||||||
<h2 class="mt-1 flex font-semibold text-sm sm:text-base leading-5 text-zinc-700 dark:text-zinc-300 text-wrap">
|
<h2 class="mt-1 flex text-sm/5 font-semibold text-wrap text-zinc-700 sm:text-base dark:text-zinc-300">
|
||||||
{@release.title}
|
{@release.title}
|
||||||
</h2>
|
</h2>
|
||||||
<p class="mt-1 text-xs leading-5 text-zinc-500 dark:text-zinc-400">
|
<p class="mt-1 text-xs/5 text-zinc-500 dark:text-zinc-400">
|
||||||
{release_format_label(@release)} · {Records.Record.format_release_date(@release.date)} · {RecordComponents.type_label(
|
{release_format_label(@release)} · {Records.Record.format_release_date(@release.date)} · {RecordComponents.type_label(
|
||||||
@release.release_group.type
|
@release.release_group.type
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ defmodule MusicLibraryWeb.ChartComponents do
|
|||||||
<svg
|
<svg
|
||||||
viewBox={"0 0 #{@width} #{@height}"}
|
viewBox={"0 0 #{@width} #{@height}"}
|
||||||
preserveAspectRatio="xMidYMid meet"
|
preserveAspectRatio="xMidYMid meet"
|
||||||
class="w-full h-full"
|
class="size-full"
|
||||||
>
|
>
|
||||||
<%!-- Bars and labels --%>
|
<%!-- Bars and labels --%>
|
||||||
<%= for {datum, index} <- Enum.with_index(@data) do %>
|
<%= for {datum, index} <- Enum.with_index(@data) do %>
|
||||||
@@ -52,7 +52,7 @@ defmodule MusicLibraryWeb.ChartComponents do
|
|||||||
y={y + @bar_height / 2 + 4}
|
y={y + @bar_height / 2 + 4}
|
||||||
text-anchor="end"
|
text-anchor="end"
|
||||||
class={[
|
class={[
|
||||||
"text-xs font-medium fill-zinc-500 hover:fill-zinc-700 dark:fill-zinc-400 dark:hover:fill-zinc-200",
|
"fill-zinc-500 text-xs font-medium hover:fill-zinc-700 dark:fill-zinc-400 dark:hover:fill-zinc-200",
|
||||||
@datum_click && "cursor-pointer"
|
@datum_click && "cursor-pointer"
|
||||||
]}
|
]}
|
||||||
phx-click={@datum_click && @datum_click.(datum)}
|
phx-click={@datum_click && @datum_click.(datum)}
|
||||||
@@ -68,7 +68,7 @@ defmodule MusicLibraryWeb.ChartComponents do
|
|||||||
height={@bar_height}
|
height={@bar_height}
|
||||||
rx="4"
|
rx="4"
|
||||||
class={[
|
class={[
|
||||||
"opacity-80 hover:opacity-100 transition-opacity",
|
"opacity-80 transition-opacity hover:opacity-100",
|
||||||
@color_class,
|
@color_class,
|
||||||
@datum_click && "cursor-pointer"
|
@datum_click && "cursor-pointer"
|
||||||
]}
|
]}
|
||||||
@@ -82,7 +82,7 @@ defmodule MusicLibraryWeb.ChartComponents do
|
|||||||
x={150 + bar_width + 5}
|
x={150 + bar_width + 5}
|
||||||
y={y + @bar_height / 2 + 4}
|
y={y + @bar_height / 2 + 4}
|
||||||
class={[
|
class={[
|
||||||
"text-xs font-semibold fill-zinc-500 dark:fill-zinc-400",
|
"fill-zinc-500 text-xs font-semibold dark:fill-zinc-400",
|
||||||
@datum_click && "cursor-pointer"
|
@datum_click && "cursor-pointer"
|
||||||
]}
|
]}
|
||||||
phx-click={@datum_click && @datum_click.(datum)}
|
phx-click={@datum_click && @datum_click.(datum)}
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ defmodule MusicLibraryWeb.Components.Chat do
|
|||||||
<.sheet
|
<.sheet
|
||||||
id={@sheet_id}
|
id={@sheet_id}
|
||||||
placement="right"
|
placement="right"
|
||||||
class="w-md sm:min-w-lg lg:min-w-2xl flex flex-col h-full"
|
class="flex h-full w-md flex-col sm:min-w-lg lg:min-w-2xl"
|
||||||
hide_close_button
|
hide_close_button
|
||||||
>
|
>
|
||||||
<%= if @view == :list do %>
|
<%= if @view == :list do %>
|
||||||
@@ -99,7 +99,7 @@ defmodule MusicLibraryWeb.Components.Chat do
|
|||||||
|
|
||||||
defp render_list_view(assigns) do
|
defp render_list_view(assigns) do
|
||||||
~H"""
|
~H"""
|
||||||
<div class="flex items-center justify-between pb-4 border-b border-zinc-200 dark:border-zinc-700">
|
<div class="flex items-center justify-between border-b border-zinc-200 pb-4 dark:border-zinc-700">
|
||||||
<h2 class="text-lg font-semibold text-zinc-900 dark:text-zinc-100">
|
<h2 class="text-lg font-semibold text-zinc-900 dark:text-zinc-100">
|
||||||
{gettext("Chat history")}
|
{gettext("Chat history")}
|
||||||
</h2>
|
</h2>
|
||||||
@@ -122,11 +122,11 @@ defmodule MusicLibraryWeb.Components.Chat do
|
|||||||
<div class="flex-1 overflow-y-auto py-4">
|
<div class="flex-1 overflow-y-auto py-4">
|
||||||
<div
|
<div
|
||||||
:if={@chats == []}
|
:if={@chats == []}
|
||||||
class="flex flex-col items-center justify-center h-full text-center text-zinc-500 dark:text-zinc-400"
|
class="flex h-full flex-col items-center justify-center text-center text-zinc-500 dark:text-zinc-400"
|
||||||
>
|
>
|
||||||
<.icon
|
<.icon
|
||||||
name="hero-chat-bubble-left-right"
|
name="hero-chat-bubble-left-right"
|
||||||
class="size-12 mb-4 text-zinc-300 dark:text-zinc-600"
|
class="mb-4 size-12 text-zinc-300 dark:text-zinc-600"
|
||||||
/>
|
/>
|
||||||
<p class="text-sm font-medium">{gettext("No previous chats")}</p>
|
<p class="text-sm font-medium">{gettext("No previous chats")}</p>
|
||||||
</div>
|
</div>
|
||||||
@@ -136,12 +136,12 @@ defmodule MusicLibraryWeb.Components.Chat do
|
|||||||
phx-click="select_chat"
|
phx-click="select_chat"
|
||||||
phx-value-id={chat.id}
|
phx-value-id={chat.id}
|
||||||
phx-target={@myself}
|
phx-target={@myself}
|
||||||
class="w-full text-left px-3 py-3 rounded-lg hover:bg-zinc-50 dark:hover:bg-zinc-800 transition-colors"
|
class="w-full rounded-lg p-3 text-left transition-colors hover:bg-zinc-50 dark:hover:bg-zinc-800"
|
||||||
>
|
>
|
||||||
<p class="text-sm font-medium text-zinc-900 dark:text-zinc-100 truncate">
|
<p class="truncate text-sm font-medium text-zinc-900 dark:text-zinc-100">
|
||||||
{chat.topic || gettext("Untitled")}
|
{chat.topic || gettext("Untitled")}
|
||||||
</p>
|
</p>
|
||||||
<p class="text-xs text-zinc-500 dark:text-zinc-400 mt-1">
|
<p class="mt-1 text-xs text-zinc-500 dark:text-zinc-400">
|
||||||
{ngettext("%{count} message", "%{count} messages", chat.message_count)} · {Calendar.strftime(
|
{ngettext("%{count} message", "%{count} messages", chat.message_count)} · {Calendar.strftime(
|
||||||
chat.updated_at,
|
chat.updated_at,
|
||||||
"%b %-d, %Y"
|
"%b %-d, %Y"
|
||||||
@@ -156,7 +156,7 @@ defmodule MusicLibraryWeb.Components.Chat do
|
|||||||
phx-value-id={chat.id}
|
phx-value-id={chat.id}
|
||||||
phx-target={@myself}
|
phx-target={@myself}
|
||||||
aria-label={gettext("Delete chat")}
|
aria-label={gettext("Delete chat")}
|
||||||
class="absolute top-3 right-2 opacity-0 group-hover:opacity-100 transition-opacity"
|
class="absolute top-3 right-2 opacity-0 transition-opacity group-hover:opacity-100"
|
||||||
>
|
>
|
||||||
<.icon name="hero-trash" class="icon" />
|
<.icon name="hero-trash" class="icon" />
|
||||||
</.button>
|
</.button>
|
||||||
@@ -167,8 +167,8 @@ defmodule MusicLibraryWeb.Components.Chat do
|
|||||||
|
|
||||||
defp render_active_view(assigns) do
|
defp render_active_view(assigns) do
|
||||||
~H"""
|
~H"""
|
||||||
<div class="flex items-center gap-2 pb-4 border-b border-zinc-200 dark:border-zinc-700">
|
<div class="flex items-center gap-2 border-b border-zinc-200 pb-4 dark:border-zinc-700">
|
||||||
<h2 class="text-lg font-semibold text-zinc-900 dark:text-zinc-100 flex-1">
|
<h2 class="flex-1 text-lg font-semibold text-zinc-900 dark:text-zinc-100">
|
||||||
{gettext("Chat about %{title}", title: @title)}
|
{gettext("Chat about %{title}", title: @title)}
|
||||||
</h2>
|
</h2>
|
||||||
<.button
|
<.button
|
||||||
@@ -203,16 +203,16 @@ defmodule MusicLibraryWeb.Components.Chat do
|
|||||||
|
|
||||||
<div
|
<div
|
||||||
id={"#{@id}-messages"}
|
id={"#{@id}-messages"}
|
||||||
class="flex-1 overflow-y-auto py-4 space-y-4"
|
class="flex-1 space-y-4 overflow-y-auto py-4"
|
||||||
phx-hook=".ScrollBottom"
|
phx-hook=".ScrollBottom"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
:if={@messages == [] and @current_response == ""}
|
:if={@messages == [] and @current_response == ""}
|
||||||
class="flex flex-col items-center justify-center h-full text-center text-zinc-500 dark:text-zinc-400"
|
class="flex h-full flex-col items-center justify-center text-center text-zinc-500 dark:text-zinc-400"
|
||||||
>
|
>
|
||||||
<.icon
|
<.icon
|
||||||
name="hero-chat-bubble-left-right"
|
name="hero-chat-bubble-left-right"
|
||||||
class="size-12 mb-4 text-zinc-300 dark:text-zinc-600"
|
class="mb-4 size-12 text-zinc-300 dark:text-zinc-600"
|
||||||
/>
|
/>
|
||||||
<p class="text-sm font-medium">{@empty_prompt}</p>
|
<p class="text-sm font-medium">{@empty_prompt}</p>
|
||||||
</div>
|
</div>
|
||||||
@@ -225,16 +225,16 @@ defmodule MusicLibraryWeb.Components.Chat do
|
|||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
<p :if={message.role == "user"} class="whitespace-pre-wrap">{message.content}</p>
|
<p :if={message.role == "user"} class="whitespace-pre-wrap">{message.content}</p>
|
||||||
<div :if={message.role == "assistant"} class="prose prose-sm dark:prose-invert">
|
<div :if={message.role == "assistant"} class="dark:prose-invert prose prose-sm">
|
||||||
{raw(Markdown.to_html(message.content))}
|
{raw(Markdown.to_html(message.content))}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
:if={@current_response != ""}
|
:if={@current_response != ""}
|
||||||
class="max-w-[85%] rounded-lg px-4 py-2 text-sm bg-zinc-100 dark:bg-zinc-700 text-zinc-900 dark:text-zinc-100"
|
class="max-w-[85%] rounded-lg bg-zinc-100 px-4 py-2 text-sm text-zinc-900 dark:bg-zinc-700 dark:text-zinc-100"
|
||||||
>
|
>
|
||||||
<div class="prose prose-sm dark:prose-invert">
|
<div class="dark:prose-invert prose prose-sm">
|
||||||
{raw(Markdown.to_html(@current_response))}
|
{raw(Markdown.to_html(@current_response))}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -249,7 +249,7 @@ defmodule MusicLibraryWeb.Components.Chat do
|
|||||||
|
|
||||||
<div
|
<div
|
||||||
:if={@error}
|
:if={@error}
|
||||||
class="max-w-[85%] rounded-lg px-4 py-2 text-sm bg-red-50 dark:bg-red-900/20 text-red-700 dark:text-red-300"
|
class="max-w-[85%] rounded-lg bg-red-50 px-4 py-2 text-sm text-red-700 dark:bg-red-900/20 dark:text-red-300"
|
||||||
>
|
>
|
||||||
<p>{@error}</p>
|
<p>{@error}</p>
|
||||||
<.button
|
<.button
|
||||||
@@ -265,7 +265,7 @@ defmodule MusicLibraryWeb.Components.Chat do
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="pt-4 border-t border-zinc-200 dark:border-zinc-700">
|
<div class="border-t border-zinc-200 pt-4 dark:border-zinc-700">
|
||||||
<form
|
<form
|
||||||
id={"#{@id}-form"}
|
id={"#{@id}-form"}
|
||||||
phx-submit="send_message"
|
phx-submit="send_message"
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ defmodule MusicLibraryWeb.CoreComponents do
|
|||||||
def debug_data_sheet(assigns) do
|
def debug_data_sheet(assigns) do
|
||||||
~H"""
|
~H"""
|
||||||
<.sheet :if={@items != []} id={@id} placement="right" class="w-md sm:min-w-lg lg:min-w-2xl">
|
<.sheet :if={@items != []} id={@id} placement="right" class="w-md sm:min-w-lg lg:min-w-2xl">
|
||||||
<h2 class="text-sm font-semibold text-zinc-900 dark:text-zinc-100 mb-4">
|
<h2 class="mb-4 text-sm font-semibold text-zinc-900 dark:text-zinc-100">
|
||||||
{gettext("Debug data")}
|
{gettext("Debug data")}
|
||||||
</h2>
|
</h2>
|
||||||
<.tabs id={"#{@id}-tabs"}>
|
<.tabs id={"#{@id}-tabs"}>
|
||||||
@@ -122,11 +122,11 @@ defmodule MusicLibraryWeb.CoreComponents do
|
|||||||
</.tabs_list>
|
</.tabs_list>
|
||||||
<.tabs_panel :for={item <- @items} name={item.name} active={item == hd(@items)}>
|
<.tabs_panel :for={item <- @items} name={item.name} active={item == hd(@items)}>
|
||||||
<%= if item.type == :json do %>
|
<%= if item.type == :json do %>
|
||||||
<div class="mt-4 overflow-auto text-xs rounded-lg [&_pre]:p-4 [&_pre]:rounded-lg">
|
<div class="mt-4 overflow-auto rounded-lg text-xs [&_pre]:rounded-lg [&_pre]:p-4">
|
||||||
{format_debug_data(item)}
|
{format_debug_data(item)}
|
||||||
</div>
|
</div>
|
||||||
<% else %>
|
<% else %>
|
||||||
<pre class="mt-4 overflow-auto text-xs font-mono text-zinc-700 dark:text-zinc-300 bg-zinc-50 dark:bg-zinc-800 rounded-lg p-4"><code>{format_debug_data(item)}</code></pre>
|
<pre class="mt-4 overflow-auto rounded-lg bg-zinc-50 p-4 font-mono text-xs text-zinc-700 dark:bg-zinc-800 dark:text-zinc-300"><code>{format_debug_data(item)}</code></pre>
|
||||||
<% end %>
|
<% end %>
|
||||||
</.tabs_panel>
|
</.tabs_panel>
|
||||||
</.tabs>
|
</.tabs>
|
||||||
@@ -160,7 +160,7 @@ defmodule MusicLibraryWeb.CoreComponents do
|
|||||||
~H"""
|
~H"""
|
||||||
<Fluxon.Components.Modal.modal
|
<Fluxon.Components.Modal.modal
|
||||||
id={@id}
|
id={@id}
|
||||||
class="mx-auto sm:min-w-2xl max-w-sm md:max-w-3xl mt-8"
|
class="mx-auto mt-8 max-w-sm sm:min-w-2xl md:max-w-3xl"
|
||||||
placement="top"
|
placement="top"
|
||||||
open={@open}
|
open={@open}
|
||||||
on_close={@on_close}
|
on_close={@on_close}
|
||||||
@@ -178,7 +178,7 @@ defmodule MusicLibraryWeb.CoreComponents do
|
|||||||
:if={@external_links != []}
|
:if={@external_links != []}
|
||||||
class="mt-4 text-zinc-700 hover:text-zinc-500 dark:text-zinc-400 dark:hover:text-zinc-300"
|
class="mt-4 text-zinc-700 hover:text-zinc-500 dark:text-zinc-400 dark:hover:text-zinc-300"
|
||||||
>
|
>
|
||||||
<summary class="text-xs sm:text-sm font-medium cursor-pointer">
|
<summary class="cursor-pointer text-xs font-medium sm:text-sm">
|
||||||
{gettext("External Links")}
|
{gettext("External Links")}
|
||||||
</summary>
|
</summary>
|
||||||
<div class="mt-4 space-y-2">
|
<div class="mt-4 space-y-2">
|
||||||
@@ -236,10 +236,10 @@ defmodule MusicLibraryWeb.CoreComponents do
|
|||||||
def dl_row(assigns) do
|
def dl_row(assigns) do
|
||||||
~H"""
|
~H"""
|
||||||
<div class="py-2 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-0">
|
<div class="py-2 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-0">
|
||||||
<dt class="text-xs md:text-sm font-medium leading-6 text-zinc-900 dark:text-zinc-400">
|
<dt class="text-xs/6 font-medium text-zinc-900 md:text-sm dark:text-zinc-400">
|
||||||
{@label}
|
{@label}
|
||||||
</dt>
|
</dt>
|
||||||
<dd class="mt-1 text-xs md:text-sm leading-6 text-zinc-700 dark:text-zinc-300 sm:col-span-2 sm:mt-0">
|
<dd class="mt-1 text-xs/6 text-zinc-700 sm:col-span-2 sm:mt-0 md:text-sm dark:text-zinc-300">
|
||||||
{render_slot(@inner_block)}
|
{render_slot(@inner_block)}
|
||||||
</dd>
|
</dd>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ defmodule MusicLibraryWeb.Layouts do
|
|||||||
@current_section == @section &&
|
@current_section == @section &&
|
||||||
"border-red-500 text-zinc-900 dark:text-zinc-100",
|
"border-red-500 text-zinc-900 dark:text-zinc-100",
|
||||||
@current_section !== @section &&
|
@current_section !== @section &&
|
||||||
"border-transparent text-zinc-500 hover:border-red-300 hover:text-zinc-700 dark:text-zinc-300 dark:hover:text-zinc-200 dark:hover:border-red-700"
|
"border-transparent text-zinc-500 hover:border-red-300 hover:text-zinc-700 dark:text-zinc-300 dark:hover:border-red-700 dark:hover:text-zinc-200"
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
{render_slot(@inner_block)}
|
{render_slot(@inner_block)}
|
||||||
@@ -56,7 +56,7 @@ defmodule MusicLibraryWeb.Layouts do
|
|||||||
)
|
)
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
<.icon name={@icon} class="h-4 w-4 mr-2" aria-hidden="true" data-slot="icon" />
|
<.icon name={@icon} class="mr-2 size-4" aria-hidden="true" data-slot="icon" />
|
||||||
{render_slot(@inner_block)}
|
{render_slot(@inner_block)}
|
||||||
</.dropdown_link>
|
</.dropdown_link>
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
<div
|
<div
|
||||||
:if={assigns[:static_changed]}
|
:if={assigns[:static_changed]}
|
||||||
class="bg-yellow-100 dark:bg-yellow-900 border-b border-yellow-300 dark:border-yellow-700 px-4 py-2 text-center text-sm text-yellow-700 dark:text-yellow-200"
|
class="border-b border-yellow-300 bg-yellow-100 px-4 py-2 text-center text-sm text-yellow-700 dark:border-yellow-700 dark:bg-yellow-900 dark:text-yellow-200"
|
||||||
>
|
>
|
||||||
{gettext("The application has been updated.")}
|
{gettext("The application has been updated.")}
|
||||||
<a href="" onclick="window.location.reload()" class="underline font-medium">
|
<a href="" onclick="window.location.reload()" class="font-medium underline">
|
||||||
{gettext("Reload")}
|
{gettext("Reload")}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
<.nav_link route={~p"/"} section={:stats} current_section={@current_section}>
|
<.nav_link route={~p"/"} section={:stats} current_section={@current_section}>
|
||||||
<.icon
|
<.icon
|
||||||
name="hero-chart-pie"
|
name="hero-chart-pie"
|
||||||
class="max-sm:hidden h-4 w-4 mr-2"
|
class="mr-2 size-4 max-sm:hidden"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
data-slot="icon"
|
data-slot="icon"
|
||||||
/>
|
/>
|
||||||
@@ -28,7 +28,7 @@
|
|||||||
>
|
>
|
||||||
<.icon
|
<.icon
|
||||||
name="hero-circle-stack"
|
name="hero-circle-stack"
|
||||||
class="max-sm:hidden h-4 w-4 mr-2"
|
class="mr-2 size-4 max-sm:hidden"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
data-slot="icon"
|
data-slot="icon"
|
||||||
/>
|
/>
|
||||||
@@ -37,7 +37,7 @@
|
|||||||
<.nav_link route={~p"/wishlist"} section={:wishlist} current_section={@current_section}>
|
<.nav_link route={~p"/wishlist"} section={:wishlist} current_section={@current_section}>
|
||||||
<.icon
|
<.icon
|
||||||
name="hero-star"
|
name="hero-star"
|
||||||
class="max-sm:hidden h-4 w-4 mr-2"
|
class="mr-2 size-4 max-sm:hidden"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
data-slot="icon"
|
data-slot="icon"
|
||||||
/>
|
/>
|
||||||
@@ -50,7 +50,7 @@
|
|||||||
>
|
>
|
||||||
<.icon
|
<.icon
|
||||||
name="hero-rectangle-stack"
|
name="hero-rectangle-stack"
|
||||||
class="max-sm:hidden h-4 w-4 mr-2"
|
class="mr-2 size-4 max-sm:hidden"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
data-slot="icon"
|
data-slot="icon"
|
||||||
/>
|
/>
|
||||||
@@ -67,7 +67,7 @@
|
|||||||
<span class="sr-only">{gettext("Actions")}</span>
|
<span class="sr-only">{gettext("Actions")}</span>
|
||||||
<.icon
|
<.icon
|
||||||
name="hero-ellipsis-vertical"
|
name="hero-ellipsis-vertical"
|
||||||
class="icon text-zinc-500 dark:text-zinc-400 cursor-pointer"
|
class="icon cursor-pointer text-zinc-500 dark:text-zinc-400"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
data-slot="icon"
|
data-slot="icon"
|
||||||
/>
|
/>
|
||||||
@@ -117,25 +117,25 @@
|
|||||||
<.dropdown_link href={~p"/dev/dashboard"}>
|
<.dropdown_link href={~p"/dev/dashboard"}>
|
||||||
<.icon
|
<.icon
|
||||||
name="hero-chart-bar"
|
name="hero-chart-bar"
|
||||||
class="h-4 w-4 mr-2"
|
class="mr-2 size-4"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
data-slot="icon"
|
data-slot="icon"
|
||||||
/>
|
/>
|
||||||
{gettext("Live Dashboard")}
|
{gettext("Live Dashboard")}
|
||||||
</.dropdown_link>
|
</.dropdown_link>
|
||||||
<.dropdown_link href={~p"/dev/oban"}>
|
<.dropdown_link href={~p"/dev/oban"}>
|
||||||
<.icon name="hero-cog" class="h-4 w-4 mr-2" aria-hidden="true" data-slot="icon" />
|
<.icon name="hero-cog" class="mr-2 size-4" aria-hidden="true" data-slot="icon" />
|
||||||
{gettext("Oban")}
|
{gettext("Oban")}
|
||||||
</.dropdown_link>
|
</.dropdown_link>
|
||||||
<.dropdown_link href={~p"/dev/errors"}>
|
<.dropdown_link href={~p"/dev/errors"}>
|
||||||
<.icon name="hero-bug-ant" class="h-4 w-4 mr-2" aria-hidden="true" data-slot="icon" />
|
<.icon name="hero-bug-ant" class="mr-2 size-4" aria-hidden="true" data-slot="icon" />
|
||||||
{gettext("Errors")}
|
{gettext("Errors")}
|
||||||
</.dropdown_link>
|
</.dropdown_link>
|
||||||
<.dropdown_separator />
|
<.dropdown_separator />
|
||||||
<.dropdown_link href={~p"/login"}>
|
<.dropdown_link href={~p"/login"}>
|
||||||
<.icon
|
<.icon
|
||||||
name="hero-arrow-left-start-on-rectangle"
|
name="hero-arrow-left-start-on-rectangle"
|
||||||
class="h-4 w-4 mr-2"
|
class="mr-2 size-4"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
data-slot="icon"
|
data-slot="icon"
|
||||||
/>
|
/>
|
||||||
@@ -147,7 +147,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
<main class="px-4 py-4 sm:px-6 lg:px-8">
|
<main class="p-4 sm:px-6 lg:px-8">
|
||||||
<div class="mx-auto max-w-screen-2xl">
|
<div class="mx-auto max-w-screen-2xl">
|
||||||
<LiveToast.toast_group
|
<LiveToast.toast_group
|
||||||
flash={@flash}
|
flash={@flash}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en" class="[scrollbar-gutter:stable] scroll-smooth subpixel-antialiased">
|
<html lang="en" class="scroll-smooth subpixel-antialiased [scrollbar-gutter:stable]">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" />
|
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" />
|
||||||
@@ -39,9 +39,9 @@
|
|||||||
<body class="bg-white dark:bg-zinc-900">
|
<body class="bg-white dark:bg-zinc-900">
|
||||||
{@inner_content}
|
{@inner_content}
|
||||||
<footer class="mt-4 border-t border-slate-900/10 dark:border-slate-300/10">
|
<footer class="mt-4 border-t border-slate-900/10 dark:border-slate-300/10">
|
||||||
<div class="mx-auto max-w-screen-2xl pb-8 px-4 sm:px-8 2xl:px-0">
|
<div class="mx-auto max-w-screen-2xl px-4 pb-8 sm:px-8 2xl:px-0">
|
||||||
<div class="pt-4 flex items-center justify-between">
|
<div class="flex items-center justify-between pt-4">
|
||||||
<div class="flex gap-x-6 order-2">
|
<div class="order-2 flex gap-x-6">
|
||||||
<a
|
<a
|
||||||
href="https://github.com/cloud8421/music_library"
|
href="https://github.com/cloud8421/music_library"
|
||||||
class="text-zinc-600 hover:text-zinc-800 dark:text-zinc-400 dark:hover:text-zinc-300"
|
class="text-zinc-600 hover:text-zinc-800 dark:text-zinc-400 dark:hover:text-zinc-300"
|
||||||
@@ -56,7 +56,7 @@
|
|||||||
</svg>
|
</svg>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<p class="text-sm/6 text-zinc-600 dark:text-zinc-400 order-1">
|
<p class="order-1 text-sm/6 text-zinc-600 dark:text-zinc-400">
|
||||||
<span>{gettext("Made by")}</span>
|
<span>{gettext("Made by")}</span>
|
||||||
<a
|
<a
|
||||||
class="font-medium text-zinc-500 hover:border-zinc-300 hover:text-zinc-700 dark:text-zinc-300 dark:hover:text-zinc-200"
|
class="font-medium text-zinc-500 hover:border-zinc-300 hover:text-zinc-700 dark:text-zinc-300 dark:hover:text-zinc-200"
|
||||||
|
|||||||
@@ -39,10 +39,10 @@ defmodule MusicLibraryWeb.Components.Notes do
|
|||||||
<.sheet
|
<.sheet
|
||||||
id={@sheet_id}
|
id={@sheet_id}
|
||||||
placement="right"
|
placement="right"
|
||||||
class="w-md sm:min-w-lg lg:min-w-2xl py-16"
|
class="w-md py-16 sm:min-w-lg lg:min-w-2xl"
|
||||||
>
|
>
|
||||||
<.tabs>
|
<.tabs>
|
||||||
<.tabs_list variant="segmented" class="w-48 mx-auto md:mx-0" active_tab={@mode}>
|
<.tabs_list variant="segmented" class="mx-auto w-48 md:mx-0" active_tab={@mode}>
|
||||||
<:tab name="read" phx-click="set_mode" phx-value-mode="read" phx-target={@myself}>
|
<:tab name="read" phx-click="set_mode" phx-value-mode="read" phx-target={@myself}>
|
||||||
{gettext("Read")}
|
{gettext("Read")}
|
||||||
</:tab>
|
</:tab>
|
||||||
@@ -51,7 +51,7 @@ defmodule MusicLibraryWeb.Components.Notes do
|
|||||||
</:tab>
|
</:tab>
|
||||||
</.tabs_list>
|
</.tabs_list>
|
||||||
<.tabs_panel active={@mode == "read"} name="read">
|
<.tabs_panel active={@mode == "read"} name="read">
|
||||||
<article class="w-full mt-5 prose dark:prose-invert prose-zinc prose-sm prose-h1:text-sm">
|
<article class="dark:prose-invert prose prose-h1:text-sm prose-sm prose-zinc mt-5 w-full">
|
||||||
{render_content(@form[:content].value)}
|
{render_content(@form[:content].value)}
|
||||||
</article>
|
</article>
|
||||||
</.tabs_panel>
|
</.tabs_panel>
|
||||||
@@ -66,7 +66,7 @@ defmodule MusicLibraryWeb.Components.Notes do
|
|||||||
>
|
>
|
||||||
<.textarea
|
<.textarea
|
||||||
class={[
|
class={[
|
||||||
"w-full min-h-128 md:min-h-164 overflow-scroll font-mono",
|
"min-h-128 w-full overflow-scroll font-mono md:min-h-164",
|
||||||
@form[:content].value != @note.content &&
|
@form[:content].value != @note.content &&
|
||||||
"border-amber-300 focus-visible:border-amber-300"
|
"border-amber-300 focus-visible:border-amber-300"
|
||||||
]}
|
]}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ defmodule MusicLibraryWeb.Components.Pagination do
|
|||||||
<div
|
<div
|
||||||
:if={@page_links.total_pages > 1}
|
:if={@page_links.total_pages > 1}
|
||||||
id={@id}
|
id={@id}
|
||||||
class="flex items-center justify-between px-4 py-6 mb-4"
|
class="mb-4 flex items-center justify-between px-4 py-6"
|
||||||
>
|
>
|
||||||
<%!-- Only on smallest viewport --%>
|
<%!-- Only on smallest viewport --%>
|
||||||
<div class={[
|
<div class={[
|
||||||
@@ -34,7 +34,7 @@ defmodule MusicLibraryWeb.Components.Pagination do
|
|||||||
{gettext("Next")}
|
{gettext("Next")}
|
||||||
</.button>
|
</.button>
|
||||||
</div>
|
</div>
|
||||||
<div class="hidden sm:flex sm:flex-1 sm:items-center sm:justify-items-center sm:justify-center">
|
<div class="hidden sm:flex sm:flex-1 sm:items-center sm:justify-center sm:justify-items-center">
|
||||||
<div>
|
<div>
|
||||||
<.button_group>
|
<.button_group>
|
||||||
<.prev_link
|
<.prev_link
|
||||||
|
|||||||
@@ -17,12 +17,12 @@ defmodule MusicLibraryWeb.RecordComponents do
|
|||||||
<span
|
<span
|
||||||
:if={Records.Record.included_release_groups_count(@record) > 0}
|
:if={Records.Record.included_release_groups_count(@record) > 0}
|
||||||
class={[
|
class={[
|
||||||
"absolute right-0 bottom-0 rounded-br-lg rounded-tl-lg",
|
"absolute right-0 bottom-0 rounded-tl-lg rounded-br-lg",
|
||||||
"font-medium",
|
"font-medium",
|
||||||
"border border-zinc-600/20 dark:border-zinc-500/20",
|
"border border-zinc-600/20 dark:border-zinc-500/20",
|
||||||
@size == :sm &&
|
@size == :sm &&
|
||||||
"px-1 text-xs bg-zinc-200/80 dark:bg-zinc-500/70 text-zinc-700 dark:text-zinc-200",
|
"bg-zinc-200/80 px-1 text-xs text-zinc-700 dark:bg-zinc-500/70 dark:text-zinc-200",
|
||||||
@size == :md && "px-2 text-sm bg-zinc-50 dark:bg-zinc-500/10 text-zinc-700 dark:text-zinc-400"
|
@size == :md && "bg-zinc-50 px-2 text-sm text-zinc-700 dark:bg-zinc-500/10 dark:text-zinc-400"
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
{Records.Record.included_release_groups_count(@record)}
|
{Records.Record.included_release_groups_count(@record)}
|
||||||
@@ -77,7 +77,7 @@ defmodule MusicLibraryWeb.RecordComponents do
|
|||||||
def record_list(assigns) do
|
def record_list(assigns) do
|
||||||
~H"""
|
~H"""
|
||||||
<ul
|
<ul
|
||||||
class="divide-y divide-zinc-100 dark:divide-zinc-300/20 mt-5"
|
class="mt-5 divide-y divide-zinc-100 dark:divide-zinc-300/20"
|
||||||
role="list"
|
role="list"
|
||||||
id="records"
|
id="records"
|
||||||
phx-update="stream"
|
phx-update="stream"
|
||||||
@@ -85,28 +85,28 @@ defmodule MusicLibraryWeb.RecordComponents do
|
|||||||
<li
|
<li
|
||||||
:for={{id, record} <- @records}
|
:for={{id, record} <- @records}
|
||||||
phx-click={JS.navigate(@record_show_path.(record))}
|
phx-click={JS.navigate(@record_show_path.(record))}
|
||||||
class="flex justify-between gap-x-6 py-5 hover:bg-zinc-50 dark:hover:bg-zinc-800 px-2 -mx-2 md:px-4 md:-mx-4 cursor-pointer"
|
class="-mx-2 flex cursor-pointer justify-between gap-x-6 px-2 py-5 hover:bg-zinc-50 md:-mx-4 md:px-4 dark:hover:bg-zinc-800"
|
||||||
id={id}
|
id={id}
|
||||||
>
|
>
|
||||||
<div class="flex min-w-0 gap-x-4 items-center">
|
<div class="flex min-w-0 items-center gap-x-4">
|
||||||
<div class="relative w-20 flex-none">
|
<div class="relative w-20 flex-none">
|
||||||
<.record_cover record={record} width={160} />
|
<.record_cover record={record} width={160} />
|
||||||
<.release_groups_badge record={record} />
|
<.release_groups_badge record={record} />
|
||||||
</div>
|
</div>
|
||||||
<div class="min-w-0 flex-auto">
|
<div class="min-w-0 flex-auto">
|
||||||
<h1 class="text-sm leading-6 text-zinc-700">
|
<h1 class="text-sm/6 text-zinc-700">
|
||||||
<.artist_links joinphrase_class="text-xs" artists={record.artists} />
|
<.artist_links joinphrase_class="text-xs" artists={record.artists} />
|
||||||
</h1>
|
</h1>
|
||||||
<h2 class="mt-1 flex font-semibold text-sm sm:text-base leading-5 text-zinc-700 dark:text-zinc-300 text-wrap">
|
<h2 class="mt-1 flex text-sm/5 font-semibold text-wrap text-zinc-700 sm:text-base dark:text-zinc-300">
|
||||||
{record.title}
|
{record.title}
|
||||||
</h2>
|
</h2>
|
||||||
<p class="mt-1 text-xs leading-5 text-zinc-500 dark:text-zinc-400">
|
<p class="mt-1 text-xs/5 text-zinc-500 dark:text-zinc-400">
|
||||||
{Records.Record.format_release_date(record.release_date)}
|
{Records.Record.format_release_date(record.release_date)}
|
||||||
<span :if={@current_date && !Records.Record.released?(record, @current_date)}>
|
<span :if={@current_date && !Records.Record.released?(record, @current_date)}>
|
||||||
({gettext("Unreleased")})
|
({gettext("Unreleased")})
|
||||||
</span>
|
</span>
|
||||||
</p>
|
</p>
|
||||||
<p class="sm:hidden mt-1 text-xs leading-5 text-zinc-500 dark:text-zinc-400">
|
<p class="mt-1 text-xs/5 text-zinc-500 sm:hidden dark:text-zinc-400">
|
||||||
{format_label(record.format)} · {type_label(record.type)}
|
{format_label(record.format)} · {type_label(record.type)}
|
||||||
<span :if={record.purchased_at}>
|
<span :if={record.purchased_at}>
|
||||||
·
|
·
|
||||||
@@ -115,7 +115,7 @@ defmodule MusicLibraryWeb.RecordComponents do
|
|||||||
</span>
|
</span>
|
||||||
<.icon
|
<.icon
|
||||||
name="hero-banknotes"
|
name="hero-banknotes"
|
||||||
class="h-4 w-4"
|
class="size-4"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
data-slot="icon"
|
data-slot="icon"
|
||||||
/>
|
/>
|
||||||
@@ -126,7 +126,7 @@ defmodule MusicLibraryWeb.RecordComponents do
|
|||||||
<span class="sr-only">
|
<span class="sr-only">
|
||||||
{gettext("Wishlisted on")}
|
{gettext("Wishlisted on")}
|
||||||
</span>
|
</span>
|
||||||
<.icon name="hero-star" class="h-4 w-4" aria-hidden="true" data-slot="icon" />
|
<.icon name="hero-star" class="size-4" aria-hidden="true" data-slot="icon" />
|
||||||
{Records.Record.format_as_date(record.inserted_at)}
|
{Records.Record.format_as_date(record.inserted_at)}
|
||||||
</span>
|
</span>
|
||||||
</p>
|
</p>
|
||||||
@@ -134,21 +134,21 @@ defmodule MusicLibraryWeb.RecordComponents do
|
|||||||
</div>
|
</div>
|
||||||
<div class="flex shrink-0 items-center gap-x-6">
|
<div class="flex shrink-0 items-center gap-x-6">
|
||||||
<div class="hidden sm:flex sm:flex-col sm:items-end">
|
<div class="hidden sm:flex sm:flex-col sm:items-end">
|
||||||
<p class="text-xs leading-6 text-zinc-900 dark:text-zinc-300">
|
<p class="text-xs/6 text-zinc-900 dark:text-zinc-300">
|
||||||
{format_label(record.format)} · {type_label(record.type)}
|
{format_label(record.format)} · {type_label(record.type)}
|
||||||
</p>
|
</p>
|
||||||
<p :if={record.purchased_at} class="text-xs leading-6 text-zinc-900 dark:text-zinc-300">
|
<p :if={record.purchased_at} class="text-xs/6 text-zinc-900 dark:text-zinc-300">
|
||||||
<span class="sr-only">
|
<span class="sr-only">
|
||||||
{gettext("Purchased on")}
|
{gettext("Purchased on")}
|
||||||
</span>
|
</span>
|
||||||
<.icon name="hero-banknotes" class="h-4 w-4" aria-hidden="true" data-slot="icon" />
|
<.icon name="hero-banknotes" class="size-4" aria-hidden="true" data-slot="icon" />
|
||||||
{Records.Record.format_as_date(record.purchased_at)}
|
{Records.Record.format_as_date(record.purchased_at)}
|
||||||
</p>
|
</p>
|
||||||
<p :if={!record.purchased_at} class="text-xs leading-6 text-zinc-900 dark:text-zinc-300">
|
<p :if={!record.purchased_at} class="text-xs/6 text-zinc-900 dark:text-zinc-300">
|
||||||
<span class="sr-only">
|
<span class="sr-only">
|
||||||
{gettext("Wishlisted on")}
|
{gettext("Wishlisted on")}
|
||||||
</span>
|
</span>
|
||||||
<.icon name="hero-star" class="h-4 w-4" aria-hidden="true" data-slot="icon" />
|
<.icon name="hero-star" class="size-4" aria-hidden="true" data-slot="icon" />
|
||||||
{Records.Record.format_as_date(record.inserted_at)}
|
{Records.Record.format_as_date(record.inserted_at)}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
@@ -162,7 +162,7 @@ defmodule MusicLibraryWeb.RecordComponents do
|
|||||||
<span class="sr-only">{gettext("Actions")}</span>
|
<span class="sr-only">{gettext("Actions")}</span>
|
||||||
<.icon
|
<.icon
|
||||||
name="hero-ellipsis-vertical"
|
name="hero-ellipsis-vertical"
|
||||||
class="icon text-zinc-500 dark:text-zinc-400 cursor-pointer"
|
class="icon cursor-pointer text-zinc-500 dark:text-zinc-400"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
data-slot="icon"
|
data-slot="icon"
|
||||||
/>
|
/>
|
||||||
@@ -172,7 +172,7 @@ defmodule MusicLibraryWeb.RecordComponents do
|
|||||||
<.dropdown_link id={"actions-#{record.id}-edit"} patch={@record_edit_path.(record)}>
|
<.dropdown_link id={"actions-#{record.id}-edit"} patch={@record_edit_path.(record)}>
|
||||||
<.icon
|
<.icon
|
||||||
name="hero-pencil-square"
|
name="hero-pencil-square"
|
||||||
class="h-4 w-4 mr-1 phx-click-loading:animate-bounce"
|
class="phx-click-loading:animate-bounce mr-1 size-4"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
data-slot="icon"
|
data-slot="icon"
|
||||||
/>
|
/>
|
||||||
@@ -189,7 +189,7 @@ defmodule MusicLibraryWeb.RecordComponents do
|
|||||||
>
|
>
|
||||||
<.icon
|
<.icon
|
||||||
name="hero-banknotes"
|
name="hero-banknotes"
|
||||||
class="h-4 w-4 mr-1 phx-click-loading:animate-shake"
|
class="phx-click-loading:animate-shake mr-1 size-4"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
data-slot="icon"
|
data-slot="icon"
|
||||||
/>
|
/>
|
||||||
@@ -206,7 +206,7 @@ defmodule MusicLibraryWeb.RecordComponents do
|
|||||||
>
|
>
|
||||||
<.icon
|
<.icon
|
||||||
name="hero-trash"
|
name="hero-trash"
|
||||||
class="h-4 w-4 mr-1 phx-click-loading:animate-spin"
|
class="phx-click-loading:animate-spin mr-1 size-4"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
data-slot="icon"
|
data-slot="icon"
|
||||||
/>
|
/>
|
||||||
@@ -237,7 +237,7 @@ defmodule MusicLibraryWeb.RecordComponents do
|
|||||||
:if={@title}
|
:if={@title}
|
||||||
class="flex items-baseline justify-start"
|
class="flex items-baseline justify-start"
|
||||||
>
|
>
|
||||||
<h2 class="font-semibold text-base sm:text-lg leading-5 text-zinc-700 dark:text-zinc-300">
|
<h2 class="text-base/5 font-semibold text-zinc-700 sm:text-lg dark:text-zinc-300">
|
||||||
{@title}
|
{@title}
|
||||||
</h2>
|
</h2>
|
||||||
<span class="ml-2 text-xs font-normal text-zinc-700 dark:text-zinc-300">
|
<span class="ml-2 text-xs font-normal text-zinc-700 dark:text-zinc-300">
|
||||||
@@ -257,22 +257,22 @@ defmodule MusicLibraryWeb.RecordComponents do
|
|||||||
>
|
>
|
||||||
<li :for={{id, record} <- @records} id={id} class="relative">
|
<li :for={{id, record} <- @records} id={id} class="relative">
|
||||||
<div
|
<div
|
||||||
class="relative cursor-pointer group"
|
class="group relative cursor-pointer"
|
||||||
phx-click={JS.navigate(@record_show_path.(record))}
|
phx-click={JS.navigate(@record_show_path.(record))}
|
||||||
>
|
>
|
||||||
<.record_cover
|
<.record_cover
|
||||||
record={record}
|
record={record}
|
||||||
class="aspect-square object-cover rounded-lg group-hover:shadow-lg/20"
|
class="aspect-square rounded-lg object-cover group-hover:shadow-lg/20"
|
||||||
width={460}
|
width={460}
|
||||||
/>
|
/>
|
||||||
<.release_groups_badge record={record} size={:md} />
|
<.release_groups_badge record={record} size={:md} />
|
||||||
<div class="absolute right-2 top-2 rounded-full bg-zinc-100/50 hover:bg-zinc-100/75 dark:bg-zinc-700/50 dark:hover:bg-zinc-700/75 size-5">
|
<div class="absolute top-2 right-2 size-5 rounded-full bg-zinc-100/50 hover:bg-zinc-100/75 dark:bg-zinc-700/50 dark:hover:bg-zinc-700/75">
|
||||||
<.dropdown id={"actions-#{record.id}"} placement="bottom-end">
|
<.dropdown id={"actions-#{record.id}"} placement="bottom-end">
|
||||||
<:toggle>
|
<:toggle>
|
||||||
<span class="sr-only">{gettext("Actions")}</span>
|
<span class="sr-only">{gettext("Actions")}</span>
|
||||||
<.icon
|
<.icon
|
||||||
name="hero-ellipsis-vertical"
|
name="hero-ellipsis-vertical"
|
||||||
class="size-5 text-zinc-800 dark:text-zinc-200 cursor-pointer"
|
class="size-5 cursor-pointer text-zinc-800 dark:text-zinc-200"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
data-slot="icon"
|
data-slot="icon"
|
||||||
phx-click={JS.toggle_class("pointer-events-none", to: "#{@id} > li")}
|
phx-click={JS.toggle_class("pointer-events-none", to: "#{@id} > li")}
|
||||||
@@ -286,7 +286,7 @@ defmodule MusicLibraryWeb.RecordComponents do
|
|||||||
>
|
>
|
||||||
<.icon
|
<.icon
|
||||||
name="hero-pencil-square"
|
name="hero-pencil-square"
|
||||||
class="h-4 w-4 mr-1 phx-click-loading:animate-bounce"
|
class="phx-click-loading:animate-bounce mr-1 size-4"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
data-slot="icon"
|
data-slot="icon"
|
||||||
/>
|
/>
|
||||||
@@ -303,7 +303,7 @@ defmodule MusicLibraryWeb.RecordComponents do
|
|||||||
>
|
>
|
||||||
<.icon
|
<.icon
|
||||||
name="hero-banknotes"
|
name="hero-banknotes"
|
||||||
class="h-4 w-4 mr-1 phx-click-loading:animate-shake"
|
class="phx-click-loading:animate-shake mr-1 size-4"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
data-slot="icon"
|
data-slot="icon"
|
||||||
/>
|
/>
|
||||||
@@ -318,7 +318,7 @@ defmodule MusicLibraryWeb.RecordComponents do
|
|||||||
>
|
>
|
||||||
<.icon
|
<.icon
|
||||||
name="hero-trash"
|
name="hero-trash"
|
||||||
class="h-4 w-4 mr-1 phx-click-loading:animate-spin"
|
class="phx-click-loading:animate-spin mr-1 size-4"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
data-slot="icon"
|
data-slot="icon"
|
||||||
/>
|
/>
|
||||||
@@ -331,7 +331,7 @@ defmodule MusicLibraryWeb.RecordComponents do
|
|||||||
<div class="mt-2">
|
<div class="mt-2">
|
||||||
<h1
|
<h1
|
||||||
:if={@display_artist_names}
|
:if={@display_artist_names}
|
||||||
class="text-sm leading-6 text-zinc-700"
|
class="text-sm/6 text-zinc-700"
|
||||||
>
|
>
|
||||||
<.artist_links joinphrase_class="text-xs" artists={record.artists} />
|
<.artist_links joinphrase_class="text-xs" artists={record.artists} />
|
||||||
</h1>
|
</h1>
|
||||||
@@ -345,7 +345,7 @@ defmodule MusicLibraryWeb.RecordComponents do
|
|||||||
<p class="pointer-events-none block text-sm font-medium text-zinc-500">
|
<p class="pointer-events-none block text-sm font-medium text-zinc-500">
|
||||||
<.icon
|
<.icon
|
||||||
name="hero-calendar-days"
|
name="hero-calendar-days"
|
||||||
class="-mt-1 h-4 w-4"
|
class="-mt-1 size-4"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
data-slot="icon"
|
data-slot="icon"
|
||||||
/>
|
/>
|
||||||
@@ -356,7 +356,7 @@ defmodule MusicLibraryWeb.RecordComponents do
|
|||||||
>
|
>
|
||||||
<.icon
|
<.icon
|
||||||
name="hero-banknotes"
|
name="hero-banknotes"
|
||||||
class="h-4 w-4"
|
class="size-4"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
data-slot="icon"
|
data-slot="icon"
|
||||||
/>
|
/>
|
||||||
@@ -376,7 +376,7 @@ defmodule MusicLibraryWeb.RecordComponents do
|
|||||||
~H"""
|
~H"""
|
||||||
<div class={[
|
<div class={[
|
||||||
@class,
|
@class,
|
||||||
"grid grid-cols-2 w-full auto-cols-min items-center space-x-1 text-zinc-700 dark:text-zinc-300"
|
"grid w-full auto-cols-min grid-cols-2 items-center space-x-1 text-zinc-700 dark:text-zinc-300"
|
||||||
]}>
|
]}>
|
||||||
<div class="space-x-1">
|
<div class="space-x-1">
|
||||||
<.format_badge release={@release} />
|
<.format_badge release={@release} />
|
||||||
@@ -454,10 +454,10 @@ defmodule MusicLibraryWeb.RecordComponents do
|
|||||||
|
|
||||||
def record_colors(assigns) do
|
def record_colors(assigns) do
|
||||||
~H"""
|
~H"""
|
||||||
<span class="inline-flex items-end gap-0.5 w-5.5 h-3.5">
|
<span class="inline-flex h-3.5 w-5.5 items-end gap-0.5">
|
||||||
<span
|
<span
|
||||||
:for={{color, i} <- Enum.with_index(@record.dominant_colors)}
|
:for={{color, i} <- Enum.with_index(@record.dominant_colors)}
|
||||||
class="w-0.75 rounded-sm animate-equalizer-bar"
|
class="animate-equalizer-bar w-0.75 rounded-sm"
|
||||||
style={"background-color: #{color}; animation-delay: #{i * -0.45}s"}
|
style={"background-color: #{color}; animation-delay: #{i * -0.45}s"}
|
||||||
>
|
>
|
||||||
</span>
|
</span>
|
||||||
@@ -483,7 +483,7 @@ defmodule MusicLibraryWeb.RecordComponents do
|
|||||||
release={release}
|
release={release}
|
||||||
class={
|
class={
|
||||||
@record.selected_release_id == release.id &&
|
@record.selected_release_id == release.id &&
|
||||||
"bg-zinc-100 outline-zinc-100 dark:bg-zinc-700 dark:outline-zinc-700 outline-4 rounded-lg"
|
"rounded-lg bg-zinc-100 outline-4 outline-zinc-100 dark:bg-zinc-700 dark:outline-zinc-700"
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -521,7 +521,7 @@ defmodule MusicLibraryWeb.RecordComponents do
|
|||||||
def record_title_and_metadata(assigns) do
|
def record_title_and_metadata(assigns) do
|
||||||
~H"""
|
~H"""
|
||||||
<div>
|
<div>
|
||||||
<h2 class="mt-1 flex font-semibold text-lg md:text-2xl text-zinc-700 dark:text-zinc-300 text-wrap">
|
<h2 class="mt-1 flex text-lg font-semibold text-wrap text-zinc-700 md:text-2xl dark:text-zinc-300">
|
||||||
{@record.title}
|
{@record.title}
|
||||||
</h2>
|
</h2>
|
||||||
<p class="mt-2 flex items-center text-sm text-zinc-500 dark:text-zinc-400">
|
<p class="mt-2 flex items-center text-sm text-zinc-500 dark:text-zinc-400">
|
||||||
@@ -529,7 +529,7 @@ defmodule MusicLibraryWeb.RecordComponents do
|
|||||||
<span class="ml-1">
|
<span class="ml-1">
|
||||||
<.icon
|
<.icon
|
||||||
name="hero-calendar-days"
|
name="hero-calendar-days"
|
||||||
class="-mt-1 h-4 w-4"
|
class="-mt-1 size-4"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
data-slot="icon"
|
data-slot="icon"
|
||||||
/>
|
/>
|
||||||
@@ -657,7 +657,7 @@ defmodule MusicLibraryWeb.RecordComponents do
|
|||||||
<li :for={record_set <- @record_sets} class="flex items-baseline gap-2">
|
<li :for={record_set <- @record_sets} class="flex items-baseline gap-2">
|
||||||
<.link
|
<.link
|
||||||
navigate={~p"/record-sets/#{record_set}"}
|
navigate={~p"/record-sets/#{record_set}"}
|
||||||
class="text-zinc-700 hover:text-zinc-500 dark:text-zinc-400 dark:hover:text-zinc-300 hover:underline"
|
class="text-zinc-700 hover:text-zinc-500 hover:underline dark:text-zinc-400 dark:hover:text-zinc-300"
|
||||||
>
|
>
|
||||||
{record_set.name}
|
{record_set.name}
|
||||||
</.link>
|
</.link>
|
||||||
@@ -678,7 +678,7 @@ defmodule MusicLibraryWeb.RecordComponents do
|
|||||||
def record_timestamps(assigns) do
|
def record_timestamps(assigns) do
|
||||||
~H"""
|
~H"""
|
||||||
<p class="mt-2 flex items-center gap-1.5 text-xs text-zinc-400 dark:text-zinc-500">
|
<p class="mt-2 flex items-center gap-1.5 text-xs text-zinc-400 dark:text-zinc-500">
|
||||||
<.icon name="hero-clock" class="h-3.5 w-3.5" aria-hidden="true" />
|
<.icon name="hero-clock" class="size-3.5" aria-hidden="true" />
|
||||||
{gettext("Added %{date}", date: Records.Record.format_as_date(@record.inserted_at))}
|
{gettext("Added %{date}", date: Records.Record.format_as_date(@record.inserted_at))}
|
||||||
<span>·</span>
|
<span>·</span>
|
||||||
{gettext("Updated %{date}", date: Records.Record.format_as_date(@record.updated_at))}
|
{gettext("Updated %{date}", date: Records.Record.format_as_date(@record.updated_at))}
|
||||||
|
|||||||
@@ -21,10 +21,10 @@ defmodule MusicLibraryWeb.Components.RecordForm do
|
|||||||
~H"""
|
~H"""
|
||||||
<div class="w-full">
|
<div class="w-full">
|
||||||
<header>
|
<header>
|
||||||
<h1 class="text-base font-medium leading-6 text-zinc-700 dark:text-zinc-300">
|
<h1 class="text-base/6 font-medium text-zinc-700 dark:text-zinc-300">
|
||||||
{Record.artist_names(@record)}
|
{Record.artist_names(@record)}
|
||||||
</h1>
|
</h1>
|
||||||
<h2 class="mt-1 flex font-semibold text-lg md:text-2xl leading-5 text-zinc-700 dark:text-zinc-300 text-wrap">
|
<h2 class="mt-1 flex text-lg/5 font-semibold text-wrap text-zinc-700 md:text-2xl dark:text-zinc-300">
|
||||||
{@record.title}
|
{@record.title}
|
||||||
</h2>
|
</h2>
|
||||||
</header>
|
</header>
|
||||||
@@ -38,7 +38,7 @@ defmodule MusicLibraryWeb.Components.RecordForm do
|
|||||||
phx-submit="save"
|
phx-submit="save"
|
||||||
>
|
>
|
||||||
<.input field={@form[:title]} label={gettext("Title")} />
|
<.input field={@form[:title]} label={gettext("Title")} />
|
||||||
<div class="sm:columns-2 space-y-2">
|
<div class="space-y-2 sm:columns-2">
|
||||||
<.select field={@form[:type]} label={gettext("Type")} options={types_with_labels()} />
|
<.select field={@form[:type]} label={gettext("Type")} options={types_with_labels()} />
|
||||||
<.select field={@form[:format]} label={gettext("Format")} options={formats_with_labels()} />
|
<.select field={@form[:format]} label={gettext("Format")} options={formats_with_labels()} />
|
||||||
</div>
|
</div>
|
||||||
@@ -81,7 +81,7 @@ defmodule MusicLibraryWeb.Components.RecordForm do
|
|||||||
class="cursor-pointer"
|
class="cursor-pointer"
|
||||||
>
|
>
|
||||||
{genre}
|
{genre}
|
||||||
<.icon name="hero-x-mark" class="h-3.5 w-3.5" />
|
<.icon name="hero-x-mark" class="size-3.5" />
|
||||||
</.badge>
|
</.badge>
|
||||||
</div>
|
</div>
|
||||||
<div class="relative" id="genre-input-container" phx-hook=".GenreInput" phx-target={@myself}>
|
<div class="relative" id="genre-input-container" phx-hook=".GenreInput" phx-target={@myself}>
|
||||||
@@ -113,7 +113,7 @@ defmodule MusicLibraryWeb.Components.RecordForm do
|
|||||||
phx-value-genre={suggestion}
|
phx-value-genre={suggestion}
|
||||||
phx-target={@myself}
|
phx-target={@myself}
|
||||||
class={[
|
class={[
|
||||||
"cursor-pointer select-none px-3 py-2 text-sm",
|
"cursor-pointer px-3 py-2 text-sm select-none",
|
||||||
"text-zinc-700 dark:text-zinc-300",
|
"text-zinc-700 dark:text-zinc-300",
|
||||||
"hover:bg-zinc-100 dark:hover:bg-zinc-700",
|
"hover:bg-zinc-100 dark:hover:bg-zinc-700",
|
||||||
"aria-selected:bg-zinc-100 dark:aria-selected:bg-zinc-700"
|
"aria-selected:bg-zinc-100 dark:aria-selected:bg-zinc-700"
|
||||||
@@ -134,8 +134,8 @@ defmodule MusicLibraryWeb.Components.RecordForm do
|
|||||||
phx-value-genre={String.downcase(String.trim(@genre_query))}
|
phx-value-genre={String.downcase(String.trim(@genre_query))}
|
||||||
phx-target={@myself}
|
phx-target={@myself}
|
||||||
class={[
|
class={[
|
||||||
"cursor-pointer select-none px-3 py-2 text-sm",
|
"cursor-pointer px-3 py-2 text-sm select-none",
|
||||||
"text-zinc-500 dark:text-zinc-400 italic",
|
"text-zinc-500 italic dark:text-zinc-400",
|
||||||
"hover:bg-zinc-100 dark:hover:bg-zinc-700",
|
"hover:bg-zinc-100 dark:hover:bg-zinc-700",
|
||||||
"aria-selected:bg-zinc-100 dark:aria-selected:bg-zinc-700"
|
"aria-selected:bg-zinc-100 dark:aria-selected:bg-zinc-700"
|
||||||
]}
|
]}
|
||||||
@@ -236,9 +236,9 @@ defmodule MusicLibraryWeb.Components.RecordForm do
|
|||||||
type="color"
|
type="color"
|
||||||
name="record[dominant_colors][]"
|
name="record[dominant_colors][]"
|
||||||
value={color}
|
value={color}
|
||||||
class="size-12 md:size-16 rounded border border-zinc-300 cursor-pointer"
|
class="size-12 cursor-pointer rounded border border-zinc-300 md:size-16"
|
||||||
/>
|
/>
|
||||||
<span class="text-xs md:text-sm mt-1 text-zinc-600 dark:text-zinc-400">
|
<span class="mt-1 text-xs text-zinc-600 md:text-sm dark:text-zinc-400">
|
||||||
{String.upcase(color)}
|
{String.upcase(color)}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -276,7 +276,7 @@ defmodule MusicLibraryWeb.Components.RecordForm do
|
|||||||
for={@uploads.cover_data.ref}
|
for={@uploads.cover_data.ref}
|
||||||
class={[
|
class={[
|
||||||
"cursor-pointer rounded-md font-semibold",
|
"cursor-pointer rounded-md font-semibold",
|
||||||
"focus-within:outline-none focus-within:ring-2 focus-within:ring-indigo-600 focus-within:ring-offset-2",
|
"focus-within:ring-2 focus-within:ring-indigo-600 focus-within:ring-offset-2 focus-within:outline-none",
|
||||||
"hover:text-zinc-200"
|
"hover:text-zinc-200"
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
@@ -335,7 +335,7 @@ defmodule MusicLibraryWeb.Components.RecordForm do
|
|||||||
<div
|
<div
|
||||||
:if={@cover_search_results != []}
|
:if={@cover_search_results != []}
|
||||||
id="cover-search-results"
|
id="cover-search-results"
|
||||||
class="grid grid-cols-3 sm:grid-cols-4 gap-2"
|
class="grid grid-cols-3 gap-2 sm:grid-cols-4"
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
:for={result <- @cover_search_results}
|
:for={result <- @cover_search_results}
|
||||||
@@ -348,8 +348,8 @@ defmodule MusicLibraryWeb.Components.RecordForm do
|
|||||||
"group relative overflow-hidden rounded-md",
|
"group relative overflow-hidden rounded-md",
|
||||||
"border border-zinc-200 dark:border-zinc-700",
|
"border border-zinc-200 dark:border-zinc-700",
|
||||||
"hover:ring-2 hover:ring-indigo-500",
|
"hover:ring-2 hover:ring-indigo-500",
|
||||||
"focus:outline-none focus:ring-2 focus:ring-indigo-500",
|
"focus:ring-2 focus:ring-indigo-500 focus:outline-none",
|
||||||
"disabled:opacity-50 disabled:cursor-not-allowed"
|
"disabled:cursor-not-allowed disabled:opacity-50"
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
@@ -361,8 +361,8 @@ defmodule MusicLibraryWeb.Components.RecordForm do
|
|||||||
<span
|
<span
|
||||||
:if={result.width && result.height}
|
:if={result.width && result.height}
|
||||||
class={[
|
class={[
|
||||||
"absolute bottom-0 inset-x-0",
|
"absolute inset-x-0 bottom-0",
|
||||||
"bg-black/60 text-white text-xs text-center",
|
"bg-black/60 text-center text-xs text-white",
|
||||||
"py-0.5"
|
"py-0.5"
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
@@ -388,7 +388,7 @@ defmodule MusicLibraryWeb.Components.RecordForm do
|
|||||||
defp release_option(assigns) do
|
defp release_option(assigns) do
|
||||||
~H"""
|
~H"""
|
||||||
<div class={[
|
<div class={[
|
||||||
"cursor-default px-2 py-1 md:px-3 md:py-2 rounded-md",
|
"cursor-default rounded-md px-2 py-1 md:px-3 md:py-2",
|
||||||
"in-data-highlighted:bg-zinc-100 dark:in-data-highlighted:bg-zinc-600",
|
"in-data-highlighted:bg-zinc-100 dark:in-data-highlighted:bg-zinc-600",
|
||||||
"[[data-highlighted]_&]:flx-focus:bg-zinc-100"
|
"[[data-highlighted]_&]:flx-focus:bg-zinc-100"
|
||||||
]}>
|
]}>
|
||||||
|
|||||||
@@ -48,8 +48,8 @@ defmodule MusicLibraryWeb.Components.Release do
|
|||||||
placement="right"
|
placement="right"
|
||||||
class="min-w-xs sm:min-w-sm"
|
class="min-w-xs sm:min-w-sm"
|
||||||
>
|
>
|
||||||
<div class="mt-6 flex justify-between items-center gap-4">
|
<div class="mt-6 flex items-center justify-between gap-4">
|
||||||
<label class="text-lg font-semibold text-zinc-700 dark:text-zinc-300 cursor-pointer">
|
<label class="cursor-pointer text-lg font-semibold text-zinc-700 dark:text-zinc-300">
|
||||||
<input
|
<input
|
||||||
:if={
|
:if={
|
||||||
@can_scrobble? && @release_with_tracks.ok? &&
|
@can_scrobble? && @release_with_tracks.ok? &&
|
||||||
@@ -66,7 +66,7 @@ defmodule MusicLibraryWeb.Components.Release do
|
|||||||
phx-click="toggle_medium"
|
phx-click="toggle_medium"
|
||||||
phx-value-medium-number={1}
|
phx-value-medium-number={1}
|
||||||
phx-target={@myself}
|
phx-target={@myself}
|
||||||
class="w-4 h-4 mr-2 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600"
|
class="mr-2 size-4 rounded border-gray-300 bg-gray-100 text-blue-600 focus:ring-2 focus:ring-blue-500 dark:border-gray-600 dark:bg-gray-700 dark:ring-offset-gray-800 dark:focus:ring-blue-600"
|
||||||
/>
|
/>
|
||||||
{gettext("Tracks")}
|
{gettext("Tracks")}
|
||||||
</label>
|
</label>
|
||||||
@@ -104,19 +104,19 @@ defmodule MusicLibraryWeb.Components.Release do
|
|||||||
</.button_group>
|
</.button_group>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div :if={@release_with_tracks} class="space-y-4 mt-4">
|
<div :if={@release_with_tracks} class="mt-4 space-y-4">
|
||||||
<.async_result :let={release_with_tracks} assign={@release_with_tracks}>
|
<.async_result :let={release_with_tracks} assign={@release_with_tracks}>
|
||||||
<:loading>
|
<:loading>
|
||||||
<div class="flex items-center justify-center mt-48">
|
<div class="mt-48 flex items-center justify-center">
|
||||||
<span class="sr-only">{gettext("Loading release with tracks")}</span>
|
<span class="sr-only">{gettext("Loading release with tracks")}</span>
|
||||||
<.loading />
|
<.loading />
|
||||||
</div>
|
</div>
|
||||||
</:loading>
|
</:loading>
|
||||||
<:failed :let={_failure}>
|
<:failed :let={_failure}>
|
||||||
<div class="mt-4 text-sm leading-5 text-zinc-500 dark:text-zinc-400">
|
<div class="mt-4 text-sm/5 text-zinc-500 dark:text-zinc-400">
|
||||||
<.icon
|
<.icon
|
||||||
name="hero-exclamation-triangle"
|
name="hero-exclamation-triangle"
|
||||||
class="h-5 w-5"
|
class="size-5"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
data-slot="icon"
|
data-slot="icon"
|
||||||
/>
|
/>
|
||||||
@@ -125,7 +125,7 @@ defmodule MusicLibraryWeb.Components.Release do
|
|||||||
variant="ghost"
|
variant="ghost"
|
||||||
size="xs"
|
size="xs"
|
||||||
phx-click={JS.push("load_release_tracks", target: @myself)}
|
phx-click={JS.push("load_release_tracks", target: @myself)}
|
||||||
class="ml-2 cursor-pointer"
|
class="ml-2 cursor-pointer"
|
||||||
>
|
>
|
||||||
{gettext("Retry")}
|
{gettext("Retry")}
|
||||||
</.button>
|
</.button>
|
||||||
@@ -162,9 +162,9 @@ defmodule MusicLibraryWeb.Components.Release do
|
|||||||
~H"""
|
~H"""
|
||||||
<div
|
<div
|
||||||
:if={@media_count > 1}
|
:if={@media_count > 1}
|
||||||
class="flex justify-between items-center gap-4"
|
class="flex items-center justify-between gap-4"
|
||||||
>
|
>
|
||||||
<label class="text-sm md:text-md font-semibold text-zinc-700 dark:text-zinc-300 cursor-pointer">
|
<label class="md:text-md cursor-pointer text-sm font-semibold text-zinc-700 dark:text-zinc-300">
|
||||||
<input
|
<input
|
||||||
:if={@can_scrobble?}
|
:if={@can_scrobble?}
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
@@ -173,7 +173,7 @@ defmodule MusicLibraryWeb.Components.Release do
|
|||||||
phx-click="toggle_medium"
|
phx-click="toggle_medium"
|
||||||
phx-value-medium-number={@medium.number}
|
phx-value-medium-number={@medium.number}
|
||||||
phx-target={@myself}
|
phx-target={@myself}
|
||||||
class="w-4 h-4 mr-2 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600"
|
class="mr-2 size-4 rounded border-gray-300 bg-gray-100 text-blue-600 focus:ring-2 focus:ring-blue-500 dark:border-gray-600 dark:bg-gray-700 dark:ring-offset-gray-800 dark:focus:ring-blue-600"
|
||||||
/>
|
/>
|
||||||
{medium_title(@medium)}
|
{medium_title(@medium)}
|
||||||
<.badge variant="soft" class="text-xs">
|
<.badge variant="soft" class="text-xs">
|
||||||
@@ -216,7 +216,7 @@ defmodule MusicLibraryWeb.Components.Release do
|
|||||||
myself={@myself}
|
myself={@myself}
|
||||||
/>
|
/>
|
||||||
<.separator />
|
<.separator />
|
||||||
<p class="text-xs md:text-sm text-right text-zinc-700 dark:text-zinc-300">
|
<p class="text-right text-xs text-zinc-700 md:text-sm dark:text-zinc-300">
|
||||||
{medium_duration(@medium)}
|
{medium_duration(@medium)}
|
||||||
</p>
|
</p>
|
||||||
"""
|
"""
|
||||||
@@ -239,10 +239,10 @@ defmodule MusicLibraryWeb.Components.Release do
|
|||||||
|
|
||||||
def track_list(assigns) do
|
def track_list(assigns) do
|
||||||
~H"""
|
~H"""
|
||||||
<ul id={"disc-#{@medium_number}"} class="w-full table table-auto">
|
<ul id={"disc-#{@medium_number}"} class="table w-full table-auto">
|
||||||
<li
|
<li
|
||||||
:for={track <- @tracks}
|
:for={track <- @tracks}
|
||||||
class="leading-5 text-zinc-700 dark:text-zinc-300 list-none"
|
class="list-none leading-5 text-zinc-700 dark:text-zinc-300"
|
||||||
>
|
>
|
||||||
<label class="contents cursor-pointer">
|
<label class="contents cursor-pointer">
|
||||||
<div class="table-row">
|
<div class="table-row">
|
||||||
@@ -254,16 +254,16 @@ defmodule MusicLibraryWeb.Components.Release do
|
|||||||
phx-click="toggle_track"
|
phx-click="toggle_track"
|
||||||
phx-value-track-id={track.id}
|
phx-value-track-id={track.id}
|
||||||
phx-target={@myself}
|
phx-target={@myself}
|
||||||
class="w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600"
|
class="size-4 rounded border-gray-300 bg-gray-100 text-blue-600 focus:ring-2 focus:ring-blue-500 dark:border-gray-600 dark:bg-gray-700 dark:ring-offset-gray-800 dark:focus:ring-blue-600"
|
||||||
/>
|
/>
|
||||||
</span>
|
</span>
|
||||||
<span class="table-cell text-xs text-right pr-1 text-nowrap">
|
<span class="table-cell pr-1 text-right text-xs text-nowrap">
|
||||||
{track.number || track.position}
|
{track.number || track.position}
|
||||||
</span>
|
</span>
|
||||||
<span class="table-cell text-xs md:text-sm font-medium leading-8 w-full">
|
<span class="table-cell w-full text-xs/8 font-medium md:text-sm">
|
||||||
{track.title}
|
{track.title}
|
||||||
</span>
|
</span>
|
||||||
<span class="table-cell text-xs md:text-sm text-right pl-2">
|
<span class="table-cell pl-2 text-right text-xs md:text-sm">
|
||||||
{track.length && Duration.format_duration(track.length)}
|
{track.length && Duration.format_duration(track.length)}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ defmodule MusicLibraryWeb.ScrobbleComponents do
|
|||||||
<span class="sr-only">{gettext("Refresh LastFm Feed")}</span>
|
<span class="sr-only">{gettext("Refresh LastFm Feed")}</span>
|
||||||
<.icon
|
<.icon
|
||||||
name="hero-arrow-path"
|
name="hero-arrow-path"
|
||||||
class="phx-click-loading:animate-spin h-5 w-5"
|
class="phx-click-loading:animate-spin size-5"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
data-slot="icon"
|
data-slot="icon"
|
||||||
/>
|
/>
|
||||||
@@ -32,10 +32,10 @@ defmodule MusicLibraryWeb.ScrobbleComponents do
|
|||||||
|
|
||||||
def track_metadata_tooltip(assigns) do
|
def track_metadata_tooltip(assigns) do
|
||||||
~H"""
|
~H"""
|
||||||
<.tooltip class="bg-white dark:bg-zinc-800 text-zinc-900 dark:text-zinc-100 shadow-lg ring-1 ring-zinc-200 dark:ring-zinc-700">
|
<.tooltip class="bg-white text-zinc-900 shadow-lg ring-1 ring-zinc-200 dark:bg-zinc-800 dark:text-zinc-100 dark:ring-zinc-700">
|
||||||
<.icon
|
<.icon
|
||||||
name="hero-information-circle"
|
name="hero-information-circle"
|
||||||
class="h-5 w-5 text-zinc-500 dark:text-zinc-400 cursor-pointer"
|
class="size-5 cursor-pointer text-zinc-500 dark:text-zinc-400"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
data-slot="icon"
|
data-slot="icon"
|
||||||
/>
|
/>
|
||||||
@@ -69,10 +69,10 @@ defmodule MusicLibraryWeb.ScrobbleComponents do
|
|||||||
|
|
||||||
def album_metadata_tooltip(assigns) do
|
def album_metadata_tooltip(assigns) do
|
||||||
~H"""
|
~H"""
|
||||||
<.tooltip class="bg-white dark:bg-zinc-800 text-zinc-900 dark:text-zinc-100 shadow-lg ring-1 ring-zinc-200 dark:ring-zinc-700">
|
<.tooltip class="bg-white text-zinc-900 shadow-lg ring-1 ring-zinc-200 dark:bg-zinc-800 dark:text-zinc-100 dark:ring-zinc-700">
|
||||||
<.icon
|
<.icon
|
||||||
name="hero-information-circle"
|
name="hero-information-circle"
|
||||||
class="h-5 w-5 text-zinc-500 dark:text-zinc-400 cursor-pointer"
|
class="size-5 cursor-pointer text-zinc-500 dark:text-zinc-400"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
data-slot="icon"
|
data-slot="icon"
|
||||||
/>
|
/>
|
||||||
@@ -102,7 +102,7 @@ defmodule MusicLibraryWeb.ScrobbleComponents do
|
|||||||
|
|
||||||
def record_status_badges(assigns) do
|
def record_status_badges(assigns) do
|
||||||
~H"""
|
~H"""
|
||||||
<div class="flex gap-1 flex-col text-right">
|
<div class="flex flex-col gap-1 text-right">
|
||||||
<.badge :if={@musicbrainz_id == ""}>
|
<.badge :if={@musicbrainz_id == ""}>
|
||||||
{gettext("No MB ID")}
|
{gettext("No MB ID")}
|
||||||
</.badge>
|
</.badge>
|
||||||
@@ -127,7 +127,7 @@ defmodule MusicLibraryWeb.ScrobbleComponents do
|
|||||||
<span class="sr-only">{gettext("Choose which format to import")}</span>
|
<span class="sr-only">{gettext("Choose which format to import")}</span>
|
||||||
<.icon
|
<.icon
|
||||||
name="hero-star"
|
name="hero-star"
|
||||||
class="icon text-zinc-500 dark:text-zinc-400 cursor-pointer"
|
class="icon cursor-pointer text-zinc-500 dark:text-zinc-400"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
data-slot="icon"
|
data-slot="icon"
|
||||||
/>
|
/>
|
||||||
@@ -159,17 +159,17 @@ defmodule MusicLibraryWeb.ScrobbleComponents do
|
|||||||
defp metadata_row(assigns) do
|
defp metadata_row(assigns) do
|
||||||
~H"""
|
~H"""
|
||||||
<div class="px-3 py-2 first:pt-1.5 last:pb-1.5">
|
<div class="px-3 py-2 first:pt-1.5 last:pb-1.5">
|
||||||
<dt class="text-[0.65rem] font-medium uppercase tracking-wider text-zinc-400 dark:text-zinc-500">
|
<dt class="text-[0.65rem] font-medium tracking-wider text-zinc-400 uppercase dark:text-zinc-500">
|
||||||
{@label}
|
{@label}
|
||||||
</dt>
|
</dt>
|
||||||
<dd class="mt-0.5 flex items-center justify-between gap-2">
|
<dd class="mt-0.5 flex items-center justify-between gap-2">
|
||||||
<code
|
<code
|
||||||
id={@id_prefix}
|
id={@id_prefix}
|
||||||
class={[
|
class={[
|
||||||
"text-xs font-mono truncate",
|
"truncate font-mono text-xs",
|
||||||
if(@value not in ["", nil],
|
if(@value not in ["", nil],
|
||||||
do: "text-zinc-800 dark:text-zinc-200",
|
do: "text-zinc-800 dark:text-zinc-200",
|
||||||
else: "text-zinc-400 dark:text-zinc-500 italic"
|
else: "text-zinc-400 italic dark:text-zinc-500"
|
||||||
)
|
)
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ defmodule MusicLibraryWeb.SearchComponents do
|
|||||||
~H"""
|
~H"""
|
||||||
<div
|
<div
|
||||||
class={[
|
class={[
|
||||||
"p-3 rounded-lg cursor-pointer transition-colors",
|
"cursor-pointer rounded-lg p-3 transition-colors",
|
||||||
"hover:bg-zinc-50 dark:hover:bg-zinc-700",
|
"hover:bg-zinc-50 dark:hover:bg-zinc-700",
|
||||||
"aria-selected:bg-zinc-200 dark:aria-selected:bg-zinc-700"
|
"aria-selected:bg-zinc-200 dark:aria-selected:bg-zinc-700"
|
||||||
]}
|
]}
|
||||||
@@ -37,22 +37,22 @@ defmodule MusicLibraryWeb.SearchComponents do
|
|||||||
<div class="shrink-0">
|
<div class="shrink-0">
|
||||||
<.record_cover
|
<.record_cover
|
||||||
record={@record}
|
record={@record}
|
||||||
class="w-12 h-12 rounded-md aspect-square object-cover"
|
class="aspect-square size-12 rounded-md object-cover"
|
||||||
width={96}
|
width={96}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="min-w-0 flex-1">
|
<div class="min-w-0 flex-1">
|
||||||
<p class="text-sm font-medium text-zinc-900 dark:text-zinc-100 truncate">
|
<p class="truncate text-sm font-medium text-zinc-900 dark:text-zinc-100">
|
||||||
{@record.title}
|
{@record.title}
|
||||||
</p>
|
</p>
|
||||||
<p class="text-sm text-zinc-500 font-medium dark:text-zinc-400 truncate">
|
<p class="truncate text-sm font-medium text-zinc-500 dark:text-zinc-400">
|
||||||
{Record.artist_names(@record)}
|
{Record.artist_names(@record)}
|
||||||
</p>
|
</p>
|
||||||
<p class="pointer-events-none block text-sm text-zinc-500">
|
<p class="pointer-events-none block text-sm text-zinc-500">
|
||||||
{format_label(@record.format)} · {type_label(@record.type)} ·
|
{format_label(@record.format)} · {type_label(@record.type)} ·
|
||||||
<.icon
|
<.icon
|
||||||
name="hero-calendar-days"
|
name="hero-calendar-days"
|
||||||
class="-mt-1 h-4 w-4"
|
class="-mt-1 size-4"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
data-slot="icon"
|
data-slot="icon"
|
||||||
/>
|
/>
|
||||||
@@ -61,7 +61,7 @@ defmodule MusicLibraryWeb.SearchComponents do
|
|||||||
·
|
·
|
||||||
<.icon
|
<.icon
|
||||||
name="hero-banknotes"
|
name="hero-banknotes"
|
||||||
class="h-4 w-4"
|
class="size-4"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
data-slot="icon"
|
data-slot="icon"
|
||||||
/>
|
/>
|
||||||
@@ -89,7 +89,7 @@ defmodule MusicLibraryWeb.SearchComponents do
|
|||||||
~H"""
|
~H"""
|
||||||
<div
|
<div
|
||||||
class={[
|
class={[
|
||||||
"p-3 rounded-lg cursor-pointer transition-colors",
|
"cursor-pointer rounded-lg p-3 transition-colors",
|
||||||
"hover:bg-zinc-50 dark:hover:bg-zinc-700",
|
"hover:bg-zinc-50 dark:hover:bg-zinc-700",
|
||||||
"aria-selected:bg-zinc-200 dark:aria-selected:bg-zinc-700"
|
"aria-selected:bg-zinc-200 dark:aria-selected:bg-zinc-700"
|
||||||
]}
|
]}
|
||||||
@@ -99,17 +99,17 @@ defmodule MusicLibraryWeb.SearchComponents do
|
|||||||
<div class="flex items-center space-x-3">
|
<div class="flex items-center space-x-3">
|
||||||
<div class="shrink-0">
|
<div class="shrink-0">
|
||||||
<.artist_image
|
<.artist_image
|
||||||
class="w-12 h-12 rounded-md aspect-square object-cover"
|
class="aspect-square size-12 rounded-md object-cover"
|
||||||
artist={@artist}
|
artist={@artist}
|
||||||
width={96}
|
width={96}
|
||||||
image_hash={@image_data_hash}
|
image_hash={@image_data_hash}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="min-w-0 flex-1">
|
<div class="min-w-0 flex-1">
|
||||||
<p class="text-sm font-medium text-zinc-900 dark:text-zinc-100 truncate">
|
<p class="truncate text-sm font-medium text-zinc-900 dark:text-zinc-100">
|
||||||
{@artist.name}
|
{@artist.name}
|
||||||
</p>
|
</p>
|
||||||
<p :if={@artist.disambiguation} class="text-sm text-zinc-500 dark:text-zinc-400 truncate">
|
<p :if={@artist.disambiguation} class="truncate text-sm text-zinc-500 dark:text-zinc-400">
|
||||||
{@artist.disambiguation}
|
{@artist.disambiguation}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
@@ -132,7 +132,7 @@ defmodule MusicLibraryWeb.SearchComponents do
|
|||||||
~H"""
|
~H"""
|
||||||
<div
|
<div
|
||||||
class={[
|
class={[
|
||||||
"p-3 rounded-lg cursor-pointer transition-colors",
|
"cursor-pointer rounded-lg p-3 transition-colors",
|
||||||
"hover:bg-zinc-50 dark:hover:bg-zinc-700",
|
"hover:bg-zinc-50 dark:hover:bg-zinc-700",
|
||||||
"aria-selected:bg-zinc-200 dark:aria-selected:bg-zinc-700"
|
"aria-selected:bg-zinc-200 dark:aria-selected:bg-zinc-700"
|
||||||
]}
|
]}
|
||||||
@@ -140,16 +140,16 @@ defmodule MusicLibraryWeb.SearchComponents do
|
|||||||
{@rest}
|
{@rest}
|
||||||
>
|
>
|
||||||
<div class="flex items-center space-x-3">
|
<div class="flex items-center space-x-3">
|
||||||
<div class="shrink-0 w-12 h-12 rounded-md bg-zinc-100 dark:bg-zinc-700 flex items-center justify-center">
|
<div class="flex size-12 shrink-0 items-center justify-center rounded-md bg-zinc-100 dark:bg-zinc-700">
|
||||||
<.icon name="hero-queue-list" class="h-6 w-6 text-zinc-400 dark:text-zinc-500" />
|
<.icon name="hero-queue-list" class="size-6 text-zinc-400 dark:text-zinc-500" />
|
||||||
</div>
|
</div>
|
||||||
<div class="min-w-0 flex-1">
|
<div class="min-w-0 flex-1">
|
||||||
<p class="text-sm font-medium text-zinc-900 dark:text-zinc-100 truncate">
|
<p class="truncate text-sm font-medium text-zinc-900 dark:text-zinc-100">
|
||||||
{@record_set.name}
|
{@record_set.name}
|
||||||
</p>
|
</p>
|
||||||
<div
|
<div
|
||||||
:if={@record_set.description}
|
:if={@record_set.description}
|
||||||
class="prose prose-zinc dark:prose-invert prose-sm"
|
class="dark:prose-invert prose prose-sm prose-zinc"
|
||||||
>
|
>
|
||||||
{render_description(@record_set.description)}
|
{render_description(@record_set.description)}
|
||||||
</div>
|
</div>
|
||||||
@@ -174,7 +174,7 @@ defmodule MusicLibraryWeb.SearchComponents do
|
|||||||
~H"""
|
~H"""
|
||||||
<div
|
<div
|
||||||
class={[
|
class={[
|
||||||
"p-3 rounded-lg cursor-pointer transition-colors",
|
"cursor-pointer rounded-lg p-3 transition-colors",
|
||||||
"hover:bg-zinc-50 dark:hover:bg-zinc-700",
|
"hover:bg-zinc-50 dark:hover:bg-zinc-700",
|
||||||
"aria-selected:bg-zinc-200 dark:aria-selected:bg-zinc-700"
|
"aria-selected:bg-zinc-200 dark:aria-selected:bg-zinc-700"
|
||||||
]}
|
]}
|
||||||
@@ -182,8 +182,8 @@ defmodule MusicLibraryWeb.SearchComponents do
|
|||||||
{@rest}
|
{@rest}
|
||||||
>
|
>
|
||||||
<div class="flex items-center space-x-3">
|
<div class="flex items-center space-x-3">
|
||||||
<div class="shrink-0 w-8 h-8 rounded-md bg-zinc-100 dark:bg-zinc-700 flex items-center justify-center">
|
<div class="flex size-8 shrink-0 items-center justify-center rounded-md bg-zinc-100 dark:bg-zinc-700">
|
||||||
<.icon name={@icon} class="h-4 w-4 text-zinc-500 dark:text-zinc-400" />
|
<.icon name={@icon} class="size-4 text-zinc-500 dark:text-zinc-400" />
|
||||||
</div>
|
</div>
|
||||||
<div class="min-w-0 flex-1">
|
<div class="min-w-0 flex-1">
|
||||||
<p class="text-sm font-medium text-zinc-900 dark:text-zinc-100">
|
<p class="text-sm font-medium text-zinc-900 dark:text-zinc-100">
|
||||||
@@ -221,7 +221,7 @@ defmodule MusicLibraryWeb.SearchComponents do
|
|||||||
def search_result_group(assigns) do
|
def search_result_group(assigns) do
|
||||||
~H"""
|
~H"""
|
||||||
<div class={["p-2", @class]}>
|
<div class={["p-2", @class]}>
|
||||||
<h3 class="text-sm font-medium text-zinc-700 dark:text-zinc-300 mb-1 uppercase tracking-wide">
|
<h3 class="mb-1 text-sm font-medium tracking-wide text-zinc-700 uppercase dark:text-zinc-300">
|
||||||
{@title}
|
{@title}
|
||||||
<span :if={@total_count && @total_count > @count}>
|
<span :if={@total_count && @total_count > @count}>
|
||||||
{gettext("(%{count} of %{total})", count: @count, total: @total_count)}
|
{gettext("(%{count} of %{total})", count: @count, total: @total_count)}
|
||||||
@@ -235,7 +235,7 @@ defmodule MusicLibraryWeb.SearchComponents do
|
|||||||
{render_slot(@inner_block)}
|
{render_slot(@inner_block)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div :for={action <- @actions} class="px-2 mt-2">
|
<div :for={action <- @actions} class="mt-2 px-2">
|
||||||
{render_slot(action)}
|
{render_slot(action)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -257,7 +257,7 @@ defmodule MusicLibraryWeb.SearchComponents do
|
|||||||
~H"""
|
~H"""
|
||||||
<button
|
<button
|
||||||
role="option"
|
role="option"
|
||||||
class="aria-selected:bg-zinc-200 dark:aria-selected:bg-zinc-700 text-sm text-blue-600 dark:text-blue-400 hover:text-blue-800 dark:hover:text-blue-300 transition-colors"
|
class="text-sm text-blue-600 transition-colors hover:text-blue-800 aria-selected:bg-zinc-200 dark:text-blue-400 dark:hover:text-blue-300 dark:aria-selected:bg-zinc-700"
|
||||||
{@rest}
|
{@rest}
|
||||||
>
|
>
|
||||||
{gettext("View all %{count} %{target} results →", count: @count, target: @target)}
|
{gettext("View all %{count} %{target} results →", count: @count, target: @target)}
|
||||||
@@ -276,20 +276,20 @@ defmodule MusicLibraryWeb.SearchComponents do
|
|||||||
|
|
||||||
def results_footer(assigns) do
|
def results_footer(assigns) do
|
||||||
~H"""
|
~H"""
|
||||||
<div class="p-2 bg-zinc-50 dark:bg-zinc-900 rounded-b-lg border-t border-zinc-200 dark:border-zinc-700">
|
<div class="rounded-b-lg border-t border-zinc-200 bg-zinc-50 p-2 dark:border-zinc-700 dark:bg-zinc-900">
|
||||||
<div class="flex items-center justify-between text-xs text-zinc-500 dark:text-zinc-400">
|
<div class="flex items-center justify-between text-xs text-zinc-500 dark:text-zinc-400">
|
||||||
<div class="flex items-center space-x-4">
|
<div class="flex items-center space-x-4">
|
||||||
<div :if={@total_results > 0} class="flex items-center">
|
<div :if={@total_results > 0} class="flex items-center">
|
||||||
<kbd class="px-2 py-1 bg-zinc-200 dark:bg-zinc-700 rounded">↑</kbd>
|
<kbd class="rounded bg-zinc-200 px-2 py-1 dark:bg-zinc-700">↑</kbd>
|
||||||
<kbd class="px-2 py-1 bg-zinc-200 dark:bg-zinc-700 rounded ml-1">↓</kbd>
|
<kbd class="ml-1 rounded bg-zinc-200 px-2 py-1 dark:bg-zinc-700">↓</kbd>
|
||||||
<span class="ml-1">{gettext("Navigate")}</span>
|
<span class="ml-1">{gettext("Navigate")}</span>
|
||||||
</div>
|
</div>
|
||||||
<div :if={@total_results > 0} class="flex items-center">
|
<div :if={@total_results > 0} class="flex items-center">
|
||||||
<kbd class="px-2 py-1 bg-zinc-200 dark:bg-zinc-700 rounded">Enter</kbd>
|
<kbd class="rounded bg-zinc-200 px-2 py-1 dark:bg-zinc-700">Enter</kbd>
|
||||||
<span class="ml-1">{gettext("Select")}</span>
|
<span class="ml-1">{gettext("Select")}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<kbd class="px-2 py-1 bg-zinc-200 dark:bg-zinc-700 rounded">Esc</kbd>
|
<kbd class="rounded bg-zinc-200 px-2 py-1 dark:bg-zinc-700">Esc</kbd>
|
||||||
<span class="ml-1">{gettext("Close")}</span>
|
<span class="ml-1">{gettext("Close")}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -311,9 +311,9 @@ defmodule MusicLibraryWeb.SearchComponents do
|
|||||||
def empty_state(assigns) do
|
def empty_state(assigns) do
|
||||||
~H"""
|
~H"""
|
||||||
<div class="p-8 text-center">
|
<div class="p-8 text-center">
|
||||||
<.icon name="hero-magnifying-glass" class="h-12 w-12 text-zinc-400 mx-auto mb-4" />
|
<.icon name="hero-magnifying-glass" class="mx-auto mb-4 size-12 text-zinc-400" />
|
||||||
<p class="text-sm text-zinc-500 dark:text-zinc-500 mt-2">
|
<p class="mt-2 text-sm text-zinc-500 dark:text-zinc-500">
|
||||||
<kbd class="px-2 py-1 bg-zinc-100 dark:bg-zinc-700 rounded text-xs">Cmd/Ctrl+K</kbd>
|
<kbd class="rounded bg-zinc-100 px-2 py-1 text-xs dark:bg-zinc-700">Cmd/Ctrl+K</kbd>
|
||||||
{gettext("to open this search")}
|
{gettext("to open this search")}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
@@ -332,12 +332,12 @@ defmodule MusicLibraryWeb.SearchComponents do
|
|||||||
def no_results(assigns) do
|
def no_results(assigns) do
|
||||||
~H"""
|
~H"""
|
||||||
<div class="p-8 text-center">
|
<div class="p-8 text-center">
|
||||||
<.icon name="hero-face-frown" class="h-12 w-12 text-zinc-400 mx-auto mb-4" />
|
<.icon name="hero-face-frown" class="mx-auto mb-4 size-12 text-zinc-400" />
|
||||||
<p class="text-zinc-600 dark:text-zinc-400">
|
<p class="text-zinc-600 dark:text-zinc-400">
|
||||||
{gettext("No results found for '%{query}'", query: @query)}
|
{gettext("No results found for '%{query}'", query: @query)}
|
||||||
</p>
|
</p>
|
||||||
<.link
|
<.link
|
||||||
class="text-sm font-medium text-zinc-900 dark:text-zinc-100 truncate"
|
class="truncate text-sm font-medium text-zinc-900 dark:text-zinc-100"
|
||||||
navigate={~p"/wishlist/import?#{[import_query: @query]}"}
|
navigate={~p"/wishlist/import?#{[import_query: @query]}"}
|
||||||
>
|
>
|
||||||
{gettext("Add a record instead", query: @query)}
|
{gettext("Add a record instead", query: @query)}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ defmodule MusicLibraryWeb.StatsComponents do
|
|||||||
<div
|
<div
|
||||||
:if={@record}
|
:if={@record}
|
||||||
class={[
|
class={[
|
||||||
"flex items-center rounded-md bg-white dark:bg-zinc-800 px-4 pb-5 pt-5 shadow-sm sm:px-6 sm:pt-6 cursor-pointer",
|
"flex cursor-pointer items-center rounded-md bg-white px-4 py-5 shadow-sm sm:px-6 sm:pt-6 dark:bg-zinc-800",
|
||||||
@class
|
@class
|
||||||
]}
|
]}
|
||||||
phx-click={JS.navigate(~p"/collection/#{@record}")}
|
phx-click={JS.navigate(~p"/collection/#{@record}")}
|
||||||
@@ -29,16 +29,16 @@ defmodule MusicLibraryWeb.StatsComponents do
|
|||||||
<div>
|
<div>
|
||||||
<.record_cover
|
<.record_cover
|
||||||
record={@record}
|
record={@record}
|
||||||
class="w-20 md:w-24 rounded-md shadow-sm"
|
class="w-20 rounded-md shadow-sm md:w-24"
|
||||||
width={192}
|
width={192}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="ml-4">
|
<div class="ml-4">
|
||||||
<p class="truncate text-xs sm:text-sm font-medium text-zinc-500 dark:text-zinc-400">
|
<p class="truncate text-xs font-medium text-zinc-500 sm:text-sm dark:text-zinc-400">
|
||||||
{@title}
|
{@title}
|
||||||
</p>
|
</p>
|
||||||
<p class="font-semibold">
|
<p class="font-semibold">
|
||||||
<span class="text-sm md:text-base lg:text-2xl block text-zinc-900 dark:text-zinc-300">
|
<span class="block text-sm text-zinc-900 md:text-base lg:text-2xl dark:text-zinc-300">
|
||||||
{@record.title}
|
{@record.title}
|
||||||
</span>
|
</span>
|
||||||
<.artist_links artists={@record.artists} joinphrase_class="text-sm md:text-base" />
|
<.artist_links artists={@record.artists} joinphrase_class="text-sm md:text-base" />
|
||||||
@@ -48,11 +48,11 @@ defmodule MusicLibraryWeb.StatsComponents do
|
|||||||
<div
|
<div
|
||||||
:if={!@record}
|
:if={!@record}
|
||||||
class={[
|
class={[
|
||||||
"flex items-center rounded-md bg-white dark:bg-zinc-800 px-4 pb-5 pt-5 shadow-sm sm:px-6 sm:pt-6 cursor-pointer",
|
"flex cursor-pointer items-center rounded-md bg-white px-4 py-5 shadow-sm sm:px-6 sm:pt-6 dark:bg-zinc-800",
|
||||||
@class
|
@class
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
<p class="truncate text-xs sm:text-sm font-medium text-zinc-500 dark:text-zinc-400">
|
<p class="truncate text-xs font-medium text-zinc-500 sm:text-sm dark:text-zinc-400">
|
||||||
{gettext("No record found")}
|
{gettext("No record found")}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
@@ -66,10 +66,10 @@ defmodule MusicLibraryWeb.StatsComponents do
|
|||||||
|
|
||||||
def counter(assigns) do
|
def counter(assigns) do
|
||||||
~H"""
|
~H"""
|
||||||
<div class="overflow-hidden rounded-md bg-white dark:bg-zinc-800 shadow-sm flex justify-center items-center">
|
<div class="flex items-center justify-center overflow-hidden rounded-md bg-white shadow-sm dark:bg-zinc-800">
|
||||||
<div class="p-4 md:p-0">
|
<div class="p-4 md:p-0">
|
||||||
<dt>
|
<dt>
|
||||||
<p class="truncate text-sm font-medium text-center text-zinc-500 dark:text-zinc-400">
|
<p class="truncate text-center text-sm font-medium text-zinc-500 dark:text-zinc-400">
|
||||||
{@title}
|
{@title}
|
||||||
</p>
|
</p>
|
||||||
</dt>
|
</dt>
|
||||||
@@ -77,13 +77,13 @@ defmodule MusicLibraryWeb.StatsComponents do
|
|||||||
<.link
|
<.link
|
||||||
:if={@path}
|
:if={@path}
|
||||||
navigate={@path}
|
navigate={@path}
|
||||||
class="block text-2xl sm:text-3xl font-semibold text-center text-zinc-900 hover:text-zinc-500 dark:text-zinc-300 dark:hover:text-zinc-200"
|
class="block text-center text-2xl font-semibold text-zinc-900 hover:text-zinc-500 sm:text-3xl dark:text-zinc-300 dark:hover:text-zinc-200"
|
||||||
>
|
>
|
||||||
{@count}
|
{@count}
|
||||||
</.link>
|
</.link>
|
||||||
<p
|
<p
|
||||||
:if={!@path}
|
:if={!@path}
|
||||||
class="block cursor-default text-2xl sm:text-3xl font-semibold text-center text-zinc-900 dark:text-zinc-300"
|
class="block cursor-default text-center text-2xl font-semibold text-zinc-900 sm:text-3xl dark:text-zinc-300"
|
||||||
>
|
>
|
||||||
{@count}
|
{@count}
|
||||||
</p>
|
</p>
|
||||||
@@ -96,13 +96,13 @@ defmodule MusicLibraryWeb.StatsComponents do
|
|||||||
<.link
|
<.link
|
||||||
:if={@path}
|
:if={@path}
|
||||||
navigate={@path}
|
navigate={@path}
|
||||||
class="block text-2xl sm:text-3xl font-semibold text-center text-zinc-900 hover:text-zinc-500 dark:text-zinc-300 dark:hover:text-zinc-200"
|
class="block text-center text-2xl font-semibold text-zinc-900 hover:text-zinc-500 sm:text-3xl dark:text-zinc-300 dark:hover:text-zinc-200"
|
||||||
>
|
>
|
||||||
{@count}
|
{@count}
|
||||||
</.link>
|
</.link>
|
||||||
<p
|
<p
|
||||||
:if={!@path}
|
:if={!@path}
|
||||||
class="block cursor-default text-2xl sm:text-3xl font-semibold text-center text-zinc-900 dark:text-zinc-300"
|
class="block cursor-default text-center text-2xl font-semibold text-zinc-900 sm:text-3xl dark:text-zinc-300"
|
||||||
>
|
>
|
||||||
{@count}
|
{@count}
|
||||||
</p>
|
</p>
|
||||||
@@ -120,16 +120,16 @@ defmodule MusicLibraryWeb.StatsComponents do
|
|||||||
def counters_by_category(assigns) do
|
def counters_by_category(assigns) do
|
||||||
~H"""
|
~H"""
|
||||||
<dl class={[
|
<dl class={[
|
||||||
"mt-5 grid divide-zinc-200 dark:divide-zinc-900 overflow-hidden rounded-md bg-white dark:bg-zinc-800 shadow-sm divide-x",
|
"mt-5 grid divide-x divide-zinc-200 overflow-hidden rounded-md bg-white shadow-sm dark:divide-zinc-900 dark:bg-zinc-800",
|
||||||
stats_class(@categories_with_counts)
|
stats_class(@categories_with_counts)
|
||||||
]}>
|
]}>
|
||||||
<div :for={{category, count} <- @categories_with_counts} class="px-2 py-5 sm:px-4">
|
<div :for={{category, count} <- @categories_with_counts} 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">
|
<dt class="text-center text-sm font-medium break-keep text-zinc-500 max-sm:text-xs dark:text-zinc-400">
|
||||||
{@category_format_fn.(category)}
|
{@category_format_fn.(category)}
|
||||||
</dt>
|
</dt>
|
||||||
<dd class="mt-1 text-center">
|
<dd class="mt-1 text-center">
|
||||||
<.link
|
<.link
|
||||||
class="text-xl lg:text-2xl font-semibold hover:text-zinc-500 dark:text-zinc-300 dark:hover:text-zinc-200"
|
class="text-xl font-semibold hover:text-zinc-500 lg:text-2xl dark:text-zinc-300 dark:hover:text-zinc-200"
|
||||||
navigate={@category_path_fn.(category)}
|
navigate={@category_path_fn.(category)}
|
||||||
>
|
>
|
||||||
{count}
|
{count}
|
||||||
@@ -153,7 +153,7 @@ defmodule MusicLibraryWeb.StatsComponents do
|
|||||||
>
|
>
|
||||||
<li
|
<li
|
||||||
id="no-records-on-this-day"
|
id="no-records-on-this-day"
|
||||||
class="hidden py-8 only:flex items-center justify-center text-sm text-zinc-500 dark:text-zinc-400"
|
class="hidden items-center justify-center py-8 text-sm text-zinc-500 only:flex dark:text-zinc-400"
|
||||||
>
|
>
|
||||||
{gettext("No records released on this day.")}
|
{gettext("No records released on this day.")}
|
||||||
</li>
|
</li>
|
||||||
@@ -166,22 +166,22 @@ defmodule MusicLibraryWeb.StatsComponents do
|
|||||||
record_show_path={@record_show_path}
|
record_show_path={@record_show_path}
|
||||||
/>
|
/>
|
||||||
<% {:group, %{representative: rep, records: records}} -> %>
|
<% {:group, %{representative: rep, records: records}} -> %>
|
||||||
<li id={"group-#{rep.musicbrainz_id}"} class="py-2 px-2 md:px-4">
|
<li id={"group-#{rep.musicbrainz_id}"} class="p-2 md:px-4">
|
||||||
<details class="group/details">
|
<details class="group/details">
|
||||||
<summary class="flex justify-between gap-x-6 cursor-pointer list-none [&::-webkit-details-marker]:hidden hover:bg-zinc-50 dark:hover:bg-zinc-700 rounded-md -mx-2 px-2 py-1">
|
<summary class="-mx-2 flex cursor-pointer list-none justify-between gap-x-6 rounded-md px-2 py-1 hover:bg-zinc-50 dark:hover:bg-zinc-700 [&::-webkit-details-marker]:hidden">
|
||||||
<div class="flex min-w-0 gap-x-4 items-center">
|
<div class="flex min-w-0 items-center gap-x-4">
|
||||||
<div class="relative w-12 flex-none">
|
<div class="relative w-12 flex-none">
|
||||||
<.record_cover record={rep} width={96} />
|
<.record_cover record={rep} width={96} />
|
||||||
<.release_groups_badge record={rep} />
|
<.release_groups_badge record={rep} />
|
||||||
</div>
|
</div>
|
||||||
<div class="min-w-0 flex-auto">
|
<div class="min-w-0 flex-auto">
|
||||||
<h1 class="text-sm leading-6 text-zinc-700">
|
<h1 class="text-sm/6 text-zinc-700">
|
||||||
<.artist_links joinphrase_class="text-xs" artists={rep.artists} />
|
<.artist_links joinphrase_class="text-xs" artists={rep.artists} />
|
||||||
</h1>
|
</h1>
|
||||||
<h2 class="mt-1 flex font-semibold text-sm sm:text-base leading-5 text-zinc-700 dark:text-zinc-300 text-wrap">
|
<h2 class="mt-1 flex text-sm/5 font-semibold text-wrap text-zinc-700 sm:text-base dark:text-zinc-300">
|
||||||
{rep.title}
|
{rep.title}
|
||||||
</h2>
|
</h2>
|
||||||
<p class="mt-1 text-xs leading-5 text-zinc-500 dark:text-zinc-400">
|
<p class="mt-1 text-xs/5 text-zinc-500 dark:text-zinc-400">
|
||||||
<.released_how_long_ago record={rep} current_date={@current_date} />
|
<.released_how_long_ago record={rep} current_date={@current_date} />
|
||||||
· {ngettext("1 release", "%{count} releases", length(records))}
|
· {ngettext("1 release", "%{count} releases", length(records))}
|
||||||
</p>
|
</p>
|
||||||
@@ -190,18 +190,18 @@ defmodule MusicLibraryWeb.StatsComponents do
|
|||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<.icon
|
<.icon
|
||||||
name="hero-chevron-right"
|
name="hero-chevron-right"
|
||||||
class="h-4 w-4 text-zinc-400 transition-transform group-open/details:rotate-90"
|
class="size-4 text-zinc-400 transition-transform group-open/details:rotate-90"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</summary>
|
</summary>
|
||||||
<ul class="ml-16 mt-1 border-l border-zinc-200 dark:border-zinc-700 pl-4">
|
<ul class="mt-1 ml-16 border-l border-zinc-200 pl-4 dark:border-zinc-700">
|
||||||
<li
|
<li
|
||||||
:for={record <- records}
|
:for={record <- records}
|
||||||
phx-click={JS.navigate(@record_show_path.(record))}
|
phx-click={JS.navigate(@record_show_path.(record))}
|
||||||
class="flex justify-between gap-x-6 py-1.5 hover:bg-zinc-50 dark:hover:bg-zinc-700 px-2 rounded-md cursor-pointer"
|
class="flex cursor-pointer justify-between gap-x-6 rounded-md px-2 py-1.5 hover:bg-zinc-50 dark:hover:bg-zinc-700"
|
||||||
id={record.id}
|
id={record.id}
|
||||||
>
|
>
|
||||||
<p class="text-xs leading-5 text-zinc-500 dark:text-zinc-400">
|
<p class="text-xs/5 text-zinc-500 dark:text-zinc-400">
|
||||||
{format_label(record.format)} · {type_label(record.type)}
|
{format_label(record.format)} · {type_label(record.type)}
|
||||||
<span :if={record.purchased_at}>
|
<span :if={record.purchased_at}>
|
||||||
·
|
·
|
||||||
@@ -210,7 +210,7 @@ defmodule MusicLibraryWeb.StatsComponents do
|
|||||||
</span>
|
</span>
|
||||||
<.icon
|
<.icon
|
||||||
name="hero-banknotes"
|
name="hero-banknotes"
|
||||||
class="h-4 w-4"
|
class="size-4"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
data-slot="icon"
|
data-slot="icon"
|
||||||
/>
|
/>
|
||||||
@@ -235,22 +235,22 @@ defmodule MusicLibraryWeb.StatsComponents do
|
|||||||
~H"""
|
~H"""
|
||||||
<li
|
<li
|
||||||
phx-click={JS.navigate(@record_show_path.(@record))}
|
phx-click={JS.navigate(@record_show_path.(@record))}
|
||||||
class="flex justify-between gap-x-6 py-2 hover:bg-zinc-50 dark:hover:bg-zinc-700 px-2 md:px-4 cursor-pointer"
|
class="flex cursor-pointer justify-between gap-x-6 p-2 hover:bg-zinc-50 md:px-4 dark:hover:bg-zinc-700"
|
||||||
id={@record.id}
|
id={@record.id}
|
||||||
>
|
>
|
||||||
<div class="flex min-w-0 gap-x-4 items-center">
|
<div class="flex min-w-0 items-center gap-x-4">
|
||||||
<div class="relative w-12 flex-none">
|
<div class="relative w-12 flex-none">
|
||||||
<.record_cover record={@record} width={96} />
|
<.record_cover record={@record} width={96} />
|
||||||
<.release_groups_badge record={@record} />
|
<.release_groups_badge record={@record} />
|
||||||
</div>
|
</div>
|
||||||
<div class="min-w-0 flex-auto">
|
<div class="min-w-0 flex-auto">
|
||||||
<h1 class="text-sm leading-6 text-zinc-700">
|
<h1 class="text-sm/6 text-zinc-700">
|
||||||
<.artist_links joinphrase_class="text-xs" artists={@record.artists} />
|
<.artist_links joinphrase_class="text-xs" artists={@record.artists} />
|
||||||
</h1>
|
</h1>
|
||||||
<h2 class="mt-1 flex font-semibold text-sm sm:text-base leading-5 text-zinc-700 dark:text-zinc-300 text-wrap">
|
<h2 class="mt-1 flex text-sm/5 font-semibold text-wrap text-zinc-700 sm:text-base dark:text-zinc-300">
|
||||||
{@record.title}
|
{@record.title}
|
||||||
</h2>
|
</h2>
|
||||||
<p class="mt-1 text-xs leading-5 text-zinc-500 dark:text-zinc-400">
|
<p class="mt-1 text-xs/5 text-zinc-500 dark:text-zinc-400">
|
||||||
<.released_how_long_ago record={@record} current_date={@current_date} />
|
<.released_how_long_ago record={@record} current_date={@current_date} />
|
||||||
· {format_label(@record.format)} · {type_label(@record.type)}
|
· {format_label(@record.format)} · {type_label(@record.type)}
|
||||||
<span :if={@record.purchased_at}>
|
<span :if={@record.purchased_at}>
|
||||||
@@ -260,7 +260,7 @@ defmodule MusicLibraryWeb.StatsComponents do
|
|||||||
</span>
|
</span>
|
||||||
<.icon
|
<.icon
|
||||||
name="hero-banknotes"
|
name="hero-banknotes"
|
||||||
class="h-4 w-4"
|
class="size-4"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
data-slot="icon"
|
data-slot="icon"
|
||||||
/>
|
/>
|
||||||
@@ -288,8 +288,8 @@ defmodule MusicLibraryWeb.StatsComponents do
|
|||||||
<span
|
<span
|
||||||
:if={same_year?(@years)}
|
:if={same_year?(@years)}
|
||||||
class={[
|
class={[
|
||||||
"text-xs leading-5",
|
"text-xs/5",
|
||||||
"font-semibold bg-linear-to-r bg-clip-text text-transparent from-red-500 via-red-200 to-red-700 animate-shine"
|
"animate-shine bg-linear-to-r from-red-500 via-red-200 to-red-700 bg-clip-text font-semibold text-transparent"
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
{gettext("Today")}
|
{gettext("Today")}
|
||||||
@@ -297,12 +297,12 @@ defmodule MusicLibraryWeb.StatsComponents do
|
|||||||
<span
|
<span
|
||||||
:if={!same_year?(@years)}
|
:if={!same_year?(@years)}
|
||||||
class={[
|
class={[
|
||||||
"text-xs leading-5",
|
"text-xs/5",
|
||||||
normal_year?(@years) && "text-zinc-500 dark:text-zinc-400",
|
normal_year?(@years) && "text-zinc-500 dark:text-zinc-400",
|
||||||
gold_year?(@years) &&
|
gold_year?(@years) &&
|
||||||
"font-semibold bg-linear-to-r bg-clip-text text-transparent from-yellow-500 via-yellow-200 to-yellow-700 animate-shine",
|
"animate-shine bg-linear-to-r from-yellow-500 via-yellow-200 to-yellow-700 bg-clip-text font-semibold text-transparent",
|
||||||
silver_year?(@years) &&
|
silver_year?(@years) &&
|
||||||
"font-semibold bg-linear-to-r bg-clip-text text-transparent from-gray-500 via-gray-200 to-gray-700 animate-shine"
|
"animate-shine bg-linear-to-r from-gray-500 via-gray-200 to-gray-700 bg-clip-text font-semibold text-transparent"
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
{ngettext(
|
{ngettext(
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<div class="flex min-h-full items-center justify-center px-4 py-12 sm:px-6 lg:px-8">
|
<div class="flex min-h-full items-center justify-center px-4 py-12 sm:px-6 lg:px-8">
|
||||||
<div class="w-full max-w-sm space-y-10">
|
<div class="w-full max-w-sm space-y-10">
|
||||||
<div>
|
<div>
|
||||||
<h2 class="mt-10 text-center text-2xl font-bold leading-9 tracking-tight text-zinc-900 dark:text-zinc-200">
|
<h2 class="mt-10 text-center text-2xl/9 font-bold tracking-tight text-zinc-900 dark:text-zinc-200">
|
||||||
{gettext("Welcome to your Music Library")}
|
{gettext("Welcome to your Music Library")}
|
||||||
</h2>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
@@ -20,7 +20,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="w-full flex justify-center">
|
<div class="flex w-full justify-center">
|
||||||
<.button variant="solid" type="submit">
|
<.button variant="solid" type="submit">
|
||||||
{gettext("Login")}
|
{gettext("Login")}
|
||||||
</.button>
|
</.button>
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ defmodule MusicLibraryWeb.ArtistLive.Form do
|
|||||||
<div class="text-center">
|
<div class="text-center">
|
||||||
<.artist_image
|
<.artist_image
|
||||||
:if={@uploads.image_data.entries == []}
|
:if={@uploads.image_data.entries == []}
|
||||||
class="rounded-lg mx-auto w-full"
|
class="mx-auto w-full rounded-lg"
|
||||||
artist={@artist}
|
artist={@artist}
|
||||||
image_hash={@artist_info.image_data_hash}
|
image_hash={@artist_info.image_data_hash}
|
||||||
/>
|
/>
|
||||||
@@ -67,7 +67,7 @@ defmodule MusicLibraryWeb.ArtistLive.Form do
|
|||||||
for={@uploads.image_data.ref}
|
for={@uploads.image_data.ref}
|
||||||
class={[
|
class={[
|
||||||
"relative cursor-pointer rounded-md font-semibold",
|
"relative cursor-pointer rounded-md font-semibold",
|
||||||
"focus-within:outline-none focus-within:ring-2 focus-within:ring-indigo-600 focus-within:ring-offset-2",
|
"focus-within:ring-2 focus-within:ring-indigo-600 focus-within:ring-offset-2 focus-within:outline-none",
|
||||||
"hover:text-zinc-200"
|
"hover:text-zinc-200"
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
@@ -126,7 +126,7 @@ defmodule MusicLibraryWeb.ArtistLive.Form do
|
|||||||
<div
|
<div
|
||||||
:if={@image_search_results != []}
|
:if={@image_search_results != []}
|
||||||
id="image-search-results"
|
id="image-search-results"
|
||||||
class="grid grid-cols-3 sm:grid-cols-4 gap-2"
|
class="grid grid-cols-3 gap-2 sm:grid-cols-4"
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
:for={result <- @image_search_results}
|
:for={result <- @image_search_results}
|
||||||
@@ -139,8 +139,8 @@ defmodule MusicLibraryWeb.ArtistLive.Form do
|
|||||||
"group relative overflow-hidden rounded-md",
|
"group relative overflow-hidden rounded-md",
|
||||||
"border border-zinc-200 dark:border-zinc-700",
|
"border border-zinc-200 dark:border-zinc-700",
|
||||||
"hover:ring-2 hover:ring-indigo-500",
|
"hover:ring-2 hover:ring-indigo-500",
|
||||||
"focus:outline-none focus:ring-2 focus:ring-indigo-500",
|
"focus:ring-2 focus:ring-indigo-500 focus:outline-none",
|
||||||
"disabled:opacity-50 disabled:cursor-not-allowed"
|
"disabled:cursor-not-allowed disabled:opacity-50"
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
@@ -152,8 +152,8 @@ defmodule MusicLibraryWeb.ArtistLive.Form do
|
|||||||
<span
|
<span
|
||||||
:if={result.width && result.height}
|
:if={result.width && result.height}
|
||||||
class={[
|
class={[
|
||||||
"absolute bottom-0 inset-x-0",
|
"absolute inset-x-0 bottom-0",
|
||||||
"bg-black/60 text-white text-xs text-center",
|
"bg-black/60 text-center text-xs text-white",
|
||||||
"py-0.5"
|
"py-0.5"
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -36,10 +36,10 @@ defmodule MusicLibraryWeb.ArtistLive.Show do
|
|||||||
|
|
||||||
defp play_count(assigns) do
|
defp play_count(assigns) do
|
||||||
~H"""
|
~H"""
|
||||||
<span :if={@play_count > 0} class="text-xs font-medium text-zinc-700 dark:text-zinc-300 grow">
|
<span :if={@play_count > 0} class="grow text-xs font-medium text-zinc-700 dark:text-zinc-300">
|
||||||
{ngettext("1 scrobble", "%{count} scrobbles", @play_count)}
|
{ngettext("1 scrobble", "%{count} scrobbles", @play_count)}
|
||||||
</span>
|
</span>
|
||||||
<span :if={@play_count == 0} class="text-xs font-medium text-zinc-700 dark:text-zinc-300 grow">
|
<span :if={@play_count == 0} class="grow text-xs font-medium text-zinc-700 dark:text-zinc-300">
|
||||||
{gettext("No scrobbles")}
|
{gettext("No scrobbles")}
|
||||||
</span>
|
</span>
|
||||||
"""
|
"""
|
||||||
@@ -52,7 +52,7 @@ defmodule MusicLibraryWeb.ArtistLive.Show do
|
|||||||
~H"""
|
~H"""
|
||||||
<div class="mt-4">
|
<div class="mt-4">
|
||||||
<header class="flex items-baseline justify-start">
|
<header class="flex items-baseline justify-start">
|
||||||
<h2 class="font-semibold text-base sm:text-lg leading-5 text-zinc-700 dark:text-zinc-300">
|
<h2 class="text-base/5 font-semibold text-zinc-700 sm:text-lg dark:text-zinc-300">
|
||||||
{@title}
|
{@title}
|
||||||
</h2>
|
</h2>
|
||||||
</header>
|
</header>
|
||||||
@@ -69,7 +69,7 @@ defmodule MusicLibraryWeb.ArtistLive.Show do
|
|||||||
}
|
}
|
||||||
>
|
>
|
||||||
<.artist_image
|
<.artist_image
|
||||||
class="aspect-square object-cover rounded-lg hover:shadow-lg/20"
|
class="aspect-square rounded-lg object-cover hover:shadow-lg/20"
|
||||||
artist={artist}
|
artist={artist}
|
||||||
image_hash={artist.image_data_hash}
|
image_hash={artist.image_data_hash}
|
||||||
/>
|
/>
|
||||||
@@ -90,7 +90,7 @@ defmodule MusicLibraryWeb.ArtistLive.Show do
|
|||||||
<div class="mt-4 px-4 sm:px-6 lg:px-8">
|
<div class="mt-4 px-4 sm:px-6 lg:px-8">
|
||||||
<header class="mt-1 gap-1">
|
<header class="mt-1 gap-1">
|
||||||
<div class="flex items-center justify-between">
|
<div class="flex items-center justify-between">
|
||||||
<h1 class="font-semibold text-2xl leading-5 text-zinc-700 dark:text-zinc-300 text-wrap">
|
<h1 class="text-2xl/5 font-semibold text-wrap text-zinc-700 dark:text-zinc-300">
|
||||||
{@artist.name}
|
{@artist.name}
|
||||||
<.country_flag country={@country} />
|
<.country_flag country={@country} />
|
||||||
</h1>
|
</h1>
|
||||||
@@ -140,7 +140,7 @@ defmodule MusicLibraryWeb.ArtistLive.Show do
|
|||||||
<span class="sr-only">{gettext("Actions")}</span>
|
<span class="sr-only">{gettext("Actions")}</span>
|
||||||
<.icon
|
<.icon
|
||||||
name="hero-ellipsis-vertical"
|
name="hero-ellipsis-vertical"
|
||||||
class="icon text-zinc-500 dark:text-zinc-400 cursor-pointer"
|
class="icon cursor-pointer text-zinc-500 dark:text-zinc-400"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
data-slot="icon"
|
data-slot="icon"
|
||||||
/>
|
/>
|
||||||
@@ -153,7 +153,7 @@ defmodule MusicLibraryWeb.ArtistLive.Show do
|
|||||||
>
|
>
|
||||||
<.icon
|
<.icon
|
||||||
name="hero-pencil-square"
|
name="hero-pencil-square"
|
||||||
class="h-4 w-4 mr-1 phx-click-loading:animate-bounce"
|
class="phx-click-loading:animate-bounce mr-1 size-4"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
data-slot="icon"
|
data-slot="icon"
|
||||||
/>
|
/>
|
||||||
@@ -165,7 +165,7 @@ defmodule MusicLibraryWeb.ArtistLive.Show do
|
|||||||
>
|
>
|
||||||
<.icon
|
<.icon
|
||||||
name="hero-photo"
|
name="hero-photo"
|
||||||
class="h-4 w-4 mr-1 phx-click-loading:animate-bounce"
|
class="phx-click-loading:animate-bounce mr-1 size-4"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
data-slot="icon"
|
data-slot="icon"
|
||||||
/>
|
/>
|
||||||
@@ -178,7 +178,7 @@ defmodule MusicLibraryWeb.ArtistLive.Show do
|
|||||||
>
|
>
|
||||||
<.icon
|
<.icon
|
||||||
name="hero-arrow-path"
|
name="hero-arrow-path"
|
||||||
class="h-4 w-4 mr-1 phx-click-loading:animate-spin"
|
class="phx-click-loading:animate-spin mr-1 size-4"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
data-slot="icon"
|
data-slot="icon"
|
||||||
/>
|
/>
|
||||||
@@ -190,7 +190,7 @@ defmodule MusicLibraryWeb.ArtistLive.Show do
|
|||||||
>
|
>
|
||||||
<.icon
|
<.icon
|
||||||
name="hero-arrow-path"
|
name="hero-arrow-path"
|
||||||
class="h-4 w-4 mr-1 phx-click-loading:animate-spin"
|
class="phx-click-loading:animate-spin mr-1 size-4"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
data-slot="icon"
|
data-slot="icon"
|
||||||
/>
|
/>
|
||||||
@@ -202,7 +202,7 @@ defmodule MusicLibraryWeb.ArtistLive.Show do
|
|||||||
>
|
>
|
||||||
<.icon
|
<.icon
|
||||||
name="hero-arrow-path"
|
name="hero-arrow-path"
|
||||||
class="h-4 w-4 mr-1 phx-click-loading:animate-spin"
|
class="phx-click-loading:animate-spin mr-1 size-4"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
data-slot="icon"
|
data-slot="icon"
|
||||||
/>
|
/>
|
||||||
@@ -221,10 +221,10 @@ defmodule MusicLibraryWeb.ArtistLive.Show do
|
|||||||
<.loading />
|
<.loading />
|
||||||
</:loading>
|
</:loading>
|
||||||
<:failed :let={_failure}>
|
<:failed :let={_failure}>
|
||||||
<div class="mt-4 text-sm leading-5 text-zinc-500 dark:text-zinc-400">
|
<div class="mt-4 text-sm/5 text-zinc-500 dark:text-zinc-400">
|
||||||
<.icon
|
<.icon
|
||||||
name="hero-exclamation-triangle"
|
name="hero-exclamation-triangle"
|
||||||
class="-mt-1 mr-1 ml-2 h-5 w-5"
|
class="-mt-1 mr-1 ml-2 size-5"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
data-slot="icon"
|
data-slot="icon"
|
||||||
/>
|
/>
|
||||||
@@ -238,24 +238,24 @@ defmodule MusicLibraryWeb.ArtistLive.Show do
|
|||||||
</header>
|
</header>
|
||||||
|
|
||||||
<div class="mt-4 grid md:grid-cols-10 md:gap-4">
|
<div class="mt-4 grid md:grid-cols-10 md:gap-4">
|
||||||
<div class="md:col-span-3 mt-4 order-2 md:order-1">
|
<div class="order-2 mt-4 md:order-1 md:col-span-3">
|
||||||
<h2 class="font-semibold text-base sm:text-lg leading-5 text-zinc-700 dark:text-zinc-300">
|
<h2 class="text-base/5 font-semibold text-zinc-700 sm:text-lg dark:text-zinc-300">
|
||||||
{gettext("Meta")}
|
{gettext("Meta")}
|
||||||
</h2>
|
</h2>
|
||||||
<.artist_image
|
<.artist_image
|
||||||
class="w-full rounded-md shadow-sm mt-4 cursor-pointer"
|
class="mt-4 w-full cursor-pointer rounded-md shadow-sm"
|
||||||
artist={@artist}
|
artist={@artist}
|
||||||
image_hash={@artist_info.image_data_hash}
|
image_hash={@artist_info.image_data_hash}
|
||||||
phx-click={Fluxon.open_dialog("artist-image-modal")}
|
phx-click={Fluxon.open_dialog("artist-image-modal")}
|
||||||
/>
|
/>
|
||||||
<.modal
|
<.modal
|
||||||
id="artist-image-modal"
|
id="artist-image-modal"
|
||||||
class="mx-auto sm:min-w-2xl max-w-sm md:max-w-3xl lg:max-w-5xl mt-8"
|
class="mx-auto mt-8 max-w-sm sm:min-w-2xl md:max-w-3xl lg:max-w-5xl"
|
||||||
placement="center"
|
placement="center"
|
||||||
open={false}
|
open={false}
|
||||||
>
|
>
|
||||||
<.artist_image
|
<.artist_image
|
||||||
class="w-full rounded-md shadow-sm mt-8"
|
class="mt-8 w-full rounded-md shadow-sm"
|
||||||
artist={@artist}
|
artist={@artist}
|
||||||
image_hash={@artist_info.image_data_hash}
|
image_hash={@artist_info.image_data_hash}
|
||||||
/>
|
/>
|
||||||
@@ -287,25 +287,25 @@ defmodule MusicLibraryWeb.ArtistLive.Show do
|
|||||||
</.button>
|
</.button>
|
||||||
</div>
|
</div>
|
||||||
<%= if @biography do %>
|
<%= if @biography do %>
|
||||||
<dt class="mt-4 text-sm font-medium leading-6 text-zinc-900 dark:text-zinc-400">
|
<dt class="mt-4 text-sm/6 font-medium text-zinc-900 dark:text-zinc-400">
|
||||||
{gettext("Biography")}
|
{gettext("Biography")}
|
||||||
<.badge variant="soft" class="ml-1">{@biography.source}</.badge>
|
<.badge variant="soft" class="ml-1">{@biography.source}</.badge>
|
||||||
</dt>
|
</dt>
|
||||||
<dd class="text-zinc-700 dark:text-zinc-300">
|
<dd class="text-zinc-700 dark:text-zinc-300">
|
||||||
<p
|
<p
|
||||||
:if={@biography.description}
|
:if={@biography.description}
|
||||||
class="mt-2 text-sm italic text-zinc-500 dark:text-zinc-400"
|
class="mt-2 text-sm text-zinc-500 italic dark:text-zinc-400"
|
||||||
>
|
>
|
||||||
{@biography.description}
|
{@biography.description}
|
||||||
</p>
|
</p>
|
||||||
<p class="mt-2 text-sm/7">{@biography.summary_html}</p>
|
<p class="mt-2 text-sm/7">{@biography.summary_html}</p>
|
||||||
<.link
|
<.link
|
||||||
class="block mt-2 text-sm font-medium text-zinc-900 dark:text-zinc-400"
|
class="mt-2 block text-sm font-medium text-zinc-900 dark:text-zinc-400"
|
||||||
phx-click={Fluxon.open_dialog("bio")}
|
phx-click={Fluxon.open_dialog("bio")}
|
||||||
>
|
>
|
||||||
<.icon
|
<.icon
|
||||||
name="hero-arrow-right-end-on-rectangle"
|
name="hero-arrow-right-end-on-rectangle"
|
||||||
class="-mt-1 mr-1 h-5 w-5"
|
class="-mt-1 mr-1 size-5"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
data-slot="icon"
|
data-slot="icon"
|
||||||
/>
|
/>
|
||||||
@@ -317,19 +317,19 @@ defmodule MusicLibraryWeb.ArtistLive.Show do
|
|||||||
class="max-w-2xl text-zinc-700 dark:text-zinc-300"
|
class="max-w-2xl text-zinc-700 dark:text-zinc-300"
|
||||||
placement="left"
|
placement="left"
|
||||||
>
|
>
|
||||||
<div class="prose prose-sm dark:prose-invert">
|
<div class="dark:prose-invert prose prose-sm">
|
||||||
{Phoenix.HTML.raw(@biography.bio_html)}
|
{Phoenix.HTML.raw(@biography.bio_html)}
|
||||||
</div>
|
</div>
|
||||||
<a
|
<a
|
||||||
:if={@biography.url}
|
:if={@biography.url}
|
||||||
href={@biography.url}
|
href={@biography.url}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
class="mt-4 block text-sm font-medium text-zinc-900 dark:text-zinc-400 hover:text-zinc-500"
|
class="mt-4 block text-sm font-medium text-zinc-900 hover:text-zinc-500 dark:text-zinc-400"
|
||||||
>
|
>
|
||||||
{gettext("Read full article on Wikipedia")}
|
{gettext("Read full article on Wikipedia")}
|
||||||
<.icon
|
<.icon
|
||||||
name="hero-arrow-top-right-on-square"
|
name="hero-arrow-top-right-on-square"
|
||||||
class="-mt-1 ml-1 h-4 w-4"
|
class="-mt-1 ml-1 size-4"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
data-slot="icon"
|
data-slot="icon"
|
||||||
/>
|
/>
|
||||||
@@ -338,15 +338,15 @@ defmodule MusicLibraryWeb.ArtistLive.Show do
|
|||||||
<% else %>
|
<% else %>
|
||||||
<.async_result :let={lastfm_artist_info} assign={@lastfm_artist_info}>
|
<.async_result :let={lastfm_artist_info} assign={@lastfm_artist_info}>
|
||||||
<:loading>
|
<:loading>
|
||||||
<div class="mt-4 text-sm leading-5 text-zinc-500 dark:text-zinc-400">
|
<div class="mt-4 text-sm/5 text-zinc-500 dark:text-zinc-400">
|
||||||
{gettext("Loading biography")}
|
{gettext("Loading biography")}
|
||||||
</div>
|
</div>
|
||||||
</:loading>
|
</:loading>
|
||||||
<:failed :let={_failure}>
|
<:failed :let={_failure}>
|
||||||
<div class="mt-4 text-sm leading-5 text-zinc-500 dark:text-zinc-400">
|
<div class="mt-4 text-sm/5 text-zinc-500 dark:text-zinc-400">
|
||||||
<.icon
|
<.icon
|
||||||
name="hero-exclamation-triangle"
|
name="hero-exclamation-triangle"
|
||||||
class="-mt-1 mr-1 h-5 w-5"
|
class="-mt-1 mr-1 size-5"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
data-slot="icon"
|
data-slot="icon"
|
||||||
/>
|
/>
|
||||||
@@ -355,7 +355,7 @@ defmodule MusicLibraryWeb.ArtistLive.Show do
|
|||||||
</:failed>
|
</:failed>
|
||||||
<dt
|
<dt
|
||||||
:if={lastfm_artist_info.bio not in [nil, ""]}
|
:if={lastfm_artist_info.bio not in [nil, ""]}
|
||||||
class="mt-4 text-sm font-medium leading-6 text-zinc-900 dark:text-zinc-400"
|
class="mt-4 text-sm/6 font-medium text-zinc-900 dark:text-zinc-400"
|
||||||
>
|
>
|
||||||
{gettext("Biography")}
|
{gettext("Biography")}
|
||||||
</dt>
|
</dt>
|
||||||
@@ -365,12 +365,12 @@ defmodule MusicLibraryWeb.ArtistLive.Show do
|
|||||||
>
|
>
|
||||||
{remove_read_more_link(lastfm_artist_info.summary)}
|
{remove_read_more_link(lastfm_artist_info.summary)}
|
||||||
<.link
|
<.link
|
||||||
class="block mt-2 text-sm font-medium text-zinc-900 dark:text-zinc-400"
|
class="mt-2 block text-sm font-medium text-zinc-900 dark:text-zinc-400"
|
||||||
phx-click={Fluxon.open_dialog("lastfm-bio")}
|
phx-click={Fluxon.open_dialog("lastfm-bio")}
|
||||||
>
|
>
|
||||||
<.icon
|
<.icon
|
||||||
name="hero-arrow-right-end-on-rectangle"
|
name="hero-arrow-right-end-on-rectangle"
|
||||||
class="-mt-1 mr-1 h-5 w-5"
|
class="-mt-1 mr-1 size-5"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
data-slot="icon"
|
data-slot="icon"
|
||||||
/>
|
/>
|
||||||
@@ -389,7 +389,7 @@ defmodule MusicLibraryWeb.ArtistLive.Show do
|
|||||||
<% end %>
|
<% end %>
|
||||||
<.external_links external_links={@external_links} />
|
<.external_links external_links={@external_links} />
|
||||||
</div>
|
</div>
|
||||||
<div class="md:col-span-7 md:order-1">
|
<div class="md:order-1 md:col-span-7">
|
||||||
<.record_grid
|
<.record_grid
|
||||||
:if={@collection_records_count > 0}
|
:if={@collection_records_count > 0}
|
||||||
title={gettext("Collection")}
|
title={gettext("Collection")}
|
||||||
@@ -402,7 +402,7 @@ defmodule MusicLibraryWeb.ArtistLive.Show do
|
|||||||
/>
|
/>
|
||||||
<.separator
|
<.separator
|
||||||
:if={@collection_records_count > 0 && @wishlist_records_count > 0}
|
:if={@collection_records_count > 0 && @wishlist_records_count > 0}
|
||||||
class="mt-8 mb-8"
|
class="my-8"
|
||||||
/>
|
/>
|
||||||
<.record_grid
|
<.record_grid
|
||||||
:if={@wishlist_records_count > 0}
|
:if={@wishlist_records_count > 0}
|
||||||
@@ -417,22 +417,22 @@ defmodule MusicLibraryWeb.ArtistLive.Show do
|
|||||||
|
|
||||||
<.async_result :let={similar_artists} assign={@similar_artists}>
|
<.async_result :let={similar_artists} assign={@similar_artists}>
|
||||||
<:loading>
|
<:loading>
|
||||||
<div class="mt-4 text-sm leading-5 text-zinc-500 dark:text-zinc-400">
|
<div class="mt-4 text-sm/5 text-zinc-500 dark:text-zinc-400">
|
||||||
{gettext("Loading similar artists")}
|
{gettext("Loading similar artists")}
|
||||||
</div>
|
</div>
|
||||||
</:loading>
|
</:loading>
|
||||||
<:failed :let={_failure}>
|
<:failed :let={_failure}>
|
||||||
<div class="mt-4 text-sm leading-5 text-zinc-500 dark:text-zinc-400">
|
<div class="mt-4 text-sm/5 text-zinc-500 dark:text-zinc-400">
|
||||||
<.icon
|
<.icon
|
||||||
name="hero-exclamation-triangle"
|
name="hero-exclamation-triangle"
|
||||||
class="-mt-1 mr-1 h-5 w-5"
|
class="-mt-1 mr-1 size-5"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
data-slot="icon"
|
data-slot="icon"
|
||||||
/>
|
/>
|
||||||
{gettext("Error loading similar artists")}
|
{gettext("Error loading similar artists")}
|
||||||
</div>
|
</div>
|
||||||
</:failed>
|
</:failed>
|
||||||
<.separator class="mt-8 mb-8" />
|
<.separator class="my-8" />
|
||||||
<.artist_grid title={gettext("Similar artists")} artists={similar_artists} />
|
<.artist_grid title={gettext("Similar artists")} artists={similar_artists} />
|
||||||
</.async_result>
|
</.async_result>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -22,8 +22,8 @@ defmodule MusicLibraryWeb.CollectionLive.Index do
|
|||||||
def render(assigns) do
|
def render(assigns) do
|
||||||
~H"""
|
~H"""
|
||||||
<Layouts.app flash={@flash} current_section={@current_section} socket={@socket}>
|
<Layouts.app flash={@flash} current_section={@current_section} socket={@socket}>
|
||||||
<header class="gap-6 mb-2">
|
<header class="mb-2 gap-6">
|
||||||
<div class="flex items-center justify-between gap-6 mb-2 mt-2">
|
<div class="my-2 flex items-center justify-between gap-6">
|
||||||
<.search_form query={@record_list_params.query} />
|
<.search_form query={@record_list_params.query} />
|
||||||
<.button_group>
|
<.button_group>
|
||||||
<.button
|
<.button
|
||||||
@@ -46,7 +46,7 @@ defmodule MusicLibraryWeb.CollectionLive.Index do
|
|||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<div class="flex items-end justify-between gap-6 mt-6">
|
<div class="mt-6 flex items-end justify-between gap-6">
|
||||||
<.button_group>
|
<.button_group>
|
||||||
<.button
|
<.button
|
||||||
patch={order_path(@record_list_params, :purchase)}
|
patch={order_path(@record_list_params, :purchase)}
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ defmodule MusicLibraryWeb.CollectionLive.Show do
|
|||||||
def render(assigns) do
|
def render(assigns) do
|
||||||
~H"""
|
~H"""
|
||||||
<Layouts.app flash={@flash} current_section={@current_section} socket={@socket}>
|
<Layouts.app flash={@flash} current_section={@current_section} socket={@socket}>
|
||||||
<div class="lg:grid lg:grid-cols-2 xl:grid-cols-5 mt-4 px-4 md:gap-x-4">
|
<div class="mt-4 px-4 md:gap-x-4 lg:grid lg:grid-cols-2 xl:grid-cols-5">
|
||||||
<div class="drop-shadow-sm xl:col-span-2">
|
<div class="drop-shadow-sm xl:col-span-2">
|
||||||
<.record_cover
|
<.record_cover
|
||||||
record={@record}
|
record={@record}
|
||||||
@@ -40,8 +40,8 @@ defmodule MusicLibraryWeb.CollectionLive.Show do
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="xl:col-span-3">
|
<div class="xl:col-span-3">
|
||||||
<div class="mt-4 md:mt-0 flex justify-between items-center">
|
<div class="mt-4 flex items-center justify-between md:mt-0">
|
||||||
<h1 class="text-base font-medium leading-6 text-zinc-700">
|
<h1 class="text-base/6 font-medium text-zinc-700">
|
||||||
<.artist_links joinphrase_class="text-sm" artists={@record.artists} />
|
<.artist_links joinphrase_class="text-sm" artists={@record.artists} />
|
||||||
</h1>
|
</h1>
|
||||||
<div class="min-w-12">
|
<div class="min-w-12">
|
||||||
@@ -91,7 +91,7 @@ defmodule MusicLibraryWeb.CollectionLive.Show do
|
|||||||
<span class="sr-only">{gettext("Actions")}</span>
|
<span class="sr-only">{gettext("Actions")}</span>
|
||||||
<.icon
|
<.icon
|
||||||
name="hero-ellipsis-vertical"
|
name="hero-ellipsis-vertical"
|
||||||
class="icon text-zinc-500 dark:text-zinc-400 cursor-pointer"
|
class="icon cursor-pointer text-zinc-500 dark:text-zinc-400"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
data-slot="icon"
|
data-slot="icon"
|
||||||
/>
|
/>
|
||||||
@@ -104,7 +104,7 @@ defmodule MusicLibraryWeb.CollectionLive.Show do
|
|||||||
>
|
>
|
||||||
<.icon
|
<.icon
|
||||||
name="hero-pencil"
|
name="hero-pencil"
|
||||||
class="h-4 w-4 mr-1"
|
class="mr-1 size-4"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
data-slot="icon"
|
data-slot="icon"
|
||||||
/>
|
/>
|
||||||
@@ -117,7 +117,7 @@ defmodule MusicLibraryWeb.CollectionLive.Show do
|
|||||||
>
|
>
|
||||||
<.icon
|
<.icon
|
||||||
name="hero-code-bracket"
|
name="hero-code-bracket"
|
||||||
class="h-4 w-4 mr-1"
|
class="mr-1 size-4"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
data-slot="icon"
|
data-slot="icon"
|
||||||
/>
|
/>
|
||||||
@@ -132,7 +132,7 @@ defmodule MusicLibraryWeb.CollectionLive.Show do
|
|||||||
>
|
>
|
||||||
<.icon
|
<.icon
|
||||||
name="hero-pencil-square"
|
name="hero-pencil-square"
|
||||||
class="h-4 w-4 mr-1 phx-click-loading:animate-bounce"
|
class="phx-click-loading:animate-bounce mr-1 size-4"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
data-slot="icon"
|
data-slot="icon"
|
||||||
/>
|
/>
|
||||||
@@ -145,7 +145,7 @@ defmodule MusicLibraryWeb.CollectionLive.Show do
|
|||||||
>
|
>
|
||||||
<.icon
|
<.icon
|
||||||
name="hero-photo"
|
name="hero-photo"
|
||||||
class="h-4 w-4 mr-1 phx-click-loading:animate-bounce"
|
class="phx-click-loading:animate-bounce mr-1 size-4"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
data-slot="icon"
|
data-slot="icon"
|
||||||
/>
|
/>
|
||||||
@@ -158,7 +158,7 @@ defmodule MusicLibraryWeb.CollectionLive.Show do
|
|||||||
>
|
>
|
||||||
<.icon
|
<.icon
|
||||||
name="hero-arrow-path"
|
name="hero-arrow-path"
|
||||||
class="h-4 w-4 mr-1 phx-click-loading:animate-spin"
|
class="phx-click-loading:animate-spin mr-1 size-4"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
data-slot="icon"
|
data-slot="icon"
|
||||||
/>
|
/>
|
||||||
@@ -171,7 +171,7 @@ defmodule MusicLibraryWeb.CollectionLive.Show do
|
|||||||
>
|
>
|
||||||
<.icon
|
<.icon
|
||||||
name="hero-sparkles"
|
name="hero-sparkles"
|
||||||
class="h-4 w-4 mr-1 phx-click-loading:animate-shake"
|
class="phx-click-loading:animate-shake mr-1 size-4"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
data-slot="icon"
|
data-slot="icon"
|
||||||
/>
|
/>
|
||||||
@@ -184,7 +184,7 @@ defmodule MusicLibraryWeb.CollectionLive.Show do
|
|||||||
>
|
>
|
||||||
<.icon
|
<.icon
|
||||||
name="hero-sparkles"
|
name="hero-sparkles"
|
||||||
class="h-4 w-4 mr-1 phx-click-loading:animate-shake"
|
class="phx-click-loading:animate-shake mr-1 size-4"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
data-slot="icon"
|
data-slot="icon"
|
||||||
/>
|
/>
|
||||||
@@ -197,7 +197,7 @@ defmodule MusicLibraryWeb.CollectionLive.Show do
|
|||||||
>
|
>
|
||||||
<.icon
|
<.icon
|
||||||
name="hero-paint-brush"
|
name="hero-paint-brush"
|
||||||
class="h-4 w-4 mr-1 phx-click-loading:animate-shake"
|
class="phx-click-loading:animate-shake mr-1 size-4"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
data-slot="icon"
|
data-slot="icon"
|
||||||
/>
|
/>
|
||||||
@@ -213,7 +213,7 @@ defmodule MusicLibraryWeb.CollectionLive.Show do
|
|||||||
>
|
>
|
||||||
<.icon
|
<.icon
|
||||||
name="hero-trash"
|
name="hero-trash"
|
||||||
class="h-4 w-4 mr-1 phx-click-loading:animate-spin"
|
class="phx-click-loading:animate-spin mr-1 size-4"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
data-slot="icon"
|
data-slot="icon"
|
||||||
/>
|
/>
|
||||||
@@ -248,7 +248,7 @@ defmodule MusicLibraryWeb.CollectionLive.Show do
|
|||||||
<div class="flex justify-between space-x-2">
|
<div class="flex justify-between space-x-2">
|
||||||
<span
|
<span
|
||||||
:if={!@record.selected_release_id}
|
:if={!@record.selected_release_id}
|
||||||
class="text-xs md:text-sm text-zinc-700 dark:text-zinc-300"
|
class="text-xs text-zinc-700 md:text-sm dark:text-zinc-300"
|
||||||
>
|
>
|
||||||
{gettext("No release selected")}
|
{gettext("No release selected")}
|
||||||
</span>
|
</span>
|
||||||
@@ -552,7 +552,7 @@ defmodule MusicLibraryWeb.CollectionLive.Show do
|
|||||||
~H"""
|
~H"""
|
||||||
<div :if={@similar_records != []} class="mt-8 px-4">
|
<div :if={@similar_records != []} class="mt-8 px-4">
|
||||||
<header class="flex items-baseline justify-start">
|
<header class="flex items-baseline justify-start">
|
||||||
<h2 class="font-semibold text-base sm:text-lg leading-5 text-zinc-700 dark:text-zinc-300">
|
<h2 class="text-base/5 font-semibold text-zinc-700 sm:text-lg dark:text-zinc-300">
|
||||||
{gettext("Similar Records")}
|
{gettext("Similar Records")}
|
||||||
</h2>
|
</h2>
|
||||||
<span class="ml-2 text-xs font-normal text-zinc-500 dark:text-zinc-400">
|
<span class="ml-2 text-xs font-normal text-zinc-500 dark:text-zinc-400">
|
||||||
@@ -562,7 +562,7 @@ defmodule MusicLibraryWeb.CollectionLive.Show do
|
|||||||
|
|
||||||
<ul
|
<ul
|
||||||
role="list"
|
role="list"
|
||||||
class="mt-4 grid grid-cols-2 gap-x-4 gap-y-6 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-6 sm:gap-x-6"
|
class="mt-4 grid grid-cols-2 gap-x-4 gap-y-6 sm:grid-cols-3 sm:gap-x-6 md:grid-cols-4 lg:grid-cols-6"
|
||||||
>
|
>
|
||||||
<li
|
<li
|
||||||
:for={%{record: record, similarity: similarity} <- @similar_records}
|
:for={%{record: record, similarity: similarity} <- @similar_records}
|
||||||
@@ -572,10 +572,10 @@ defmodule MusicLibraryWeb.CollectionLive.Show do
|
|||||||
<div class="group">
|
<div class="group">
|
||||||
<.record_cover
|
<.record_cover
|
||||||
record={record}
|
record={record}
|
||||||
class="aspect-square object-cover rounded-lg group-hover:shadow-lg/20"
|
class="aspect-square rounded-lg object-cover group-hover:shadow-lg/20"
|
||||||
width={300}
|
width={300}
|
||||||
/>
|
/>
|
||||||
<span class="absolute top-2 right-2 rounded-full px-2 py-0.5 text-xs font-medium bg-zinc-900/75 text-white backdrop-blur-sm">
|
<span class="absolute top-2 right-2 rounded-full bg-zinc-900/75 px-2 py-0.5 text-xs font-medium text-white backdrop-blur-sm">
|
||||||
{Float.round(100 - similarity * 100, 0)}%
|
{Float.round(100 - similarity * 100, 0)}%
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -46,21 +46,21 @@ defmodule MusicLibraryWeb.OnlineStoreTemplateLive.Form do
|
|||||||
|
|
||||||
<.switch field={@form[:enabled]} label={gettext("Enable this template")} />
|
<.switch field={@form[:enabled]} label={gettext("Enable this template")} />
|
||||||
|
|
||||||
<div class="mt-4 p-4 bg-gray-50 dark:bg-gray-800 rounded-lg">
|
<div class="mt-4 rounded-lg bg-gray-50 p-4 dark:bg-gray-800">
|
||||||
<h4 class="text-sm font-medium text-gray-900 dark:text-white mb-2">
|
<h4 class="mb-2 text-sm font-medium text-gray-900 dark:text-white">
|
||||||
{gettext("Available Variables")}
|
{gettext("Available Variables")}
|
||||||
</h4>
|
</h4>
|
||||||
<div class="text-sm text-gray-600 dark:text-gray-400">
|
<div class="text-sm text-gray-600 dark:text-gray-400">
|
||||||
<p>
|
<p>
|
||||||
<code class="bg-gray-200 dark:bg-gray-700 px-1 rounded">{"{artist}"}</code>
|
<code class="rounded bg-gray-200 px-1 dark:bg-gray-700">{"{artist}"}</code>
|
||||||
- {gettext("Artist name(s)")}
|
- {gettext("Artist name(s)")}
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<code class="bg-gray-200 dark:bg-gray-700 px-1 rounded">{"{title}"}</code>
|
<code class="rounded bg-gray-200 px-1 dark:bg-gray-700">{"{title}"}</code>
|
||||||
- {gettext("Record title")}
|
- {gettext("Record title")}
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<code class="bg-gray-200 dark:bg-gray-700 px-1 rounded">{"{format}"}</code>
|
<code class="rounded bg-gray-200 px-1 dark:bg-gray-700">{"{format}"}</code>
|
||||||
- {gettext("Record format")}
|
- {gettext("Record format")}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -17,8 +17,8 @@ defmodule MusicLibraryWeb.OnlineStoreTemplateLive.Index do
|
|||||||
def render(assigns) do
|
def render(assigns) do
|
||||||
~H"""
|
~H"""
|
||||||
<Layouts.app flash={@flash} current_section={@current_section} socket={@socket}>
|
<Layouts.app flash={@flash} current_section={@current_section} socket={@socket}>
|
||||||
<header class="gap-6 mb-2">
|
<header class="mb-2 gap-6">
|
||||||
<div class="flex items-center justify-between gap-6 mb-2 mt-2">
|
<div class="my-2 flex items-center justify-between gap-6">
|
||||||
<.search_form query={@list_params.query} />
|
<.search_form query={@list_params.query} />
|
||||||
<.button variant="solid" size="sm" patch={~p"/online-store-templates/new"}>
|
<.button variant="solid" size="sm" patch={~p"/online-store-templates/new"}>
|
||||||
<.icon name="hero-plus" class="icon" aria-hidden="true" data-slot="icon" />
|
<.icon name="hero-plus" class="icon" aria-hidden="true" data-slot="icon" />
|
||||||
@@ -36,9 +36,9 @@ defmodule MusicLibraryWeb.OnlineStoreTemplateLive.Index do
|
|||||||
>
|
>
|
||||||
<li
|
<li
|
||||||
id="no-templates"
|
id="no-templates"
|
||||||
class="hidden only:block p-8 text-center bg-zinc-50 dark:bg-zinc-800 rounded-lg"
|
class="hidden rounded-lg bg-zinc-50 p-8 text-center only:block dark:bg-zinc-800"
|
||||||
>
|
>
|
||||||
<.icon name="hero-building-storefront" class="h-12 w-12 text-zinc-400 mx-auto mb-4" />
|
<.icon name="hero-building-storefront" class="mx-auto mb-4 size-12 text-zinc-400" />
|
||||||
<p class="text-zinc-600 dark:text-zinc-400">
|
<p class="text-zinc-600 dark:text-zinc-400">
|
||||||
{gettext("No online store templates found")}
|
{gettext("No online store templates found")}
|
||||||
</p>
|
</p>
|
||||||
@@ -74,7 +74,7 @@ defmodule MusicLibraryWeb.OnlineStoreTemplateLive.Index do
|
|||||||
<span class="sr-only">{gettext("Actions")}</span>
|
<span class="sr-only">{gettext("Actions")}</span>
|
||||||
<.icon
|
<.icon
|
||||||
name="hero-ellipsis-vertical"
|
name="hero-ellipsis-vertical"
|
||||||
class="icon text-zinc-500 dark:text-zinc-400 cursor-pointer"
|
class="icon cursor-pointer text-zinc-500 dark:text-zinc-400"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
data-slot="icon"
|
data-slot="icon"
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ defmodule MusicLibraryWeb.RecordSetLive.Form do
|
|||||||
|
|
||||||
<.textarea
|
<.textarea
|
||||||
class={[
|
class={[
|
||||||
"w-full min-h-128 md:min-h-164 overflow-scroll font-mono"
|
"min-h-128 w-full overflow-scroll font-mono md:min-h-164"
|
||||||
]}
|
]}
|
||||||
field={@form[:description]}
|
field={@form[:description]}
|
||||||
label={gettext("Description (optional)")}
|
label={gettext("Description (optional)")}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ defmodule MusicLibraryWeb.RecordSetLive.Index do
|
|||||||
~H"""
|
~H"""
|
||||||
<Layouts.app flash={@flash} current_section={@current_section} socket={@socket}>
|
<Layouts.app flash={@flash} current_section={@current_section} socket={@socket}>
|
||||||
<header class="mb-6">
|
<header class="mb-6">
|
||||||
<div class="flex items-center justify-between gap-6 mb-2 mt-2">
|
<div class="my-2 flex items-center justify-between gap-6">
|
||||||
<.search_form query={@list_params.query} />
|
<.search_form query={@list_params.query} />
|
||||||
<.button
|
<.button
|
||||||
variant="solid"
|
variant="solid"
|
||||||
@@ -34,7 +34,7 @@ defmodule MusicLibraryWeb.RecordSetLive.Index do
|
|||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<div class="flex items-end justify-between gap-6 mt-4">
|
<div class="mt-4 flex items-end justify-between gap-6">
|
||||||
<.button_group>
|
<.button_group>
|
||||||
<.button
|
<.button
|
||||||
patch={order_path(@list_params, :updated_at)}
|
patch={order_path(@list_params, :updated_at)}
|
||||||
@@ -59,9 +59,9 @@ defmodule MusicLibraryWeb.RecordSetLive.Index do
|
|||||||
<ul id="record-sets-list" class="space-y-6" phx-update="stream">
|
<ul id="record-sets-list" class="space-y-6" phx-update="stream">
|
||||||
<li
|
<li
|
||||||
id="no-record-sets"
|
id="no-record-sets"
|
||||||
class="hidden only:block p-8 text-center bg-zinc-50 dark:bg-zinc-800 rounded-lg"
|
class="hidden rounded-lg bg-zinc-50 p-8 text-center only:block dark:bg-zinc-800"
|
||||||
>
|
>
|
||||||
<.icon name="hero-rectangle-stack" class="h-12 w-12 text-zinc-400 mx-auto mb-4" />
|
<.icon name="hero-rectangle-stack" class="mx-auto mb-4 size-12 text-zinc-400" />
|
||||||
<p class="text-zinc-600 dark:text-zinc-400">
|
<p class="text-zinc-600 dark:text-zinc-400">
|
||||||
{gettext("No record sets yet")}
|
{gettext("No record sets yet")}
|
||||||
</p>
|
</p>
|
||||||
@@ -271,23 +271,23 @@ defmodule MusicLibraryWeb.RecordSetLive.Index do
|
|||||||
~H"""
|
~H"""
|
||||||
<li
|
<li
|
||||||
id={@id}
|
id={@id}
|
||||||
class="bg-white dark:bg-zinc-900 rounded-md shadow-sm border-zinc-200 dark:border-zinc-700 p-4"
|
class="rounded-md border-zinc-200 bg-white p-4 shadow-sm dark:border-zinc-700 dark:bg-zinc-900"
|
||||||
>
|
>
|
||||||
<div class="flex items-baseline justify-between mb-3">
|
<div class="mb-3 flex items-baseline justify-between">
|
||||||
<div class="grow">
|
<div class="grow">
|
||||||
<header class="sm:flex items-baseline justify-start">
|
<header class="items-baseline justify-start sm:flex">
|
||||||
<h2 class="text-lg font-semibold text-zinc-900 dark:text-zinc-100">
|
<h2 class="text-lg font-semibold text-zinc-900 dark:text-zinc-100">
|
||||||
<.link navigate={~p"/record-sets/#{@record_set}"} class="hover:underline">
|
<.link navigate={~p"/record-sets/#{@record_set}"} class="hover:underline">
|
||||||
{@record_set.name}
|
{@record_set.name}
|
||||||
</.link>
|
</.link>
|
||||||
</h2>
|
</h2>
|
||||||
<span class="sm:ml-2 text-xs text-zinc-500 dark:text-zinc-400">
|
<span class="text-xs text-zinc-500 sm:ml-2 dark:text-zinc-400">
|
||||||
{gettext("%{collected}/%{total} records", RecordSet.count_by_status(@record_set))}
|
{gettext("%{collected}/%{total} records", RecordSet.count_by_status(@record_set))}
|
||||||
</span>
|
</span>
|
||||||
</header>
|
</header>
|
||||||
<article
|
<article
|
||||||
:if={@record_set.description}
|
:if={@record_set.description}
|
||||||
class="text-sm my-4 prose dark:prose-invert prose-zinc prose-sm prose-h1:text-sm max-w-none"
|
class="dark:prose-invert prose prose-h1:text-sm prose-sm prose-zinc my-4 max-w-none text-sm"
|
||||||
>
|
>
|
||||||
{@html_description}
|
{@html_description}
|
||||||
</article>
|
</article>
|
||||||
@@ -299,7 +299,7 @@ defmodule MusicLibraryWeb.RecordSetLive.Index do
|
|||||||
<span class="sr-only">{gettext("Actions")}</span>
|
<span class="sr-only">{gettext("Actions")}</span>
|
||||||
<.icon
|
<.icon
|
||||||
name="hero-ellipsis-vertical"
|
name="hero-ellipsis-vertical"
|
||||||
class="h-5 w-5 text-zinc-500 dark:text-zinc-400 cursor-pointer"
|
class="size-5 cursor-pointer text-zinc-500 dark:text-zinc-400"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
data-slot="icon"
|
data-slot="icon"
|
||||||
/>
|
/>
|
||||||
@@ -327,7 +327,7 @@ defmodule MusicLibraryWeb.RecordSetLive.Index do
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
class="grid grid-cols-3 md:grid-cols-6 lg:grid-cols-8 xl:grid-cols-12 gap-3 pb-2"
|
class="grid grid-cols-3 gap-3 pb-2 md:grid-cols-6 lg:grid-cols-8 xl:grid-cols-12"
|
||||||
id={"record-set-#{@record_set.id}-items"}
|
id={"record-set-#{@record_set.id}-items"}
|
||||||
phx-hook="SortableList"
|
phx-hook="SortableList"
|
||||||
data-set-id={@record_set.id}
|
data-set-id={@record_set.id}
|
||||||
@@ -338,9 +338,9 @@ defmodule MusicLibraryWeb.RecordSetLive.Index do
|
|||||||
data-sortable-item
|
data-sortable-item
|
||||||
data-record-id={item.record.id}
|
data-record-id={item.record.id}
|
||||||
class={[
|
class={[
|
||||||
"flex-none group relative",
|
"group relative flex-none",
|
||||||
is_nil(item.record.purchased_at) &&
|
is_nil(item.record.purchased_at) &&
|
||||||
"opacity-60 dark:opacity-40 hover:opacity-100 transition-opacity"
|
"opacity-60 transition-opacity hover:opacity-100 dark:opacity-40"
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
<.link
|
<.link
|
||||||
@@ -349,7 +349,7 @@ defmodule MusicLibraryWeb.RecordSetLive.Index do
|
|||||||
>
|
>
|
||||||
<MusicLibraryWeb.RecordComponents.record_cover
|
<MusicLibraryWeb.RecordComponents.record_cover
|
||||||
record={item.record}
|
record={item.record}
|
||||||
class="rounded-lg aspect-square object-cover"
|
class="aspect-square rounded-lg object-cover"
|
||||||
width={256}
|
width={256}
|
||||||
/>
|
/>
|
||||||
</.link>
|
</.link>
|
||||||
@@ -359,13 +359,13 @@ defmodule MusicLibraryWeb.RecordSetLive.Index do
|
|||||||
>
|
>
|
||||||
<MusicLibraryWeb.RecordComponents.record_cover
|
<MusicLibraryWeb.RecordComponents.record_cover
|
||||||
record={item.record}
|
record={item.record}
|
||||||
class="rounded-lg aspect-square object-cover"
|
class="aspect-square rounded-lg object-cover"
|
||||||
width={256}
|
width={256}
|
||||||
/>
|
/>
|
||||||
</.link>
|
</.link>
|
||||||
<div
|
<div
|
||||||
data-sortable-handle
|
data-sortable-handle
|
||||||
class="absolute top-1 left-1 flex items-center justify-center rounded-full bg-zinc-100/50 hover:bg-zinc-100/75 dark:bg-zinc-700/50 dark:hover:bg-zinc-700/75 size-8 sm:size-5 cursor-grab active:cursor-grabbing"
|
class="absolute top-1 left-1 flex size-8 cursor-grab items-center justify-center rounded-full bg-zinc-100/50 hover:bg-zinc-100/75 active:cursor-grabbing sm:size-5 dark:bg-zinc-700/50 dark:hover:bg-zinc-700/75"
|
||||||
>
|
>
|
||||||
<.icon
|
<.icon
|
||||||
name="hero-bars-2"
|
name="hero-bars-2"
|
||||||
@@ -378,7 +378,7 @@ defmodule MusicLibraryWeb.RecordSetLive.Index do
|
|||||||
phx-value-set-id={@record_set.id}
|
phx-value-set-id={@record_set.id}
|
||||||
phx-value-record-id={item.record.id}
|
phx-value-record-id={item.record.id}
|
||||||
data-confirm={gettext("Remove this record from the set?")}
|
data-confirm={gettext("Remove this record from the set?")}
|
||||||
class="absolute top-1 right-1 flex items-center justify-center rounded-full bg-zinc-100/50 hover:bg-red-100/75 dark:bg-zinc-700/50 dark:hover:bg-red-900/50 size-8 sm:size-5 cursor-pointer"
|
class="absolute top-1 right-1 flex size-8 cursor-pointer items-center justify-center rounded-full bg-zinc-100/50 hover:bg-red-100/75 sm:size-5 dark:bg-zinc-700/50 dark:hover:bg-red-900/50"
|
||||||
>
|
>
|
||||||
<span class="sr-only">{gettext("Remove")}</span>
|
<span class="sr-only">{gettext("Remove")}</span>
|
||||||
<.icon
|
<.icon
|
||||||
@@ -387,10 +387,10 @@ defmodule MusicLibraryWeb.RecordSetLive.Index do
|
|||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
/>
|
/>
|
||||||
</button>
|
</button>
|
||||||
<h2 class="mt-1 text-sm leading-6 text-zinc-700">
|
<h2 class="mt-1 text-sm/6 text-zinc-700">
|
||||||
<.artist_links joinphrase_class="text-sm" artists={item.record.artists} />
|
<.artist_links joinphrase_class="text-sm" artists={item.record.artists} />
|
||||||
</h2>
|
</h2>
|
||||||
<h3 class="flex font-semibold text-sm leading-5 text-zinc-700 dark:text-zinc-300 text-wrap">
|
<h3 class="flex text-sm/5 font-semibold text-wrap text-zinc-700 dark:text-zinc-300">
|
||||||
{item.record.title}
|
{item.record.title}
|
||||||
</h3>
|
</h3>
|
||||||
<p class="pointer-events-none block text-sm font-medium text-zinc-500">
|
<p class="pointer-events-none block text-sm font-medium text-zinc-500">
|
||||||
@@ -399,7 +399,7 @@ defmodule MusicLibraryWeb.RecordSetLive.Index do
|
|||||||
<p class="pointer-events-none block text-sm font-medium text-zinc-500">
|
<p class="pointer-events-none block text-sm font-medium text-zinc-500">
|
||||||
<.icon
|
<.icon
|
||||||
name="hero-calendar-days"
|
name="hero-calendar-days"
|
||||||
class="-mt-1 h-4 w-4"
|
class="-mt-1 size-4"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
data-slot="icon"
|
data-slot="icon"
|
||||||
/>
|
/>
|
||||||
@@ -410,17 +410,17 @@ defmodule MusicLibraryWeb.RecordSetLive.Index do
|
|||||||
<.link
|
<.link
|
||||||
patch={~p"/record-sets/#{@record_set}/add-record"}
|
patch={~p"/record-sets/#{@record_set}/add-record"}
|
||||||
class={[
|
class={[
|
||||||
"flex-none aspect-square",
|
"aspect-square flex-none",
|
||||||
"border-2 border-dashed border-zinc-300 dark:border-zinc-600",
|
"border-2 border-dashed border-zinc-300 dark:border-zinc-600",
|
||||||
"rounded-lg flex items-center justify-center",
|
"flex items-center justify-center rounded-lg",
|
||||||
"hover:border-zinc-400 dark:hover:border-zinc-500",
|
"hover:border-zinc-400 dark:hover:border-zinc-500",
|
||||||
"hover:bg-zinc-50 dark:hover:bg-zinc-800",
|
"hover:bg-zinc-50 dark:hover:bg-zinc-800",
|
||||||
"transition-colors cursor-pointer"
|
"cursor-pointer transition-colors"
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
<.icon
|
<.icon
|
||||||
name="hero-plus"
|
name="hero-plus"
|
||||||
class="h-8 w-8 text-zinc-400 dark:text-zinc-500"
|
class="size-8 text-zinc-400 dark:text-zinc-500"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
data-slot="icon"
|
data-slot="icon"
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ defmodule MusicLibraryWeb.RecordSetLive.RecordPicker do
|
|||||||
<h1 class="text-lg font-semibold text-zinc-900 dark:text-zinc-100">
|
<h1 class="text-lg font-semibold text-zinc-900 dark:text-zinc-100">
|
||||||
{@title}
|
{@title}
|
||||||
</h1>
|
</h1>
|
||||||
<p class="text-sm text-zinc-500 dark:text-zinc-400 mt-1">
|
<p class="mt-1 text-sm text-zinc-500 dark:text-zinc-400">
|
||||||
{gettext("Search your records to add a record to this set.")}
|
{gettext("Search your records to add a record to this set.")}
|
||||||
</p>
|
</p>
|
||||||
</header>
|
</header>
|
||||||
@@ -51,7 +51,7 @@ defmodule MusicLibraryWeb.RecordSetLive.RecordPicker do
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div :if={@collected_results != []}>
|
<div :if={@collected_results != []}>
|
||||||
<h3 class="text-xs font-medium uppercase tracking-wide text-zinc-500 dark:text-zinc-400 mb-1">
|
<h3 class="mb-1 text-xs font-medium tracking-wide text-zinc-500 uppercase dark:text-zinc-400">
|
||||||
{gettext("Collected")}
|
{gettext("Collected")}
|
||||||
</h3>
|
</h3>
|
||||||
<ul class="divide-y divide-zinc-100 dark:divide-zinc-700">
|
<ul class="divide-y divide-zinc-100 dark:divide-zinc-700">
|
||||||
@@ -60,7 +60,7 @@ defmodule MusicLibraryWeb.RecordSetLive.RecordPicker do
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div :if={@wishlisted_results != []} class={[@collected_results != [] && "mt-4"]}>
|
<div :if={@wishlisted_results != []} class={[@collected_results != [] && "mt-4"]}>
|
||||||
<h3 class="text-xs font-medium uppercase tracking-wide text-zinc-500 dark:text-zinc-400 mb-1">
|
<h3 class="mb-1 text-xs font-medium tracking-wide text-zinc-500 uppercase dark:text-zinc-400">
|
||||||
{gettext("Wishlisted")}
|
{gettext("Wishlisted")}
|
||||||
</h3>
|
</h3>
|
||||||
<ul class="divide-y divide-zinc-100 dark:divide-zinc-700">
|
<ul class="divide-y divide-zinc-100 dark:divide-zinc-700">
|
||||||
@@ -77,7 +77,7 @@ defmodule MusicLibraryWeb.RecordSetLive.RecordPicker do
|
|||||||
<li
|
<li
|
||||||
role="option"
|
role="option"
|
||||||
class={[
|
class={[
|
||||||
"flex items-center gap-3 py-3 px-2 hover:bg-zinc-50 dark:hover:bg-zinc-800 cursor-pointer rounded-lg",
|
"flex cursor-pointer items-center gap-3 rounded-lg px-2 py-3 hover:bg-zinc-50 dark:hover:bg-zinc-800",
|
||||||
"aria-selected:bg-zinc-100 dark:aria-selected:bg-zinc-700"
|
"aria-selected:bg-zinc-100 dark:aria-selected:bg-zinc-700"
|
||||||
]}
|
]}
|
||||||
phx-click="add_record"
|
phx-click="add_record"
|
||||||
@@ -87,18 +87,18 @@ defmodule MusicLibraryWeb.RecordSetLive.RecordPicker do
|
|||||||
<div class="w-12 flex-none">
|
<div class="w-12 flex-none">
|
||||||
<MusicLibraryWeb.RecordComponents.record_cover
|
<MusicLibraryWeb.RecordComponents.record_cover
|
||||||
record={@record}
|
record={@record}
|
||||||
class="rounded aspect-square object-cover"
|
class="aspect-square rounded object-cover"
|
||||||
width={96}
|
width={96}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="min-w-0 flex-auto">
|
<div class="min-w-0 flex-auto">
|
||||||
<p class="text-sm font-medium text-zinc-900 dark:text-zinc-100 truncate">
|
<p class="truncate text-sm font-medium text-zinc-900 dark:text-zinc-100">
|
||||||
{@record.title}
|
{@record.title}
|
||||||
</p>
|
</p>
|
||||||
<p class="text-xs text-zinc-500 dark:text-zinc-400 truncate">
|
<p class="truncate text-xs text-zinc-500 dark:text-zinc-400">
|
||||||
{Record.artist_names(@record)}
|
{Record.artist_names(@record)}
|
||||||
</p>
|
</p>
|
||||||
<p class="mt-1 text-xs leading-5 text-zinc-500 dark:text-zinc-400">
|
<p class="mt-1 text-xs/5 text-zinc-500 dark:text-zinc-400">
|
||||||
{Record.format_release_date(@record.release_date)} · {format_label(@record.format)} · {type_label(
|
{Record.format_release_date(@record.release_date)} · {format_label(@record.format)} · {type_label(
|
||||||
@record.type
|
@record.type
|
||||||
)}
|
)}
|
||||||
@@ -110,7 +110,7 @@ defmodule MusicLibraryWeb.RecordSetLive.RecordPicker do
|
|||||||
</span>
|
</span>
|
||||||
<.icon
|
<.icon
|
||||||
name="hero-banknotes"
|
name="hero-banknotes"
|
||||||
class="h-4 w-4"
|
class="size-4"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
data-slot="icon"
|
data-slot="icon"
|
||||||
/>
|
/>
|
||||||
@@ -121,7 +121,7 @@ defmodule MusicLibraryWeb.RecordSetLive.RecordPicker do
|
|||||||
<div class="flex-none">
|
<div class="flex-none">
|
||||||
<.icon
|
<.icon
|
||||||
name="hero-plus-circle"
|
name="hero-plus-circle"
|
||||||
class="h-5 w-5 text-zinc-400 hover:text-zinc-600 dark:hover:text-zinc-300"
|
class="size-5 text-zinc-400 hover:text-zinc-600 dark:hover:text-zinc-300"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
data-slot="icon"
|
data-slot="icon"
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ defmodule MusicLibraryWeb.RecordSetLive.Show do
|
|||||||
<span class="sr-only">{gettext("Actions")}</span>
|
<span class="sr-only">{gettext("Actions")}</span>
|
||||||
<.icon
|
<.icon
|
||||||
name="hero-ellipsis-vertical"
|
name="hero-ellipsis-vertical"
|
||||||
class="icon text-zinc-500 dark:text-zinc-400 cursor-pointer"
|
class="icon cursor-pointer text-zinc-500 dark:text-zinc-400"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
data-slot="icon"
|
data-slot="icon"
|
||||||
/>
|
/>
|
||||||
@@ -57,14 +57,14 @@ defmodule MusicLibraryWeb.RecordSetLive.Show do
|
|||||||
|
|
||||||
<article
|
<article
|
||||||
:if={@record_set.description}
|
:if={@record_set.description}
|
||||||
class="mt-4 prose dark:prose-invert prose-zinc prose-sm prose-h1:text-sm max-w-none"
|
class="dark:prose-invert prose prose-h1:text-sm prose-sm prose-zinc mt-4 max-w-none"
|
||||||
>
|
>
|
||||||
{render_description(@record_set.description)}
|
{render_description(@record_set.description)}
|
||||||
</article>
|
</article>
|
||||||
|
|
||||||
<div class="mt-6">
|
<div class="mt-6">
|
||||||
<div
|
<div
|
||||||
class="grid grid-cols-3 sm:grid-cols-6 lg:grid-cols-8 gap-4"
|
class="grid grid-cols-3 gap-4 sm:grid-cols-6 lg:grid-cols-8"
|
||||||
id="record-set-records"
|
id="record-set-records"
|
||||||
phx-hook="SortableList"
|
phx-hook="SortableList"
|
||||||
>
|
>
|
||||||
@@ -76,7 +76,7 @@ defmodule MusicLibraryWeb.RecordSetLive.Show do
|
|||||||
class={[
|
class={[
|
||||||
"group relative",
|
"group relative",
|
||||||
is_nil(item.record.purchased_at) &&
|
is_nil(item.record.purchased_at) &&
|
||||||
"opacity-60 dark:opacity-40 hover:opacity-100 transition-opacity"
|
"opacity-60 transition-opacity hover:opacity-100 dark:opacity-40"
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
<.link
|
<.link
|
||||||
@@ -85,7 +85,7 @@ defmodule MusicLibraryWeb.RecordSetLive.Show do
|
|||||||
>
|
>
|
||||||
<MusicLibraryWeb.RecordComponents.record_cover
|
<MusicLibraryWeb.RecordComponents.record_cover
|
||||||
record={item.record}
|
record={item.record}
|
||||||
class="rounded-lg aspect-square object-cover"
|
class="aspect-square rounded-lg object-cover"
|
||||||
width={468}
|
width={468}
|
||||||
/>
|
/>
|
||||||
</.link>
|
</.link>
|
||||||
@@ -95,13 +95,13 @@ defmodule MusicLibraryWeb.RecordSetLive.Show do
|
|||||||
>
|
>
|
||||||
<MusicLibraryWeb.RecordComponents.record_cover
|
<MusicLibraryWeb.RecordComponents.record_cover
|
||||||
record={item.record}
|
record={item.record}
|
||||||
class="rounded-lg aspect-square object-cover"
|
class="aspect-square rounded-lg object-cover"
|
||||||
width={468}
|
width={468}
|
||||||
/>
|
/>
|
||||||
</.link>
|
</.link>
|
||||||
<button
|
<button
|
||||||
data-sortable-handle
|
data-sortable-handle
|
||||||
class="absolute top-1 left-1 flex items-center justify-center rounded-full bg-zinc-100/50 hover:bg-zinc-100/75 dark:bg-zinc-700/50 dark:hover:bg-zinc-700/75 size-8 sm:size-6 cursor-grab active:cursor-grabbing"
|
class="absolute top-1 left-1 flex size-8 cursor-grab items-center justify-center rounded-full bg-zinc-100/50 hover:bg-zinc-100/75 active:cursor-grabbing sm:size-6 dark:bg-zinc-700/50 dark:hover:bg-zinc-700/75"
|
||||||
>
|
>
|
||||||
<.icon
|
<.icon
|
||||||
name="hero-bars-2"
|
name="hero-bars-2"
|
||||||
@@ -113,7 +113,7 @@ defmodule MusicLibraryWeb.RecordSetLive.Show do
|
|||||||
phx-click="remove_record"
|
phx-click="remove_record"
|
||||||
phx-value-record-id={item.record.id}
|
phx-value-record-id={item.record.id}
|
||||||
data-confirm={gettext("Remove this record from the set?")}
|
data-confirm={gettext("Remove this record from the set?")}
|
||||||
class="absolute top-1 right-1 flex items-center justify-center rounded-full bg-zinc-100/50 hover:bg-red-100/75 dark:bg-zinc-700/50 dark:hover:bg-red-900/50 size-8 sm:size-6 cursor-pointer"
|
class="absolute top-1 right-1 flex size-8 cursor-pointer items-center justify-center rounded-full bg-zinc-100/50 hover:bg-red-100/75 sm:size-6 dark:bg-zinc-700/50 dark:hover:bg-red-900/50"
|
||||||
>
|
>
|
||||||
<span class="sr-only">{gettext("Remove")}</span>
|
<span class="sr-only">{gettext("Remove")}</span>
|
||||||
<.icon
|
<.icon
|
||||||
@@ -122,10 +122,10 @@ defmodule MusicLibraryWeb.RecordSetLive.Show do
|
|||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
/>
|
/>
|
||||||
</button>
|
</button>
|
||||||
<h2 class="mt-1 text-sm leading-6 text-zinc-700">
|
<h2 class="mt-1 text-sm/6 text-zinc-700">
|
||||||
<.artist_links joinphrase_class="text-sm" artists={item.record.artists} />
|
<.artist_links joinphrase_class="text-sm" artists={item.record.artists} />
|
||||||
</h2>
|
</h2>
|
||||||
<h3 class="flex font-semibold text-sm leading-5 text-zinc-700 dark:text-zinc-300 text-wrap">
|
<h3 class="flex text-sm/5 font-semibold text-wrap text-zinc-700 dark:text-zinc-300">
|
||||||
{item.record.title}
|
{item.record.title}
|
||||||
</h3>
|
</h3>
|
||||||
<p class="pointer-events-none block text-sm font-medium text-zinc-500">
|
<p class="pointer-events-none block text-sm font-medium text-zinc-500">
|
||||||
@@ -134,7 +134,7 @@ defmodule MusicLibraryWeb.RecordSetLive.Show do
|
|||||||
<p class="pointer-events-none block text-sm font-medium text-zinc-500">
|
<p class="pointer-events-none block text-sm font-medium text-zinc-500">
|
||||||
<.icon
|
<.icon
|
||||||
name="hero-calendar-days"
|
name="hero-calendar-days"
|
||||||
class="-mt-1 h-4 w-4"
|
class="-mt-1 size-4"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
data-slot="icon"
|
data-slot="icon"
|
||||||
/>
|
/>
|
||||||
@@ -146,15 +146,15 @@ defmodule MusicLibraryWeb.RecordSetLive.Show do
|
|||||||
class={[
|
class={[
|
||||||
"aspect-square",
|
"aspect-square",
|
||||||
"border-2 border-dashed border-zinc-300 dark:border-zinc-600",
|
"border-2 border-dashed border-zinc-300 dark:border-zinc-600",
|
||||||
"rounded-lg flex items-center justify-center",
|
"flex items-center justify-center rounded-lg",
|
||||||
"hover:border-zinc-400 dark:hover:border-zinc-500",
|
"hover:border-zinc-400 dark:hover:border-zinc-500",
|
||||||
"hover:bg-zinc-50 dark:hover:bg-zinc-800",
|
"hover:bg-zinc-50 dark:hover:bg-zinc-800",
|
||||||
"transition-colors cursor-pointer"
|
"cursor-pointer transition-colors"
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
<.icon
|
<.icon
|
||||||
name="hero-plus"
|
name="hero-plus"
|
||||||
class="h-8 w-8 text-zinc-400 dark:text-zinc-500"
|
class="size-8 text-zinc-400 dark:text-zinc-500"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
data-slot="icon"
|
data-slot="icon"
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -12,8 +12,8 @@ defmodule MusicLibraryWeb.ScrobbleLive.Index do
|
|||||||
~H"""
|
~H"""
|
||||||
<Layouts.app flash={@flash} current_section={@current_section} socket={@socket}>
|
<Layouts.app flash={@flash} current_section={@current_section} socket={@socket}>
|
||||||
<div>
|
<div>
|
||||||
<header class="gap-6 mb-2">
|
<header class="mb-2 gap-6">
|
||||||
<div class="flex items-center justify-between gap-6 mb-2 mt-2">
|
<div class="my-2 flex items-center justify-between gap-6">
|
||||||
<.search_form query={@search_query} />
|
<.search_form query={@search_query} />
|
||||||
<.button :if={!@can_scrobble?} size="sm" href={LastFm.auth_url()}>
|
<.button :if={!@can_scrobble?} size="sm" href={LastFm.auth_url()}>
|
||||||
{gettext("Connect your Last.fm account")}
|
{gettext("Connect your Last.fm account")}
|
||||||
@@ -33,23 +33,23 @@ defmodule MusicLibraryWeb.ScrobbleLive.Index do
|
|||||||
:for={release_group <- @search_results}
|
:for={release_group <- @search_results}
|
||||||
phx-click="select_release_group"
|
phx-click="select_release_group"
|
||||||
phx-value-release_group_id={release_group.id}
|
phx-value-release_group_id={release_group.id}
|
||||||
class="flex justify-between gap-x-6 py-5 hover:bg-zinc-50 dark:hover:bg-zinc-700 cursor-pointer"
|
class="flex cursor-pointer justify-between gap-x-6 py-5 hover:bg-zinc-50 dark:hover:bg-zinc-700"
|
||||||
>
|
>
|
||||||
<div class="shrink-0 flex items-center justify-between w-full px-4">
|
<div class="flex w-full shrink-0 items-center justify-between px-4">
|
||||||
<img
|
<img
|
||||||
class="w-20 flex-none rounded-lg mr-4"
|
class="mr-4 w-20 flex-none rounded-lg"
|
||||||
alt={release_group.title}
|
alt={release_group.title}
|
||||||
src={ReleaseGroupSearchResult.thumb_url(release_group)}
|
src={ReleaseGroupSearchResult.thumb_url(release_group)}
|
||||||
onerror={"this.src = '" <> ~p"/images/cover-not-found.png" <> "';"}
|
onerror={"this.src = '" <> ~p"/images/cover-not-found.png" <> "';"}
|
||||||
/>
|
/>
|
||||||
<div class="min-w-0 flex-auto">
|
<div class="min-w-0 flex-auto">
|
||||||
<p class="truncate text-sm leading-6 text-zinc-700 dark:text-zinc-400">
|
<p class="truncate text-sm/6 text-zinc-700 dark:text-zinc-400">
|
||||||
{release_group.artists}
|
{release_group.artists}
|
||||||
</p>
|
</p>
|
||||||
<p class="truncate mt-1 flex font-semibold text-sm sm:text-base leading-5 text-zinc-700 dark:text-zinc-300 text-wrap">
|
<p class="mt-1 flex truncate text-sm/5 font-semibold text-wrap text-zinc-700 sm:text-base dark:text-zinc-300">
|
||||||
{release_group.title}
|
{release_group.title}
|
||||||
</p>
|
</p>
|
||||||
<p class="mt-1 flex items-center gap-1 text-xs leading-5 text-zinc-500 dark:text-zinc-400">
|
<p class="mt-1 flex items-center gap-1 text-xs/5 text-zinc-500 dark:text-zinc-400">
|
||||||
{Records.Record.format_release_date(release_group.release_date)}
|
{Records.Record.format_release_date(release_group.release_date)}
|
||||||
<span>·</span>
|
<span>·</span>
|
||||||
<.badge variant="soft" size="xs">{type_label(release_group.type)}</.badge>
|
<.badge variant="soft" size="xs">{type_label(release_group.type)}</.badge>
|
||||||
@@ -81,7 +81,7 @@ defmodule MusicLibraryWeb.ScrobbleLive.Index do
|
|||||||
<li :for={release <- @releases}>
|
<li :for={release <- @releases}>
|
||||||
<.link
|
<.link
|
||||||
navigate={~p"/scrobble/#{release.id}"}
|
navigate={~p"/scrobble/#{release.id}"}
|
||||||
class="flex items-center gap-x-4 py-5 px-4 hover:bg-zinc-50 dark:hover:bg-zinc-700 transition-colors"
|
class="flex items-center gap-x-4 px-4 py-5 transition-colors hover:bg-zinc-50 dark:hover:bg-zinc-700"
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
class="w-20 flex-none rounded-lg"
|
class="w-20 flex-none rounded-lg"
|
||||||
@@ -113,9 +113,9 @@ defmodule MusicLibraryWeb.ScrobbleLive.Index do
|
|||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<%= if @loading && @search_query != "" do %>
|
<%= if @loading && @search_query != "" do %>
|
||||||
<div class="text-center py-8">
|
<div class="py-8 text-center">
|
||||||
<.loading class="size-8 mx-auto text-zinc-400" />
|
<.loading class="mx-auto size-8 text-zinc-400" />
|
||||||
<p class="text-zinc-600 dark:text-zinc-400 mt-2">
|
<p class="mt-2 text-zinc-600 dark:text-zinc-400">
|
||||||
<%= if @selected_release_group do %>
|
<%= if @selected_release_group do %>
|
||||||
{gettext("Loading releases...")}
|
{gettext("Loading releases...")}
|
||||||
<% else %>
|
<% else %>
|
||||||
@@ -126,15 +126,15 @@ defmodule MusicLibraryWeb.ScrobbleLive.Index do
|
|||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<%= if @search_query != "" && @search_results == [] && not @loading do %>
|
<%= if @search_query != "" && @search_results == [] && not @loading do %>
|
||||||
<div class="text-center py-8">
|
<div class="py-8 text-center">
|
||||||
<.icon
|
<.icon
|
||||||
name="hero-magnifying-glass"
|
name="hero-magnifying-glass"
|
||||||
class="h-12 w-12 mx-auto text-zinc-300 dark:text-zinc-600"
|
class="mx-auto size-12 text-zinc-300 dark:text-zinc-600"
|
||||||
/>
|
/>
|
||||||
<p class="text-zinc-600 dark:text-zinc-400 mt-3">
|
<p class="mt-3 text-zinc-600 dark:text-zinc-400">
|
||||||
{gettext("No release groups found for \"%{query}\"", query: @search_query)}
|
{gettext("No release groups found for \"%{query}\"", query: @search_query)}
|
||||||
</p>
|
</p>
|
||||||
<p class="text-sm text-zinc-500 dark:text-zinc-500 mt-1">
|
<p class="mt-1 text-sm text-zinc-500 dark:text-zinc-500">
|
||||||
{gettext("Try a different search term or check the spelling")}
|
{gettext("Try a different search term or check the spelling")}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ defmodule MusicLibraryWeb.ScrobbleLive.Show do
|
|||||||
</.button>
|
</.button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="md:flex mt-4 px-4 md:gap-x-4">
|
<div class="mt-4 px-4 md:flex md:gap-x-4">
|
||||||
<div class="drop-shadow-sm md:max-w-152 lg:min-w-152">
|
<div class="drop-shadow-sm md:max-w-152 lg:min-w-152">
|
||||||
<img
|
<img
|
||||||
src={MusicBrainz.Release.thumb_url(@release)}
|
src={MusicBrainz.Release.thumb_url(@release)}
|
||||||
@@ -43,12 +43,12 @@ defmodule MusicLibraryWeb.ScrobbleLive.Show do
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="grow">
|
<div class="grow">
|
||||||
<div class="mt-4 md:mt-0 flex justify-between items-center">
|
<div class="mt-4 flex items-center justify-between md:mt-0">
|
||||||
<h1 :if={@release.artists != []} class="text-base font-medium leading-6 text-zinc-700">
|
<h1 :if={@release.artists != []} class="text-base/6 font-medium text-zinc-700">
|
||||||
{@release.artists |> Enum.map(& &1.name) |> Enum.join(", ")}
|
{@release.artists |> Enum.map(& &1.name) |> Enum.join(", ")}
|
||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
<h2 class="mt-1 flex font-semibold text-lg md:text-2xl text-zinc-700 dark:text-zinc-300 text-wrap">
|
<h2 class="mt-1 flex text-lg font-semibold text-wrap text-zinc-700 md:text-2xl dark:text-zinc-300">
|
||||||
{@release.title}
|
{@release.title}
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
@@ -73,7 +73,7 @@ defmodule MusicLibraryWeb.ScrobbleLive.Show do
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div :if={@release.media != []} class="mt-6 space-y-4">
|
<div :if={@release.media != []} class="mt-6 space-y-4">
|
||||||
<div class="flex justify-between items-center">
|
<div class="flex items-center justify-between">
|
||||||
<h3 class="text-lg font-semibold text-zinc-900 dark:text-zinc-200">
|
<h3 class="text-lg font-semibold text-zinc-900 dark:text-zinc-200">
|
||||||
{gettext("Tracks")}
|
{gettext("Tracks")}
|
||||||
</h3>
|
</h3>
|
||||||
|
|||||||
@@ -18,8 +18,8 @@ defmodule MusicLibraryWeb.ScrobbleRulesLive.Index do
|
|||||||
def render(assigns) do
|
def render(assigns) do
|
||||||
~H"""
|
~H"""
|
||||||
<Layouts.app flash={@flash} current_section={@current_section} socket={@socket}>
|
<Layouts.app flash={@flash} current_section={@current_section} socket={@socket}>
|
||||||
<header class="gap-6 mb-2">
|
<header class="mb-2 gap-6">
|
||||||
<div class="flex items-center justify-between gap-6 mb-2 mt-2">
|
<div class="my-2 flex items-center justify-between gap-6">
|
||||||
<.search_form query={@list_params.query} />
|
<.search_form query={@list_params.query} />
|
||||||
<.button_group>
|
<.button_group>
|
||||||
<.button
|
<.button
|
||||||
@@ -42,7 +42,7 @@ defmodule MusicLibraryWeb.ScrobbleRulesLive.Index do
|
|||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<div class="flex items-end justify-between gap-6 mt-6">
|
<div class="mt-6 flex items-end justify-between gap-6">
|
||||||
<.button_group>
|
<.button_group>
|
||||||
<.button
|
<.button
|
||||||
patch={order_path(@list_params, :alphabetical)}
|
patch={order_path(@list_params, :alphabetical)}
|
||||||
@@ -75,9 +75,9 @@ defmodule MusicLibraryWeb.ScrobbleRulesLive.Index do
|
|||||||
>
|
>
|
||||||
<li
|
<li
|
||||||
id="no-scrobble-rules"
|
id="no-scrobble-rules"
|
||||||
class="hidden only:block p-8 text-center bg-zinc-50 dark:bg-zinc-800 rounded-lg"
|
class="hidden rounded-lg bg-zinc-50 p-8 text-center only:block dark:bg-zinc-800"
|
||||||
>
|
>
|
||||||
<.icon name="hero-beaker" class="h-12 w-12 text-zinc-400 mx-auto mb-4" />
|
<.icon name="hero-beaker" class="mx-auto mb-4 size-12 text-zinc-400" />
|
||||||
<p class="text-zinc-600 dark:text-zinc-400">
|
<p class="text-zinc-600 dark:text-zinc-400">
|
||||||
{gettext("No scrobble rules found")}
|
{gettext("No scrobble rules found")}
|
||||||
</p>
|
</p>
|
||||||
@@ -91,25 +91,25 @@ defmodule MusicLibraryWeb.ScrobbleRulesLive.Index do
|
|||||||
<div class="min-w-0">
|
<div class="min-w-0">
|
||||||
<div class="flex items-center gap-2">
|
<div class="flex items-center gap-2">
|
||||||
<.type_badge type={scrobble_rule.type} />
|
<.type_badge type={scrobble_rule.type} />
|
||||||
<p class="text-sm font-semibold text-zinc-900 dark:text-zinc-100 truncate">
|
<p class="truncate text-sm font-semibold text-zinc-900 dark:text-zinc-100">
|
||||||
{scrobble_rule.match_value}
|
{scrobble_rule.match_value}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<p class="text-xs font-mono text-zinc-500 dark:text-zinc-400 mt-1 truncate">
|
<p class="mt-1 truncate font-mono text-xs text-zinc-500 dark:text-zinc-400">
|
||||||
{scrobble_rule.target_musicbrainz_id}
|
{scrobble_rule.target_musicbrainz_id}
|
||||||
</p>
|
</p>
|
||||||
<p
|
<p
|
||||||
:if={scrobble_rule.description}
|
:if={scrobble_rule.description}
|
||||||
class="text-xs text-zinc-500 dark:text-zinc-400 mt-1 truncate"
|
class="mt-1 truncate text-xs text-zinc-500 dark:text-zinc-400"
|
||||||
>
|
>
|
||||||
{scrobble_rule.description}
|
{scrobble_rule.description}
|
||||||
</p>
|
</p>
|
||||||
<div class="flex items-center gap-1 mt-1 text-xs text-zinc-500 dark:text-zinc-400">
|
<div class="mt-1 flex items-center gap-1 text-xs text-zinc-500 dark:text-zinc-400">
|
||||||
<.icon name="hero-clock" class="h-3.5 w-3.5" aria-hidden="true" />
|
<.icon name="hero-clock" class="size-3.5" aria-hidden="true" />
|
||||||
{Calendar.strftime(scrobble_rule.inserted_at, "%Y-%m-%d")}
|
{Calendar.strftime(scrobble_rule.inserted_at, "%Y-%m-%d")}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center gap-2 shrink-0">
|
<div class="flex shrink-0 items-center gap-2">
|
||||||
<.status_badge enabled={scrobble_rule.enabled} />
|
<.status_badge enabled={scrobble_rule.enabled} />
|
||||||
<.dropdown id={"actions-#{scrobble_rule.id}"} placement="bottom-end">
|
<.dropdown id={"actions-#{scrobble_rule.id}"} placement="bottom-end">
|
||||||
<:toggle>
|
<:toggle>
|
||||||
@@ -117,7 +117,7 @@ defmodule MusicLibraryWeb.ScrobbleRulesLive.Index do
|
|||||||
<span class="sr-only">{gettext("Actions")}</span>
|
<span class="sr-only">{gettext("Actions")}</span>
|
||||||
<.icon
|
<.icon
|
||||||
name="hero-ellipsis-vertical"
|
name="hero-ellipsis-vertical"
|
||||||
class="icon text-zinc-500 dark:text-zinc-400 cursor-pointer"
|
class="icon cursor-pointer text-zinc-500 dark:text-zinc-400"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
data-slot="icon"
|
data-slot="icon"
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -22,12 +22,12 @@ defmodule MusicLibraryWeb.ScrobbledTracksLive.Index do
|
|||||||
<Layouts.app flash={@flash} current_section={@current_section} socket={@socket}>
|
<Layouts.app flash={@flash} current_section={@current_section} socket={@socket}>
|
||||||
<div>
|
<div>
|
||||||
<header class="gap-6">
|
<header class="gap-6">
|
||||||
<div class="mb-2 mt-2">
|
<div class="my-2">
|
||||||
<.search_form query={@track_list_params.query} />
|
<.search_form query={@track_list_params.query} />
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<div class="flex items-end gap-6 mt-6 justify-between">
|
<div class="mt-6 flex items-end justify-between gap-6">
|
||||||
<.button_group>
|
<.button_group>
|
||||||
<.button
|
<.button
|
||||||
patch={order_path(@track_list_params, :scrobbled_at)}
|
patch={order_path(@track_list_params, :scrobbled_at)}
|
||||||
@@ -81,16 +81,16 @@ defmodule MusicLibraryWeb.ScrobbledTracksLive.Index do
|
|||||||
|
|
||||||
<div class="mt-6">
|
<div class="mt-6">
|
||||||
<ul
|
<ul
|
||||||
class="divide-y divide-zinc-100 dark:divide-zinc-300/20 mt-5"
|
class="mt-5 divide-y divide-zinc-100 dark:divide-zinc-300/20"
|
||||||
role="list"
|
role="list"
|
||||||
id="tracks"
|
id="tracks"
|
||||||
phx-update="stream"
|
phx-update="stream"
|
||||||
>
|
>
|
||||||
<li
|
<li
|
||||||
id="no-scrobbled-tracks"
|
id="no-scrobbled-tracks"
|
||||||
class="hidden only:block p-8 text-center bg-zinc-50 dark:bg-zinc-800 rounded-lg"
|
class="hidden rounded-lg bg-zinc-50 p-8 text-center only:block dark:bg-zinc-800"
|
||||||
>
|
>
|
||||||
<.icon name="hero-musical-note" class="h-12 w-12 text-zinc-400 mx-auto mb-4" />
|
<.icon name="hero-musical-note" class="mx-auto mb-4 size-12 text-zinc-400" />
|
||||||
<p class="text-zinc-600 dark:text-zinc-400">
|
<p class="text-zinc-600 dark:text-zinc-400">
|
||||||
{gettext("No scrobbled tracks found")}
|
{gettext("No scrobbled tracks found")}
|
||||||
</p>
|
</p>
|
||||||
@@ -108,12 +108,12 @@ defmodule MusicLibraryWeb.ScrobbledTracksLive.Index do
|
|||||||
}} <- @streams.tracks
|
}} <- @streams.tracks
|
||||||
}
|
}
|
||||||
id={id}
|
id={id}
|
||||||
class="flex justify-between gap-x-6 py-5 hover:bg-zinc-50 dark:hover:bg-zinc-800 px-2 -mx-2 md:px-4 md:-mx-4 cursor-pointer"
|
class="-mx-2 flex cursor-pointer justify-between gap-x-6 px-2 py-5 hover:bg-zinc-50 md:-mx-4 md:px-4 dark:hover:bg-zinc-800"
|
||||||
>
|
>
|
||||||
<div class="flex items-center space-x-4 flex-1 min-w-0">
|
<div class="flex min-w-0 flex-1 items-center space-x-4">
|
||||||
<div class="shrink-0">
|
<div class="shrink-0">
|
||||||
<img
|
<img
|
||||||
class="h-12 w-12 rounded-md shadow-sm"
|
class="size-12 rounded-md shadow-sm"
|
||||||
src={track_cover_url(track, cover_hash)}
|
src={track_cover_url(track, cover_hash)}
|
||||||
alt={track.title}
|
alt={track.title}
|
||||||
onerror={"this.src = '" <> ~p"/images/cover-not-found.png" <> "';"}
|
onerror={"this.src = '" <> ~p"/images/cover-not-found.png" <> "';"}
|
||||||
@@ -121,18 +121,18 @@ defmodule MusicLibraryWeb.ScrobbledTracksLive.Index do
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="min-w-0 flex-1">
|
<div class="min-w-0 flex-1">
|
||||||
<p class="text-sm font-medium text-zinc-900 dark:text-zinc-100 truncate">
|
<p class="truncate text-sm font-medium text-zinc-900 dark:text-zinc-100">
|
||||||
{track.title}
|
{track.title}
|
||||||
</p>
|
</p>
|
||||||
<p class="text-sm text-zinc-600 dark:text-zinc-400 truncate">
|
<p class="truncate text-sm text-zinc-600 dark:text-zinc-400">
|
||||||
{track.artist.name}
|
{track.artist.name}
|
||||||
</p>
|
</p>
|
||||||
<p class="text-sm text-zinc-500 dark:text-zinc-500 truncate">
|
<p class="truncate text-sm text-zinc-500 dark:text-zinc-500">
|
||||||
{track.album.title}
|
{track.album.title}
|
||||||
</p>
|
</p>
|
||||||
<time
|
<time
|
||||||
datetime={format_scrobbled_at_uts(track.scrobbled_at_uts)}
|
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"
|
class="text-right text-xs whitespace-nowrap text-zinc-500 sm:text-sm dark:text-zinc-400"
|
||||||
>
|
>
|
||||||
{track.scrobbled_at_label}
|
{track.scrobbled_at_label}
|
||||||
</time>
|
</time>
|
||||||
@@ -161,7 +161,7 @@ defmodule MusicLibraryWeb.ScrobbledTracksLive.Index do
|
|||||||
<span class="sr-only">{gettext("Actions")}</span>
|
<span class="sr-only">{gettext("Actions")}</span>
|
||||||
<.icon
|
<.icon
|
||||||
name="hero-ellipsis-vertical"
|
name="hero-ellipsis-vertical"
|
||||||
class="icon text-zinc-500 dark:text-zinc-400 cursor-pointer"
|
class="icon cursor-pointer text-zinc-500 dark:text-zinc-400"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
data-slot="icon"
|
data-slot="icon"
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ defmodule MusicLibraryWeb.StatsLive.Index do
|
|||||||
~H"""
|
~H"""
|
||||||
<Layouts.app flash={@flash} current_section={@current_section} socket={@socket}>
|
<Layouts.app flash={@flash} current_section={@current_section} socket={@socket}>
|
||||||
<div>
|
<div>
|
||||||
<h1 class="mt-5 text-base lg:text-2xl text-zinc-900 dark:text-zinc-200 font-semibold">
|
<h1 class="mt-5 text-base font-semibold text-zinc-900 lg:text-2xl dark:text-zinc-200">
|
||||||
{gettext("Records")}
|
{gettext("Records")}
|
||||||
</h1>
|
</h1>
|
||||||
<dl class="mt-5 grid grid-cols-3 gap-5 sm:grid-cols-5">
|
<dl class="mt-5 grid grid-cols-3 gap-5 sm:grid-cols-5">
|
||||||
@@ -41,9 +41,9 @@ defmodule MusicLibraryWeb.StatsLive.Index do
|
|||||||
</dl>
|
</dl>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="grid lg:grid-cols-2 gap-5">
|
<div class="grid gap-5 lg:grid-cols-2">
|
||||||
<div>
|
<div>
|
||||||
<h1 class="mt-5 text-base lg:text-2xl text-zinc-900 dark:text-zinc-200 font-semibold">
|
<h1 class="mt-5 text-base font-semibold text-zinc-900 lg:text-2xl dark:text-zinc-200">
|
||||||
{gettext("Formats")}
|
{gettext("Formats")}
|
||||||
</h1>
|
</h1>
|
||||||
<.counters_by_category
|
<.counters_by_category
|
||||||
@@ -54,7 +54,7 @@ defmodule MusicLibraryWeb.StatsLive.Index do
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<h1 class="mt-5 text-base lg:text-2xl text-zinc-900 dark:text-zinc-200 font-semibold">
|
<h1 class="mt-5 text-base font-semibold text-zinc-900 lg:text-2xl dark:text-zinc-200">
|
||||||
{gettext("Types")}
|
{gettext("Types")}
|
||||||
</h1>
|
</h1>
|
||||||
<.counters_by_category
|
<.counters_by_category
|
||||||
@@ -66,15 +66,15 @@ defmodule MusicLibraryWeb.StatsLive.Index do
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<div class="mt-5 grid grid-cols-1 lg:grid-cols-2 gap-5">
|
<div class="mt-5 grid grid-cols-1 gap-5 lg:grid-cols-2">
|
||||||
<TopArtists.live id="top-artists" timezone={@timezone} last_updated_uts={@last_updated_uts} />
|
<TopArtists.live id="top-artists" timezone={@timezone} last_updated_uts={@last_updated_uts} />
|
||||||
<TopAlbums.live id="top-albums" timezone={@timezone} last_updated_uts={@last_updated_uts} />
|
<TopAlbums.live id="top-albums" timezone={@timezone} last_updated_uts={@last_updated_uts} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flow-root">
|
<div class="flow-root">
|
||||||
<div class="mt-5 flex justify-between items-center">
|
<div class="mt-5 flex items-center justify-between">
|
||||||
<h1 class="text-base lg:text-2xl text-zinc-900 dark:text-zinc-200 font-semibold">
|
<h1 class="text-base font-semibold text-zinc-900 lg:text-2xl dark:text-zinc-200">
|
||||||
{gettext("Scrobble activity")}
|
{gettext("Scrobble activity")}
|
||||||
</h1>
|
</h1>
|
||||||
<.refresh_lastfm_feed_button />
|
<.refresh_lastfm_feed_button />
|
||||||
@@ -99,7 +99,7 @@ defmodule MusicLibraryWeb.StatsLive.Index do
|
|||||||
<ul
|
<ul
|
||||||
id="scrobble-activity-albums"
|
id="scrobble-activity-albums"
|
||||||
role="list"
|
role="list"
|
||||||
class="mt-5 p-6 bg-white dark:bg-zinc-800 rounded-md shadow-sm"
|
class="mt-5 rounded-md bg-white p-6 shadow-sm dark:bg-zinc-800"
|
||||||
phx-update="stream"
|
phx-update="stream"
|
||||||
>
|
>
|
||||||
<li
|
<li
|
||||||
@@ -118,37 +118,37 @@ defmodule MusicLibraryWeb.StatsLive.Index do
|
|||||||
>
|
>
|
||||||
<div class="relative pb-4 group-last:pb-0">
|
<div class="relative pb-4 group-last:pb-0">
|
||||||
<span
|
<span
|
||||||
class="group-last:hidden absolute left-6 top-6 -ml-px h-full w-0.5 bg-zinc-200"
|
class="absolute top-6 left-6 -ml-px h-full w-0.5 bg-zinc-200 group-last:hidden"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
>
|
>
|
||||||
</span>
|
</span>
|
||||||
<div class="relative flex space-x-3 items-center justify-between">
|
<div class="relative flex items-center justify-between space-x-3">
|
||||||
<div class="flex min-w-0 justify-between space-x-4 items-center">
|
<div class="flex min-w-0 items-center justify-between space-x-4">
|
||||||
<img
|
<img
|
||||||
class="h-12 w-12 rounded-md shadow-sm"
|
class="size-12 rounded-md shadow-sm"
|
||||||
src={track_or_album_cover_url(album, cover_hash)}
|
src={track_or_album_cover_url(album, cover_hash)}
|
||||||
alt={album.metadata.title}
|
alt={album.metadata.title}
|
||||||
/>
|
/>
|
||||||
<div>
|
<div>
|
||||||
<p
|
<p
|
||||||
:if={!artist_id(album, artist_id)}
|
:if={!artist_id(album, artist_id)}
|
||||||
class="font-semibold text-sm block text-zinc-500 dark:text-zinc-400"
|
class="block text-sm font-semibold text-zinc-500 dark:text-zinc-400"
|
||||||
>
|
>
|
||||||
{album.artist.name}
|
{album.artist.name}
|
||||||
</p>
|
</p>
|
||||||
<.link
|
<.link
|
||||||
:if={artist_id(album, artist_id)}
|
:if={artist_id(album, artist_id)}
|
||||||
class="font-semibold text-sm block text-zinc-700 hover:text-zinc-500 dark:text-zinc-400 dark:hover:text-zinc-300"
|
class="block text-sm font-semibold text-zinc-700 hover:text-zinc-500 dark:text-zinc-400 dark:hover:text-zinc-300"
|
||||||
navigate={~p"/artists/#{artist_id(album, artist_id)}"}
|
navigate={~p"/artists/#{artist_id(album, artist_id)}"}
|
||||||
>
|
>
|
||||||
{album.artist.name}
|
{album.artist.name}
|
||||||
</.link>
|
</.link>
|
||||||
<p class="font-semibold text-sm md:text-base text-zinc-700 dark:text-zinc-300">
|
<p class="text-sm font-semibold text-zinc-700 md:text-base dark:text-zinc-300">
|
||||||
{album.metadata.title}
|
{album.metadata.title}
|
||||||
</p>
|
</p>
|
||||||
<time
|
<time
|
||||||
datetime={format_scrobbled_at_uts(album.scrobbled_at_uts)}
|
datetime={format_scrobbled_at_uts(album.scrobbled_at_uts)}
|
||||||
class="whitespace-nowrap text-right text-xs sm:text-sm text-zinc-500 dark:text-zinc-400"
|
class="text-right text-xs whitespace-nowrap text-zinc-500 sm:text-sm dark:text-zinc-400"
|
||||||
>
|
>
|
||||||
{album.scrobbled_at_label}
|
{album.scrobbled_at_label}
|
||||||
</time>
|
</time>
|
||||||
@@ -179,7 +179,7 @@ defmodule MusicLibraryWeb.StatsLive.Index do
|
|||||||
<ul
|
<ul
|
||||||
id="scrobble-activity-tracks"
|
id="scrobble-activity-tracks"
|
||||||
role="list"
|
role="list"
|
||||||
class="mt-5 p-6 bg-white dark:bg-zinc-800 rounded-md shadow-sm"
|
class="mt-5 rounded-md bg-white p-6 shadow-sm dark:bg-zinc-800"
|
||||||
phx-update="stream"
|
phx-update="stream"
|
||||||
>
|
>
|
||||||
<li
|
<li
|
||||||
@@ -198,40 +198,40 @@ defmodule MusicLibraryWeb.StatsLive.Index do
|
|||||||
>
|
>
|
||||||
<div class="relative pb-4 group-last:pb-0">
|
<div class="relative pb-4 group-last:pb-0">
|
||||||
<span
|
<span
|
||||||
class="group-last:hidden absolute left-6 top-6 -ml-px h-full w-0.5 bg-zinc-200"
|
class="absolute top-6 left-6 -ml-px h-full w-0.5 bg-zinc-200 group-last:hidden"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
>
|
>
|
||||||
</span>
|
</span>
|
||||||
<div class="relative flex space-x-3 items-center justify-between">
|
<div class="relative flex items-center justify-between space-x-3">
|
||||||
<div class="flex min-w-0 justify-between space-x-4 items-center">
|
<div class="flex min-w-0 items-center justify-between space-x-4">
|
||||||
<img
|
<img
|
||||||
class="h-12 w-12 rounded-md shadow-sm"
|
class="size-12 rounded-md shadow-sm"
|
||||||
src={track_or_album_cover_url(track, cover_hash)}
|
src={track_or_album_cover_url(track, cover_hash)}
|
||||||
alt={track.title}
|
alt={track.title}
|
||||||
/>
|
/>
|
||||||
<div>
|
<div>
|
||||||
<p
|
<p
|
||||||
:if={!artist_id(track, artist_id)}
|
:if={!artist_id(track, artist_id)}
|
||||||
class="font-semibold text-sm block text-zinc-500 dark:text-zinc-400"
|
class="block text-sm font-semibold text-zinc-500 dark:text-zinc-400"
|
||||||
>
|
>
|
||||||
{track.artist.name}
|
{track.artist.name}
|
||||||
</p>
|
</p>
|
||||||
<.link
|
<.link
|
||||||
:if={artist_id(track, artist_id)}
|
:if={artist_id(track, artist_id)}
|
||||||
class="font-semibold text-sm block text-zinc-700 hover:text-zinc-500 dark:text-zinc-400 dark:hover:text-zinc-300"
|
class="block text-sm font-semibold text-zinc-700 hover:text-zinc-500 dark:text-zinc-400 dark:hover:text-zinc-300"
|
||||||
navigate={~p"/artists/#{artist_id(track, artist_id)}"}
|
navigate={~p"/artists/#{artist_id(track, artist_id)}"}
|
||||||
>
|
>
|
||||||
{track.artist.name}
|
{track.artist.name}
|
||||||
</.link>
|
</.link>
|
||||||
<p class="font-semibold text-sm md:text-base text-zinc-700 dark:text-zinc-300">
|
<p class="text-sm font-semibold text-zinc-700 md:text-base dark:text-zinc-300">
|
||||||
{track.title}
|
{track.title}
|
||||||
</p>
|
</p>
|
||||||
<p class="font-semibold text-sm text-zinc-500 dark:text-zinc-400">
|
<p class="text-sm font-semibold text-zinc-500 dark:text-zinc-400">
|
||||||
{track.album.title}
|
{track.album.title}
|
||||||
</p>
|
</p>
|
||||||
<time
|
<time
|
||||||
datetime={format_scrobbled_at_uts(track.scrobbled_at_uts)}
|
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"
|
class="text-right text-xs whitespace-nowrap text-zinc-500 sm:text-sm dark:text-zinc-400"
|
||||||
>
|
>
|
||||||
{track.scrobbled_at_label}
|
{track.scrobbled_at_label}
|
||||||
</time>
|
</time>
|
||||||
@@ -261,10 +261,10 @@ defmodule MusicLibraryWeb.StatsLive.Index do
|
|||||||
</.tabs>
|
</.tabs>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mt-5 grid grid-cols-1 lg:grid-cols-11 gap-5">
|
<div class="mt-5 grid grid-cols-1 gap-5 lg:grid-cols-11">
|
||||||
<div class="lg:col-span-3">
|
<div class="lg:col-span-3">
|
||||||
<div class="flex justify-between items-center">
|
<div class="flex items-center justify-between">
|
||||||
<h1 class="text-base lg:text-2xl text-zinc-900 dark:text-zinc-200 font-semibold">
|
<h1 class="text-base font-semibold text-zinc-900 lg:text-2xl dark:text-zinc-200">
|
||||||
{gettext("On This day")}
|
{gettext("On This day")}
|
||||||
</h1>
|
</h1>
|
||||||
<.form
|
<.form
|
||||||
@@ -287,7 +287,7 @@ defmodule MusicLibraryWeb.StatsLive.Index do
|
|||||||
</.date_picker>
|
</.date_picker>
|
||||||
</.form>
|
</.form>
|
||||||
</div>
|
</div>
|
||||||
<div class="bg-white dark:bg-zinc-800 rounded-md shadow-sm">
|
<div class="rounded-md bg-white shadow-sm dark:bg-zinc-800">
|
||||||
<.records_on_this_day
|
<.records_on_this_day
|
||||||
current_date={@current_date}
|
current_date={@current_date}
|
||||||
records={@records_on_this_day}
|
records={@records_on_this_day}
|
||||||
@@ -296,10 +296,10 @@ defmodule MusicLibraryWeb.StatsLive.Index do
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="lg:col-span-4">
|
<div class="lg:col-span-4">
|
||||||
<h1 class="text-base lg:text-2xl text-zinc-900 dark:text-zinc-200 font-semibold">
|
<h1 class="text-base font-semibold text-zinc-900 lg:text-2xl dark:text-zinc-200">
|
||||||
{gettext("Top %{n} Collection Artists", %{n: length(@records_by_artist)})}
|
{gettext("Top %{n} Collection Artists", %{n: length(@records_by_artist)})}
|
||||||
</h1>
|
</h1>
|
||||||
<div class="mt-5 bg-white dark:bg-zinc-800 rounded-md shadow-sm">
|
<div class="mt-5 rounded-md bg-white shadow-sm dark:bg-zinc-800">
|
||||||
<.vertical_bar_chart
|
<.vertical_bar_chart
|
||||||
data={@records_by_artist}
|
data={@records_by_artist}
|
||||||
width={600}
|
width={600}
|
||||||
@@ -318,10 +318,10 @@ defmodule MusicLibraryWeb.StatsLive.Index do
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="lg:col-span-4">
|
<div class="lg:col-span-4">
|
||||||
<h1 class="text-base lg:text-2xl text-zinc-900 dark:text-zinc-200 font-semibold">
|
<h1 class="text-base font-semibold text-zinc-900 lg:text-2xl dark:text-zinc-200">
|
||||||
{gettext("Top %{n} Collection Genres", %{n: length(@records_by_genre)})}
|
{gettext("Top %{n} Collection Genres", %{n: length(@records_by_genre)})}
|
||||||
</h1>
|
</h1>
|
||||||
<div class="mt-5 bg-white dark:bg-zinc-800 rounded-md shadow-sm">
|
<div class="mt-5 rounded-md bg-white shadow-sm dark:bg-zinc-800">
|
||||||
<.vertical_bar_chart
|
<.vertical_bar_chart
|
||||||
data={@records_by_genre}
|
data={@records_by_genre}
|
||||||
width={600}
|
width={600}
|
||||||
|
|||||||
@@ -30,18 +30,18 @@ defmodule MusicLibraryWeb.StatsLive.TopAlbums do
|
|||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
class="w-12 h-12 rounded-md shadow-sm object-cover"
|
class="size-12 rounded-md object-cover shadow-sm"
|
||||||
src={cover_url(album)}
|
src={cover_url(album)}
|
||||||
alt={album.album_title}
|
alt={album.album_title}
|
||||||
/>
|
/>
|
||||||
<div class="flex-1 min-w-0">
|
<div class="min-w-0 flex-1">
|
||||||
<.link
|
<.link
|
||||||
class="text-xs text-zinc-700 hover:text-zinc-500 dark:text-zinc-400 dark:hover:text-zinc-300 truncate"
|
class="truncate text-xs text-zinc-700 hover:text-zinc-500 dark:text-zinc-400 dark:hover:text-zinc-300"
|
||||||
navigate={~p"/artists/#{album.artist_musicbrainz_id}"}
|
navigate={~p"/artists/#{album.artist_musicbrainz_id}"}
|
||||||
>
|
>
|
||||||
{album.artist_name}
|
{album.artist_name}
|
||||||
</.link>
|
</.link>
|
||||||
<p class="text-sm font-medium text-zinc-900 dark:text-zinc-300 truncate">
|
<p class="truncate text-sm font-medium text-zinc-900 dark:text-zinc-300">
|
||||||
{album.album_title}
|
{album.album_title}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -35,19 +35,19 @@ defmodule MusicLibraryWeb.StatsLive.TopArtists do
|
|||||||
>
|
>
|
||||||
<.artist_image
|
<.artist_image
|
||||||
:if={artist.musicbrainz_id != ""}
|
:if={artist.musicbrainz_id != ""}
|
||||||
class="w-12 h-12 rounded-md shadow-sm object-cover"
|
class="size-12 rounded-md object-cover shadow-sm"
|
||||||
artist={artist}
|
artist={artist}
|
||||||
width={96}
|
width={96}
|
||||||
image_hash={artist.image_hash}
|
image_hash={artist.image_hash}
|
||||||
/>
|
/>
|
||||||
<div
|
<div
|
||||||
:if={artist.musicbrainz_id == ""}
|
:if={artist.musicbrainz_id == ""}
|
||||||
class="w-12 h-12 rounded-md bg-zinc-200 dark:bg-zinc-700 flex items-center justify-center"
|
class="flex size-12 items-center justify-center rounded-md bg-zinc-200 dark:bg-zinc-700"
|
||||||
>
|
>
|
||||||
<.icon name="hero-user" class="w-6 h-6 text-zinc-400" />
|
<.icon name="hero-user" class="size-6 text-zinc-400" />
|
||||||
</div>
|
</div>
|
||||||
<div class="flex-1 min-w-0">
|
<div class="min-w-0 flex-1">
|
||||||
<p class="text-sm font-medium text-zinc-900 dark:text-zinc-300 truncate">
|
<p class="truncate text-sm font-medium text-zinc-900 dark:text-zinc-300">
|
||||||
{artist.name}
|
{artist.name}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ defmodule MusicLibraryWeb.StatsLive.TopByPeriod do
|
|||||||
def render(assigns) do
|
def render(assigns) do
|
||||||
~H"""
|
~H"""
|
||||||
<div>
|
<div>
|
||||||
<h1 class="text-base lg:text-2xl text-zinc-900 dark:text-zinc-200 font-semibold">
|
<h1 class="text-base font-semibold text-zinc-900 lg:text-2xl dark:text-zinc-200">
|
||||||
{@title}
|
{@title}
|
||||||
</h1>
|
</h1>
|
||||||
<.tabs class="mt-4">
|
<.tabs class="mt-4">
|
||||||
@@ -68,11 +68,11 @@ defmodule MusicLibraryWeb.StatsLive.TopByPeriod do
|
|||||||
</.tabs_list>
|
</.tabs_list>
|
||||||
<.async_result :let={items} assign={assigns[@key]}>
|
<.async_result :let={items} assign={assigns[@key]}>
|
||||||
<:loading>
|
<:loading>
|
||||||
<div class="h-182 flex items-center justify-center">
|
<div class="flex h-182 items-center justify-center">
|
||||||
<.loading />
|
<.loading />
|
||||||
</div>
|
</div>
|
||||||
</:loading>
|
</:loading>
|
||||||
<div class="mt-4 p-4 bg-white dark:bg-zinc-800 rounded-md shadow-sm">
|
<div class="mt-4 rounded-md bg-white p-4 shadow-sm dark:bg-zinc-800">
|
||||||
<div class="space-y-2">
|
<div class="space-y-2">
|
||||||
{render_slot(@item, items)}
|
{render_slot(@item, items)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ defmodule MusicLibraryWeb.UniversalSearchLive.Index do
|
|||||||
<div class="relative">
|
<div class="relative">
|
||||||
<.icon
|
<.icon
|
||||||
name="hero-magnifying-glass"
|
name="hero-magnifying-glass"
|
||||||
class="absolute left-3 top-1/2 transform -translate-y-1/2 h-5 w-5 text-zinc-400"
|
class="absolute top-1/2 left-3 size-5 -translate-y-1/2 transform text-zinc-400"
|
||||||
/>
|
/>
|
||||||
<label for="universal-search-input" class="sr-only">Universal Search</label>
|
<label for="universal-search-input" class="sr-only">Universal Search</label>
|
||||||
<.input
|
<.input
|
||||||
@@ -38,7 +38,7 @@ defmodule MusicLibraryWeb.UniversalSearchLive.Index do
|
|||||||
|
|
||||||
<.no_results :if={@search_query != "" and @total_results == 0} query={@search_query} />
|
<.no_results :if={@search_query != "" and @total_results == 0} query={@search_query} />
|
||||||
|
|
||||||
<div :if={@total_results > 0} class="max-h-148 md:max-h-164 overflow-y-auto mt-4">
|
<div :if={@total_results > 0} class="mt-4 max-h-148 overflow-y-auto md:max-h-164">
|
||||||
<.search_result_group
|
<.search_result_group
|
||||||
:if={length(@navigation_links_results) > 0}
|
:if={length(@navigation_links_results) > 0}
|
||||||
title={gettext("Go to")}
|
title={gettext("Go to")}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ defmodule MusicLibraryWeb.WishlistLive.Index do
|
|||||||
~H"""
|
~H"""
|
||||||
<Layouts.app flash={@flash} current_section={@current_section} socket={@socket}>
|
<Layouts.app flash={@flash} current_section={@current_section} socket={@socket}>
|
||||||
<header class="mb-2">
|
<header class="mb-2">
|
||||||
<div class="flex items-center justify-between gap-6 mb-2 mt-2">
|
<div class="my-2 flex items-center justify-between gap-6">
|
||||||
<.search_form query={@record_list_params.query} />
|
<.search_form query={@record_list_params.query} />
|
||||||
<.button
|
<.button
|
||||||
variant="solid"
|
variant="solid"
|
||||||
@@ -34,7 +34,7 @@ defmodule MusicLibraryWeb.WishlistLive.Index do
|
|||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<div class="flex items-end justify-between gap-6 mt-6">
|
<div class="mt-6 flex items-end justify-between gap-6">
|
||||||
<.button_group>
|
<.button_group>
|
||||||
<.button
|
<.button
|
||||||
patch={order_path(@record_list_params, :insertion)}
|
patch={order_path(@record_list_params, :insertion)}
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ defmodule MusicLibraryWeb.WishlistLive.Show do
|
|||||||
def render(assigns) do
|
def render(assigns) do
|
||||||
~H"""
|
~H"""
|
||||||
<Layouts.app flash={@flash} current_section={@current_section} socket={@socket}>
|
<Layouts.app flash={@flash} current_section={@current_section} socket={@socket}>
|
||||||
<div class="lg:grid lg:grid-cols-2 xl:grid-cols-5 mt-4 px-4 md:gap-x-4">
|
<div class="mt-4 px-4 md:gap-x-4 lg:grid lg:grid-cols-2 xl:grid-cols-5">
|
||||||
<div class="drop-shadow-sm xl:col-span-2">
|
<div class="drop-shadow-sm xl:col-span-2">
|
||||||
<.record_cover
|
<.record_cover
|
||||||
record={@record}
|
record={@record}
|
||||||
@@ -35,8 +35,8 @@ defmodule MusicLibraryWeb.WishlistLive.Show do
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="xl:col-span-3">
|
<div class="xl:col-span-3">
|
||||||
<div class="mt-4 md:mt-0 flex justify-between items-center">
|
<div class="mt-4 flex items-center justify-between md:mt-0">
|
||||||
<h1 class="text-base font-medium leading-6 text-zinc-700">
|
<h1 class="text-base/6 font-medium text-zinc-700">
|
||||||
<.artist_links joinphrase_class="text-sm" artists={@record.artists} />
|
<.artist_links joinphrase_class="text-sm" artists={@record.artists} />
|
||||||
</h1>
|
</h1>
|
||||||
<div class="min-w-12">
|
<div class="min-w-12">
|
||||||
@@ -60,7 +60,7 @@ defmodule MusicLibraryWeb.WishlistLive.Show do
|
|||||||
<span class="sr-only">{gettext("Actions")}</span>
|
<span class="sr-only">{gettext("Actions")}</span>
|
||||||
<.icon
|
<.icon
|
||||||
name="hero-ellipsis-vertical"
|
name="hero-ellipsis-vertical"
|
||||||
class="icon text-zinc-500 dark:text-zinc-400 cursor-pointer"
|
class="icon cursor-pointer text-zinc-500 dark:text-zinc-400"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
data-slot="icon"
|
data-slot="icon"
|
||||||
/>
|
/>
|
||||||
@@ -73,7 +73,7 @@ defmodule MusicLibraryWeb.WishlistLive.Show do
|
|||||||
>
|
>
|
||||||
<.icon
|
<.icon
|
||||||
name="hero-code-bracket"
|
name="hero-code-bracket"
|
||||||
class="h-4 w-4 mr-1"
|
class="mr-1 size-4"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
data-slot="icon"
|
data-slot="icon"
|
||||||
/>
|
/>
|
||||||
@@ -88,7 +88,7 @@ defmodule MusicLibraryWeb.WishlistLive.Show do
|
|||||||
>
|
>
|
||||||
<.icon
|
<.icon
|
||||||
name="hero-pencil-square"
|
name="hero-pencil-square"
|
||||||
class="h-4 w-4 mr-1 phx-click-loading:animate-bounce"
|
class="phx-click-loading:animate-bounce mr-1 size-4"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
data-slot="icon"
|
data-slot="icon"
|
||||||
/>
|
/>
|
||||||
@@ -101,7 +101,7 @@ defmodule MusicLibraryWeb.WishlistLive.Show do
|
|||||||
>
|
>
|
||||||
<.icon
|
<.icon
|
||||||
name="hero-photo"
|
name="hero-photo"
|
||||||
class="h-4 w-4 mr-1 phx-click-loading:animate-bounce"
|
class="phx-click-loading:animate-bounce mr-1 size-4"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
data-slot="icon"
|
data-slot="icon"
|
||||||
/>
|
/>
|
||||||
@@ -114,7 +114,7 @@ defmodule MusicLibraryWeb.WishlistLive.Show do
|
|||||||
>
|
>
|
||||||
<.icon
|
<.icon
|
||||||
name="hero-arrow-path"
|
name="hero-arrow-path"
|
||||||
class="h-4 w-4 mr-1 phx-click-loading:animate-spin"
|
class="phx-click-loading:animate-spin mr-1 size-4"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
data-slot="icon"
|
data-slot="icon"
|
||||||
/>
|
/>
|
||||||
@@ -127,7 +127,7 @@ defmodule MusicLibraryWeb.WishlistLive.Show do
|
|||||||
>
|
>
|
||||||
<.icon
|
<.icon
|
||||||
name="hero-sparkles"
|
name="hero-sparkles"
|
||||||
class="h-4 w-4 mr-1 phx-click-loading:animate-shake"
|
class="phx-click-loading:animate-shake mr-1 size-4"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
data-slot="icon"
|
data-slot="icon"
|
||||||
/>
|
/>
|
||||||
@@ -144,7 +144,7 @@ defmodule MusicLibraryWeb.WishlistLive.Show do
|
|||||||
>
|
>
|
||||||
<.icon
|
<.icon
|
||||||
name="hero-banknotes"
|
name="hero-banknotes"
|
||||||
class="h-4 w-4 mr-1 phx-click-loading:animate-shake"
|
class="phx-click-loading:animate-shake mr-1 size-4"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
data-slot="icon"
|
data-slot="icon"
|
||||||
/>
|
/>
|
||||||
@@ -157,7 +157,7 @@ defmodule MusicLibraryWeb.WishlistLive.Show do
|
|||||||
>
|
>
|
||||||
<.icon
|
<.icon
|
||||||
name="hero-paint-brush"
|
name="hero-paint-brush"
|
||||||
class="h-4 w-4 mr-1 phx-click-loading:animate-shake"
|
class="phx-click-loading:animate-shake mr-1 size-4"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
data-slot="icon"
|
data-slot="icon"
|
||||||
/>
|
/>
|
||||||
@@ -173,7 +173,7 @@ defmodule MusicLibraryWeb.WishlistLive.Show do
|
|||||||
>
|
>
|
||||||
<.icon
|
<.icon
|
||||||
name="hero-trash"
|
name="hero-trash"
|
||||||
class="h-4 w-4 mr-1 phx-click-loading:animate-spin"
|
class="phx-click-loading:animate-spin mr-1 size-4"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
data-slot="icon"
|
data-slot="icon"
|
||||||
/>
|
/>
|
||||||
@@ -194,7 +194,7 @@ defmodule MusicLibraryWeb.WishlistLive.Show do
|
|||||||
<div class="flex justify-between space-x-2">
|
<div class="flex justify-between space-x-2">
|
||||||
<span
|
<span
|
||||||
:if={!@record.selected_release_id}
|
:if={!@record.selected_release_id}
|
||||||
class="text-xs md:text-sm text-zinc-700 dark:text-zinc-300"
|
class="text-xs text-zinc-700 md:text-sm dark:text-zinc-300"
|
||||||
>
|
>
|
||||||
{gettext("No release selected")}
|
{gettext("No release selected")}
|
||||||
</span>
|
</span>
|
||||||
@@ -214,7 +214,7 @@ defmodule MusicLibraryWeb.WishlistLive.Show do
|
|||||||
|
|
||||||
<div :if={@online_store_templates != []} class="mt-4">
|
<div :if={@online_store_templates != []} class="mt-4">
|
||||||
<details class="px-4 text-zinc-700 hover:text-zinc-500 dark:text-zinc-400 dark:hover:text-zinc-300">
|
<details class="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 font-medium cursor-pointer">
|
<summary class="cursor-pointer text-xs font-medium sm:text-sm">
|
||||||
{gettext("Check Online Stores")}
|
{gettext("Check Online Stores")}
|
||||||
</summary>
|
</summary>
|
||||||
<div class="mt-4 space-y-2">
|
<div class="mt-4 space-y-2">
|
||||||
@@ -238,7 +238,7 @@ defmodule MusicLibraryWeb.WishlistLive.Show do
|
|||||||
</span>
|
</span>
|
||||||
<.icon
|
<.icon
|
||||||
name="hero-arrow-top-right-on-square"
|
name="hero-arrow-top-right-on-square"
|
||||||
class="h-3.5 w-3.5 text-zinc-400"
|
class="size-3.5 text-zinc-400"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
/>
|
/>
|
||||||
</.button>
|
</.button>
|
||||||
|
|||||||
@@ -77,6 +77,7 @@ defmodule MusicLibrary.MixProject do
|
|||||||
{:phoenix_live_reload, "~> 1.2", only: :dev},
|
{:phoenix_live_reload, "~> 1.2", only: :dev},
|
||||||
{:esbuild, "~> 0.8", runtime: Mix.env() == :dev},
|
{:esbuild, "~> 0.8", runtime: Mix.env() == :dev},
|
||||||
{:tailwind, "~> 0.3", runtime: Mix.env() == :dev},
|
{:tailwind, "~> 0.3", runtime: Mix.env() == :dev},
|
||||||
|
{:canonical_tailwind, "~> 0.1.0", only: [:dev, :test], runtime: false},
|
||||||
{:benchee, "~> 1.3", only: :dev, runtime: false},
|
{:benchee, "~> 1.3", only: :dev, runtime: false},
|
||||||
{:credo, "~> 1.7", only: [:dev, :test], runtime: false},
|
{:credo, "~> 1.7", only: [:dev, :test], runtime: false},
|
||||||
{:quokka, "~> 2.6", only: [:dev, :test], runtime: false},
|
{:quokka, "~> 2.6", only: [:dev, :test], runtime: false},
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
"benchee": {:hex, :benchee, "1.5.0", "4d812c31d54b0ec0167e91278e7de3f596324a78a096fd3d0bea68bb0c513b10", [:mix], [{:deep_merge, "~> 1.0", [hex: :deep_merge, repo: "hexpm", optional: false]}, {:statistex, "~> 1.1", [hex: :statistex, repo: "hexpm", optional: false]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "5b075393aea81b8ae74eadd1c28b1d87e8a63696c649d8293db7c4df3eb67535"},
|
"benchee": {:hex, :benchee, "1.5.0", "4d812c31d54b0ec0167e91278e7de3f596324a78a096fd3d0bea68bb0c513b10", [:mix], [{:deep_merge, "~> 1.0", [hex: :deep_merge, repo: "hexpm", optional: false]}, {:statistex, "~> 1.1", [hex: :statistex, repo: "hexpm", optional: false]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "5b075393aea81b8ae74eadd1c28b1d87e8a63696c649d8293db7c4df3eb67535"},
|
||||||
"briefly": {:hex, :briefly, "0.5.1", "ee10d48da7f79ed2aebdc3e536d5f9a0c3e36ff76c0ad0d4254653a152b13a8a", [:mix], [], "hexpm", "bd684aa92ad8b7b4e0d92c31200993c4bc1469fc68cd6d5f15144041bd15cb57"},
|
"briefly": {:hex, :briefly, "0.5.1", "ee10d48da7f79ed2aebdc3e536d5f9a0c3e36ff76c0ad0d4254653a152b13a8a", [:mix], [], "hexpm", "bd684aa92ad8b7b4e0d92c31200993c4bc1469fc68cd6d5f15144041bd15cb57"},
|
||||||
"bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"},
|
"bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"},
|
||||||
|
"canonical_tailwind": {:hex, :canonical_tailwind, "0.1.0", "76ca1225b6804b2e7daaff1ec5ebeb3bb2db39fc28d17ff2b71ca4aa234bddc1", [:mix], [{:tailwind, "~> 0.3", [hex: :tailwind, repo: "hexpm", optional: true]}], "hexpm", "989c1bf1518843e1ce24a6f5c794b9c2a89d1bd873fa1a266c8ee3d1e0367703"},
|
||||||
"castore": {:hex, :castore, "1.0.18", "5e43ef0ec7d31195dfa5a65a86e6131db999d074179d2ba5a8de11fe14570f55", [:mix], [], "hexpm", "f393e4fe6317829b158fb74d86eb681f737d2fe326aa61ccf6293c4104957e34"},
|
"castore": {:hex, :castore, "1.0.18", "5e43ef0ec7d31195dfa5a65a86e6131db999d074179d2ba5a8de11fe14570f55", [:mix], [], "hexpm", "f393e4fe6317829b158fb74d86eb681f737d2fe326aa61ccf6293c4104957e34"},
|
||||||
"cc_precompiler": {:hex, :cc_precompiler, "0.1.11", "8c844d0b9fb98a3edea067f94f616b3f6b29b959b6b3bf25fee94ffe34364768", [:mix], [{:elixir_make, "~> 0.7", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm", "3427232caf0835f94680e5bcf082408a70b48ad68a5f5c0b02a3bea9f3a075b9"},
|
"cc_precompiler": {:hex, :cc_precompiler, "0.1.11", "8c844d0b9fb98a3edea067f94f616b3f6b29b959b6b3bf25fee94ffe34364768", [:mix], [{:elixir_make, "~> 0.7", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm", "3427232caf0835f94680e5bcf082408a70b48ad68a5f5c0b02a3bea9f3a075b9"},
|
||||||
"circular_buffer": {:hex, :circular_buffer, "1.0.0", "25c004da0cba7bd8bc1bdabded4f9a902d095e20600fd15faf1f2ffbaea18a07", [:mix], [], "hexpm", "c829ec31c13c7bafd1f546677263dff5bfb006e929f25635878ac3cfba8749e5"},
|
"circular_buffer": {:hex, :circular_buffer, "1.0.0", "25c004da0cba7bd8bc1bdabded4f9a902d095e20600fd15faf1f2ffbaea18a07", [:mix], [], "hexpm", "c829ec31c13c7bafd1f546677263dff5bfb006e929f25635878ac3cfba8749e5"},
|
||||||
|
|||||||
Reference in New Issue
Block a user