From 22f9d5c6bd17c1bd590288d4f9ee093af9603a11 Mon Sep 17 00:00:00 2001 From: Jonathan Bourdon Date: Thu, 24 Apr 2025 22:07:47 -0400 Subject: [PATCH] feat: open file selection in BannerEditor and CreatorLogoEditor when no image to edit --- frontend/src/views/creators/BannerEditor.vue | 40 ++++++++++++------- .../src/views/creators/CreatorLogoEditor.vue | 40 ++++++++++++------- 2 files changed, 50 insertions(+), 30 deletions(-) diff --git a/frontend/src/views/creators/BannerEditor.vue b/frontend/src/views/creators/BannerEditor.vue index 96f9d30..0f64868 100644 --- a/frontend/src/views/creators/BannerEditor.vue +++ b/frontend/src/views/creators/BannerEditor.vue @@ -103,7 +103,10 @@ const uploadProgress = ref(0) const { t } = useI18n() const triggerFileInput = () => { - fileInput.value.click() + if (fileInput.value) { + fileInput.value.value = '' // Reset the input value to ensure the change event fires + fileInput.value.click() + } } const onFileSelected = (event) => { @@ -124,23 +127,30 @@ const onFileSelected = (event) => { } const startEditing = () => { - if (fileUrl.value && fileUrl.value !== fallbackUrl) { - // Use our API client to get the image - client.get(fileUrl.value, { responseType: 'blob' }) - .then(response => { - const blob = response.data - selectedFile.value = new File([blob], 'current-image.jpg', { type: 'image/jpeg' }) - // Create a local URL for the cropper - fileUrl.value = URL.createObjectURL(blob) - showCropper.value = true - }) - .catch(error => { - console.error('Error loading image for editing:', error) - errorMessage.value = t('errors.imageLoad') - }) + if (fileUrl.value && fileUrl.value.startsWith('data:')) { + // Only try to load the image if it's a data URL (newly selected image) + const blob = dataURLtoBlob(fileUrl.value) + selectedFile.value = new File([blob], 'current-image.jpg', { type: 'image/jpeg' }) + showCropper.value = true + } else { + // If no image is selected, using fallback, or have an existing uploaded image, trigger the file input + triggerFileInput() } } +// Helper function to convert data URL to blob +const dataURLtoBlob = (dataURL) => { + const arr = dataURL.split(',') + const mime = arr[0].match(/:(.*?);/)[1] + const bstr = atob(arr[1]) + let n = bstr.length + const u8arr = new Uint8Array(n) + while (n--) { + u8arr[n] = bstr.charCodeAt(n) + } + return new Blob([u8arr], { type: mime }) +} + const applyCrop = () => { if (!cropper.value) return diff --git a/frontend/src/views/creators/CreatorLogoEditor.vue b/frontend/src/views/creators/CreatorLogoEditor.vue index 9a1e1c1..e2c9973 100644 --- a/frontend/src/views/creators/CreatorLogoEditor.vue +++ b/frontend/src/views/creators/CreatorLogoEditor.vue @@ -108,7 +108,10 @@ const TARGET_HEIGHT = 200 const { t } = useI18n(); const triggerFileInput = () => { - fileInput.value.click() + if (fileInput.value) { + fileInput.value.value = '' // Reset the input value to ensure the change event fires + fileInput.value.click() + } } const onFileSelected = (event) => { @@ -129,23 +132,30 @@ const onFileSelected = (event) => { } const startEditing = () => { - if (fileUrl.value && fileUrl.value !== fallbackUrl) { - // Use our API client to get the image - client.get(fileUrl.value, { responseType: 'blob' }) - .then(response => { - const blob = response.data - selectedFile.value = new File([blob], 'current-image.jpg', { type: 'image/jpeg' }) - // Create a local URL for the cropper - fileUrl.value = URL.createObjectURL(blob) - showCropper.value = true - }) - .catch(error => { - console.error('Error loading image for editing:', error) - errorMessage.value = t('errors.imageLoad') - }) + if (fileUrl.value && fileUrl.value.startsWith('data:')) { + // Only try to load the image if it's a data URL (newly selected image) + const blob = dataURLtoBlob(fileUrl.value) + selectedFile.value = new File([blob], 'current-image.jpg', { type: 'image/jpeg' }) + showCropper.value = true + } else { + // If no image is selected, using fallback, or have an existing uploaded image, trigger the file input + triggerFileInput() } } +// Helper function to convert data URL to blob +const dataURLtoBlob = (dataURL) => { + const arr = dataURL.split(',') + const mime = arr[0].match(/:(.*?);/)[1] + const bstr = atob(arr[1]) + let n = bstr.length + const u8arr = new Uint8Array(n) + while (n--) { + u8arr[n] = bstr.charCodeAt(n) + } + return new Blob([u8arr], { type: mime }) +} + const applyCrop = () => { if (!cropper.value) return