From ae9ab3668dd54c6053f32f1e5bc55adb24a0517a Mon Sep 17 00:00:00 2001 From: April Hall Date: Wed, 5 Mar 2025 09:24:25 -0500 Subject: [PATCH] fix: Only allow image uploads --- src/lib/components/forms/updatePFP.svelte | 4 +++- .../ui/image-cropper/image-cropper-crop.svelte | 2 +- .../ui/image-cropper/image-cropper.svelte | 15 ++++++++++++++- .../ui/image-cropper/image-cropper.svelte.ts | 3 --- 4 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/lib/components/forms/updatePFP.svelte b/src/lib/components/forms/updatePFP.svelte index ed79d1d..b0cce36 100644 --- a/src/lib/components/forms/updatePFP.svelte +++ b/src/lib/components/forms/updatePFP.svelte @@ -10,7 +10,7 @@ const { data }: { data: PageData } = $props(); let src = $state(data.user.image ?? `https://api.dicebear.com/9.x/identicon/svg?seed=${data.session?.user.id}`); - let open: boolean = $state(false); + let error: string | null = $state(null); async function submit(file: File) { await generateStream(file).then((res) => { @@ -23,6 +23,7 @@
Upload Profile Image { const file = await getFileFromUrl(url); @@ -45,5 +46,6 @@ + {#if error}{error}{/if}
diff --git a/src/lib/components/ui/image-cropper/image-cropper-crop.svelte b/src/lib/components/ui/image-cropper/image-cropper-crop.svelte index cd66895..c9d7e47 100644 --- a/src/lib/components/ui/image-cropper/image-cropper-crop.svelte +++ b/src/lib/components/ui/image-cropper/image-cropper-crop.svelte @@ -15,7 +15,7 @@ const cropState = useImageCropperCrop(); - diff --git a/src/lib/components/ui/image-cropper/image-cropper.svelte b/src/lib/components/ui/image-cropper/image-cropper.svelte index 320a658..3ec8620 100644 --- a/src/lib/components/ui/image-cropper/image-cropper.svelte +++ b/src/lib/components/ui/image-cropper/image-cropper.svelte @@ -11,7 +11,14 @@ import { onDestroy } from 'svelte'; import { useId } from 'bits-ui'; - let { id = useId(), src = $bindable(''), onCropped = () => {}, children, ...rest }: ImageCropperRootProps = $props(); + let { + id = useId(), + src = $bindable(''), + onCropped = () => {}, + children, + error = $bindable(null), + ...rest + }: ImageCropperRootProps & { error?: string | null } = $props(); const rootState = useImageCropperRoot({ id: box.with(() => id), @@ -31,6 +38,12 @@ onchange={(e) => { const file = e.currentTarget.files?.[0]; if (!file) return; + // Prevent the user from uploading non-image files + if (file.type.split('/')[0] !== 'image') { + error = 'Please upload a valid image.'; + return; + } + error = null; rootState.onUpload(file); // reset so that we can reupload the same file (e.target! as HTMLInputElement).value = ''; diff --git a/src/lib/components/ui/image-cropper/image-cropper.svelte.ts b/src/lib/components/ui/image-cropper/image-cropper.svelte.ts index 1bd9587..3d34755 100644 --- a/src/lib/components/ui/image-cropper/image-cropper.svelte.ts +++ b/src/lib/components/ui/image-cropper/image-cropper.svelte.ts @@ -45,11 +45,8 @@ class ImageCropperRootState { async onCrop() { if (!this.pixelCrop || !this.tempUrl) return; - this.opts.src.current = await getCroppedImg(this.tempUrl, this.pixelCrop); - this.open = false; - this.opts.onCropped(this.opts.src.current); }