Skip to content
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 looks cropped In the Preview page #8804

Merged
merged 14 commits into from
May 17, 2022
Merged

Fix image looks cropped In the Preview page #8804

merged 14 commits into from
May 17, 2022

Conversation

mollfpr
Copy link
Contributor

@mollfpr mollfpr commented Apr 27, 2022

Details

  1. The container height of ImageView is not calculated right. Use onLayout to get the height of view and use the height to get the correct aspect ratio of the image and the container.
  2. To remove the extra space on the Android attachment modal, set shouldAddTopSafeAreaPadding only on iOS.

Fixed Issues

$ #8115

Tests

  1. Open the app
  2. Go to a chat
  3. Click on the "+" sign
  4. Select add Attachment
  5. Select a screenshot (mad from your phone)
  6. Verify that image is not cropped
  7. View the image attachment that already sends
  8. Verify that image is not cropped
  9. On Android verify that the extra space on header is gone
  • Verify that no errors appear in the JS console

PR Review Checklist

Contributor (PR Author) Checklist

  • I linked the correct issue in the ### Fixed Issues section above
  • I wrote clear testing steps that cover the changes made in this PR
    • I added steps for local testing in the Tests section
    • I added steps for Staging and/or Production testing in the QA steps section
    • I added steps to cover failure scenarios (i.e. verify an input displays the correct error message if the entered data is not correct)
    • I turned off my network connection and tested it while offline to ensure it matches the expected behavior (i.e. verify the default avatar icon is displayed if app is offline)
  • I included screenshots or videos for tests on all platforms
  • I ran the tests on all platforms & verified they passed on:
    • iOS / native
    • Android / native
    • iOS / Safari
    • Android / Chrome
    • MacOS / Chrome
    • MacOS / Desktop
  • I verified there are no console errors (if there’s a console error not related to the PR, report it or open an issue for it to be fixed)
  • I followed proper code patterns (see Reviewing the code)
    • I verified that any callback methods that were added or modified are named for what the method does and never what callback they handle (i.e. toggleReport and not onIconClick)
    • I verified that comments were added to code that is not self explanatory
    • I verified that any new or modified comments were clear, correct English, and explained “why” the code was doing something instead of only explaining “what” the code was doing.
    • I verified any copy / text shown in the product was added in all src/languages/* files
    • I verified any copy / text that was added to the app is correct English and approved by marketing by tagging the marketing team on the original GH to get the correct copy.
    • I verified proper file naming conventions were followed for any new files or renamed files. All non-platform specific files are named after what they export and are not named “index.js”. All platform-specific files are named for the platform the code supports as outlined in the README.
    • I verified the JSDocs style guidelines (in STYLE.md) were followed
  • If a new code pattern is added I verified it was agreed to be used by multiple Expensify engineers
  • I followed the guidelines as stated in the Review Guidelines
  • I tested other components that can be impacted by my changes (i.e. if the PR modifies a shared library or component like Avatar, I verified the components using Avatar are working as expected)
  • I verified all code is DRY (the PR doesn't include any logic written more than once, with the exception of tests)
  • I verified any variables that can be defined as constants (ie. in CONST.js or at the top of the file that uses the constant) are defined as such
  • If a new component is created I verified that:
    • A similar component doesn't exist in the codebase
    • All props are defined accurately and each prop has a /** comment above it */
    • Any functional components have the displayName property
    • The file is named correctly
    • The component has a clear name that is non-ambiguous and the purpose of the component can be inferred from the name alone
    • The only data being stored in the state is data necessary for rendering and nothing else
    • For Class Components, any internal methods passed to components event handlers are bound to this properly so there are no scoping issues (i.e. for onClick={this.submit} the method this.submit should be bound to this in the constructor)
    • Any internal methods bound to this are necessary to be bound (i.e. avoid this.submit = this.submit.bind(this); if this.submit is never passed to a component event handler like onClick)
    • All JSX used for rendering exists in the render method
    • The component has the minimum amount of code necessary for its purpose and it is
  • If a new CSS style is added I verified that:
    • A similar style doesn’t already exist
    • The style can’t be created with an existing StyleUtils function (i.e. StyleUtils.getBackgroundAndBorderStyle(themeColors.componentBG)
  • If the PR modifies a generic component, I tested and verified that those changes do not break usages of that component in the rest of the App (i.e. if a shared library or component like Avatar is modified, I verified that Avatar is working as expected in all cases)
  • If the PR modifies a component related to any of the existing Storybook stories, I tested and verified all stories for that component are still working as expected.

PR Reviewer Checklist

  • I verified the correct issue is linked in the ### Fixed Issues section above
  • I verified testing steps are clear and they cover the changes made in this PR
    • I verified the steps for local testing are in the Tests section
    • I verified the steps for Staging and/or Production testing are in the QA steps section
    • I verified the steps cover any possible failure scenarios (i.e. verify an input displays the correct error message if the entered data is not correct)
    • I turned off my network connection and tested it while offline to ensure it matches the expected behavior (i.e. verify the default avatar icon is displayed if app is offline)
  • I checked that screenshots or videos are included for tests on all platforms
  • I verified tests pass on all platforms & I tested again on:
    • iOS / native
    • Android / native
    • iOS / Safari
    • Android / Chrome
    • MacOS / Chrome
    • MacOS / Desktop
  • I verified there are no console errors (if there’s a console error not related to the PR, report it or open an issue for it to be fixed)
  • I verified proper code patterns were followed (see Reviewing the code)
    • I verified that any callback methods that were added or modified are named for what the method does and never what callback they handle (i.e. toggleReport and not onIconClick).
    • I verified that comments were added to code that is not self explanatory
    • I verified that any new or modified comments were clear, correct English, and explained “why” the code was doing something instead of only explaining “what” the code was doing.
    • I verified any copy / text shown in the product was added in all src/languages/* files
    • I verified any copy / text that was added to the app is correct English and approved by marketing by tagging the marketing team on the original GH to get the correct copy.
    • I verified proper file naming conventions were followed for any new files or renamed files. All non-platform specific files are named after what they export and are not named “index.js”. All platform-specific files are named for the platform the code supports as outlined in the README.
    • I verified the JSDocs style guidelines (in STYLE.md) were followed
  • If a new code pattern is added I verified it was agreed to be used by multiple Expensify engineers
  • I verified that this PR follows the guidelines as stated in the Review Guidelines
  • I verified all code is DRY (the PR doesn't include any logic written more than once, with the exception of tests)
  • I verified any variables that can be defined as constants (ie. in CONST.js or at the top of the file that uses the constant) are defined as such
  • If a new component is created I verified that:
    • A similar component doesn't exist in the codebase
    • All props are defined accurately and each prop has a /** comment above it */
    • Any functional components have the displayName property
    • The file is named correctly
    • The component has a clear name that is non-ambiguous and the purpose of the component can be inferred from the name alone
    • The only data being stored in the state is data necessary for rendering and nothing else
    • For Class Components, any internal methods passed to components event handlers are bound to this properly so there are no scoping issues (i.e. for onClick={this.submit} the method this.submit should be bound to this in the constructor)
    • Any internal methods bound to this are necessary to be bound (i.e. avoid this.submit = this.submit.bind(this); if this.submit is never passed to a component event handler like onClick)
    • All JSX used for rendering exists in the render method
    • The component has the minimum amount of code necessary for its purpose and it is broken down into smaller components in order to separate concerns and functions
  • If a new CSS style is added I verified that:
    • A similar style doesn’t already exist
    • The style can’t be created with an existing StyleUtils function (i.e. StyleUtils.getBackgroundAndBorderStyle(themeColors.componentBG)
  • If the PR modifies a generic component, I tested and verified that those changes do not break usages of that component in the rest of the App (i.e. if a shared library or component like Avatar is modified, I verified that Avatar is working as expected in all cases)
  • If the PR modifies a component related to any of the existing Storybook stories, I tested and verified all stories for that component are still working as expected.

QA Steps

  1. Open the app
  2. Go to a chat
  3. Click on the "+" sign
  4. Select add Attachment
  5. Select a screenshot (mad from your phone)
  6. Verify that image is not cropped
  7. View the image attachment that already sends
  8. Verify that image is not cropped
  9. On Android verify that the extra space on header is gone
  • Verify that no errors appear in the JS console

Screenshots

Web

screen-recording-2022-04-28-at-001441_OPmDjIIA.mp4

Mobile Web

screen-recording-2022-04-28-at-002128_HCHQXpgR.mp4
screen-recording-2022-04-28-at-002226_lavPlAEH.mp4

Desktop

screen-recording-2022-04-28-at-002457_SGBSqGvX.mp4

iOS

screen-recording-2022-04-28-at-003039_YbCTeXb8.mp4

Android

screen-recording-2022-04-28-at-005258_PFsJEebF.mp4

@mollfpr mollfpr requested a review from a team as a code owner April 27, 2022 17:59
@melvin-bot melvin-bot bot requested review from AndrewGable and Santhosh-Sellavel and removed request for a team April 27, 2022 18:00
@mollfpr mollfpr changed the title Fix 8115 Fix image looks cropped In the Preview page Apr 27, 2022
@mollfpr
Copy link
Contributor Author

mollfpr commented Apr 29, 2022

bump @Santhosh-Sellavel @AndrewGable

shouldAddTopSafeAreaPadding = true;

// Only apply top padding on iOS since only iOS using SafeAreaView and the top insets is not apply
shouldAddTopSafeAreaPadding = Platform.OS === 'ios';
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please use getPlatform to compare CONST.OS constants to compare platform.

@Santhosh-Sellavel
Copy link
Collaborator

@mollfpr
Once the requested changes are done, will review this today or by Monday. Thanks

cc: @AndrewGable

@mollfpr
Copy link
Contributor Author

mollfpr commented Apr 29, 2022

@Santhosh-Sellavel

Updated! I'm using CONST.PLATFORM instead, since the getPlatform() returning those variable. Tested on both devices.

@Santhosh-Sellavel
Copy link
Collaborator

Reviewing this now

src/styles/getModalStyles.js Outdated Show resolved Hide resolved
@Santhosh-Sellavel
Copy link
Collaborator

Everything looks good tests well.

Just comment here seems incomplete to me!

cc: @mollfpr @AndrewGable

Co-authored-by: Santhoshkumar Sellavel <85645967+Santhosh-Sellavel@users.noreply.github.com>
@AndrewGable
Copy link
Contributor

Sorry I didn't catch this earlier in the proposal but I posted a question in our Slack channel about this PR https://expensify.slack.com/archives/C01GTK53T8Q/p1651544907690039

I thought that the specific platform checks were not allowed, but will discuss with the team and get back to you on this PR.


export default (type, windowDimensions, popoverAnchorPosition = {}, containerStyle = {}) => {
export default ({shouldModalAddTopSafeAreaPadding = {}}) => (type, windowDimensions, popoverAnchorPosition = {}, containerStyle = {}) => {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here I modified the current function with a new function that accept parameters that can be determined what modal type should apply the top padding.

The previous code has shouldAddTopSafeAreaPadding returning true on CONST.MODAL.MODAL_TYPE.CENTERED, CONST.MODAL.MODAL_TYPE.CENTERED_UNSWIPEABLE, and CONST.MODAL.MODAL_TYPE.RIGHT_DOCKED. For android we can specified CONST.MODAL.MODAL_TYPE.CENTERED and CONST.MODAL.MODAL_TYPE.CENTERED_UNSWIPEABLE no to add top padding by returning shouldAddTopSafeAreaPadding with false.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mollfpr

I think shouldAddSafeAreaPadding could be a library where computations can happen in platform-specific files.
Could be added inside the getModalStyle folder itself.

Any thoughts @AndrewGable?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Santhosh-Sellavel Can you outline your suggested fix?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Santhosh-Sellavel Can you outline your suggested fix?

Copy link
Collaborator

@Santhosh-Sellavel Santhosh-Sellavel May 4, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@AndrewGable

Suggestion 1

Could be as simple as the library name shouldAddSafeAreaPadding where index.ios.js returns true and index.js returns false. And call it from the appropriate line (as per the proposed solution).

Suggestion 2

Could be as simple as the library name shouldAddSafeAreaPadding where
index.ios.js
index.android.js
index.js

returns appropriate boolean value based on MODAL_TYPE.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think suggestion 2 will be good solution.

@@ -16,7 +16,7 @@ export default (type, windowDimensions, popoverAnchorPosition = {}, containerSty
let animationOut;
let hideBackdrop = false;
let shouldAddBottomSafeAreaPadding = false;
let shouldAddTopSafeAreaPadding = false;
const shouldAddTopSafeAreaPadding = shouldModalAddTopSafeAreaPadding[type] || false;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This where shouldAddTopSafeAreaPadding will have according to what value we want from specific platform.

Comment on lines 1 to 10
import CONST from '../../CONST';
import getModalStyles from './getModalStyles';

export default getModalStyles({
shouldModalAddTopSafeAreaPadding: {
[CONST.MODAL.MODAL_TYPE.CENTERED]: true,
[CONST.MODAL.MODAL_TYPE.CENTERED_UNSWIPEABLE]: true,
[CONST.MODAL.MODAL_TYPE.RIGHT_DOCKED]: true,
},
});
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This are the default value before refactoring.


export default getModalStyles({
shouldModalAddTopSafeAreaPadding: {
[CONST.MODAL.MODAL_TYPE.RIGHT_DOCKED]: true,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We only need to set CONST.MODAL.MODAL_TYPE.RIGHT_DOCKED to true since that's the only thing that doesn't no break on android.


export default (type, windowDimensions, popoverAnchorPosition = {}, containerStyle = {}) => {
export default ({shouldModalAddTopSafeAreaPadding = {}}) => (type, windowDimensions, popoverAnchorPosition = {}, containerStyle = {}) => {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mollfpr

I think shouldAddSafeAreaPadding could be a library where computations can happen in platform-specific files.
Could be added inside the getModalStyle folder itself.

Any thoughts @AndrewGable?

@mollfpr
Copy link
Contributor Author

mollfpr commented May 5, 2022

I just create a function called getShouldAddTopSafeAreaPadding which will be used by android platform and others. I also revert back to the getModalStyles.js file and update to use getShouldAddTopSafeAreaPadding().

cc @Santhosh-Sellavel @AndrewGable

@AndrewGable
Copy link
Contributor

@Santhosh-Sellavel - Happy to defer to you here on specific design of the platform specific design 👍

@mollfpr
Copy link
Contributor Author

mollfpr commented May 9, 2022

Hey @Santhosh-Sellavel is my latest commit correct?

Copy link
Collaborator

@Santhosh-Sellavel Santhosh-Sellavel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getModalStyles folder should stay in the styles folder only. @mollfpr

also, rename the existing getModalStyles.js file to baseGetModalStyles.js.

@mollfpr mollfpr requested a review from Santhosh-Sellavel May 13, 2022 01:19
Copy link
Collaborator

@Santhosh-Sellavel Santhosh-Sellavel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the back and forth @mollfpr,

Just one small suggestion, rename baseGetModalStyles to getBaseModalStyles,

Everything else looks good, and tests well!

@AndrewGable I'll leave it to you for the final review!

@Santhosh-Sellavel
Copy link
Collaborator

Santhosh-Sellavel commented May 13, 2022

PR Reviewer Checklist

  • I verified the correct issue is linked in the ### Fixed Issues section above
  • I verified testing steps are clear and they cover the changes made in this PR
    • I verified the steps for local testing are in the Tests section
    • I verified the steps for Staging and/or Production testing are in the QA steps section
    • I verified the steps cover any possible failure scenarios (i.e. verify an input displays the correct error message if the entered data is not correct)
    • I turned off my network connection and tested it while offline to ensure it matches the expected behavior (i.e. verify the default avatar icon is displayed if app is offline)
  • I checked that screenshots or videos are included for tests on all platforms
  • I verified tests pass on all platforms & I tested again on:
    • iOS / native
    • Android / native
    • iOS / Safari
    • Android / Chrome
    • MacOS / Chrome
    • MacOS / Desktop
  • I verified there are no console errors (if there’s a console error not related to the PR, report it or open an issue for it to be fixed)
  • I verified proper code patterns were followed (see Reviewing the code)
    • I verified that any callback methods that were added or modified are named for what the method does and never what callback they handle (i.e. toggleReport and not onIconClick).
    • I verified that comments were added to code that is not self explanatory
    • I verified that any new or modified comments were clear, correct English, and explained “why” the code was doing something instead of only explaining “what” the code was doing.
    • I verified any copy / text shown in the product was added in all src/languages/* files
    • I verified any copy / text that was added to the app is correct English and approved by marketing by tagging the marketing team on the original GH to get the correct copy.
    • I verified proper file naming conventions were followed for any new files or renamed files. All non-platform specific files are named after what they export and are not named “index.js”. All platform-specific files are named for the platform the code supports as outlined in the README.
    • I verified the JSDocs style guidelines (in STYLE.md) were followed
  • If a new code pattern is added I verified it was agreed to be used by multiple Expensify engineers
  • I verified that this PR follows the guidelines as stated in the Review Guidelines
  • I verified all code is DRY (the PR doesn't include any logic written more than once, with the exception of tests)
  • I verified any variables that can be defined as constants (ie. in CONST.js or at the top of the file that uses the constant) are defined as such
  • If a new component is created I verified that:
    • A similar component doesn't exist in the codebase
    • All props are defined accurately and each prop has a /** comment above it */
    • Any functional components have the displayName property
    • The file is named correctly
    • The component has a clear name that is non-ambiguous and the purpose of the component can be inferred from the name alone
    • The only data being stored in the state is data necessary for rendering and nothing else
    • For Class Components, any internal methods passed to components event handlers are bound to this properly so there are no scoping issues (i.e. for onClick={this.submit} the method this.submit should be bound to this in the constructor)
    • Any internal methods bound to this are necessary to be bound (i.e. avoid this.submit = this.submit.bind(this); if this.submit is never passed to a component event handler like onClick)
    • All JSX used for rendering exists in the render method
    • The component has the minimum amount of code necessary for its purpose and it is broken down into smaller components in order to separate concerns and functions
  • If a new CSS style is added I verified that:
    • A similar style doesn’t already exist
    • The style can’t be created with an existing StyleUtils function (i.e. StyleUtils.getBackgroundAndBorderStyle(themeColors.componentBG)
  • If the PR modifies a generic component, I tested and verified that those changes do not break usages of that component in the rest of the App (i.e. if a shared library or component like Avatar is modified, I verified that Avatar is working as expected in all cases)
  • If the PR modifies a component related to any of the existing Storybook stories, I tested and verified all stories for that component are still working as expected.

@mollfpr mollfpr requested a review from Santhosh-Sellavel May 13, 2022 18:15
Copy link
Collaborator

@Santhosh-Sellavel Santhosh-Sellavel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Asking to update the comments, otherwise looks good, and tests well!

cc: @AndrewGable

src/styles/getModalStyles/index.android.js Outdated Show resolved Hide resolved
Co-authored-by: Santhoshkumar Sellavel <85645967+Santhosh-Sellavel@users.noreply.github.com>
@mollfpr mollfpr requested a review from Santhosh-Sellavel May 16, 2022 01:16
Copy link
Collaborator

@Santhosh-Sellavel Santhosh-Sellavel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, and tests well!

@AndrewGable All you!

@mollfpr
Copy link
Contributor Author

mollfpr commented May 17, 2022

@AndrewGable bump 👆

@AndrewGable AndrewGable merged commit 44326c9 into Expensify:main May 17, 2022
@OSBotify
Copy link
Contributor

✋ This PR was not deployed to staging yet because QA is ongoing. It will be automatically deployed to staging after the next production release.

@OSBotify
Copy link
Contributor

🚀 Deployed to staging by @AndrewGable in version: 1.1.63-0 🚀

platform result
🤖 android 🤖 success ✅
🖥 desktop 🖥 success ✅
🍎 iOS 🍎 failure ❌
🕸 web 🕸 success ✅

@OSBotify
Copy link
Contributor

🚀 Deployed to staging by @AndrewGable in version: 1.1.63-0 🚀

platform result
🤖 android 🤖 success ✅
🖥 desktop 🖥 success ✅
🍎 iOS 🍎 success ✅
🕸 web 🕸 success ✅

@OSBotify
Copy link
Contributor

🚀 Deployed to production by @AndrewGable in version: 1.1.63-2 🚀

platform result
🤖 android 🤖 success ✅
🖥 desktop 🖥 success ✅
🍎 iOS 🍎 success ✅
🕸 web 🕸 success ✅

@s77rt
Copy link
Contributor

s77rt commented Mar 3, 2023

This PR is partly responsible for a regression here #15288. The containerHeight is mishandled where it's referenced here before being correctly set onLayout i.e. there is no guarantee that containerHeight will be set then referenced, a race condition is to reference containerHeight before being set.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants