aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2025-03-27 15:42:07 -0700
committerAdam Soltys <[email protected]>2025-03-27 15:42:07 -0700
commit877a07bb37af52d360cec6148c41dc98393c2dd8 (patch)
treed2ea4441a2df4eb504fdee947c247890cc05dba4 /src
parent30cc3ff1acec4deecd88e4ee446203fc1ce95590 (diff)
downloadcoinos-ui-877a07bb37af52d360cec6148c41dc98393c2dd8.tar.gz
coinos-ui-877a07bb37af52d360cec6148c41dc98393c2dd8.zip
revert scanner
Diffstat (limited to 'src')
-rw-r--r--src/routes/(app)/scan/+page.svelte205
1 files changed, 31 insertions, 174 deletions
diff --git a/src/routes/(app)/scan/+page.svelte b/src/routes/(app)/scan/+page.svelte
index 874fef96..b21a7458 100644
--- a/src/routes/(app)/scan/+page.svelte
+++ b/src/routes/(app)/scan/+page.svelte
@@ -1,204 +1,61 @@
<script>
+ import { tick } from "svelte";
+ import Icon from "$comp/Icon.svelte";
+ import QrScanner from "qr-scanner";
+ import { onMount, onDestroy } from "svelte";
import { back } from "$lib/utils";
import { goto } from "$app/navigation";
- import { onMount, onDestroy } from "svelte";
import { BarcodeDetector } from "barcode-detector/ponyfill";
- import { camera } from "$lib/store";
- let resizing = $state();
+ let scanner,
+ vid = $state(),
+ resizing;
+
let resize = () => {
if (resizing) clearTimeout(resizing);
resizing = setTimeout(initialize, 1000);
};
- let videoEl = $state();
- let canvasEl = $state();
- let cameras = $state([]);
- let isIOS = $state();
- let scanningStarted = $state();
-
- let barcodeDetector;
- let scanningFrameId;
- let detectionResult = null;
-
- async function getCameraDevices() {
- try {
- const devices = await navigator.mediaDevices.enumerateDevices();
- cameras = devices.filter((device) => device.kind === "videoinput");
-
- if (!$camera && cameras.length > 0) {
- $camera = cameras[0].deviceId;
- }
- } catch (err) {
- console.error("Error enumerating devices:", err);
- }
- }
-
- async function startCamera(deviceId) {
- stopCameraStream();
- detectionResult = null;
- try {
- const constraints = deviceId
- ? { video: { deviceId: { exact: deviceId } } }
- : { video: { facingMode: "environment" } };
- const stream = await navigator.mediaDevices.getUserMedia(constraints);
- videoEl.srcObject = stream;
- await videoEl.play();
- } catch (err) {
- console.error("Error accessing camera:", err);
- }
- }
-
- function stopCameraStream() {
- if (videoEl && videoEl.srcObject) {
- const stream = videoEl.srcObject;
- if (stream.getTracks) {
- stream.getTracks().forEach((track) => track.stop());
- }
- }
- if (scanningFrameId) {
- cancelAnimationFrame(scanningFrameId);
- }
- }
-
- function handleDetection(barcode) {
- detectionResult = barcode.rawValue;
- stopCameraStream();
- goto(`/send/${encodeURIComponent(detectionResult)}`);
- }
-
- function scanLoop() {
- if (!videoEl.videoWidth || !videoEl.videoHeight) {
- scanningFrameId = requestAnimationFrame(scanLoop);
- return;
- }
-
- const context = canvasEl.getContext("2d");
- if (!context) return;
-
- canvasEl.width = videoEl.videoWidth;
- canvasEl.height = videoEl.videoHeight;
- context.drawImage(videoEl, 0, 0, canvasEl.width, canvasEl.height);
-
- barcodeDetector
- .detect(canvasEl)
- .then((barcodes) => {
- if (barcodes.length > 0) {
- handleDetection(barcodes[0]);
- return;
- }
- })
- .catch((err) => {
- console.error("Detection error:", err);
- });
-
- if (!detectionResult) {
- scanningFrameId = requestAnimationFrame(scanLoop);
+ let initialize = async () => {
+ if (scanner) {
+ scanner.stop();
+ await new Promise((r) => setTimeout(r, 1000));
}
- }
-
- async function onCameraChange(event) {
- $camera = event.target.value;
- await startCamera($camera);
- videoEl.addEventListener("loadeddata", () => {
- canvasEl.width = videoEl.videoWidth;
- canvasEl.height = videoEl.videoHeight;
- scanLoop();
- });
- }
-
- async function restart() {
- detectionResult = null;
- await startCamera($camera);
- videoEl.addEventListener("loadeddata", () => {
- canvasEl.width = videoEl.videoWidth;
- canvasEl.height = videoEl.videoHeight;
- scanLoop();
- });
- }
-
- function startScanning() {
- scanningStarted = true;
- stopCameraStream();
- detectionResult = null;
- const constraints = $camera
- ? { video: { deviceId: { ideal: $camera } } }
- : { video: { facingMode: "environment" } };
- navigator.mediaDevices
- .getUserMedia(constraints)
- .then((stream) => {
- videoEl.srcObject = stream;
- return videoEl.play();
- })
- .then(() => {
- canvasEl.width = videoEl.videoWidth;
- canvasEl.height = videoEl.videoHeight;
- scanLoop();
- })
- .catch((err) => {
- console.error("Error accessing camera:", err);
- });
- }
- let initialize = async () => {
- isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent);
- barcodeDetector = new BarcodeDetector({ formats: ["qr_code"] });
- await getCameraDevices();
- if (!isIOS) startScanning();
+ let options = {
+ highlightScanRegion: true,
+ highlightCodeOutline: true,
+ qrEngine: BarcodeDetector,
+ };
+ let cb = ({ data }) =>
+ scanner.stop() || goto(`/send/${encodeURIComponent(data)}`);
+ scanner = new QrScanner(vid, cb, options);
+ await tick();
+ scanner.start();
};
onMount(initialize);
-
- onDestroy(() => {
- stopCameraStream();
- });
+ onDestroy(() => scanner?.stop());
</script>
<svelte:window onresize={resize} />
+
<div class="flex w-full mb-4 p-4">
- <div class="mx-auto rounded-3xl space-y-5">
+ <div class="mx-auto rounded-3xl">
<video
- bind:this={videoEl}
+ bind:this={vid}
class="border-4 rounded-3xl border-black max-h-[calc(100vh*0.7)]"
></video>
- <canvas bind:this={canvasEl} style="display: none;"></canvas>
- <div class="flex justify-center">
- <button class="btn !w-auto" onclick={back}>Cancel</button>
- </div>
-
- {#if cameras.length > 1}
- <div>
- <select
- id="cameraSelect"
- bind:value={$camera}
- onchange={onCameraChange}
- >
- {#each cameras as camera}
- <option value={camera.deviceId}>
- {camera.label || `Camera ${camera.deviceId}`}
- </option>
- {/each}
- </select>
- </div>
- {/if}
-
- {#if !scanningStarted}
- <div class="flex justify-center">
- <button class="btn !w-auto" onclick={startScanning}>
- Start Scanning
- </button>
- </div>
- {/if}
</div>
</div>
+<div class="flex justify-center">
+ <button class="btn !w-auto" onclick={back}>Cancel</button>
+</div>
+
<style>
video {
- width: 100%;
- max-width: 600px;
- border: 4px solid black;
- border-radius: 1rem;
- transform: scale(1);
transition: transform 0.3s ease-out;
+ transform: scale(1);
}
</style>