diff --git a/lib/music_library_web/components/core_components.ex b/lib/music_library_web/components/core_components.ex index 5787ef4e..f352d8b1 100644 --- a/lib/music_library_web/components/core_components.ex +++ b/lib/music_library_web/components/core_components.ex @@ -186,6 +186,37 @@ defmodule MusicLibraryWeb.CoreComponents do "https://www.google.com/s2/favicons?domain=#{uri.host}&sz=16" end + attr :target_id, :string, required: true + attr :label, :string, required: true + + def copy_to_clipboard(assigns) do + ~H""" + + """ + end + + attr :label, :string, required: true + slot :inner_block, required: true + + def dl_row(assigns) do + ~H""" +
+
+ {@label} +
+
+ {render_slot(@inner_block)} +
+
+ """ + end + ## JS Commands def show(js \\ %JS{}, selector) do diff --git a/lib/music_library_web/components/scrobble_components.ex b/lib/music_library_web/components/scrobble_components.ex index e9ab7dd1..d11c2f3f 100644 --- a/lib/music_library_web/components/scrobble_components.ex +++ b/lib/music_library_web/components/scrobble_components.ex @@ -4,9 +4,12 @@ defmodule MusicLibraryWeb.ScrobbleComponents do """ alias LastFm.Track + alias MusicLibrary.Records use MusicLibraryWeb, :html + import MusicLibraryWeb.RecordComponents, only: [format_label: 1] + def refresh_lastfm_feed_button(assigns) do ~H""" + target_id={"tooltip-track-#{@track.scrobbled_at_uts}"} + label={gettext("Copy track MusicBrainz ID to clipboard")} + />
@@ -71,25 +60,11 @@ defmodule MusicLibraryWeb.ScrobbleComponents do {@track.album.musicbrainz_id || gettext("Unknown")} - + target_id={"tooltip-track-album-#{@track.scrobbled_at_uts}"} + label={gettext("Copy album MusicBrainz ID to clipboard")} + />
@@ -98,25 +73,11 @@ defmodule MusicLibraryWeb.ScrobbleComponents do {@track.artist.musicbrainz_id || gettext("Unknown")} - + target_id={"tooltip-track-artist-#{@track.scrobbled_at_uts}"} + label={gettext("Copy artist MusicBrainz ID to clipboard")} + />
@@ -144,25 +105,11 @@ defmodule MusicLibraryWeb.ScrobbleComponents do {@album.metadata.musicbrainz_id || gettext("Unknown")} - + target_id={"tooltip-album-#{@album.scrobbled_at_uts}"} + label={gettext("Copy album MusicBrainz ID to clipboard")} + />
@@ -171,25 +118,11 @@ defmodule MusicLibraryWeb.ScrobbleComponents do {@album.artist.musicbrainz_id || gettext("Unknown")} - + target_id={"tooltip-artist-#{@album.scrobbled_at_uts}"} + label={gettext("Copy artist MusicBrainz ID to clipboard")} + />
@@ -197,4 +130,59 @@ defmodule MusicLibraryWeb.ScrobbleComponents do """ end + + attr :musicbrainz_id, :string, required: true + attr :collected_record_id, :string, default: nil + attr :wishlisted_record_id, :string, default: nil + + def record_status_badges(assigns) do + ~H""" +
+ <.badge :if={@musicbrainz_id == ""}> + {gettext("No MB ID")} + + <.link :if={@collected_record_id} navigate={~p"/collection/#{@collected_record_id}"}> + <.badge color="success">{gettext("Collected")} + + <.link :if={@wishlisted_record_id} navigate={~p"/wishlist/#{@wishlisted_record_id}"}> + <.badge color="warning">{gettext("Wishlisted")} + +
+ """ + end + + attr :id, :string, required: true + attr :musicbrainz_id, :string, required: true + + def import_format_dropdown(assigns) do + ~H""" + <.dropdown id={@id} placement="bottom-end"> + <:toggle> + <.button variant="ghost"> + {gettext("Choose which format to import")} + <.icon + name="hero-star" + class="h-5 w-5 text-zinc-500 dark:text-zinc-400 cursor-pointer" + aria-hidden="true" + data-slot="icon" + /> + + + <.focus_wrap id={@id <> "-focus-wrap"}> + <.dropdown_link + :for={format <- Records.Record.formats()} + id={@id <> "-#{format}-import"} + phx-click={ + JS.push("import", + value: %{id: @musicbrainz_id, format: format}, + page_loading: true + ) + } + > + {format_label(format)} + + + + """ + end end diff --git a/lib/music_library_web/live/artist_live/show.html.heex b/lib/music_library_web/live/artist_live/show.html.heex index 67b949a3..d23f870c 100644 --- a/lib/music_library_web/live/artist_live/show.html.heex +++ b/lib/music_library_web/live/artist_live/show.html.heex @@ -135,18 +135,10 @@ {@artist.musicbrainz_id} - + <.copy_to_clipboard + target_id={"mb-#{@artist.musicbrainz_id}"} + label={gettext("Copy MusicBrainz ID to clipboard")} + /> <.async_result :let={lastfm_artist_info} assign={@lastfm_artist_info}> diff --git a/lib/music_library_web/live/collection_live/show.html.heex b/lib/music_library_web/live/collection_live/show.html.heex index a14b0732..437fbc8c 100644 --- a/lib/music_library_web/live/collection_live/show.html.heex +++ b/lib/music_library_web/live/collection_live/show.html.heex @@ -177,77 +177,41 @@

- <%!-- TODO: replace with OSS version --%>
-
-
- {gettext("ID")} -
-
+ <.dl_row label={gettext("ID")}> +
{@record.id} - -
-
-
-
- {gettext("Genres")} -
-
- <.link - :for={genre <- @record.genres} - class="mr-2 text-zinc-700 hover:text-zinc-500 dark:text-zinc-400 dark:hover:text-zinc-300" - patch={~p"/collection?#{%{query: ~s(genre:"#{genre}")}}"} - > - {genre} - -
-
-
-
- {gettext("MusicBrainz ID")} -
-
+ <.copy_to_clipboard + target_id={"record-#{@record.id}"} + label={gettext("Copy record ID to clipboard")} + /> +
+ + <.dl_row label={gettext("Genres")}> + <.link + :for={genre <- @record.genres} + class="mr-2 text-zinc-700 hover:text-zinc-500 dark:text-zinc-400 dark:hover:text-zinc-300" + patch={~p"/collection?#{%{query: ~s(genre:"#{genre}")}}"} + > + {genre} + + + <.dl_row label={gettext("MusicBrainz ID")}> +
{@record.musicbrainz_id} - - -
-
-
- {gettext("Purchased on")} -
-
- {Records.Record.format_as_date(@record.purchased_at)} -
-
-
-
- {gettext("Published releases")} -
-
+ <.copy_to_clipboard + target_id={"mb-#{@record.musicbrainz_id}"} + label={gettext("Copy MusicBrainz ID to clipboard")} + /> +
+ + <.dl_row label={gettext("Purchased on")}> + {Records.Record.format_as_date(@record.purchased_at)} + + <.dl_row label={gettext("Published releases")}> +
{Records.Record.release_count(@record)} <.release_list record={@record} /> - -
-
-
- {gettext("Collected release")} -
-
+
+ + <.dl_row label={gettext("Collected release")}> +
{@record.selected_release_id} - - - -
-
@record.id} + label={gettext("Copy record selected release ID to clipboard")} + /> +
+ + <.dl_row :if={Records.Record.included_release_groups_count(@record) > 0} - class="py-2 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-0" + label={gettext("Includes")} > -
- {gettext("Includes")} -
-
-
    -
  • - {included_release_group.artists} - {included_release_group.title} -
  • -
-
-
-
-
- {gettext("Inserted at")} -
-
- {Records.Record.format_as_date(@record.inserted_at)} -
-
-
-
- {gettext("Updated at")} -
-
- {Records.Record.format_as_date(@record.updated_at)} -
-
-
-
- {gettext("Last listened at")} -
-
- - {localize_scrobbled_at(@last_listened_track.scrobbled_at_uts, @timezone)} - - - {gettext("Never")} - - 0}> - {ngettext("(1 scrobble)", "(%{count} scrobbles)", @play_count)} - -
-
+ + + <.dl_row label={gettext("Inserted at")}> + {Records.Record.format_as_date(@record.inserted_at)} + + <.dl_row label={gettext("Updated at")}> + {Records.Record.format_as_date(@record.updated_at)} + + <.dl_row label={gettext("Last listened at")}> + + {localize_scrobbled_at(@last_listened_track.scrobbled_at_uts, @timezone)} + + + {gettext("Never")} + + 0}> + {ngettext("(1 scrobble)", "(%{count} scrobbles)", @play_count)} + + diff --git a/lib/music_library_web/live/scrobbled_tracks_live/index.ex b/lib/music_library_web/live/scrobbled_tracks_live/index.ex index 8a41b522..7ab31a33 100644 --- a/lib/music_library_web/live/scrobbled_tracks_live/index.ex +++ b/lib/music_library_web/live/scrobbled_tracks_live/index.ex @@ -2,12 +2,11 @@ defmodule MusicLibraryWeb.ScrobbledTracksLive.Index do use MusicLibraryWeb, :live_view import MusicLibraryWeb.Components.Pagination - import MusicLibraryWeb.RecordComponents, only: [format_label: 1] import MusicLibraryWeb.ScrobbleComponents alias LastFm.Track alias MusicLibrary.Assets.Transform - alias MusicLibrary.{Records, ScrobbleActivity} + alias MusicLibrary.ScrobbleActivity @default_tracks_list_params %{ query: "", diff --git a/lib/music_library_web/live/scrobbled_tracks_live/index.html.heex b/lib/music_library_web/live/scrobbled_tracks_live/index.html.heex index 6deeec0e..a2ad6fa8 100644 --- a/lib/music_library_web/live/scrobbled_tracks_live/index.html.heex +++ b/lib/music_library_web/live/scrobbled_tracks_live/index.html.heex @@ -120,56 +120,20 @@
-
- <.badge :if={track.album.musicbrainz_id == ""}> - {gettext("No MB ID")} - - <.link - :if={collected_record_id} - navigate={~p"/collection/#{collected_record_id}"} - > - <.badge color="success">{gettext("Collected")} - - <.link - :if={wishlisted_record_id} - navigate={~p"/wishlist/#{wishlisted_record_id}"} - > - <.badge color="warning">{gettext("Wishlisted")} - -
+ <.record_status_badges + musicbrainz_id={track.album.musicbrainz_id} + collected_record_id={collected_record_id} + wishlisted_record_id={wishlisted_record_id} + /> - <.dropdown + <.import_format_dropdown :if={ track.album.musicbrainz_id !== "" and !collected_record_id and !wishlisted_record_id } id={"actions-#{track.scrobbled_at_uts}-tracks"} - placement="bottom-end" - > - <:toggle> - {gettext("Choose which format to import")} - <.icon - name="hero-star" - class="-mt-1 h-5 w-5 text-zinc-500 dark:text-zinc-400 cursor-pointer" - aria-hidden="true" - data-slot="icon" - /> - - <.focus_wrap id={"actions-#{track.scrobbled_at_uts}-tracks-focus-wrap"}> - <.dropdown_link - :for={format <- Records.Record.formats()} - id={"actions-#{track.scrobbled_at_uts}-#{format}-import"} - phx-click={ - JS.push("import", - value: %{id: track.album.musicbrainz_id, format: format}, - page_loading: true - ) - } - > - {format_label(format)} - - - + musicbrainz_id={track.album.musicbrainz_id} + /> <.dropdown id={"actions-#{track.scrobbled_at_uts}"} placement="bottom-end"> <:toggle> <.button variant="ghost"> diff --git a/lib/music_library_web/live/stats_live/index.html.heex b/lib/music_library_web/live/stats_live/index.html.heex index 214c4715..e09e6857 100644 --- a/lib/music_library_web/live/stats_live/index.html.heex +++ b/lib/music_library_web/live/stats_live/index.html.heex @@ -139,62 +139,20 @@
-
- <.badge :if={album.metadata.musicbrainz_id == ""}> - {gettext("No MB ID")} - - <.link - :if={collected_record_id} - navigate={~p"/collection/#{collected_record_id}"} - > - <.badge color="success"> - {gettext("Collected")} - - - <.link - :if={wishlisted_record_id} - navigate={~p"/wishlist/#{wishlisted_record_id}"} - > - <.badge color="warning"> - {gettext("Wishlisted")} - - -
+ <.record_status_badges + musicbrainz_id={album.metadata.musicbrainz_id} + collected_record_id={collected_record_id} + wishlisted_record_id={wishlisted_record_id} + /> - <.dropdown + <.import_format_dropdown :if={ album.metadata.musicbrainz_id !== "" and !collected_record_id and !wishlisted_record_id } id={"actions-#{album.scrobbled_at_uts}-albums"} - placement="bottom-end" - > - <:toggle> - <.button variant="ghost"> - {gettext("Choose which format to import")} - <.icon - name="hero-star" - class="h-5 w-5 text-zinc-500 dark:text-zinc-400 cursor-pointer" - aria-hidden="true" - data-slot="icon" - /> - - - <.focus_wrap id={"actions-#{album.scrobbled_at_uts}-albums-focus-wrap"}> - <.dropdown_link - :for={format <- Records.Record.formats()} - id={"actions-#{album.scrobbled_at_uts}-#{format}-import"} - phx-click={ - JS.push("import", - value: %{id: album.metadata.musicbrainz_id, format: format}, - page_loading: true - ) - } - > - {format_label(format)} - - - + musicbrainz_id={album.metadata.musicbrainz_id} + /> @@ -264,58 +222,20 @@ -
- <.badge :if={track.album.musicbrainz_id == ""}> - {gettext("No MB ID")} - - <.link - :if={collected_record_id} - navigate={~p"/collection/#{collected_record_id}"} - > - <.badge color="success">{gettext("Collected")} - - <.link - :if={wishlisted_record_id} - navigate={~p"/wishlist/#{wishlisted_record_id}"} - > - <.badge color="warning">{gettext("Wishlisted")} - -
+ <.record_status_badges + musicbrainz_id={track.album.musicbrainz_id} + collected_record_id={collected_record_id} + wishlisted_record_id={wishlisted_record_id} + /> - <.dropdown + <.import_format_dropdown :if={ track.album.musicbrainz_id !== "" and !collected_record_id and !wishlisted_record_id } id={"actions-#{track.scrobbled_at_uts}-tracks"} - placement="bottom-end" - > - <:toggle> - <.button variant="ghost"> - {gettext("Choose which format to import")} - <.icon - name="hero-star" - class="h-5 w-5 text-zinc-500 dark:text-zinc-400 cursor-pointer" - aria-hidden="true" - data-slot="icon" - /> - - - <.focus_wrap id={"actions-#{track.scrobbled_at_uts}-tracks-focus-wrap"}> - <.dropdown_link - :for={format <- Records.Record.formats()} - id={"actions-#{track.scrobbled_at_uts}-#{format}-import"} - phx-click={ - JS.push("import", - value: %{id: track.album.musicbrainz_id, format: format}, - page_loading: true - ) - } - > - {format_label(format)} - - - + musicbrainz_id={track.album.musicbrainz_id} + /> diff --git a/lib/music_library_web/live/wishlist_live/show.html.heex b/lib/music_library_web/live/wishlist_live/show.html.heex index 64006257..b8c11507 100644 --- a/lib/music_library_web/live/wishlist_live/show.html.heex +++ b/lib/music_library_web/live/wishlist_live/show.html.heex @@ -153,69 +153,38 @@
- <%!-- TODO: replace with OSS version --%>
-
-
- {gettext("ID")} -
-
+ <.dl_row label={gettext("ID")}> +
{@record.id} - -
-
-
-
- {gettext("Genres")} -
-
- <.link - :for={genre <- @record.genres} - class="mr-2 text-zinc-700 hover:text-zinc-500 dark:text-zinc-400 dark:hover:text-zinc-300" - patch={~p"/wishlist?#{%{query: ~s(genre:"#{genre}")}}"} - > - {genre} - -
-
-
-
- {gettext("MusicBrainz ID")} -
-
+ <.copy_to_clipboard + target_id={"record-#{@record.id}"} + label={gettext("Copy record ID to clipboard")} + /> +
+ + <.dl_row label={gettext("Genres")}> + <.link + :for={genre <- @record.genres} + class="mr-2 text-zinc-700 hover:text-zinc-500 dark:text-zinc-400 dark:hover:text-zinc-300" + patch={~p"/wishlist?#{%{query: ~s(genre:"#{genre}")}}"} + > + {genre} + + + <.dl_row label={gettext("MusicBrainz ID")}> +
{@record.musicbrainz_id} - - -
-
-
- {gettext("Published releases")} -
-
+ <.copy_to_clipboard + target_id={"mb-#{@record.musicbrainz_id}"} + label={gettext("Copy MusicBrainz ID to clipboard")} + /> +
+ + <.dl_row label={gettext("Published releases")}> +
{Records.Record.release_count(@record)} <.release_list record={@record} /> - -
-
-
- {gettext("Wishlisted release")} -
-
+
+ + <.dl_row label={gettext("Wishlisted release")}> +
{gettext("No release selected")} - <.release_summary :if={@record.selected_release_id} release={Records.Record.selected_release(@record)} /> - -
-
+ + <.dl_row :if={Records.Record.included_release_groups_count(@record) > 0} - class="py-2 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-0" + label={gettext("Includes")} > -
- {gettext("Includes")} -
-
-
    -
  • - {included_release_group.artists} - {included_release_group.title} -
  • -
-
-
-
-
- {gettext("Inserted at")} -
-
- {Records.Record.format_as_date(@record.inserted_at)} -
-
-
-
- {gettext("Updated at")} -
-
- {Records.Record.format_as_date(@record.updated_at)} -
-
+ + + <.dl_row label={gettext("Inserted at")}> + {Records.Record.format_as_date(@record.inserted_at)} + + <.dl_row label={gettext("Updated at")}> + {Records.Record.format_as_date(@record.updated_at)} +
diff --git a/priv/gettext/default.pot b/priv/gettext/default.pot index 27a72e58..67daf110 100644 --- a/priv/gettext/default.pot +++ b/priv/gettext/default.pot @@ -267,24 +267,21 @@ msgid "Scrobble activity" msgstr "" #: lib/music_library_web/components/add_record.ex -#: lib/music_library_web/live/scrobbled_tracks_live/index.html.heex -#: lib/music_library_web/live/stats_live/index.html.heex +#: lib/music_library_web/components/scrobble_components.ex #, elixir-autogen, elixir-format msgid "Choose which format to import" msgstr "" #: lib/music_library_web/components/barcode_scanner.ex +#: lib/music_library_web/components/scrobble_components.ex #: lib/music_library_web/live/record_set_live/record_picker.ex -#: lib/music_library_web/live/scrobbled_tracks_live/index.html.heex -#: lib/music_library_web/live/stats_live/index.html.heex #, elixir-autogen, elixir-format msgid "Collected" msgstr "" #: lib/music_library_web/components/barcode_scanner.ex +#: lib/music_library_web/components/scrobble_components.ex #: lib/music_library_web/live/record_set_live/record_picker.ex -#: lib/music_library_web/live/scrobbled_tracks_live/index.html.heex -#: lib/music_library_web/live/stats_live/index.html.heex #, elixir-autogen, elixir-format msgid "Wishlisted" msgstr "" @@ -328,8 +325,7 @@ msgstr "" msgid "Error refreshing cover" msgstr "" -#: lib/music_library_web/live/scrobbled_tracks_live/index.html.heex -#: lib/music_library_web/live/stats_live/index.html.heex +#: lib/music_library_web/components/scrobble_components.ex #, elixir-autogen, elixir-format msgid "No MB ID" msgstr "" diff --git a/priv/gettext/en/LC_MESSAGES/default.po b/priv/gettext/en/LC_MESSAGES/default.po index 8f552c7d..f9d627d8 100644 --- a/priv/gettext/en/LC_MESSAGES/default.po +++ b/priv/gettext/en/LC_MESSAGES/default.po @@ -267,24 +267,21 @@ msgid "Scrobble activity" msgstr "" #: lib/music_library_web/components/add_record.ex -#: lib/music_library_web/live/scrobbled_tracks_live/index.html.heex -#: lib/music_library_web/live/stats_live/index.html.heex +#: lib/music_library_web/components/scrobble_components.ex #, elixir-autogen, elixir-format msgid "Choose which format to import" msgstr "" #: lib/music_library_web/components/barcode_scanner.ex +#: lib/music_library_web/components/scrobble_components.ex #: lib/music_library_web/live/record_set_live/record_picker.ex -#: lib/music_library_web/live/scrobbled_tracks_live/index.html.heex -#: lib/music_library_web/live/stats_live/index.html.heex #, elixir-autogen, elixir-format msgid "Collected" msgstr "" #: lib/music_library_web/components/barcode_scanner.ex +#: lib/music_library_web/components/scrobble_components.ex #: lib/music_library_web/live/record_set_live/record_picker.ex -#: lib/music_library_web/live/scrobbled_tracks_live/index.html.heex -#: lib/music_library_web/live/stats_live/index.html.heex #, elixir-autogen, elixir-format msgid "Wishlisted" msgstr "" @@ -328,8 +325,7 @@ msgstr "" msgid "Error refreshing cover" msgstr "" -#: lib/music_library_web/live/scrobbled_tracks_live/index.html.heex -#: lib/music_library_web/live/stats_live/index.html.heex +#: lib/music_library_web/components/scrobble_components.ex #, elixir-autogen, elixir-format msgid "No MB ID" msgstr ""