From c0e7f5d7af80628b3afdae3ff371420f6431cbd1 Mon Sep 17 00:00:00 2001 From: Rizumu Ayaka Date: Fri, 11 Oct 2024 00:30:30 +0800 Subject: [PATCH] feat: Prevent accidental leave when the scan is not completed --- app/components/Scan.vue | 16 ++++++++++++++-- app/composables/unsavedChange.ts | 15 +++++++++++++++ 2 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 app/composables/unsavedChange.ts diff --git a/app/components/Scan.vue b/app/components/Scan.vue index 811cd7d..1aa88a6 100644 --- a/app/components/Scan.vue +++ b/app/components/Scan.vue @@ -262,11 +262,17 @@ async function scanFrame(result: QrScanner.ScanResult) { const data = binaryToBlock(binary) // Data set changed, reset decoder if (checksum.value !== data.checksum) { + if (k.value && !dataUrl.value) { + // eslint-disable-next-line no-alert + if (!window.confirm('Scanned different files. You have unfinished transmission, are you sure to start a new one?')) { + return + } + } decoderInitPromise = decoderWorker.createDecoder() checksum.value = data.checksum bytes.value = data.bytes k.value = data.k - startTime.value = performance.now() + startTime.value = now() endTime.value = 0 cached.clear() filename.value = undefined @@ -288,7 +294,7 @@ async function scanFrame(result: QrScanner.ScanResult) { decoderStatus.value = await decoderWorker.getStatus() status.value = getStatus() if (success) { - endTime.value = performance.now() + endTime.value = now() const merged = (await decoderWorker.getDecoded())! const [mergedData, meta] = readFileHeaderMetaFromBuffer(merged) @@ -327,6 +333,12 @@ async function scanFrame(result: QrScanner.ScanResult) { // } } +useUnsavedChange(() => { + if (k.value && !dataUrl.value) { + return 'You have unfinished transmission, are you sure to leave?' + } +}) + function now() { return performance.now() } diff --git a/app/composables/unsavedChange.ts b/app/composables/unsavedChange.ts new file mode 100644 index 0000000..fa4ad55 --- /dev/null +++ b/app/composables/unsavedChange.ts @@ -0,0 +1,15 @@ +export function useUnsavedChange(callback: () => string | null | undefined | false, confirm = window.confirm.bind(window)) { + onBeforeRouteLeave((to, from, next) => { + let answer = true + const message = callback() + if (message) { + answer = confirm(message) + } + next(answer) + }) + useEventListener(window, 'beforeunload', (event) => { + if (callback()) { + event.preventDefault() + } + }) +}