mirror of
https://github.com/tauri-apps/plugins-workspace.git
synced 2026-05-25 13:17:47 +02:00
feat: add barcode scanner plugin (#536)
This commit is contained in:
committed by
GitHub
parent
eccd6f977a
commit
454428cd50
@@ -17,6 +17,7 @@
|
||||
import Updater from "./views/Updater.svelte";
|
||||
import Clipboard from "./views/Clipboard.svelte";
|
||||
import WebRTC from "./views/WebRTC.svelte";
|
||||
import Scanner from "./views/Scanner.svelte";
|
||||
import App from "./views/App.svelte";
|
||||
|
||||
import { onMount } from "svelte";
|
||||
@@ -113,6 +114,11 @@
|
||||
component: WebRTC,
|
||||
icon: "i-ph-broadcast",
|
||||
},
|
||||
isMobile && {
|
||||
label: "Scanner",
|
||||
component: Scanner,
|
||||
icon: "i-ph-scan",
|
||||
},
|
||||
];
|
||||
|
||||
let selected = views[0];
|
||||
@@ -444,6 +450,7 @@
|
||||
</aside>
|
||||
<main
|
||||
class="flex-1 bg-primary dark:bg-darkPrimary transition-transform transition-colors-250 grid grid-rows-[2fr_auto]"
|
||||
class:transparent={isMobile}
|
||||
>
|
||||
<div class="px-5 overflow-hidden grid grid-rows-[auto_1fr]">
|
||||
<h1>{selected.label}</h1>
|
||||
|
||||
@@ -55,3 +55,7 @@ body {
|
||||
#console {
|
||||
padding-bottom: calc(env(safe-area-inset-bottom) + 24px);
|
||||
}
|
||||
|
||||
.transparent {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,155 @@
|
||||
<script>
|
||||
import { scan, checkPermissions, requestPermissions, Format, cancel } from "@tauri-apps/plugin-barcode-scanner";
|
||||
|
||||
export let onMessage;
|
||||
|
||||
let scanning = false;
|
||||
let windowed = true;
|
||||
let formats = [Format.QRCode];
|
||||
const supportedFormats = [Format.QRCode, Format.EAN13];
|
||||
|
||||
async function startScan() {
|
||||
let permission = await checkPermissions();
|
||||
if (permission === 'prompt') {
|
||||
permission = await requestPermissions();
|
||||
}
|
||||
if (permission === 'granted') {
|
||||
scanning = true;
|
||||
scan({ windowed, formats })
|
||||
.then((res) => {
|
||||
scanning = false;
|
||||
onMessage(res);
|
||||
})
|
||||
.catch((error) => {
|
||||
scanning = false;
|
||||
onMessage(error);
|
||||
});
|
||||
} else {
|
||||
onMessage('Permission denied')
|
||||
}
|
||||
}
|
||||
|
||||
async function cancelScan() {
|
||||
await cancel();
|
||||
scanning = false;
|
||||
onMessage("cancelled");
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="full-height">
|
||||
<div class:invisible={scanning}>
|
||||
<div>
|
||||
<input type="checkbox" id="scanner-windowed" bind:checked={windowed} />
|
||||
<label for="scanner-windowed">Windowed</label>
|
||||
</div>
|
||||
<div>
|
||||
<select class="input" id="format" multiple bind:value={formats}>
|
||||
{#each supportedFormats as f}
|
||||
<option value={f}>{f}</option>
|
||||
{/each}
|
||||
</select>
|
||||
</div>
|
||||
<button class="btn" type="button" on:click={startScan}>Scan</button>
|
||||
</div>
|
||||
<div class="scanning full-height" class:invisible={!scanning}>
|
||||
<div class="scanner-background">
|
||||
<!-- this background simulates the camera view -->
|
||||
</div>
|
||||
<div class="container full-height">
|
||||
<div class="barcode-scanner--area--container">
|
||||
<div class="relative">
|
||||
<p>Aim your camera at a QR code</p>
|
||||
<button class="btn" type="button" on:click={cancelScan}>Cancel</button>
|
||||
</div>
|
||||
<div class="square surround-cover">
|
||||
<div class="barcode-scanner--area--outer surround-cover">
|
||||
<div class="barcode-scanner--area--inner" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.invisible {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.full-height {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
p {
|
||||
color: #fff;
|
||||
font-family: sans-serif;
|
||||
text-align: center;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
.container {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.relative {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.square {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
transition: 0.3s;
|
||||
}
|
||||
.square:after {
|
||||
content: "";
|
||||
top: 0;
|
||||
display: block;
|
||||
padding-bottom: 100%;
|
||||
}
|
||||
.square > div {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.surround-cover {
|
||||
box-shadow: 0 0 0 99999px rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
.barcode-scanner--area--container {
|
||||
width: 80%;
|
||||
max-width: min(500px, 80vh);
|
||||
margin: auto;
|
||||
}
|
||||
.barcode-scanner--area--outer {
|
||||
display: flex;
|
||||
border-radius: 1em;
|
||||
}
|
||||
.barcode-scanner--area--inner {
|
||||
width: 100%;
|
||||
margin: 1rem;
|
||||
border: 2px solid #fff;
|
||||
box-shadow: 0px 0px 2px 1px rgb(0 0 0 / 0.5),
|
||||
inset 0px 0px 2px 1px rgb(0 0 0 / 0.5);
|
||||
border-radius: 1rem;
|
||||
}
|
||||
|
||||
.scanner-background {
|
||||
background: linear-gradient(45deg, #673ab7, transparent);
|
||||
background-position: 45% 50%;
|
||||
background-size: cover;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user