231 lines
7.9 KiB
Plaintext
231 lines
7.9 KiB
Plaintext
<div>
|
|
<header class="gap-6 mb-2">
|
|
<div class="flex items-center justify-between gap-6 mb-2 mt-2">
|
|
<form class="w-2/3" for={@record_list_params.query} phx-submit="search" phx-change="search">
|
|
<.input
|
|
type="search"
|
|
id={:query}
|
|
name={:query}
|
|
value={@record_list_params.query}
|
|
placeholder={gettext("Search")}
|
|
phx-debounce="500"
|
|
autocorrect="off"
|
|
autocapitalize="none"
|
|
/>
|
|
</form>
|
|
<.link patch={~p"/collection/import"}>
|
|
<.button><%= gettext("Import") %></.button>
|
|
</.link>
|
|
</div>
|
|
</header>
|
|
|
|
<p class="text-right text-sm max-sm:text-xs mt-8 text-zinc-900 dark:text-zinc-400">
|
|
<%= gettext(
|
|
"Showing <b>%{visible}</b> of <b>%{total}</b> records",
|
|
%{visible: Enum.count(@streams.records), total: @record_list_params.total_entries}
|
|
)
|
|
|> raw() %>
|
|
</p>
|
|
</div>
|
|
|
|
<ul
|
|
class="divide-y divide-zinc-100 dark:divide-slate-300/30 mt-5"
|
|
role="list"
|
|
id="records"
|
|
phx-update="stream"
|
|
>
|
|
<li
|
|
:for={{id, record} <- @streams.records}
|
|
phx-click={JS.navigate(~p"/collection/#{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"
|
|
id={id}
|
|
>
|
|
<div class="flex min-w-0 gap-x-4 items-center">
|
|
<img
|
|
class="w-20 flex-none rounded-lg"
|
|
alt={record.title}
|
|
src={~p"/covers/#{record.id}?vsn=#{record.cover_hash || ""}"}
|
|
/>
|
|
<div class="min-w-0 flex-auto">
|
|
<h1 class="text-sm leading-6 text-zinc-700">
|
|
<.link
|
|
:for={artist <- record.artists}
|
|
class="text-zinc-700 hover:text-zinc-500 dark:text-zinc-400 dark:hover:text-zinc-300"
|
|
patch={~p"/collection?query=mbid:#{artist.musicbrainz_id}"}
|
|
>
|
|
<%= artist.name %>
|
|
</.link>
|
|
</h1>
|
|
<h2 class="mt-1 flex font-semibold text-sm sm:text-base leading-5 text-zinc-700 dark:text-zinc-300 text-wrap">
|
|
<%= record.title %>
|
|
</h2>
|
|
<p class="mt-1 text-xs leading-5 text-zinc-500 dark:text-zinc-400">
|
|
<%= Records.Record.format_release(record.release) %>
|
|
<span class="sm:hidden">
|
|
· <%= Records.Record.format_long_label(record.format) %> · <%= Records.Record.type_long_label(
|
|
record.type
|
|
) %>
|
|
<span :if={Records.Record.child_release_groups_count(record) > 0}>
|
|
·
|
|
<span class="sr-only">
|
|
<%= gettext("Number of included records") %>
|
|
</span>
|
|
<span class={[
|
|
"inline-flex items-center rounded-full",
|
|
"px-2 py-1 text-xs font-medium",
|
|
"ring-1 ring-inset",
|
|
"bg-gray-50 dark:bg-gray-400/10",
|
|
"text-gray-600 dark:text-gray-500",
|
|
"ring-gray-500/10 dark:ring-gray-400/20"
|
|
]}>
|
|
<%= Records.Record.child_release_groups_count(record) %>
|
|
</span>
|
|
</span>
|
|
</span>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
<div class="flex shrink-0 items-center gap-x-6">
|
|
<div class="hidden sm:flex sm:flex-col sm:items-end">
|
|
<p class="text-xs leading-6 text-zinc-900 dark:text-zinc-300">
|
|
<%= Records.Record.format_long_label(record.format) %> · <%= Records.Record.type_long_label(
|
|
record.type
|
|
) %>
|
|
<span :if={Records.Record.child_release_groups_count(record) > 0}>
|
|
·
|
|
<span class="sr-only">
|
|
<%= gettext("Number of included records") %>
|
|
</span>
|
|
<span class={[
|
|
"inline-flex items-center rounded-full",
|
|
"px-2 py-1 text-xs font-medium",
|
|
"ring-1 ring-inset",
|
|
"bg-gray-50 dark:bg-gray-400/10",
|
|
"text-gray-600 dark:text-gray-500",
|
|
"ring-gray-500/10 dark:ring-gray-400/20"
|
|
]}>
|
|
<%= Records.Record.child_release_groups_count(record) %>
|
|
</span>
|
|
</span>
|
|
</p>
|
|
</div>
|
|
<div class="relative flex-none">
|
|
<button
|
|
type="button"
|
|
class="text-zinc-500 hover:text-zinc-900 dark:text-zinc-400 dark:hover:text-zinc-300"
|
|
aria-expanded="false"
|
|
aria-haspopup="true"
|
|
phx-click={toggle_actions_menu(record.id)}
|
|
phx-click-away={close_actions_menu(record.id)}
|
|
>
|
|
<span class="sr-only"><%= gettext("Open options") %></span>
|
|
<.icon
|
|
name="hero-ellipsis-vertical"
|
|
class="-mt-1 h-5 w-5"
|
|
aria-hidden="true"
|
|
data-slot="icon"
|
|
/>
|
|
</button>
|
|
<!--
|
|
Dropdown menu, show/hide based on menu state.
|
|
|
|
Entering: "transition ease-out duration-100"
|
|
From: "transform opacity-0 scale-95"
|
|
To: "transform opacity-100 scale-100"
|
|
Leaving: "transition ease-in duration-75"
|
|
From: "transform opacity-100 scale-100"
|
|
To: "transform opacity-0 scale-95"
|
|
-->
|
|
<.focus_wrap
|
|
id={"actions-#{record.id}"}
|
|
class={[
|
|
"hidden pointer-events-auto absolute right-0 z-10 mt-2 w-48 origin-top-right rounded-md bg-white dark:bg-zinc-800 py-2 shadow-lg ring-1 ring-zinc-900/5 focus:outline-none"
|
|
]}
|
|
role="menu"
|
|
aria-orientation="vertical"
|
|
aria-labelledby="options-menu-0-button"
|
|
tabindex="-1"
|
|
>
|
|
<.link
|
|
class="block px-3 py-1 text-sm leading-6 text-zinc-900 dark:text-zinc-400 hover:bg-zinc-50 dark:hover:text-zinc-300 dark:hover:bg-zinc-700"
|
|
role="menuitem"
|
|
tabindex="-1"
|
|
id={"actions-#{record.id}-show"}
|
|
navigate={~p"/collection/#{record}"}
|
|
>
|
|
<%= gettext("Show") %>
|
|
</.link>
|
|
<a
|
|
href={musicbrainz_url(record)}
|
|
target=".blank"
|
|
class="block px-3 py-1 text-sm leading-6 text-zinc-900 dark:text-zinc-400 hover:bg-zinc-50 dark:hover:text-zinc-300 dark:hover:bg-zinc-700"
|
|
role="menuitem"
|
|
tabindex="-1"
|
|
id={"actions-#{record.id}-musicbrainz"}
|
|
>
|
|
<%= gettext("View on MusicBrainz") %>
|
|
</a>
|
|
|
|
<.link
|
|
class="block px-3 py-1 text-sm leading-6 text-zinc-900 dark:text-zinc-400 hover:bg-zinc-50 dark:hover:text-zinc-300 dark:hover:bg-zinc-700"
|
|
role="menuitem"
|
|
tabindex="-1"
|
|
id={"actions-#{record.id}-edit"}
|
|
patch={~p"/collection/#{record}/edit"}
|
|
>
|
|
<%= gettext("Edit") %>
|
|
</.link>
|
|
|
|
<.link
|
|
class="block px-3 py-1 text-sm leading-6 text-red-900 hover:bg-red-50 dark:text-red-700 dark:hover:bg-red-900/30 dark:hover:text-red-600"
|
|
role="menuitem"
|
|
tabindex="-1"
|
|
id={"actions-#{record.id}-delete"}
|
|
phx-click={JS.push("delete", value: %{id: record.id}) |> hide("##{id}")}
|
|
data-confirm={gettext("Are you sure?")}
|
|
>
|
|
<%= gettext("Delete") %>
|
|
</.link>
|
|
</.focus_wrap>
|
|
</div>
|
|
</div>
|
|
</li>
|
|
</ul>
|
|
|
|
<.modal
|
|
:if={@live_action == :edit}
|
|
id="record-modal"
|
|
show
|
|
on_cancel={JS.patch(back_path(@record_list_params))}
|
|
>
|
|
<.live_component
|
|
module={MusicLibraryWeb.RecordLive.FormComponent}
|
|
id={@record.id}
|
|
title={@page_title}
|
|
action={@live_action}
|
|
show_purchased_at={true}
|
|
record={@record}
|
|
patch={back_path(@record_list_params)}
|
|
/>
|
|
</.modal>
|
|
|
|
<.modal
|
|
:if={@live_action == :import}
|
|
id="record-modal"
|
|
show
|
|
on_cancel={JS.patch(back_path(@record_list_params))}
|
|
>
|
|
<.live_component
|
|
module={MusicLibraryWeb.RecordLive.ImportComponent}
|
|
id={:search}
|
|
title={@page_title}
|
|
action={@live_action}
|
|
record={@record}
|
|
patch={back_path(@record_list_params)}
|
|
initial_query=""
|
|
icon_name="hero-plus"
|
|
/>
|
|
</.modal>
|
|
|
|
<.pagination id={:bottom_pagination} pagination_params={@record_list_params} />
|