Misc universal search improvements
- Use zinc instead of gray - Translate all strings, and remove redundant ones - Add format, type and release year to record results - Use existing helpers instead of hand-rolled variants
This commit is contained in:
@@ -5,6 +5,8 @@ defmodule MusicLibraryWeb.SearchComponents do
|
|||||||
|
|
||||||
use MusicLibraryWeb, :html
|
use MusicLibraryWeb, :html
|
||||||
|
|
||||||
|
import MusicLibraryWeb.RecordComponents, only: [format_label: 1, type_label: 1]
|
||||||
|
|
||||||
alias MusicLibrary.Records.Record
|
alias MusicLibrary.Records.Record
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
@@ -23,10 +25,10 @@ defmodule MusicLibraryWeb.SearchComponents do
|
|||||||
type="button"
|
type="button"
|
||||||
class={[
|
class={[
|
||||||
"flex items-center justify-center h-9 w-9 rounded-lg",
|
"flex items-center justify-center h-9 w-9 rounded-lg",
|
||||||
"text-gray-500 dark:text-gray-400",
|
"text-zinc-500 dark:text-zinc-400",
|
||||||
"hover:text-gray-700 dark:hover:text-gray-300",
|
"hover:text-zinc-700 dark:hover:text-zinc-300",
|
||||||
"hover:bg-gray-100 dark:hover:bg-gray-800",
|
"hover:bg-zinc-100 dark:hover:bg-zinc-800",
|
||||||
"focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 dark:focus:ring-offset-gray-900",
|
"focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 dark:focus:ring-offset-zinc-900",
|
||||||
"transition-colors duration-200",
|
"transition-colors duration-200",
|
||||||
@class
|
@class
|
||||||
]}
|
]}
|
||||||
@@ -55,7 +57,7 @@ defmodule MusicLibraryWeb.SearchComponents do
|
|||||||
<div
|
<div
|
||||||
class={[
|
class={[
|
||||||
"p-3 rounded-lg cursor-pointer transition-colors",
|
"p-3 rounded-lg cursor-pointer transition-colors",
|
||||||
"hover:bg-gray-50 dark:hover:bg-gray-700",
|
"hover:bg-zinc-50 dark:hover:bg-zinc-700",
|
||||||
if(@selected, do: "bg-blue-50 dark:bg-blue-900", else: "")
|
if(@selected, do: "bg-blue-50 dark:bg-blue-900", else: "")
|
||||||
]}
|
]}
|
||||||
{@rest}
|
{@rest}
|
||||||
@@ -69,12 +71,17 @@ defmodule MusicLibraryWeb.SearchComponents do
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="min-w-0 flex-1">
|
<div class="min-w-0 flex-1">
|
||||||
<p class="text-sm font-medium text-gray-900 dark:text-gray-100 truncate">
|
<p class="text-sm font-medium text-zinc-900 dark:text-zinc-100 truncate">
|
||||||
{@record.title}
|
{@record.title}
|
||||||
</p>
|
</p>
|
||||||
<p class="text-sm text-gray-500 dark:text-gray-400 truncate">
|
<p class="text-sm text-zinc-500 font-medium dark:text-zinc-400 truncate">
|
||||||
{Record.artist_names(@record)}
|
{Record.artist_names(@record)}
|
||||||
</p>
|
</p>
|
||||||
|
<p class="pointer-events-none block text-sm text-zinc-500">
|
||||||
|
{format_label(@record.format)} · {type_label(@record.type)} · {Record.format_release_date(
|
||||||
|
@record.release_date
|
||||||
|
)}
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -97,7 +104,7 @@ defmodule MusicLibraryWeb.SearchComponents do
|
|||||||
<div
|
<div
|
||||||
class={[
|
class={[
|
||||||
"p-3 rounded-lg cursor-pointer transition-colors",
|
"p-3 rounded-lg cursor-pointer transition-colors",
|
||||||
"hover:bg-gray-50 dark:hover:bg-gray-700",
|
"hover:bg-zinc-50 dark:hover:bg-zinc-700",
|
||||||
if(@selected, do: "bg-blue-50 dark:bg-blue-900", else: "")
|
if(@selected, do: "bg-blue-50 dark:bg-blue-900", else: "")
|
||||||
]}
|
]}
|
||||||
{@rest}
|
{@rest}
|
||||||
@@ -112,10 +119,10 @@ defmodule MusicLibraryWeb.SearchComponents do
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="min-w-0 flex-1">
|
<div class="min-w-0 flex-1">
|
||||||
<p class="text-sm font-medium text-gray-900 dark:text-gray-100 truncate">
|
<p class="text-sm font-medium text-zinc-900 dark:text-zinc-100 truncate">
|
||||||
{@artist.name}
|
{@artist.name}
|
||||||
</p>
|
</p>
|
||||||
<p :if={@artist.disambiguation} class="text-sm text-gray-500 dark:text-gray-400 truncate">
|
<p :if={@artist.disambiguation} class="text-sm text-zinc-500 dark:text-zinc-400 truncate">
|
||||||
{@artist.disambiguation}
|
{@artist.disambiguation}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
@@ -147,11 +154,14 @@ defmodule MusicLibraryWeb.SearchComponents do
|
|||||||
def search_result_group(assigns) do
|
def search_result_group(assigns) do
|
||||||
~H"""
|
~H"""
|
||||||
<div class={["p-4", @class]}>
|
<div class={["p-4", @class]}>
|
||||||
<h3 class="text-sm font-medium text-gray-700 dark:text-gray-300 mb-3 uppercase tracking-wide">
|
<h3 class="text-sm font-medium text-zinc-700 dark:text-zinc-300 mb-3 uppercase tracking-wide">
|
||||||
{@title} ({@count}
|
{@title}
|
||||||
<span :if={@total_count && @total_count > @count}>
|
<span :if={@total_count && @total_count > @count}>
|
||||||
of <%= @total_count %>
|
{gettext("(%{count} of %{total})", count: @count, total: @total_count)}
|
||||||
</span>)
|
</span>
|
||||||
|
<span :if={@total_count && @total_count <= @count}>
|
||||||
|
({@count})
|
||||||
|
</span>
|
||||||
</h3>
|
</h3>
|
||||||
|
|
||||||
<div class="space-y-2">
|
<div class="space-y-2">
|
||||||
@@ -182,7 +192,7 @@ defmodule MusicLibraryWeb.SearchComponents do
|
|||||||
class="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 dark:text-blue-400 hover:text-blue-800 dark:hover:text-blue-300 transition-colors"
|
||||||
{@rest}
|
{@rest}
|
||||||
>
|
>
|
||||||
View all {@count} {@target} results →
|
{gettext("View all %{count} %{target} results →", count: @count, target: @target)}
|
||||||
</button>
|
</button>
|
||||||
"""
|
"""
|
||||||
end
|
end
|
||||||
@@ -198,24 +208,24 @@ defmodule MusicLibraryWeb.SearchComponents do
|
|||||||
|
|
||||||
def keyboard_shortcuts(assigns) do
|
def keyboard_shortcuts(assigns) do
|
||||||
~H"""
|
~H"""
|
||||||
<div class="p-4 bg-gray-50 dark:bg-gray-900 rounded-b-lg border-t border-gray-200 dark:border-gray-700">
|
<div class="p-4 bg-zinc-50 dark:bg-zinc-900 rounded-b-lg border-t border-zinc-200 dark:border-zinc-700">
|
||||||
<div class="flex items-center justify-between text-xs text-gray-500 dark:text-gray-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 class="flex items-center">
|
<div class="flex items-center">
|
||||||
<kbd class="px-2 py-1 bg-gray-200 dark:bg-gray-700 rounded">↑↓</kbd>
|
<kbd class="px-2 py-1 bg-zinc-200 dark:bg-zinc-700 rounded">↑↓</kbd>
|
||||||
<span class="ml-1">Navigate</span>
|
<span class="ml-1">{gettext("Navigate")}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<kbd class="px-2 py-1 bg-gray-200 dark:bg-gray-700 rounded">↵</kbd>
|
<kbd class="px-2 py-1 bg-zinc-200 dark:bg-zinc-700 rounded">↵</kbd>
|
||||||
<span class="ml-1">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-gray-200 dark:bg-gray-700 rounded">Esc</kbd>
|
<kbd class="px-2 py-1 bg-zinc-200 dark:bg-zinc-700 rounded">Esc</kbd>
|
||||||
<span class="ml-1">Close</span>
|
<span class="ml-1">{gettext("Close")}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div :if={@total_results > 0} class="text-gray-500 dark:text-gray-400">
|
<div :if={@total_results > 0} class="text-zinc-500 dark:text-zinc-400">
|
||||||
{@total_results} results
|
{ngettext("1 result", "%{count} results", @total_results)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -232,11 +242,10 @@ 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-gray-400 mx-auto mb-4" />
|
<.icon name="hero-magnifying-glass" class="h-12 w-12 text-zinc-400 mx-auto mb-4" />
|
||||||
<p class="text-gray-600 dark:text-gray-400">Start typing to search your records and artists</p>
|
<p class="text-sm text-zinc-500 dark:text-zinc-500 mt-2">
|
||||||
<p class="text-sm text-gray-500 dark:text-gray-500 mt-2">
|
<kbd class="px-2 py-1 bg-zinc-100 dark:bg-zinc-700 rounded text-xs">Ctrl+K</kbd>
|
||||||
Use <kbd class="px-2 py-1 bg-gray-100 dark:bg-gray-700 rounded text-xs">Ctrl+K</kbd>
|
{gettext("to open this search")}
|
||||||
to open this search
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
"""
|
"""
|
||||||
@@ -254,10 +263,9 @@ 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-gray-400 mx-auto mb-4" />
|
<.icon name="hero-face-frown" class="h-12 w-12 text-zinc-400 mx-auto mb-4" />
|
||||||
<p class="text-gray-600 dark:text-gray-400">No results found for "{@query}"</p>
|
<p class="text-zinc-600 dark:text-zinc-400">
|
||||||
<p class="text-sm text-gray-500 dark:text-gray-500 mt-2">
|
{gettext("No results found for '%{query}'", query: @query)}
|
||||||
Try a different search term or check your spelling
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
"""
|
"""
|
||||||
@@ -274,7 +282,7 @@ defmodule MusicLibraryWeb.SearchComponents do
|
|||||||
~H"""
|
~H"""
|
||||||
<div class="p-8 text-center">
|
<div class="p-8 text-center">
|
||||||
<div class="animate-spin rounded-full h-8 w-8 border-b-2 border-blue-500 mx-auto"></div>
|
<div class="animate-spin rounded-full h-8 w-8 border-b-2 border-blue-500 mx-auto"></div>
|
||||||
<p class="mt-4 text-gray-600 dark:text-gray-400">Searching...</p>
|
<p class="mt-4 text-zinc-600 dark:text-zinc-400">{gettext("Searching...")}</p>
|
||||||
</div>
|
</div>
|
||||||
"""
|
"""
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1122,3 +1122,50 @@ msgstr ""
|
|||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Enabled"
|
msgid "Enabled"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/music_library_web/components/search_components.ex
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "No results found for '%{query}'"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/music_library_web/components/search_components.ex
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Searching..."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/music_library_web/components/search_components.ex
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "View all %{count} %{target} results →"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/music_library_web/components/search_components.ex
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "(%{count} of %{total})"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/music_library_web/components/search_components.ex
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "1 result"
|
||||||
|
msgid_plural "%{count} results"
|
||||||
|
msgstr[0] ""
|
||||||
|
msgstr[1] ""
|
||||||
|
|
||||||
|
#: lib/music_library_web/components/search_components.ex
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Close"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/music_library_web/components/search_components.ex
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Navigate"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/music_library_web/components/search_components.ex
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Select"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/music_library_web/components/search_components.ex
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "to open this search"
|
||||||
|
msgstr ""
|
||||||
|
|||||||
@@ -1122,3 +1122,50 @@ msgstr ""
|
|||||||
#, elixir-autogen, elixir-format, fuzzy
|
#, elixir-autogen, elixir-format, fuzzy
|
||||||
msgid "Enabled"
|
msgid "Enabled"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/music_library_web/components/search_components.ex
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "No results found for '%{query}'"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/music_library_web/components/search_components.ex
|
||||||
|
#, elixir-autogen, elixir-format, fuzzy
|
||||||
|
msgid "Searching..."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/music_library_web/components/search_components.ex
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "View all %{count} %{target} results →"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/music_library_web/components/search_components.ex
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "(%{count} of %{total})"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/music_library_web/components/search_components.ex
|
||||||
|
#, elixir-autogen, elixir-format, fuzzy
|
||||||
|
msgid "1 result"
|
||||||
|
msgid_plural "%{count} results"
|
||||||
|
msgstr[0] ""
|
||||||
|
msgstr[1] ""
|
||||||
|
|
||||||
|
#: lib/music_library_web/components/search_components.ex
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Close"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/music_library_web/components/search_components.ex
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Navigate"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/music_library_web/components/search_components.ex
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Select"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/music_library_web/components/search_components.ex
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "to open this search"
|
||||||
|
msgstr ""
|
||||||
|
|||||||
Reference in New Issue
Block a user