diff --git a/web/src/at_record_web/photo_scan.gleam b/web/src/at_record_web/photo_scan.gleam index 007aaa0..0cf6034 100644 --- a/web/src/at_record_web/photo_scan.gleam +++ b/web/src/at_record_web/photo_scan.gleam @@ -1,11 +1,9 @@ -//// Photo-mode barcode decode: capture a still frame from the camera video -//// and decode it once, off the continuous-scan loop. Reuses the same -//// lazily-imported zxing-wasm ponyfill as ffi.mjs's live-scan fallback. +//// Photo-mode barcode decode: one still frame, decoded once via the same +//// lazily-imported zxing-wasm ponyfill as ffi.mjs's live scanner. import gleam/list import lustre/effect.{type Effect} -/// A captured still frame (a JS `Blob`), consumed by `decode_barcodes`. pub type Frame pub type DecodeError { @@ -14,14 +12,11 @@ pub type DecodeError { DecodeFailed(String) } -/// True when the live-detect loop can run here: a native BarcodeDetector, -/// or the vendored zxing-wasm ponyfill (any camera-capable browser with -/// wasm). Safe off-browser (tests): returns False. +/// Native BarcodeDetector or the wasm ponyfill; False off-browser. @external(javascript, "./photo_scan_ffi.mjs", "supportsLiveDetection") pub fn supports_live_detection() -> Bool -/// True wherever getUserMedia plus canvas capture work, a strictly broader -/// set than native BarcodeDetector. Safe off-browser (tests): returns False. +/// Broader than live detection (any getUserMedia browser); False off-browser. @external(javascript, "./photo_scan_ffi.mjs", "supportsPhotoCapture") pub fn supports_photo_capture() -> Bool @@ -52,8 +47,7 @@ fn capture_and_decode_ffi( on_error: fn(String, String) -> Nil, ) -> Nil -/// Camera preview without the live-detect loop, for photo mode: attaches a -/// stream to the `video_id` element; `on_error` fires once if it can't start. +/// Preview-only camera, no detect loop; `on_error` fires once. pub fn start_camera( video_id: String, on_error: fn(String) -> msg, @@ -67,8 +61,7 @@ pub fn stop_camera() -> Effect(msg) { effect.from(fn(_dispatch) { stop_camera_ffi() }) } -/// Maps the ffi's `(code, message)` pair to a typed error; split out so the -/// mapping is testable without a browser. +/// Split out so the error mapping is testable without a browser. pub fn decode_error_from_code(code: String, message: String) -> DecodeError { case code { "unsupported" -> Unsupported(message) @@ -77,7 +70,6 @@ pub fn decode_error_from_code(code: String, message: String) -> DecodeError { } } -/// Grab a still frame from the `video_id` element without decoding it. pub fn capture_frame( video_id: String, on_result: fn(Result(Frame, DecodeError)) -> msg, @@ -93,8 +85,7 @@ pub fn capture_frame( }) } -/// Decode a captured frame; an empty Ok list is a clean decode with no -/// barcode in the shot, not an error. +/// An empty Ok list is a clean decode with no barcode, not an error. pub fn decode_barcodes( frame: Frame, on_result: fn(Result(List(String), DecodeError)) -> msg, @@ -110,7 +101,6 @@ pub fn decode_barcodes( }) } -/// Capture and decode in one step; the shutter-button path. pub fn capture_and_decode( video_id: String, on_result: fn(Result(List(String), DecodeError)) -> msg,