Compare commits

...

2 commits

Author SHA1 Message Date
Rodolphe Bréard
954eaad446 Put the QR code scanner in a modal 2023-09-26 14:14:50 +02:00
Rodolphe Bréard
9bad471bf3 Fix error message reset 2023-09-26 14:12:52 +02:00
3 changed files with 35 additions and 6 deletions

View file

@ -32,6 +32,7 @@
"domainName": "Domain name", "domainName": "Domain name",
"privateKey": "Private key", "privateKey": "Private key",
"scan": "Scan", "scan": "Scan",
"scanTitle": "Scan a QR code",
"addAccount": "Add account", "addAccount": "Add account",
"cancel": "@:invariants.controls.cancel", "cancel": "@:invariants.controls.cancel",
"error": { "error": {

View file

@ -32,6 +32,7 @@
"domainName": "Nom de domaine", "domainName": "Nom de domaine",
"privateKey": "Clé privée", "privateKey": "Clé privée",
"scan": "Scanner", "scan": "Scanner",
"scanTitle": "Scanner un QR code",
"addAccount": "Ajouter", "addAccount": "Ajouter",
"cancel": "@:invariants.controls.cancel", "cancel": "@:invariants.controls.cancel",
"error": { "error": {

View file

@ -1,9 +1,10 @@
<script setup> <script setup>
import { ref, computed } from 'vue'; import { ref, reactive, computed, onMounted } from 'vue';
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
import { useStorage } from '@vueuse/core'; import { useStorage } from '@vueuse/core';
import { QrcodeStream, setZXingModuleOverrides } from 'vue-qrcode-reader'; import { QrcodeStream, setZXingModuleOverrides } from 'vue-qrcode-reader';
import { sha256 } from '@noble/hashes/sha256'; import { sha256 } from '@noble/hashes/sha256';
import { Modal } from 'bootstrap';
import base32Encode from 'base32-encode'; import base32Encode from 'base32-encode';
import ButtonGroupComponent from '../components/ButtonGroupComponent.vue'; import ButtonGroupComponent from '../components/ButtonGroupComponent.vue';
import LayoutComponent from '../components/LayoutComponent.vue'; import LayoutComponent from '../components/LayoutComponent.vue';
@ -16,6 +17,9 @@ const separator = ref('+');
const domainName = ref(''); const domainName = ref('');
const privateKey = ref(''); const privateKey = ref('');
const authorizedKeyLengths = [16, 32]; const authorizedKeyLengths = [16, 32];
const state = reactive({
QrCodeModal: null,
});
const errorMessageId = ref(''); const errorMessageId = ref('');
const separatorErrorMessageId = ref(''); const separatorErrorMessageId = ref('');
@ -103,17 +107,26 @@ setZXingModuleOverrides({
return prefix + path; return prefix + path;
}, },
}); });
onMounted(() => {
state.QrCodeModal = new Modal('#qr-code-modal', {});
});
const scanQrCode = ref(false); const scanQrCode = ref(false);
const showQrCodeScanner = (data) => { const showQrCodeScanner = (data) => {
state.QrCodeModal.show();
scanQrCode.value = true; scanQrCode.value = true;
}; };
const hideQrCodeScanner = () => {
scanQrCode.value = false;
state.QrCodeModal.hide();
};
const onQrCodeDetected = (result_list) => { const onQrCodeDetected = (result_list) => {
if (result_list.length >= 1) { if (result_list.length >= 1) {
privateKey.value = result_list[0].rawValue; privateKey.value = result_list[0].rawValue;
scanQrCode.value = false; hideQrCodeScanner();
} }
}; };
const onQrCodeError = (err) => { const onQrCodeError = (err) => {
hideQrCodeScanner();
if (err.name === 'NotAllowedError') { if (err.name === 'NotAllowedError') {
setErrorMessage('addAccount.error.cameraNotAllowed'); setErrorMessage('addAccount.error.cameraNotAllowed');
} else if (err.name === 'NotFoundError') { } else if (err.name === 'NotFoundError') {
@ -150,9 +163,11 @@ const setErrorMessage = (messageId, messageType) => {
} }
return true; return true;
}; };
const resetErrorMessage = () => { const resetFloatingErrorMessage = () => {
errorMessageId.value = ''; errorMessageId.value = '';
};
const resetErrorMessage = () => {
resetFloatingErrorMessage();
separatorErrorMessageId.value = ''; separatorErrorMessageId.value = '';
localPartErrorMessageId.value = ''; localPartErrorMessageId.value = '';
addrKeyErrorMessageId.value = ''; addrKeyErrorMessageId.value = '';
@ -165,7 +180,7 @@ const resetErrorMessage = () => {
<div class="alert alert-danger alert-dismissible fade show" role="alert" v-if="errorMessageId"> <div class="alert alert-danger alert-dismissible fade show" role="alert" v-if="errorMessageId">
{{ $t(errorMessageId) }} {{ $t(errorMessageId) }}
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close" @click="resetErrorMessage"></button> <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close" @click="resetFloatingErrorMessage"></button>
</div> </div>
<div class="mb-3"> <div class="mb-3">
@ -191,7 +206,19 @@ const resetErrorMessage = () => {
</div> </div>
</div> </div>
<qrcode-stream v-if="scanQrCode" @detect="onQrCodeDetected" @error="onQrCodeError"></qrcode-stream> <div class="modal fade" id="qr-code-modal" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1" aria-labelledby="staticBackdropLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" id="staticBackdropLabel">{{ $t("addAccount.scanTitle") }}</h1>
<button type="button" class="btn-close" aria-label="Close" @click="hideQrCodeScanner"></button>
</div>
<div class="modal-body">
<qrcode-stream v-if="scanQrCode" @detect="onQrCodeDetected" @error="onQrCodeError"></qrcode-stream>
</div>
</div>
</div>
</div>
<ButtonGroupComponent> <ButtonGroupComponent>
<button type="button" class="btn btn-primary" :disabled="addDisabled" @click="addAccount">{{ $t("addAccount.addAccount") }}</button> <button type="button" class="btn btn-primary" :disabled="addDisabled" @click="addAccount">{{ $t("addAccount.addAccount") }}</button>