diff --git a/src/lib/components/CardAdd.svelte b/src/lib/components/CardAdd.svelte index 7a51519..4a8bc0d 100644 --- a/src/lib/components/CardAdd.svelte +++ b/src/lib/components/CardAdd.svelte @@ -17,23 +17,21 @@ let { short_name: string } = $props(); -// Local state for file input binding (Svelte 5 best practice) -let files = $state(null); -let upload_error = $state(""); - // Constants for validation const ALLOWED_MIME_TYPES = ['image/webp', 'image/jpeg', 'image/jpg', 'image/png']; const MAX_FILE_SIZE = 5 * 1024 * 1024; // 5MB -// React to file selection using $effect (Svelte 5 best practice) -// This effect intentionally has side effects - it's reacting to user file selection -$effect(() => { - const file = files?.[0]; +// Handle file selection via onchange event +function handleFileSelect(event: Event) { + const input = event.currentTarget as HTMLInputElement; + const file = input.files?.[0]; - // Only process when there's an actual file selected - if (!file) return; + if (!file) { + console.log('[CardAdd] No file selected'); + return; + } - console.log('[CardAdd] File selected via bind:files:', { + console.log('[CardAdd] File selected:', { name: file.name, size: file.size, type: file.type @@ -41,39 +39,35 @@ $effect(() => { // Validate MIME type if (!ALLOWED_MIME_TYPES.includes(file.type)) { - upload_error = 'Invalid file type. Please upload a JPEG, PNG, or WebP image.'; console.error('[CardAdd] Invalid MIME type:', file.type); - alert(upload_error); - files = null; + alert('Invalid file type. Please upload a JPEG, PNG, or WebP image.'); + input.value = ''; return; } console.log('[CardAdd] MIME type valid:', file.type); // Validate file size if (file.size > MAX_FILE_SIZE) { - upload_error = `File too large. Maximum size is 5MB. Your file is ${(file.size / 1024 / 1024).toFixed(2)}MB.`; console.error('[CardAdd] File too large:', file.size); - alert(upload_error); - files = null; + alert(`File too large. Maximum size is 5MB. Your file is ${(file.size / 1024 / 1024).toFixed(2)}MB.`); + input.value = ''; return; } console.log('[CardAdd] File size valid:', file.size, 'bytes'); - // Validation passed - create preview and update bindable prop - upload_error = ""; - // Clean up old preview URL if exists if (image_preview_url && image_preview_url.startsWith('blob:')) { URL.revokeObjectURL(image_preview_url); } + // Create preview and store file image_preview_url = URL.createObjectURL(file); selected_image_file = file; console.log('[CardAdd] Image preview created, file stored for upload:', { previewUrl: image_preview_url, - fileName: selected_image_file.name + fileName: file.name }); -}); +} // Check if initial image_preview_url redirects to placeholder onMount(() => { @@ -111,6 +105,9 @@ if (!card_data.tags) { // Tag management let new_tag = $state(""); +// Reference to file input for clearing +let fileInput: HTMLInputElement; + function remove_selected_images() { console.log('[CardAdd] Removing selected image'); if (image_preview_url && image_preview_url.startsWith('blob:')) { @@ -118,8 +115,10 @@ function remove_selected_images() { } image_preview_url = ""; selected_image_file = null; - files = null; - upload_error = ""; + // Reset the file input + if (fileInput) { + fileInput.value = ''; + } } @@ -440,7 +439,7 @@ input::placeholder{ - +