Skip to content

Commit 1e72747

Browse files
committed
feat(ui): camera permission & navigator check
Signed-off-by: Neko Ayaka <[email protected]>
1 parent ed0c55d commit 1e72747

File tree

1 file changed

+32
-1
lines changed

1 file changed

+32
-1
lines changed

app/components/Scan.vue

+32-1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ const props = withDefaults(defineProps<{
1515
})
1616
1717
enum CameraSignalStatus {
18+
NotGranted,
19+
NotSupported,
1820
Waiting,
1921
Ready,
2022
}
@@ -102,6 +104,11 @@ function disconnectCamera() {
102104
103105
async function connectCamera() {
104106
try {
107+
if (!(navigator && 'mediaDevices' in navigator && 'getUserMedia' in navigator.mediaDevices && typeof navigator.mediaDevices.getUserMedia === 'function')) {
108+
cameraSignalStatus.value = CameraSignalStatus.NotSupported
109+
return
110+
}
111+
105112
cameraSignalStatus.value = CameraSignalStatus.Waiting
106113
107114
stream = await navigator.mediaDevices.getUserMedia({
@@ -117,6 +124,11 @@ async function connectCamera() {
117124
video.value!.play()
118125
}
119126
catch (e) {
127+
if ((e as Error).name === 'NotAllowedError' || (e as Error).name === 'NotFoundError') {
128+
cameraSignalStatus.value = CameraSignalStatus.NotGranted
129+
return
130+
}
131+
120132
error.value = e
121133
}
122134
}
@@ -169,6 +181,11 @@ function pluse(index: number) {
169181
}
170182
171183
async function scanFrame() {
184+
if (cameraSignalStatus.value === CameraSignalStatus.NotGranted
185+
|| cameraSignalStatus.value === CameraSignalStatus.NotSupported) {
186+
return
187+
}
188+
172189
shutterCount.value += 1
173190
const canvas = document.createElement('canvas')
174191
canvas.width = video.value!.videoWidth
@@ -339,11 +356,25 @@ function now() {
339356
</div>
340357
<div
341358
v-if="cameraSignalStatus === CameraSignalStatus.Waiting"
342-
top="50%" left="[calc(50%-4.5ch)]" text="neutral-500" absolute flex flex-col items-center gap-2 font-mono
359+
top="50%" left="50%" translate-x="[-50%]" text="neutral-500" absolute flex flex-col items-center gap-2 font-mono
343360
>
344361
<div i-carbon:circle-dash animate-spin animate-duration-5000 text-3xl />
345362
<p>No Signal</p>
346363
</div>
364+
<div
365+
v-else-if="cameraSignalStatus === CameraSignalStatus.NotGranted"
366+
top="50%" left="50%" translate-x="[-50%]" text="neutral-500" absolute flex flex-col items-center gap-2 font-mono
367+
>
368+
<div i-carbon:error-outline text-3xl />
369+
<p>Not Granted</p>
370+
</div>
371+
<div
372+
v-else-if="cameraSignalStatus === CameraSignalStatus.NotSupported"
373+
top="50%" left="50%" translate-x="[-50%]" text="neutral-500" absolute flex flex-col items-center gap-2 font-mono
374+
>
375+
<div i-carbon:circle-dash text-3xl />
376+
<p>Not Supported</p>
377+
</div>
347378
<p absolute right-1 top-1 border="~ gray:50 rounded-md" bg-black:75 px2 py1 text-white font-mono shadow>
348379
{{ fps.toFixed(0) }} hz | {{ currentValidBytesSpeedFormatted }} <span text-neutral-400>({{ currentBytesFormatted }})</span>
349380
</p>

0 commit comments

Comments
 (0)