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 frequently used emojis list doesn't get updated when adding emojis by typing emoji code with colon #18396

Conversation

bernhardoj
Copy link
Contributor

@bernhardoj bernhardoj commented May 4, 2023

Details

We are not updating the frequently used emojis list when adding emojis by typing emoji code with colon in the composer. This PR will make sure the list is updated.

Fixed Issues

$ #17599
PROPOSAL: #17599 (comment)

Tests

Same as QA Steps

  • Verify that no errors appear in the JS console

Offline tests

No request will be called while offline

QA Steps

There are 2 ways to test this:
Simple way to test

  1. Open a chat.
  2. Type an emoji code that is not in your frequently used emoji list in the composer with colon, for example :wave:.
  3. Open the emoji picker and verify that the typed emoji is added to the Frequently Used emoji list.
  4. Edit the message.
  5. Repeat step 2 in the edit composer.
  6. Open the emoji picker and verify that the typed emoji is added to the frequently used emoji list.

A bit technical way to test

First of all, open the Network Tab.

Web (Safari)

  1. Open Safari > Settings
  2. Open Advanced Tab
  3. Check Show Develop menu
  4. Open Develop menu > Show JavaScript console
  5. Switch to Network Tab

Desktop

  1. Open View > Toggle Developer Tools
  2. Switch to Network tab

mWeb (Safari)

  1. Open Safari > Settings
  2. Open Advanced Tab
  3. Check Show Develop menu
  4. Open Develop menu > [iOS Device Name, e.g. Simulator - iPhone 14 - iOS 16.2] > Choose New Expensify url
  5. It will open a Web Inspector. Switch to Network Tab

mWeb (Chrome)

  1. Open Chrome
  2. Go to chrome://inspect
  3. Look for the New Expensify url and click inspect
  4. It will open an inspector. Switch to Network Tab

Native
I don't think there is a Network Tab in native, so to see the request is being made, we can look at the terminal (dev only)


  1. Open any chat
  2. Type :smile: in the composer
  3. Verify UpdateFrequentlyUsedEmojis request is being made in the Network Tab
  4. Send a message
  5. Edit the message
  6. Type :smile: in the edit composer
  7. Verify UpdateFrequentlyUsedEmojis request is being made in the Network Tab
  • Verify that no errors appear in the JS console

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 the expected offline behavior in the Offline steps 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 tested this PR with a High Traffic account against the staging or production API to ensure there are no regressions (e.g. long loading states that impact usability).
  • I included screenshots or videos for tests on all platforms
  • I ran the tests on all platforms & verified they passed on:
    • Android / native
    • Android / Chrome
    • iOS / native
    • iOS / Safari
    • MacOS / Chrome / Safari
    • 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 the left part of a conditional rendering a React component is a boolean and NOT a string, e.g. myBool && <MyComponent />.
    • 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 is localized by adding it to src/languages/* files and using the translation method
      • If any non-english text was added/modified, I verified the translation was requested/reviewed in #expensify-open-source and it was approved by an internal Expensify engineer. Link to Slack message:
    • I verified all numbers, amounts, dates and phone numbers shown in the product are using the localization methods
    • I verified any copy / text that was added to the app is grammatically correct in English. It adheres to proper capitalization guidelines (note: only the first word of header/labels should be capitalized), and is approved by marketing by adding the Waiting for Copy label 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
  • 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
  • I verified that if a function's arguments changed that all usages have also been updated correctly
  • 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 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 any new file was added I verified that:
    • The file has a description of what it does and/or why is needed at the top of the file if the code is not self explanatory
  • 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 code that runs when editing or sending messages, I tested and verified there is no unexpected behavior for all supported markdown - URLs, single line code, code blocks, quotes, headings, bold, strikethrough, and italic.
  • 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.
  • If a new page is added, I verified it's using the ScrollView component to make it scrollable when more elements are added to the page.
  • If the main branch was merged into this PR after a review, I tested again and verified the outcome was still expected according to the Test steps.
  • I have checked off every checkbox in the PR author checklist, including those that don't apply to this PR.

Screenshots/Videos

Web
Screen.Recording.2023-05-04.at.15.12.04.mov
Mobile Web - Chrome
Screen.Recording.2023-05-04.at.15.27.42.mov
Mobile Web - Safari
Screen.Recording.2023-05-04.at.15.20.48.mov
Desktop
Screen.Recording.2023-05-04.at.15.16.13.mov
iOS
Screen.Recording.2023-05-04.at.15.25.08.mov
Android
Screen.Recording.2023-05-04.at.15.30.40.mov

@bernhardoj bernhardoj requested a review from a team as a code owner May 4, 2023 08:18
@melvin-bot melvin-bot bot requested review from fedirjh and MonilBhavsar and removed request for a team May 4, 2023 08:18
@MelvinBot
Copy link

@MonilBhavsar @fedirjh One of you needs to 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]

@bernhardoj
Copy link
Contributor Author

Here is additional video showing the count is added correctly.

Screen.Recording.2023-05-04.at.16.23.02.1.mov

Copy link
Contributor

@fedirjh fedirjh left a comment

Choose a reason for hiding this comment

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

Over all looks good, left a suggestion to refactor addToFrequentlyUsedEmojis

src/libs/EmojiUtils.js Outdated Show resolved Hide resolved
src/libs/EmojiUtils.js Show resolved Hide resolved
src/libs/EmojiUtils.js Outdated Show resolved Hide resolved
src/libs/EmojiUtils.js Show resolved Hide resolved
@fedirjh
Copy link
Contributor

fedirjh commented May 5, 2023

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 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 included screenshots or videos for tests on all platforms
  • I verified tests pass on all platforms & I tested again on:
    • Android / native
    • Android / Chrome
    • iOS / native
    • iOS / Safari
    • MacOS / Chrome / Safari
    • 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. toggleReport and not onIconClick).
    • I verified that the left part of a conditional rendering a React component is a boolean and NOT a string, e.g. myBool && <MyComponent />.
    • 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 is localized by adding it to src/languages/* files and using the translation method
    • I verified all numbers, amounts, dates and phone numbers shown in the product are using the localization methods
    • I verified any copy / text that was added to the app is grammatically correct in English. It adheres to proper capitalization guidelines (note: only the first word of header/labels should be capitalized), and is approved by marketing by adding the Waiting for Copy label 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
  • 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 using Avatar have 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 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 any new file was added I verified that:
    • The file has a description of what it does and/or why is needed at the top of the file if the code is not self explanatory
  • 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 code that runs when editing or sending messages, I tested and verified there is no unexpected behavior for all supported markdown - URLs, single line code, code blocks, quotes, headings, bold, strikethrough, and italic.
  • 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.
  • If a new page is added, I verified it's using the ScrollView component to make it scrollable when more elements are added to the page.
  • If the main branch was merged into this PR after a review, I tested again and verified the outcome was still expected according to the Test steps.
  • I have checked off every checkbox in the PR reviewer checklist, including those that don't apply to this PR.

Screenshots/Videos

Web
Screen.Recording.2023-05-06.at.2.34.03.AM.mov
Mobile Web - Chrome
Screen.Recording.2023-05-08.at.5.45.52.PM.mov
Mobile Web - Safari
Screen.Recording.2023-05-08.at.4.46.53.PM.mov
Desktop
Screen.Recording.2023-05-06.at.2.30.40.AM.mov
iOS
Screen.Recording.2023-05-06.at.2.35.33.AM.mov
Android
Screen.Recording.2023-05-08.at.5.48.04.PM.mov

@bernhardoj
Copy link
Contributor Author

@fedirjh Addressed the suggestion with a little bit differences and addition.

We can't use the suggestion name as the emoji name as the suggestion is different. I also pass the types so the emoji skin works for the frequent emoji list.

Comment on lines 199 to 200
const frequentEmojiListOrdered = lodashOrderBy(mergedEmojisWithFrequent, ['count', 'lastUpdatedAt'], ['desc', 'desc'])
.slice(0, maxFrequentEmojiCount);
Copy link
Contributor

Choose a reason for hiding this comment

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

@bernhardoj Thanks for the update. While testing, I noticed that we missed the case where we select a new emoji from the emoji picker. The newly selected emoji should appear on the frequent list. However, the above changes do not account for that case. Therefore, we need to fix it. Here is a simple fix:

Suggested change
const frequentEmojiListOrdered = lodashOrderBy(mergedEmojisWithFrequent, ['count', 'lastUpdatedAt'], ['desc', 'desc'])
.slice(0, maxFrequentEmojiCount);
let frequentEmojiListOrdered = lodashOrderBy(mergedEmojisWithFrequent, ['count', 'lastUpdatedAt'], ['desc', 'desc']);
if (uniqueEmojisWithCounts.length === 1 && _.last(frequentEmojiListOrdered).name === uniqueEmojisWithCounts[0].name) {
frequentEmojiListOrdered.splice(maxFrequentEmojiCount, 1);
} else {
frequentEmojiListOrdered = frequentEmojiListOrdered.slice(0, maxFrequentEmojiCount);
}

Copy link
Contributor Author

@bernhardoj bernhardoj May 6, 2023

Choose a reason for hiding this comment

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

It works fine for me though. Can you share your repro steps?

Screen.Recording.2023-05-06.at.09.00.57.mov

Copy link
Contributor

Choose a reason for hiding this comment

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

@bernhardoj Your emojis should have count > 1 , because we are ordering the emojis by count, if the newly added is the last in the list , it will be removed , check explanation

emoji.mov

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'm not aware the video I attached is a link. updated.

The emoji I add is a new emoji (the monkey emoji), not an emoji with count > 1

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah, I think I understand.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

My bad. That's what will happen with the new behavior. Updated my comment.

Copy link
Contributor

Choose a reason for hiding this comment

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

which means with the new behavior, no matter how many times we insert the new emoji, it won't be added to the list (because the count is always 0).

I'm not sure if we're on the same page. Which count are you referring to? The current behavior is to extract emojis from the copy/pasted comment, group them by emoji name, and assign each emoji a count that corresponds to the number of occurrences in the comment. Then, we merge this list with the old frequently used emojis list.

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 count on the frequent emoji list. Let say all 24 emoji has count of 2. Then, we add a new emoji. Because it doesn't exist in the list, it will have a count of 1. With our new logic, we won't take the new emoji. The next time we add the same emoji, the count will still be 1 because it doesn't exist in the list.

Copy link
Contributor

@fedirjh fedirjh May 6, 2023

Choose a reason for hiding this comment

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

@bernhardoj That’s why I suggested these changes here , If the last emoji in the list is the inserted emoji then We shouldn’t remove it , and we remove the previous emoji.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Updated to solve the issue. Also added a test.

@fedirjh
Copy link
Contributor

fedirjh commented May 5, 2023

@bernhardoj I think the testing steps could be simplified. We can check if the emoji is added to the frequently used list in the emoji picker. This is because the request is made when the frequently used list is updated. The steps could be:

  1. Open a chat.
  2. Type an emoji that is not in your frequently used emoji list in the composer.
  3. Send the message.
  4. Open the emoji picker and verify that the typed emoji is added to the frequently used emoji list.
  5. Edit the message.
  6. Type another emoji that is not in your frequently used emoji list in the edit composer.
  7. Open the emoji picker and verify that the typed emoji is added to the frequently used emoji list.

@bernhardoj
Copy link
Contributor Author

The new steps sounds good. I added it as an alternative for QA.

Copy link
Contributor

@fedirjh fedirjh left a comment

Choose a reason for hiding this comment

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

Left some comments

src/libs/EmojiUtils.js Outdated Show resolved Hide resolved
src/libs/EmojiUtils.js Outdated Show resolved Hide resolved
src/libs/EmojiUtils.js Outdated Show resolved Hide resolved
...frequentlyEmojisList.slice(0, (-1 - (newEmoji.length - 1))),
..._.map(newEmoji.slice(1), e => ({...e, count: 1, lastUpdatedAt: currentTime})),
];
expect(spy).toBeCalledWith(expectedFrequentlyEmojisList);
Copy link
Contributor

Choose a reason for hiding this comment

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

we should expect that FrequentlyEmojisList length doesn’t exceed the max allowed value

expectedFrequentlyEmojisList.length === (CONST.EMOJI_FREQUENT_ROW_COUNT * CONST.EMOJI_NUM_PER_ROW)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

expectedFrequentlyEmojisList is the array that we construct ourself. Testing the length is not needed.

Copy link
Contributor

Choose a reason for hiding this comment

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

Not totally agree here, the length should not pass the (CONST.EMOJI_FREQUENT_ROW_COUNT * CONST.EMOJI_NUM_PER_ROW) and we should test that

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 I got your point, but honestly I found it's weird to test an expected result. So, I add the length check to the frequentlyEmojisList length instead.

@bernhardoj
Copy link
Contributor Author

bernhardoj commented May 7, 2023

@fedirjh Here is the explanation of why our current logic is wrong:

Let say a user already has 24 frequently used emojis with a count of 2.

First, let's agree on what should be the expected behavior when we insert multiple emojis at the same time. I expect it should have the same behavior of inserting single emoji multiple times (lmk if you disagree).

First case
Previously, we are talking about the issue that inserting a new emoji to a full list with count > 1 won't work. Then, I decided to use this fix f1184b8#diff-31af63e60e05edaca5584223a4cb595c02d2a3487e916c01b44846a5e9f8ec95R199 which could lead to negative value, but let's ignore that for now. Let say the number of emoji we want to insert is 5.
If we insert those at the same time, it means we will remove last 5 item from the list, then insert the 5 new emojis.

24 frequent emojis, remove last 5
19 frequent emojis, insert 5 new emojis
24 frequent emojis

However, if we insert them one by one (from emoji picker), then it will only replace the last emoji from the list.

24 frequent emojis, remove last 1
23 frequent emojis, insert 1 new emoji
24 frequent emojis, remove last 1
keep repeat...

You can notice that when inserting multiple emojis, we will replace 4 other different emojis.

Let say somehow we fix it so they have the same behavior, we still have the 2nd case.

Second case
With our current logic, inserting multiple emojis at the same time will group the same emoji and count them. This will have a different outcome for this case:

The user then insert multiple new emojis, A, B, and A again from emoji picker and emoji code with colon (:smile:). Here is what happen:

  1. Insert one by one from emoji picker
    First, insert A. Emoji A will be put at the last item of frequently used emojis list with count of 1.
    Next, insert B. Emoji B will replace emoji A position with count of 1.
    Last, insert A again. Emoji A will replace emoji B position with count of 1.

The final result is: 23 frequently used emojis + A emoji with a count of 1

  1. Insert multiple emojis at the same time by emoji code
    Let say the emoji code is :A: and :B:. So, the user paste into the composer this text :A: :B: :A:
    The emojis are grouped which makes the emoji A has a count of 2 and B has a count of 1.

First, insert A. Emoji A will be put at the last item of frequently used emojis list with count of 2.
Next, insert B. Emoji B will replace emoji A position with count of 1.

The final result is: 23 frequently used emojis + B emoji with a count of 1

Conclusion
I think we should use the previous logic, of course with a modification to support emoji array. Here is how it looks: (almost the same with prev logic, just with a loop)

let frequentEmojiList = [...frequentlyUsedEmojis];

const maxFrequentEmojiCount = (CONST.EMOJI_FREQUENT_ROW_COUNT * CONST.EMOJI_NUM_PER_ROW) - 1;
const currentTimestamp = moment().unix();
_.each([].concat(newEmoji), (emoji) => {
    let currentEmojiCount = 1;
    const emojiIndex = _.findIndex(frequentEmojiList, e => e.code === emoji.code);
    if (emojiIndex >= 0) {
        currentEmojiCount = frequentEmojiList[emojiIndex].count + 1;
        frequentEmojiList.splice(emojiIndex, 1);
    }
    const updatedEmoji = {...emoji, ...{count: currentEmojiCount, lastUpdatedAt: currentTimestamp}};

    // We want to make sure the current emoji is added to the list
    // Hence, we take one less than the current frequent used emojis
    frequentEmojiList = frequentEmojiList.slice(0, maxFrequentEmojiCount);
    frequentEmojiList.push(updatedEmoji);

    // Sort the list after adding a new emoji to the frequent used emojis list
    frequentEmojiList = lodashOrderBy(frequentEmojiList, ['count', 'lastUpdatedAt'], ['desc', 'desc']);
});

User.updateFrequentlyUsedEmojis(frequentEmojiList);

Complexity
M = new emojis
N = frequent emojis

M * (N + N log N) which I think could be simplified to M * N log N.

This is assuming the sort is N log N.

Let me know if it make sense to you and I will commit it.

@fedirjh
Copy link
Contributor

fedirjh commented May 8, 2023

@bernhardoj Okay, thank you for the explanation, that make sense. I think we can proceed with that implementation 🟢

@bernhardoj
Copy link
Contributor Author

Great. Updated.

Just a note: it is slow when pasting > 1000 emojis code

src/libs/EmojiUtils.js Outdated Show resolved Hide resolved
@fedirjh
Copy link
Contributor

fedirjh commented May 8, 2023

@bernhardoj Code looks good. units test are failing , please fix it .

@bernhardoj
Copy link
Contributor Author

bernhardoj commented May 8, 2023

Hmm. I see all the test jobs are green. Maybe it becomes flaky (I'm guessing it reruns after your new comment) after changing it to native sort? I will try run the test multiple times locally.

@fedirjh

This comment was marked as outdated.

@fedirjh
Copy link
Contributor

fedirjh commented May 8, 2023

cc @bernhardoj looks good , I just forgot to revert some changes I did for testing 😕

@bernhardoj
Copy link
Contributor Author

Hmm, it's really weird, the test in CI and my device is working fine.

can you log the final frequentEmojiList array in addToFrequentlyUsedEmojis and tell which one of the test is failing (the name)?

@bernhardoj
Copy link
Contributor Author

Ah okay, that's great to hear (or read). I was confused why you suddenly comment "looks good" only 🤣.

fedirjh
fedirjh previously approved these changes May 8, 2023
Copy link
Contributor

@fedirjh fedirjh 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 🚀

cc @MonilBhavsar over to you

@MonilBhavsar
Copy link
Contributor

Hi! Apologies for delay. Some priority issues took me aside. But I'll review it now.
@bernhardoj sorry there are some conflicts to fix 😬
Most probably should be prettier changes, as we merged it last night

Copy link
Contributor

@MonilBhavsar MonilBhavsar 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, couple of NAB's..

src/libs/EmojiUtils.js Outdated Show resolved Hide resolved
// Given an existing frequently used emojis list with count > 1
const frequentlyEmojisList = [
{
code: '👋', name: 'wave', count: 2, lastUpdatedAt: 4,
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 try to mimic real data as much as possible by using unix timestamp in lastUpdatedAt?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Personally, I think it's fine to have a simple number instead of unix timestamp as it's easier to read. The purpose of lastUpdatedAt is to show which emoji is used the most recent and I think as long as the number can represent that clearly, then it's fine.

code: '💯', name: '100', count: 2, lastUpdatedAt: 2,
},
{
code: '👿', name: 'imp', count: 2, lastUpdatedAt: 1,
Copy link
Contributor

Choose a reason for hiding this comment

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

Lol, today I learnt, this emoji is named as imp 😄

@MonilBhavsar
Copy link
Contributor

@bernhardoj @fedirjh
I appreciate the collaborative work, adding the automated tests and talking about performance 🚀 🙇

@bernhardoj
Copy link
Contributor Author

Merged with main.

@MonilBhavsar MonilBhavsar merged commit 615ebd9 into Expensify:main May 12, 2023
@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 https://github.com/MonilBhavsar in version: 1.3.14-0 🚀

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

@OSBotify
Copy link
Contributor

🚀 Deployed to production by https://github.com/yuwenmemon in version: 1.3.14-14 🚀

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

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