diff --git a/assets/js/app.js b/assets/js/app.js index 587eff60..39e2eb5b 100644 --- a/assets/js/app.js +++ b/assets/js/app.js @@ -30,7 +30,7 @@ let csrfToken = document.querySelector("meta[name='csrf-token']").getAttribute(" let liveSocket = new LiveSocket("/live", Socket, { longPollFallbackMs: 2500, params: { _csrf_token: csrfToken }, - hooks: { Hooks } + hooks: Hooks }) // Show progress bar on live navigation and form submits diff --git a/assets/js/barcode-scanner.js b/assets/js/barcode-scanner.js index 1bc674a3..d5aefe3e 100644 --- a/assets/js/barcode-scanner.js +++ b/assets/js/barcode-scanner.js @@ -19,6 +19,29 @@ const barcodeTest = async function () { export default { mounted() { - console.log(this.el); + const video = this.el; + const constraints = { + audio: false, + video: { width: 800, height: 600 }, + }; + + navigator.mediaDevices + .getUserMedia(constraints) + .then((mediaStream) => { + console.debug("Camera access allowed") + this.pushEventTo(video, "camera:allowed", {}); + console.log(mediaStream); + video.srcObject = mediaStream; + video.onloadedmetadata = () => { + video.play(); + }; + }) + .catch((err) => { + console.error(`${err.name}: ${err.message}`); + this.pushEventTo(video, "camera:denied", {}); + }); + }, + destroyed() { + this.el.srcObject.getTracks().forEach(track => track.stop()); } } diff --git a/lib/music_library_web/live/collection_live/index.ex b/lib/music_library_web/live/collection_live/index.ex index 0095765e..d76ed374 100644 --- a/lib/music_library_web/live/collection_live/index.ex +++ b/lib/music_library_web/live/collection_live/index.ex @@ -45,6 +45,20 @@ defmodule MusicLibraryWeb.CollectionLive.Index do |> assign(:record, nil) end + defp apply_action(socket, :barcode_scan, params) do + socket = + if get_in(socket.assigns, [:streams, :records]) == nil do + socket + |> apply_action(:index, params) + else + socket + end + + socket + |> assign(:page_title, gettext("Scan barcodes ยท Collection")) + |> assign(:record, nil) + end + defp apply_action(socket, :edit, params = %{"id" => id}) do socket = if get_in(socket.assigns, [:streams, :records]) == nil do diff --git a/lib/music_library_web/live/collection_live/index.html.heex b/lib/music_library_web/live/collection_live/index.html.heex index 47cfc283..438c0cd2 100644 --- a/lib/music_library_web/live/collection_live/index.html.heex +++ b/lib/music_library_web/live/collection_live/index.html.heex @@ -2,9 +2,14 @@
<.search_form query={@record_list_params.query} /> - <.link patch={~p"/collection/import"}> - <.button>{gettext("Import")} - +
@@ -93,4 +98,19 @@ /> +<.modal + :if={@live_action == :barcode_scan} + id="barcode-scanner-modal" + show + on_cancel={JS.patch(back_path(@record_list_params))} +> + <.live_component + module={MusicLibraryWeb.RecordLive.BarcodeScannerComponent} + id={:barcode_scanner} + title={@page_title} + action={@live_action} + patch={back_path(@record_list_params)} + /> + + <.pagination id={:bottom_pagination} pagination_params={@record_list_params} /> 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 new file mode 100644 index 00000000..29b7f377 --- /dev/null +++ b/lib/music_library_web/live/record_live/barcode_scanner_component.ex @@ -0,0 +1,26 @@ +defmodule MusicLibraryWeb.RecordLive.BarcodeScannerComponent do + use MusicLibraryWeb, :live_component + + require Logger + + @impl true + def render(assigns) do + ~H""" +
+

Barcode Scan

+ +
+ """ + end + + @impl true + def handle_event("camera:allowed", _params, socket) do + Logger.debug(fn -> "Camera access allowed" end) + {:noreply, assign(socket, camera: :allowed)} + end + + def handle_event("camera:denied", _params, socket) do + Logger.debug(fn -> "Camera access denied" end) + {:noreply, assign(socket, camera: :denied)} + end +end diff --git a/lib/music_library_web/router.ex b/lib/music_library_web/router.ex index 39c384c5..b078cb9e 100644 --- a/lib/music_library_web/router.ex +++ b/lib/music_library_web/router.ex @@ -39,6 +39,7 @@ defmodule MusicLibraryWeb.Router do live "/collection", CollectionLive.Index, :index live "/collection/import", CollectionLive.Index, :import + live "/collection/scan", CollectionLive.Index, :barcode_scan live "/collection/:id/edit", CollectionLive.Index, :edit live "/collection/:id", CollectionLive.Show, :show