From 26020a01bb1101fc1c1473b83f5f09be27f958a5 Mon Sep 17 00:00:00 2001 From: lyqht Date: Fri, 5 Jan 2024 17:59:25 +0800 Subject: [PATCH] add feature to automatically save and load custom preset to local storage translate custom text --- locales/en.json | 2 + src/App.vue | 229 +++++++++++++++++++++++++++------------------- src/utils/i18n.ts | 1 + 3 files changed, 138 insertions(+), 94 deletions(-) diff --git a/locales/en.json b/locales/en.json index 8b9b9f0..5570c4b 100644 --- a/locales/en.json +++ b/locales/en.json @@ -7,6 +7,8 @@ "Data to encode": "Data to encode", "data to encode e.g. a URL or a string": "data to encode e.g. a URL or a string", "Logo image URL": "Logo image URL", + "Last saved locally": "Last saved locally", + "Loaded from file": "Loaded from file", "Copy QR Code to clipboard": "Copy QR Code to clipboard", "Export as": "Export as", "Download QR Code as PNG": "Download QR Code as PNG", diff --git a/src/App.vue b/src/App.vue index b63200b..76b350f 100644 --- a/src/App.vue +++ b/src/App.vue @@ -7,27 +7,30 @@ import { IS_COPY_IMAGE_TO_CLIPBOARD_SUPPORTED } from '@/utils/convertToImage' import type { CornerDotType, CornerSquareType, DotType } from 'qr-code-styling' -import { computed, ref, watch } from 'vue' +import { computed, onMounted, ref, watch } from 'vue' import 'vue-i18n' +import { useI18n } from 'vue-i18n' import { getNumericCSSValue } from './utils/formatting' import { sortedLocales } from './utils/language' import { allPresets } from './utils/presets' +const { t } = useI18n() + const defaultPreset = allPresets[0] -const data = ref(defaultPreset.data) -const image = ref(defaultPreset.image) -const width = ref(defaultPreset.width) -const height = ref(defaultPreset.height) -const margin = ref(defaultPreset.margin) -const imageMargin = ref(defaultPreset.imageOptions.margin) - -const dotsOptionsColor = ref(defaultPreset.dotsOptions.color) -const dotsOptionsType = ref(defaultPreset.dotsOptions.type) -const cornersSquareOptionsColor = ref(defaultPreset.cornersSquareOptions.color) -const cornersSquareOptionsType = ref(defaultPreset.cornersSquareOptions.type) -const cornersDotOptionsColor = ref(defaultPreset.cornersDotOptions.color) -const cornersDotOptionsType = ref(defaultPreset.cornersDotOptions.type) -const styleBorderRadius = ref(getNumericCSSValue(defaultPreset.style.borderRadius as string)) +const data = ref() +const image = ref() +const width = ref() +const height = ref() +const margin = ref() +const imageMargin = ref() + +const dotsOptionsColor = ref() +const dotsOptionsType = ref() +const cornersSquareOptionsColor = ref() +const cornersSquareOptionsType = ref() +const cornersDotOptionsColor = ref() +const cornersDotOptionsType = ref() +const styleBorderRadius = ref() const styledBorderRadiusFormatted = computed(() => `${styleBorderRadius.value}px`) const styleBackground = ref(defaultPreset.style.background) @@ -146,12 +149,39 @@ function downloadQRImageAsSvg() { } } -function saveQRConfig() { - console.debug('Saving QR code config') - const qrCodeConfig = { +function uploadImage() { + console.debug('Uploading image') + const imageInput = document.createElement('input') + imageInput.type = 'file' + imageInput.accept = 'image/*' + imageInput.onchange = (event: Event) => { + const target = event.target as HTMLInputElement + if (target.files) { + const file = target.files[0] + const reader = new FileReader() + reader.onload = (event: ProgressEvent) => { + const target = event.target as FileReader + const result = target.result as string + image.value = result + } + reader.readAsDataURL(file) + } + } + imageInput.click() +} + +/* QR Config Utils */ + +function createQrConfig() { + return { props: qrCodeProps.value, style: style.value } +} + +function downloadQRConfig() { + console.debug('Downloading QR code config') + const qrCodeConfig = createQrConfig() const qrCodeConfigString = JSON.stringify(qrCodeConfig) const qrCodeConfigBlob = new Blob([qrCodeConfigString], { type: 'application/json' }) const qrCodeConfigUrl = URL.createObjectURL(qrCodeConfigBlob) @@ -161,7 +191,38 @@ function saveQRConfig() { qrCodeConfigLink.click() } -function loadQrConfig() { +function saveQRConfigToLocalStorage() { + const qrCodeConfig = createQrConfig() + const qrCodeConfigString = JSON.stringify(qrCodeConfig) + localStorage.setItem('qrCodeConfig', qrCodeConfigString) +} + +function loadQRConfig(jsonString: string, name?: string) { + const qrCodeConfig = JSON.parse(jsonString) + const qrCodeProps = qrCodeConfig.props + const qrCodeStyle = qrCodeConfig.style + const preset = { + ...qrCodeProps, + style: qrCodeStyle + } + + selectedPreset.value = { + ...preset, + name: name ?? qrCodeProps.name + } +} + +function loadQRConfigFromLocalStorage() { + const qrCodeConfigString = localStorage.getItem('qrCodeConfig') + if (qrCodeConfigString) { + console.debug('Loading QR code config from local storage') + loadQRConfig(qrCodeConfigString, t('Last saved locally')) + } else { + selectedPreset.value = defaultPreset + } +} + +function loadQrConfigFromFile() { console.debug('Loading QR code config') const qrCodeConfigInput = document.createElement('input') qrCodeConfigInput.type = 'file' @@ -174,22 +235,7 @@ function loadQrConfig() { reader.onload = (event: ProgressEvent) => { const target = event.target as FileReader const result = target.result as string - const qrCodeConfig = JSON.parse(result) - const qrCodeProps = qrCodeConfig.props - const qrCodeStyle = qrCodeConfig.style - data.value = qrCodeProps.data - image.value = qrCodeProps.image - width.value = qrCodeProps.width - height.value = qrCodeProps.height - margin.value = qrCodeProps.margin - dotsOptionsColor.value = qrCodeProps.dotsOptions.color - dotsOptionsType.value = qrCodeProps.dotsOptions.type - cornersSquareOptionsColor.value = qrCodeProps.cornersSquareOptions.color - cornersSquareOptionsType.value = qrCodeProps.cornersSquareOptions.type - cornersDotOptionsColor.value = qrCodeProps.cornersDotOptions.color - cornersDotOptionsType.value = qrCodeProps.cornersDotOptions.type - styleBorderRadius.value = qrCodeStyle.borderRadius - styleBackground.value = qrCodeStyle.background + loadQRConfig(result, t('Loaded from file')) } reader.readAsText(file) } @@ -197,26 +243,13 @@ function loadQrConfig() { qrCodeConfigInput.click() } -function uploadImage() { - console.debug('Uploading image') - const imageInput = document.createElement('input') - imageInput.type = 'file' - imageInput.accept = 'image/*' - imageInput.onchange = (event: Event) => { - const target = event.target as HTMLInputElement - if (target.files) { - const file = target.files[0] - const reader = new FileReader() - reader.onload = (event: ProgressEvent) => { - const target = event.target as FileReader - const result = target.result as string - image.value = result - } - reader.readAsDataURL(file) - } - } - imageInput.click() -} +watch(qrCodeProps, () => { + saveQRConfigToLocalStorage() +}) + +onMounted(() => { + loadQRConfigFromLocalStorage() +})