|
|
@@ -8,7 +8,14 @@
|
|
|
:class="selfieDone ? 'photo-circle--done' : 'photo-circle--pending'"
|
|
|
@click="takeSelfie"
|
|
|
>
|
|
|
+ <img
|
|
|
+ v-if="selfiePreviewUrl"
|
|
|
+ class="photo-circle__thumb"
|
|
|
+ :src="selfiePreviewUrl"
|
|
|
+ />
|
|
|
+
|
|
|
<q-icon
|
|
|
+ v-else
|
|
|
color="white"
|
|
|
name="photo_camera"
|
|
|
size="52px"
|
|
|
@@ -56,15 +63,40 @@
|
|
|
<div class="column items-center q-gutter-y-sm">
|
|
|
<div
|
|
|
:ref="fieldRefs.document_front"
|
|
|
- class="photo-circle"
|
|
|
- :class="docDone ? 'photo-circle--done' : 'photo-circle--pending'"
|
|
|
+ class="cursor-pointer"
|
|
|
@click="openDocSubStep"
|
|
|
>
|
|
|
- <q-icon
|
|
|
- color="white"
|
|
|
- name="mdi-card-account-details-outline"
|
|
|
- size="52px"
|
|
|
- />
|
|
|
+ <div
|
|
|
+ v-if="docDone"
|
|
|
+ class="row items-center justify-center q-gutter-x-sm"
|
|
|
+ >
|
|
|
+ <div class="photo-circle photo-circle--small photo-circle--done">
|
|
|
+ <img
|
|
|
+ v-if="documentFrontPreviewUrl"
|
|
|
+ class="photo-circle__thumb"
|
|
|
+ :src="documentFrontPreviewUrl"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="photo-circle photo-circle--small photo-circle--done">
|
|
|
+ <img
|
|
|
+ v-if="documentBackPreviewUrl"
|
|
|
+ class="photo-circle__thumb"
|
|
|
+ :src="documentBackPreviewUrl"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div
|
|
|
+ v-else
|
|
|
+ class="photo-circle photo-circle--pending"
|
|
|
+ >
|
|
|
+ <q-icon
|
|
|
+ color="white"
|
|
|
+ name="mdi-card-account-details-outline"
|
|
|
+ size="52px"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
</div>
|
|
|
|
|
|
<div
|
|
|
@@ -344,7 +376,7 @@ import {
|
|
|
CameraSource,
|
|
|
} from '@capacitor/camera';
|
|
|
import {
|
|
|
- computed, inject, onBeforeUnmount, ref,
|
|
|
+ computed, inject, onBeforeUnmount, ref, watch,
|
|
|
} from 'vue';
|
|
|
import { useI18n } from 'vue-i18n';
|
|
|
|
|
|
@@ -387,6 +419,10 @@ const loadingDocBack = ref(false);
|
|
|
const docFrontError = ref(false);
|
|
|
const docBackError = ref(false);
|
|
|
|
|
|
+const selfiePreviewUrl = ref(null);
|
|
|
+const documentFrontPreviewUrl = ref(null);
|
|
|
+const documentBackPreviewUrl = ref(null);
|
|
|
+
|
|
|
const docDone = computed(() => (
|
|
|
!!form.value.document_back
|
|
|
&& !!form.value.document_front
|
|
|
@@ -399,6 +435,18 @@ const docSubStepDone = computed(() => (
|
|
|
|
|
|
const selfieDone = computed(() => !!form.value.selfie);
|
|
|
|
|
|
+const syncPreviewUrl = (previewRef, file) => {
|
|
|
+ if (previewRef.value) {
|
|
|
+ URL.revokeObjectURL(previewRef.value);
|
|
|
+ }
|
|
|
+
|
|
|
+ previewRef.value = file ? URL.createObjectURL(file) : null;
|
|
|
+};
|
|
|
+
|
|
|
+watch(() => form.value.selfie, (file) => syncPreviewUrl(selfiePreviewUrl, file), { immediate: true });
|
|
|
+watch(() => form.value.document_front, (file) => syncPreviewUrl(documentFrontPreviewUrl, file), { immediate: true });
|
|
|
+watch(() => form.value.document_back, (file) => syncPreviewUrl(documentBackPreviewUrl, file), { immediate: true });
|
|
|
+
|
|
|
const base64ToFile = (base64, filename, mimeType = 'image/jpeg') => {
|
|
|
const byteString = atob(base64);
|
|
|
const ab = new ArrayBuffer(byteString.length);
|
|
|
@@ -446,12 +494,8 @@ const setDraftFile = (side, file) => {
|
|
|
const draftRef = side === 'front' ? docFrontDraft : docBackDraft;
|
|
|
const previewRef = side === 'front' ? docFrontPreviewUrl : docBackPreviewUrl;
|
|
|
|
|
|
- if (previewRef.value) {
|
|
|
- URL.revokeObjectURL(previewRef.value);
|
|
|
- }
|
|
|
-
|
|
|
draftRef.value = file;
|
|
|
- previewRef.value = file ? URL.createObjectURL(file) : null;
|
|
|
+ syncPreviewUrl(previewRef, file);
|
|
|
};
|
|
|
|
|
|
const captureDocSide = async (side) => {
|
|
|
@@ -522,13 +566,17 @@ const confirmDocCapture = () => {
|
|
|
};
|
|
|
|
|
|
onBeforeUnmount(() => {
|
|
|
- if (docFrontPreviewUrl.value) {
|
|
|
- URL.revokeObjectURL(docFrontPreviewUrl.value);
|
|
|
- }
|
|
|
-
|
|
|
- if (docBackPreviewUrl.value) {
|
|
|
- URL.revokeObjectURL(docBackPreviewUrl.value);
|
|
|
- }
|
|
|
+ [
|
|
|
+ docFrontPreviewUrl,
|
|
|
+ docBackPreviewUrl,
|
|
|
+ selfiePreviewUrl,
|
|
|
+ documentFrontPreviewUrl,
|
|
|
+ documentBackPreviewUrl,
|
|
|
+ ].forEach((previewRef) => {
|
|
|
+ if (previewRef.value) {
|
|
|
+ URL.revokeObjectURL(previewRef.value);
|
|
|
+ }
|
|
|
+ });
|
|
|
});
|
|
|
|
|
|
const takeSelfie = async () => {
|
|
|
@@ -590,6 +638,18 @@ const takeSelfie = async () => {
|
|
|
&--pending {
|
|
|
background-color: rgba(139, 92, 246, 0.18);
|
|
|
}
|
|
|
+
|
|
|
+ &--small {
|
|
|
+ width: 90px;
|
|
|
+ height: 90px;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.photo-circle__thumb {
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ border-radius: 50%;
|
|
|
+ object-fit: cover;
|
|
|
}
|
|
|
|
|
|
.fs-overlay {
|