diff --git a/src/components/QrcodeReader.vue b/src/components/QrcodeReader.vue index 231dd637..b07c2af1 100644 --- a/src/components/QrcodeReader.vue +++ b/src/components/QrcodeReader.vue @@ -28,6 +28,7 @@ import * as Scanner from '../misc/scanner.js' import Camera from '../misc/camera.js' import { imageDataFromFile, imageDataFromUrl } from '../misc/image-data.js' +import { hasFired } from '../misc/promisify.js' import isBoolean from 'lodash/isBoolean' export default { @@ -160,7 +161,7 @@ export default { } }, - paused (paused) { + async paused (paused) { const video = this.$refs.video if (paused) { @@ -172,11 +173,9 @@ export default { video.play() - video.addEventListener( - 'timeupdate', - () => { this.readyAfterPause = true }, - { once: true } - ) + await hasFired(video, 'timeupdate') + + this.readyAfterPause = true } }, diff --git a/src/misc/camera.js b/src/misc/camera.js index 5eb8c2ac..7a8d628f 100644 --- a/src/misc/camera.js +++ b/src/misc/camera.js @@ -1,4 +1,5 @@ import { imageDataFromVideo } from './image-data.js' +import { hasFired } from './promisify.js' class Camera { @@ -41,11 +42,7 @@ export default async function (constraints, videoEl) { } const stream = await navigator.mediaDevices.getUserMedia(constraints) - - const streamLoadedPromise = new Promise((resolve, reject) => { - videoEl.addEventListener('loadeddata', resolve, { once: true }) - videoEl.addEventListener('error', reject, { once: true }) - }) + const streamLoaded = hasFired(videoEl, 'loadeddata', 'error') if (videoEl.srcObject !== undefined) { videoEl.srcObject = stream @@ -62,7 +59,7 @@ export default async function (constraints, videoEl) { videoEl.playsInline = true videoEl.play() // firefox does not emit `loadeddata` if video not playing - await streamLoadedPromise + await streamLoaded return new Camera(videoEl, stream) } diff --git a/src/misc/image-data.js b/src/misc/image-data.js index 30ae1498..32803f27 100644 --- a/src/misc/image-data.js +++ b/src/misc/image-data.js @@ -1,4 +1,5 @@ import { DropImageFetchError, DropImageDecodeError } from './errors.js' +import { hasFired } from './promisify.js' const canvas = document.createElement('canvas') const canvasCtx = canvas.getContext('2d') @@ -31,14 +32,11 @@ export async function imageDataFromUrl (url) { } const image = document.createElement('img') - - const imageLoadedPromise = new Promise((resolve, reject) => { - image.onload = resolve - }) + const imageLoaded = hasFired(image, 'load') image.src = url - await imageLoadedPromise + await imageLoaded return imageDataFromImage(image) } @@ -46,14 +44,11 @@ export async function imageDataFromUrl (url) { export async function imageDataFromFile (file) { if (/image.*/.test(file.type)) { const reader = new FileReader() - - const readerLoadedPromise = new Promise((resolve, reject) => { - reader.onload = event => resolve(event.target.result) - }) + const readerLoaded = hasFired(reader, 'load') reader.readAsDataURL(file) - const dataURL = await readerLoadedPromise + const dataURL = (await readerLoaded).target.result return imageDataFromUrl(dataURL) } else { diff --git a/src/misc/promisify.js b/src/misc/promisify.js new file mode 100644 index 00000000..df32497f --- /dev/null +++ b/src/misc/promisify.js @@ -0,0 +1,10 @@ + +export function hasFired (element, successEvent, errorEvent) { + return new Promise((resolve, reject) => { + element.addEventListener(successEvent, resolve, { once: true }) + + if (errorEvent !== undefined) { + element.addEventListener(errorEvent, reject, { once: true }) + } + }) +}