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

feat: Dynamic emoji size #3561

Merged

Conversation

pranshuchittora
Copy link
Contributor

@pranshuchittora pranshuchittora commented Jun 11, 2021

Details

Fixed Issues

Fixes #2662

Tests

QA Steps

  • Check for emoji sizes in small devices.
  • Check for emoji overflow/clipping

Tested On

  • Web
  • Mobile Web
  • Desktop
  • iOS
  • Android

Screenshots

Web

Screenshot 2021-07-03 at 12 11 19 AM

Mobile Web

Screenshot 2021-07-03 at 12 11 57 AM

Desktop

Screenshot 2021-07-03 at 12 23 49 AM

iOS

Simulator Screen Shot - iPhone 12 - 2021-07-02 at 22 09 58

Android

Smallest device possible (approx 320)
Screenshot from 2021-06-28 22-40-58

Medium Size WVGA
Screenshot from 2021-06-28 22-41-21

High DPI
Screenshot from 2021-06-28 22-43-08

@pranshuchittora pranshuchittora requested a review from a team as a code owner June 11, 2021 20:02
@MelvinBot MelvinBot requested review from nickmurray47 and removed request for a team June 11, 2021 20:02
@pranshuchittora
Copy link
Contributor Author

@chiragsalian I am able to get this to work.

Screenshot from 2021-06-12 01-21-02
Screenshot from 2021-06-12 01-20-19

But the flatlist is not re-rendering and getting this weird effect on hover as the size changes are not being reflected.

Peek.2021-06-12.01-22.mp4

return styleVariables.fontSizeSmall;
}
if (
windowWidth <= 480
Copy link
Contributor

Choose a reason for hiding this comment

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

Let's convert this to a single line if condition for consistency. Its weird seeing a mix of single and double line if statements when they have just 1 condition in them.


componentDidUpdate(prevProps) {
if (
this.props.windowWidth !== prevProps.windowWidth
Copy link
Contributor

Choose a reason for hiding this comment

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

Same as before, let's make this a single line if statement.

if (
this.props.windowWidth !== prevProps.windowWidth
) {
// eslint-disable-next-line react/no-did-update-set-state
Copy link
Contributor

Choose a reason for hiding this comment

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

Is there a reason you would prefer to disable this rule. IMO it feels just as easy to create a method like setDynamicEmojiSize and call that method here that would do,

this.setState({emojiSize: dynamicEmojiSize(this.props.windowWidth)});

Then you wouldn't need to disable the eslint rule.

@@ -17,6 +17,8 @@ const propTypes = {

/** Whether this menu item is currently highlighted or not */
isHighlighted: PropTypes.bool.isRequired,

size: PropTypes.number.isRequired,
Copy link
Contributor

Choose a reason for hiding this comment

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

missing JS doc.

}


Copy link
Contributor

Choose a reason for hiding this comment

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

remove unnecessary line break

if (
this.props.windowWidth !== prevProps.windowWidth
) {
// eslint-disable-next-line react/no-did-update-set-state
Copy link
Contributor

@chiragsalian chiragsalian Jun 14, 2021

Choose a reason for hiding this comment

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

Similar comment as here


const propTypes = {
/** Function to add the selected emoji to the main compose text input */
onEmojiSelected: PropTypes.func.isRequired,

...windowDimensionsPropTypes,
Copy link
Contributor

Choose a reason for hiding this comment

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

NAB: I see there are many places in our code where this is prop is not documented but as per our style guide it would be nice if you include a JS comment doc for this for consistency.

@pranshuchittora
Copy link
Contributor Author

@chiragsalian I have updated the PR

@chiragsalian
Copy link
Contributor

But the flatlist is not re-rendering and getting this weird effect on hover as the size changes are not being reflected.

Just saw this. I was OOO on Friday so just getting to this today. I'll first ask @stitesExpensify opinion if he knows how to tackle this since he worked on this. Stites could you let us know if you know a fix for the problem he mentioned. He shared a video of the problem too which helps. If you have no idea then I'll pull the code and start debugging. (I'm a little swamped today hence was asking you first)

@chiragsalian
Copy link
Contributor

Also i think you should be giving emoji size as a prop to EmojiPickerMenu/index.js because the way it is now, if you calculate and call setState on EmojiPickerMenu/index.js you'll be rerendering so many times within the emoji component (you can test this by logging the render and see that it'll be called almost infinitely). I definitely think we should avoid a setState if possible and I don't think we should care about the width changing dynamically for now so the problem you mentioned may be a non issue but I'll let @stitesExpensify share his thoughts on the same as well.

}

if (windowWidth <= 320) { return styleVariables.fontSizeSmall; }
if (windowWidth <= 480) { return styleVariables.fontSizeNormal; }
Copy link
Contributor

Choose a reason for hiding this comment

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

oh sorry for the confusion, i didn't mean the whole line, just the if condition, i.e.,

if (windowWidth <= 480) {
    return styleVariables.fontSizeNormal;
}

That would match our examples in the style guide. Could you make the same changes to the if conditions in your file.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

@pranshuchittora
Copy link
Contributor Author

Also i think you should be giving emoji size as a prop to EmojiPickerMenu/index.js because the way it is now, if you calculate and call setState on EmojiPickerMenu/index.js you'll be rerendering so many times within the emoji component (you can test this by logging the render and see that it'll be called almost infinitely). I definitely think we should avoid a setState if possible and I don't think we should care about the width changing dynamically for now so the problem you mentioned may be a non issue but I'll let @stitesExpensify share his thoughts on the same as well.

Is this for me @chiragsalian

@chiragsalian
Copy link
Contributor

I don't think we should care about the width changing dynamically for now so the problem you mentioned may be a non issue but I'll let @stitesExpensify share his thoughts on the same as well.

So just this part is for stites and the rest was for you. Also it looks like stites is OOO today so I guess now all of it is for you 🙂
Let me know your thoughts.

@chiragsalian
Copy link
Contributor

Also i don't think there is any reason to make your changes to index.js. We don't have any issue with the way the emojis work on web so I think we should just focus on fixing it for mobile. So just having your code for index.native.js and testing it on android and ios for different mobile widths would suffice.

@nickmurray47
Copy link
Contributor

@pranshuchittora hey! I'm interested in pushing this along and wondering if there were any updates on your end. It looks like the issue is that we expect the extraData prop to help trigger a flatList re-render but instead the items only re-render when you hover over them. Does that sound accurate and have you found out anything additional?

@pranshuchittora
Copy link
Contributor Author

pranshuchittora commented Jun 18, 2021

@nickmurray47
Yep the items are not re-rendering even extraData changes. And only re-renders on hovering, I am not able to find any workaround.

@chiragsalian
Copy link
Contributor

@pranshuchittora, so you mention re-rendering. But i don't see how the dimension would change on the mobile device such that we'd have to worry about re-renders (well landscape and portrait could exist but I think that's an improvement for a later date).
For now can't we detect whats the current width, if its less than a certain number pass it as a prop and then over here instead of styles.emojiText use a new style like styles.emojiTextSmall which has a smaller font.

Then test if its works for Huawei P20 Pro / Android 10 on a simulator and we should be good right?

Comment on lines 77 to 79
emojiSize: {
fontSize: dynamicEmojiSize(this.props.windowWidth),
},
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Why this?

To reduce the memory overhead of creating objects for each emoji.

Copy link
Contributor

Choose a reason for hiding this comment

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

Nice

@pranshuchittora
Copy link
Contributor Author

@chiragsalian I have updated the PR

Smallest device possible (approx 320)
Screenshot from 2021-06-28 22-40-58

Medium Size WVGA
Screenshot from 2021-06-28 22-41-21

High DPI
Screenshot from 2021-06-28 22-43-08

Copy link
Contributor

@chiragsalian chiragsalian left a comment

Choose a reason for hiding this comment

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

Left a minor comment. The rest looks much better to me. I tested and it works well too.


this.state = {
emojiSize: {fontSize: dynamicEmojiSize(this.props.windowWidth)},
};
Copy link
Contributor

Choose a reason for hiding this comment

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

Do you need this state variable? Its not really changing anywhere in the component so I don't quite see the benefit.
How about if you just did,

emojiSize={fontSize: dynamicEmojiSize(this.props.windowWidth)}

over here.

If you think that's not too readable then we should just do this.emojiSize than save it in a state variable. Thoughts?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The idea of keeping it in a state opens the door for any future development for reactivity for emoji sizes.
And adding it to the state doesn't create any overhead.

We can remove it from the state and make it a normal class property.

- this.state.emojiSize
+ this.emojiSize

Copy link
Contributor

Choose a reason for hiding this comment

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

The idea of keeping it in a state opens the door for any future development for reactivity for emoji sizes.

Making code more complex than it needs to be with the assumption that it will be modified in the future is unnecessary preoptimization. When its needed to be a state variable for any reason then its easy enough to convert so let's not have it be a state variable right now.

Sure I'm fine with class property 👍
Could you update?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done I have updated the PR

@pranshuchittora
Copy link
Contributor Author

I have updated the PR. Updating the screenshots and QA steps asynchronously.

Copy link
Contributor

@chiragsalian chiragsalian left a comment

Choose a reason for hiding this comment

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

Nice, ty. Code LGTM 👍

@chiragsalian
Copy link
Contributor

@nickmurray47 bump to review.

@pranshuchittora
Copy link
Contributor Author

I have updated all the screenshots and QA steps

Copy link
Contributor

@nickmurray47 nickmurray47 left a comment

Choose a reason for hiding this comment

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

Tests well and code LGTM

@nickmurray47 nickmurray47 merged commit e78340b into Expensify:main Jul 6, 2021
@OSBotify
Copy link
Contributor

OSBotify commented Jul 6, 2021

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

@roryabraham
Copy link
Contributor

Unfortunately the deploy comments are not working right now. This was deployed to staging yesterday.

@Jag96
Copy link
Contributor

Jag96 commented Jul 14, 2021

Commented in #4030 (comment) about a regression from this PR

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.

[Hold for payment 2021-07-13] Emojis - Emojis are cut on the sides in emoji picker
6 participants