fix: Only allow image uploads

This commit is contained in:
April Hall 2025-03-05 09:24:25 -05:00
parent 193bd380c3
commit ae9ab3668d
No known key found for this signature in database
GPG Key ID: A49AC35CB186266C
4 changed files with 18 additions and 6 deletions

View File

@ -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 @@
<fieldset class="flex size-full flex-col items-center justify-center gap-3 rounded-lg border p-4">
<legend class="-ml-1 px-1 text-sm font-medium"> Upload Profile Image </legend>
<ImageCropper.Root
bind:error
bind:src
onCropped={async (url) => {
const file = await getFileFromUrl(url);
@ -45,5 +46,6 @@
</ImageCropper.Controls>
</ImageCropper.Dialog>
</ImageCropper.Root>
{#if error}<span class="text-sm text-red-500">{error}</span>{/if}
</fieldset>
</form>

View File

@ -15,7 +15,7 @@
const cropState = useImageCropperCrop();
</script>
<Button {...rest} {size} {variant} onclick={cropState.onclick}>
<Button {...rest} {size} {variant} onclick={cropState.onclick} data-testid="crop">
<ImageUp />
<span>Upload</span>
</Button>

View File

@ -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 = '';

View File

@ -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);
}