diff --git a/lib/music_library/records.ex b/lib/music_library/records.ex index a677883c..393ad8e6 100644 --- a/lib/music_library/records.ex +++ b/lib/music_library/records.ex @@ -98,6 +98,18 @@ defmodule MusicLibrary.Records do def get_record!(id), do: Repo.get!(Record, id) + def get_release_status(release_id, format) do + q = + from r in fragment("records, json_each(records.release_ids)"), + where: fragment("records.format = ?", ^format) and r.value == ^release_id, + select: %{ + record_id: fragment("records.id"), + purchased_at: fragment("records.purchased_at") + } + + Repo.one(q) + end + def get_artist_records(musicbrainz_id) do q = from r in Record, diff --git a/lib/music_library_web/live/record_live/barcode_scanner_component.ex b/lib/music_library_web/live/record_live/barcode_scanner_component.ex index ac1bbe37..2a56d3a9 100644 --- a/lib/music_library_web/live/record_live/barcode_scanner_component.ex +++ b/lib/music_library_web/live/record_live/barcode_scanner_component.ex @@ -1,8 +1,8 @@ defmodule MusicLibraryWeb.RecordLive.BarcodeScannerComponent do use MusicLibraryWeb, :live_component - alias MusicLibraryWeb.RecordComponents alias MusicLibrary.Records + alias MusicLibraryWeb.RecordComponents require Logger @@ -24,37 +24,25 @@ defmodule MusicLibraryWeb.RecordLive.BarcodeScannerComponent do
- + <.camera_button camera={@camera} />
@@ -70,37 +58,62 @@ defmodule MusicLibraryWeb.RecordLive.BarcodeScannerComponent do """ end - attr :id, :string, required: true - attr :release, MusicBrainz.ReleaseSearchResult, required: true + attr :camera, :atom, required: true, values: [:pending, :allowed, :denied] - defp result(assigns) do + def camera_button(assigns) do ~H""" -
  • JS.dispatch("camera_request", to: "#barcode-scanner") + |> 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 focus:outline-none focus:ring-2 focus:ring-zinc-500 focus:ring-offset-2" > -
    -
    -

    - {@release.artists} -

    -

    - {@release.title} -

    -

    - {release_format_label(@release)} · {Records.Record.format_release(@release.date)} · {RecordComponents.type_label( - @release.release_group.type - )} -

    -
    + + {gettext("Open camera")} + + """ + end + + attr :release, MusicBrainz.ReleaseSearchResult, required: true + attr :status, :atom, required: true, values: [:collected, :wishlisted, :new] + + defp release(assigns) do + ~H""" +
    +
    +

    + {@release.artists} +

    +

    + {@release.title} +

    +

    + {release_format_label(@release)} · {Records.Record.format_release(@release.date)} · {RecordComponents.type_label( + @release.release_group.type + )} +

    -
  • + <.badge :if={@status == :new} color={:gray} text={gettext("New")} /> + <.badge :if={@status == :wishlisted} color={:yellow} text={gettext("Wishlisted")} /> + <.badge :if={@status == :collected} color={:green} text={gettext("Collected")} /> +
    """ end @@ -118,11 +131,10 @@ defmodule MusicLibraryWeb.RecordLive.BarcodeScannerComponent do def handle_event("barcode_scanned", %{"number" => number}, socket) do Logger.debug(fn -> "Scanned barcode #{number}" end) - # TODO: inform when record is already in collection socket = case MusicBrainz.search_release_by_barcode(number) do {:ok, [best_match_release | _other_releases]} -> - assign(socket, :releases, [best_match_release | socket.assigns.releases]) + assign_release_with_status(best_match_release, socket) {:ok, []} -> put_flash( @@ -146,11 +158,13 @@ defmodule MusicLibraryWeb.RecordLive.BarcodeScannerComponent do current_time = DateTime.utc_now() # TODO: error handling when a release fails to import :ok = - Enum.each(socket.assigns.releases, fn release -> - Records.import_from_musicbrainz_release(release.id, - format: MusicBrainz.ReleaseSearchResult.format(release), - purchased_at: current_time - ) + Enum.each(socket.assigns.releases, fn {status, release} -> + if status == :new do + Records.import_from_musicbrainz_release(release.id, + format: MusicBrainz.ReleaseSearchResult.format(release), + purchased_at: current_time + ) + end end) qs = %{order: :purchase} @@ -162,6 +176,24 @@ defmodule MusicLibraryWeb.RecordLive.BarcodeScannerComponent do |> push_patch(to: ~p"/collection?#{qs}")} end + defp assign_release_with_status(release, socket) do + format = MusicBrainz.ReleaseSearchResult.format(release) + + release_with_status = + case Records.get_release_status(release.id, format) do + nil -> + {:new, release} + + %{record_id: _, purchased_at: nil} -> + {:wishlisted, release} + + _collected -> + {:collected, release} + end + + assign(socket, :releases, [release_with_status | socket.assigns.releases]) + end + defp release_format_label(release) do release |> MusicBrainz.ReleaseSearchResult.format() diff --git a/priv/gettext/default.pot b/priv/gettext/default.pot index 48659ccc..a8dec8e6 100644 --- a/priv/gettext/default.pot +++ b/priv/gettext/default.pot @@ -343,11 +343,13 @@ msgstr "" msgid "Choose which format to import" msgstr "" +#: lib/music_library_web/live/record_live/barcode_scanner_component.ex:115 #: lib/music_library_web/live/stats_live/index.html.heex:141 #, elixir-autogen, elixir-format msgid "Collected" msgstr "" +#: lib/music_library_web/live/record_live/barcode_scanner_component.ex:114 #: lib/music_library_web/live/stats_live/index.html.heex:147 #, elixir-autogen, elixir-format msgid "Wishlisted" @@ -635,32 +637,37 @@ msgstr "" msgid "Scan one or more barcodes" msgstr "" -#: lib/music_library_web/live/record_live/barcode_scanner_component.ex:51 +#: lib/music_library_web/live/record_live/barcode_scanner_component.ex:89 #, elixir-autogen, elixir-format msgid "Open camera" msgstr "" -#: lib/music_library_web/live/record_live/barcode_scanner_component.ex:66 +#: lib/music_library_web/live/record_live/barcode_scanner_component.ex:54 #, elixir-autogen, elixir-format msgid "Import releases" msgstr "" -#: lib/music_library_web/live/record_live/barcode_scanner_component.ex:138 +#: lib/music_library_web/live/record_live/barcode_scanner_component.ex:150 #, elixir-autogen, elixir-format msgid "Failed to search release for barcode %{number}" msgstr "" -#: lib/music_library_web/live/record_live/barcode_scanner_component.ex:131 +#: lib/music_library_web/live/record_live/barcode_scanner_component.ex:143 #, elixir-autogen, elixir-format msgid "No release found for barcode %{number}" msgstr "" -#: lib/music_library_web/live/record_live/barcode_scanner_component.ex:63 +#: lib/music_library_web/live/record_live/barcode_scanner_component.ex:51 #, elixir-autogen, elixir-format msgid "Importing..." msgstr "" -#: lib/music_library_web/live/record_live/barcode_scanner_component.ex:161 +#: lib/music_library_web/live/record_live/barcode_scanner_component.ex:175 #, elixir-autogen, elixir-format msgid "Records imported successfully" msgstr "" + +#: lib/music_library_web/live/record_live/barcode_scanner_component.ex:113 +#, elixir-autogen, elixir-format +msgid "New" +msgstr ""