-
Notifications
You must be signed in to change notification settings - Fork 2.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix image picker conversions #46025
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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can wrap those into a function, and then use it here. It helps code look leaner. What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sure
@@ -1,11 +1,15 @@ | |||
/* eslint-disable @lwc/lwc/no-async-await */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we're not allowed to use async/await atm. Can you convert your code to Promise?
src/libs/fileDownload/FileUtils.ts
Outdated
@@ -255,6 +257,24 @@ function validateImageForCorruption(file: FileObject): Promise<void> { | |||
}); | |||
} | |||
|
|||
function verifyFileFormat({fileUri, formatSignature}: {fileUri: string; formatSignature: string}) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
okay cool, then can we rename the const isHEIC
below to a more common variable?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we plan to fix this upstream also?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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 Issues
section aboveTests
sectionOffline steps
sectionQA steps
sectiontoggleReport
and notonIconClick
)myBool && <MyComponent />
.src/languages/*
files and using the translation methodSTYLE.md
) were followedAvatar
, I verified the components usingAvatar
are working as expected)StyleUtils.getBackgroundAndBorderStyle(theme.componentBG)
)Avatar
is modified, I verified thatAvatar
is working as expected in all cases)Design
label and/or tagged@Expensify/design
so the design team can review the changes.ScrollView
component to make it scrollable when more elements are added to the page.main
branch was merged into this PR after a review, I tested again and verified the outcome was still expected according to theTest
steps.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