<template> <button type="button" class="btn btn-primary tw-inline-flex tw-items-center" @click.stop="open()"> <icon-carbon-cloud-upload class="tw-mr-1" /> {{ t('imagePicker.uploadImage') }} </button> </template> <script lang="ts" setup> import { useFileDialog } from '@vueuse/core' import { watch } from 'vue' import { useI18n } from '@/i18n' import type { NewImage } from '@/stores/images' const emit = defineEmits<{ (e: 'input', value: NewImage): void }>() const { t } = useI18n() const { files, open } = useFileDialog({ multiple: false, accept: 'image/*', capture: 'environment', }) watch(files, async () => { if (files.value && files.value.length > 0) { const file = files.value.item(0) if (file) { const content = await readFile(file) emit('input', newImage(file, content)) } } }) function readFile(file: File): Promise<string> { return new Promise((resolve) => { const reader = new FileReader() reader.onload = function (event) { if (event.target) { resolve(event.target.result as string) } } reader.readAsDataURL(file) }) } function newImage(file: File, content: string): NewImage { return { image: content, file, altText: file.name, isUseExplicitlyGrantedByAuthor: false, licenseId: null, credits: '', width: 0, height: 0, ppoi: '0.5x0.5', thumbnails: [], } } </script> <script lang="ts"> export default { compatConfig: { MODE: 3, }, } </script>