<template> <div class="modal is-active"> <div class="modal-background"></div> <div class="modal-content"> <section class="section"> <div class="columns is-centered"> <div class="column is-three-quarters"> <div class="modal-slot box has-text-centered is-shadowless"> <div v-if="errorText"> <p class="block is-size-5">{{ $t('twofaccounts.stream.live_scan_cant_start') }}</p> <p class="block" :class="{'has-text-light': $root.showDarkMode}">{{ $t('twofaccounts.stream.' + errorText + '.reason') }}</p> <p class="is-size-7">{{ $t('twofaccounts.stream.' + errorText + '.solution') }}</p> </div> <span v-else class="is-size-4" :class="$root.showDarkMode ? 'has-text-light':'has-text-grey-dark'"> <font-awesome-icon :icon="['fas', 'spinner']" size="2x" spin /> </span> </div> </div> </div> </section> </div> <div class="fullscreen-streamer"> <qrcode-stream @decode="submitUri" @init="onStreamerInit" camera="auto" /> </div> <div class="fullscreen-footer"> <!-- Cancel button --> <button class="button is-large is-warning is-rounded" @click="exitStream()"> {{ $t('commons.cancel') }} </button> </div> </div> </template> <script> import { QrcodeStream } from 'vue-qrcode-reader' import Form from './../components/Form' export default { data(){ return { showStream: true, errorText: '', form: new Form({ qrcode: null, uri: '', }), } }, components: { QrcodeStream, }, methods: { exitStream() { this.camera = 'off' this.$router.go(-1) }, async onStreamerInit (promise) { try { await promise } catch (error) { if (error.name === 'NotAllowedError') { this.errorText = 'need_grant_permission' } else if (error.name === 'NotReadableError') { this.errorText = 'not_readable' } else if (error.name === 'NotFoundError') { this.errorText = 'no_cam_on_device' } else if (error.name === 'NotSupportedError' || error.name === 'InsecureContextError') { this.errorText = 'secured_context_required' } else if (error.name === 'OverconstrainedError') { this.errorText = 'camera_not_suitable' } else if (error.name === 'StreamApiNotSupportedError') { this.errorText = 'stream_api_not_supported' } } }, /** * Push a decoded URI to the Create or Import form * * The basicQRcodeReader option is Off, so qrcode decoding has already be done by vue-qrcode-reader, whether * from livescan or file input. * We simply check the uri validity to prevent useless push to the form, but the form will check uri validity too. */ async submitUri(event) { this.form.uri = event if( !this.form.uri ) { this.$notify({type: 'is-warning', text: this.$t('errors.qrcode_cannot_be_read') }) } else if( this.form.uri.slice(0, 33).toLowerCase() == "otpauth-migration://offline?data=" ) { this.pushUriToImportForm(this.form.uri) } else if( this.form.uri.slice(0, 15).toLowerCase() !== "otpauth://totp/" && this.form.uri.slice(0, 15).toLowerCase() !== "otpauth://hotp/" ) { this.$notify({type: 'is-warning', text: this.$t('errors.no_valid_otp') }) } else { this.pushUriToCreateForm(this.form.uri) } }, pushUriToCreateForm(data) { this.$router.push({ name: 'createAccount', params: { decodedUri: data } }); }, pushUriToImportForm(data) { this.$router.push({ name: 'importAccounts', params: { migrationUri: data } }); } } } </script>