Fix emoji offset issues#8902
Conversation
src/CONST.js
Outdated
| NON_NATIVE_EMOJI_PICKER_LIST_HEIGHT: 300, | ||
| EMOJI_PICKER_ITEM_HEIGHT: 40, | ||
| NON_NATIVE_EMOJI_PICKER_LIST_HEIGHT: 295, | ||
| EMOJI_PICKER_ITEM_HEIGHT: 34.5, |
There was a problem hiding this comment.
We definitely don't want floats so let's round this off to 35.
There was a problem hiding this comment.
I tried rounding off. But with 35, highlighted emoji shifts up with each click and with 34, shifts down with each click.
| } else if (offsetAtEmojiTop - CONST.EMOJI_PICKER_HEADER_HEIGHT <= this.currentScrollOffset) { | ||
| targetOffset = offsetAtEmojiTop - CONST.EMOJI_PICKER_HEADER_HEIGHT; |
There was a problem hiding this comment.
Could you please explain this change?
There was a problem hiding this comment.
As Emoji Picker Header is what remains at the top, we need to subtract emoji picker header height not emoji height. Here, this calculation is trying to detect if emoji has gone out of view while pressing up arrow.
There was a problem hiding this comment.
let's put this as a comment in the code.
There was a problem hiding this comment.
@parasharrajat Any suggestion?
} else if (offsetAtEmojiTop - CONST.EMOJI_PICKER_HEADER_HEIGHT <= this.currentScrollOffset) {
+ // As Emoji Picker Header is what remains at the top, EMOJI_PICKER_HEADER_HEIGHT is subtracted from offsetAtEmojiTop
targetOffset = offsetAtEmojiTop - CONST.EMOJI_PICKER_HEADER_HEIGHT;
}
parasharrajat
left a comment
There was a problem hiding this comment.
It's not working for me on Chrome Mac. After a while, highlighted emoji is out of view. Also, it is important that the fix works for reverse scrolling as well.
I will take a look.
I have tested it for reverse scrolling as well and it is working fine for reverse as well. |
|
Hello @parasharrajat! As you mentioned, after scrolling a while, the scrollbar bumps up and highlighted emoji goes out of view. So, I thought it might be because of initial number of emojis rendered in the flat list. I tried adding initialNumToRender. And it worked. Also, I found that some emojis has different height. So, we need to add lineheight in emojiText in styles.js // Emoji Picker Styles
emojiText: {
fontFamily: fontFamily.GTA_BOLD,
textAlign: 'center',
fontSize: variables.emojiSize,
+ lineHeight: 27, //variables.emojiLineHeight
...spacing.pv0,
...spacing.ph0,
},
After this change, we can avoid use of float in EMOJI_PICKER_ITEM_HEIGHT in CONST.js . |
|
Ok.
Could you please explain to me, how?
Good point I was going to suggest the same. We should fix the height of emojis. But why line-height? Can't we do with height and width? |
After scrolling a while, the scrollbar jumps up as if new items are added to the bottom of the scrollview and highlighted emoji goes out of view. So, I thought it might be because of initial number of items rendered. It should not be the case by default. But as we are using our own calculations to move the scroll view, this issue might have arisen.
Yes, we can also achieve it by adding height in emojiItem. emojiItem: {
width: '12.5%',
textAlign: 'center',
borderRadius: 8,
+ height: CONST.EMOJI_PICKER_ITEM_HEIGHT,
},But with this change, we need to make some change in styling in EmojiSkinToneList as the addition of height breaks the styling. |
we can maintain the scroll position.
Using line-Height will not work as expected all the time. Height on the other hand should be best for performance reasons as well. I think all emojis have fixed sizes so we should be good to use heights. Let's do that and you can also use line heights to center the emojis. |
|
Thanks for waiting, I will review this asap. |
parasharrajat
left a comment
There was a problem hiding this comment.
Scrolling seems to work better now but there is one issue which you mentioned. I noticed such kind of issue when I was scrolling around Objects section.
| : ( | ||
| <FlatList | ||
| ref={el => this.emojiList = el} | ||
| initialNumToRender={400} |
There was a problem hiding this comment.
This needs to be removed. This is not a solution to the problem you were mentioning.
First, I do not understand the problem. Please add a video so that we can open this to broader audiences.
This change will also hurt performance.
I noticed a similar issue. When I was scrolling around the objects section of emoji, highlighted emoji was out of view. I think this is due to something else. Let's try maintainescrollPosition.
There was a problem hiding this comment.
With the introduction of intialNumToRender={400} (even we can have initialNumToRender as low as 100), this issue is no longer reproducible.
Screen.Recording.2022-06-16.at.19.11.16.mov
There was a problem hiding this comment.
scrollPosition is maintained onScroll={e => this.currentScrollOffset = e.nativeEvent.contentOffset.y}. But this value this.currentScrollOffset changes abruptly resulting the issue. I cannot find any bug in calculations in scrollToHighlightedIndex() function. Introduction of initialNumToRender={100} solving the issue also suggests no bugs in scrollToHighlightedIndex()
There was a problem hiding this comment.
But this value this.currentScrollOffset changes abruptly resulting the issue.
Good catch, we are one step closer to the real problem now. Now the thing is to find out what is causing this .
There was a problem hiding this comment.
I cannot find the reason why this.currentScrollOffset value changes abruptly. I also cannot find the reason why, with the introduction of initalNumToRender, this.currentScrollOffset value does not change abruptly.
There was a problem hiding this comment.
No luck. The flat list is giving me nuts.
So first let's set this to 100.
| () => this.setState(prev => ({isSkinToneListVisible: !prev.isSkinToneListVisible})) | ||
| } | ||
| style={[ | ||
| styles.pv1, |
There was a problem hiding this comment.
Let's add this back to the emoji but include this on the emoji height so that we can cover this value. Motive should always be to keep the same UI. I see that UI is little bit different from staging.
There was a problem hiding this comment.
This is not the reason for slight change in UI. It is due to the introduction of EMOJI_PICKER_ITEM_HEIGHT and variables.emojiLineHeight.
I am also not sure what is causing this. But I think we need to maintain the scroll position to fix this. |
|
@sobitneupane Any update for me. |
|
@sobitneupane Could you please merge into this? |
|
Bump @sobitneupane. |
I will do it shortly. I was away last two months. Sorry for the inconvenience. |
|
Bump. |
|
@sobitneupane I tested that there are no changes in the behavior after merging the latest main. But I am still actively looking into it. Could you please merge main again? |
@parasharrajat Merged Main. |
|
Thanks |
|
Bump @sobitneupane ⬆️ |
|
@sobitneupane can you confirm when you've made changes and it's ready for re-review? |
|
It is ready for review. |
|
Cool, thanks! It would be great to comment to let people know explicitly, or request a re-review. |
|
I am facing some issues with Mac so I won't be able to test all platforms until that issue is fixed. Hoping to get it fixed asap and get back on it.
|
|
@sobitneupane Could you please merge into this? Need that for testing. |
@parasharrajat Merged. |
parasharrajat
left a comment
There was a problem hiding this comment.
Screenshots
🔲 iOS / native
screen-2022-11-09_04.29.01.mp4
🔲 iOS / Safari
screen-2022-11-09_03.23.10.mp4
🔲 MacOS / Desktop
screen-2022-11-09_03.21.53.mp4
🔲 MacOS / Chrome
screen-2022-11-09_00.35.27.mp4
screen-2022-11-09_00.38.24.mp4
🔲 Android / Chrome
screen-2022-11-09_02.47.49.mp4
🔲 Android / native
screen-2022-11-09_02.42.02.mp4
|
It seems that emojis are not centered in the highlighted area on iOS. @sobitneupane Can you please update the videos in the details with the latest. |
@parasharrajat Videos/Screenshots in the details are latest. |
|
|
Oh, I have a feeling that's because of this issue that @fedirjh has just submitted a proposal. Edit: Ah, you're not talking about the compose box once selected here. My mind when right there when looking at the video. 😅 |
@parasharrajat Issue fixed |
parasharrajat
left a comment
There was a problem hiding this comment.
LGTM. Thanks for the changes and your patience.
cc: @chiragsalian
PR Reviewer Checklist
- I have verified the author checklist is complete (all boxes are checked off).
- I verified the correct issue is linked in the
### Fixed Issuessection 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
Testssection - I verified the steps for Staging and/or Production testing are in the
QA stepssection - 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 verified the steps for local testing are in the
- I checked that screenshots or videos are included for tests on all platforms
- I included screenshots or videos 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
- If there are any errors in the console that are unrelated to this PR, I either fixed them (preferred) or linked to where I reported them in Slack
- 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.
toggleReportand notonIconClick). - 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 adding the
Waiting for Copylabel for a copy review 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
- 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.
- 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 other components that can be impacted by these changes have been tested, and I retested again (i.e. if the PR modifies a shared library or component like
Avatar, I verified the components usingAvatarhave been tested & I retested again) - 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 */ - 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
thisproperly so there are no scoping issues (i.e. foronClick={this.submit}the methodthis.submitshould be bound tothisin the constructor) - Any internal methods bound to
thisare necessary to be bound (i.e. avoidthis.submit = this.submit.bind(this);ifthis.submitis never passed to a component event handler likeonClick) - 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
Avataris modified, I verified thatAvataris 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.
- I have checked off every checkbox in the PR reviewer checklist, including those that don't apply to this PR.
🎀 👀 🎀 C+ reviewed
chiragsalian
left a comment
There was a problem hiding this comment.
Code LGTM and seems to work well for me. Tested on web and ios.
Thanks for pushing this forward gents 🙇
|
I will create a follow-up issue for the Flatlist behavior when this is merged. |
|
@chiragsalian looks like this was merged without the checklist test passing. Please add a note explaining why this was done and remove the |
|
Not an emergency, GH actions were failing on |
|
✋ 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 @chiragsalian in version: 1.2.28-0 🚀
|
|
🚀 Deployed to staging by @chiragsalian in version: 1.2.28-0 🚀
|
|
🚀 Deployed to production by @roryabraham in version: 1.2.28-2 🚀
|
Details
Fixed Issues
$ #8459
Tests
PR Review Checklist
PR Author Checklist
### Fixed Issuessection aboveTestssectionQA stepssectiontoggleReportand notonIconClick)src/languages/*filesWaiting for Copylabel for a copy review on the original GH to get the correct copy.STYLE.md) were followedAvatar, I verified the components usingAvatarare working as expected)/** comment above it */thisproperly so there are no scoping issues (i.e. foronClick={this.submit}the methodthis.submitshould be bound tothisin the constructor)thisare necessary to be bound (i.e. avoidthis.submit = this.submit.bind(this);ifthis.submitis never passed to a component event handler likeonClick)StyleUtils.getBackgroundAndBorderStyle(themeColors.componentBG)Avataris modified, I verified thatAvataris working as expected in all cases)PR Reviewer Checklist
### Fixed Issuessection aboveTestssectionQA stepssectiontoggleReportand notonIconClick).src/languages/*filesSTYLE.md) were followed/** comment above it */displayNamepropertythisproperly so there are no scoping issues (i.e. foronClick={this.submit}the methodthis.submitshould be bound tothisin the constructor)thisare necessary to be bound (i.e. avoidthis.submit = this.submit.bind(this);ifthis.submitis never passed to a component event handler likeonClick)StyleUtils.getBackgroundAndBorderStyle(themeColors.componentBG)Avataris modified, I verified thatAvataris working as expected in all cases)QA Steps
Screenshots
Web
Screen.Recording.2022-11-09.at.07.40.26.mov
Mobile Web - Chrome
screen_recording_chrome.mov
Mobile Web - Safari
Screen.Recording.2022-11-09.at.07.36.16.mov
Desktop
Screen.Recording.2022-11-09.at.07.43.10.mov
iOS
Screen.Recording.2022-11-09.at.07.33.29.mov
Android
Screen.Recording.2022-11-09.at.07.49.13.mov