fix(images): fix iOS image upload and improve logging #80
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "exe-dev-bot/market:fix/ios-image-upload"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem
A user on iOS (iPhone, Safari 18.1.1) reported being unable to upload item images. The feature works on Linux and Android. Cloudflare logs showed minimal diagnostic information.
Root Cause Analysis
1. Critical: Race condition unmounts form during upload
The
onSubmitflow calledonSave(result.data, true)beforeuploadImages()completed. This triggeredhandleSaveinItemFormPage, which setsuccess=true, causing React to unmountItemFormand render the success message instead. The unmount cleanup firedabortControllerRef.current.abort(), killing all in-flight image uploads. TheisUploadingparameter was accepted in the type signature but completely ignored byhandleSave.This race existed on all platforms but iOS Safari is more aggressive about unmount timing, making the window tighter.
2. High: HEIC/HEIF not accepted
iOS cameras default to HEIC format. The file input
acceptattribute andALLOWED_TYPESonly included JPEG/PNG/WebP. While iOS Safari auto-converts HEIC on selection, the conversion is inconsistent across iOS versions — sometimes reporting emptyfile.typeorimage/heif, whichvalidateImageFilerejected.3. Medium: Web Workers in image compression
browser-image-compressionwithuseWebWorker: trueusesOffscreenCanvasandcreateImageBitmapinside workers. iOS Safari has had longstanding issues with these APIs in worker contexts.4. Medium: No FileReader error handler
If
FileReader.readAsDataURLfailed (e.g., corrupted compression output),loadedCountnever reachedfiles.length, leaving the UI stuck in "Processing images..." state forever.Changes
src/components/react/ItemForm.tsxonSave(result.data, true)call. NowonSaveis called only once, after uploads completeacceptattributeuseWebWorker: falsefor iOS compatibilitycompressedBlob.typeinstead of hardcodingimage/jpegsrc/lib/storage.tsALLOWED_TYPESand MIME-to-extension maptests/unit/storage.test.tsTesting
just test-unit— all 331 tests pass