Fix image picker conversions#46025
Conversation
|
@hoangzinh Please copy/paste the Reviewer Checklist from here into a new comment on this PR and complete it. If you have the K2 extension, you can simply click: [this button] |
Reviewer Checklist
Screenshots/VideosAndroid: NativeScreen.Recording.2024-08-05.at.18.33.16.android.movAndroid: mWeb ChromeScreen.Recording.2024-08-05.at.18.27.48.android.chrome.moviOS: NativeScreen.Recording.2024-08-05.at.18.35.53.ios.moviOS: mWeb SafariScreen.Recording.2024-08-05.at.18.39.39.ios.safari.movMacOS: Chrome / SafariScreen.Recording.2024-08-05.at.18.07.22.movMacOS: DesktopScreen.Recording.2024-08-05.at.18.12.24.desktop.mov |
hoangzinh
left a comment
There was a problem hiding this comment.
Sorry for late review. Overall, your approach looks good to me.
| const fileContent = await RNFS.read(targetAsset.uri, 12, 0, 'base64'); | ||
| const hexSignature = Array.from(decode(fileContent)) | ||
| .map((char) => char.charCodeAt(0).toString(16).padStart(2, '0')) | ||
| .slice(0, 32) | ||
| .join('') | ||
| .toUpperCase(); | ||
|
|
||
| const isHEIC = hexSignature.startsWith(CONST.HEIC_SIGNATURE); |
There was a problem hiding this comment.
We can wrap those into a function, and then use it here. It helps code look leaner. What do you think?
| @@ -1,11 +1,15 @@ | |||
| /* eslint-disable @lwc/lwc/no-async-await */ | |||
There was a problem hiding this comment.
I think we're not allowed to use async/await atm. Can you convert your code to Promise?
src/libs/fileDownload/FileUtils.ts
Outdated
| }); | ||
| } | ||
|
|
||
| function verifyFileFormat({fileUri, formatSignature}: {fileUri: string; formatSignature: string}) { |
There was a problem hiding this comment.
I'm unsure whether we can reuse this method to verify other format types (like pdf/jpeg...). If not, we can name this function more specifically to verify the HEIC file. What do you think?
There was a problem hiding this comment.
we can reuse it, but we would need to pass a different magic bytes for each, for now I'd leave it this way. If we need it in the future we could define a map with signatures for each specific type
There was a problem hiding this comment.
okay cool, then can we rename the const isHEIC below to a more common variable?
There was a problem hiding this comment.
my miss, sorry for that. It's ready now
|
Looks good. @BrtqKr what do you think if we explicitly add another "testing steps" for other platforms (except IOS)? I think it should be same with current, but don't include HEIC file |
|
It appears that it's broken somewhere after refactoring. The HEIC file is not shown after uploading. Can you check again? Thank you. Screen.Recording.2024-07-30.at.18.16.34.mov |
Simulator.Screen.Recording.-.iPhone.15.Pro.-.2024-07-31.at.10.09.34.mp4It seems to be working as expected. Would mind sharing the file you've used in this recording? |
|
Yep, you can try this file https://drive.google.com/file/d/1BsY-7m9Igsecnrp98QgmqCf5lusLi1Zu/view?usp=sharing |
…tible with other platforms
|
@hoangzinh it wasn't a standard heic. According to the signature of the file you've provided, it was ftypmif1 - a multi-image format related to heic. I've added additional signatures for the related types, which should help in this scenario. Also, I've changed the implementation to use fetch for the purpose of compatibility. I think this should be enough. Simulator.Screen.Recording.-.iPhone.15.Pro.-.2024-08-02.at.16.49.30.mp4 |
|
Great. Thanks @BrtqKr |
| if (targetAsset?.type?.startsWith('image')) { | ||
| FileUtils.verifyFileFormat({fileUri: targetAssetUri, formatSignatures: CONST.HEIC_SIGNATURES}) | ||
| .then((isHEIC) => { | ||
| // react-native-image-picker incorrectly changes file extension without transcoding the HEIC file, so we are doing it manually if we detect HEIC signature |
There was a problem hiding this comment.
Do we plan to fix this upstream also?
There was a problem hiding this comment.
I've sent a feature request to the repository. If they think this approach is ok, I'll send a PR react-native-image-picker/react-native-image-picker#2317
|
✋ This PR was not deployed to staging yet because QA is ongoing. It will be automatically deployed to staging after the next production release. |
|
🚀 Deployed to staging by https://github.com/puneetlath in version: 9.0.18-0 🚀
|
|
🚀 Deployed to production by https://github.com/mountiny in version: 9.0.18-10 🚀
|
Details
There has been a related PR that was seemingly fixing this issue, but at the same time was the cause of another bug related to HEIC files. It turns out that when using
assetRepresentationMode: 'current'HEIC files were being given .jpg extension without being converted, so the solution was to convert them manually when detecting the magic bytes with heic signature. It's quite a weird workaround, but since jpg conversion for HEIC is a standard approach, the most reasonable solution was to fix the conversion.Fixed Issues
$ #38478
PROPOSAL:
Tests
Normally I'd upload both files I've been using for the tests, but github does't accept .heic. The one with the squares from the recordings was .heic
On iOS
On other platforms
HEIC files are treated as file attachments, but they should be sent without any issues. Also, verify using the same steps that images of different formats are being uploaded with correct previews in the messages.
Offline tests
Everything is related to the picker and the format of the images, so the offline behaviour shouldn't be relevant in this case.
QA Steps
Same as in standard tests, but please make sure that it's working for various types of media. The last time regression was related to .heic format - this time it's working, but it would be good to verify all available data types of the media picked.
PR Author Checklist
### Fixed Issuessection aboveTestssectionOffline stepssectionQA stepssectiontoggleReportand notonIconClick)myBool && <MyComponent />.src/languages/*files and using the translation methodSTYLE.md) were followedAvatar, I verified the components usingAvatarare working as expected)StyleUtils.getBackgroundAndBorderStyle(theme.componentBG))Avataris modified, I verified thatAvataris working as expected in all cases)Designlabel and/or tagged@Expensify/designso the design team can review the changes.ScrollViewcomponent to make it scrollable when more elements are added to the page.mainbranch was merged into this PR after a review, I tested again and verified the outcome was still expected according to theTeststeps.Screenshots/Videos
Android: Native
Screen.Recording.2024-07-24.at.10.48.24.mov
Android: mWeb Chrome
Screen.Recording.2024-07-24.at.10.54.22.mov
iOS: Native
Simulator.Screen.Recording.-.iPhone.15.Pro.-.2024-07-23.at.17.09.31.mp4
iOS: mWeb Safari
Simulator.Screen.Recording.-.iPhone.15.Pro.-.2024-07-23.at.17.17.21.mp4
MacOS: Chrome / Safari
Screen.Recording.2024-07-23.at.17.26.52.mov
Screen.Recording.2024-07-23.at.17.28.25.mov
MacOS: Desktop
Screen.Recording.2024-07-24.at.10.57.07.mov