-
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
feat(search): Debounce and phone number validation #3124
feat(search): Debounce and phone number validation #3124
Conversation
82699ae
to
3effa64
Compare
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.
There are many unnecessary changes related to the code style that shouldn't be in this PR. Please undo these and try to make sure the PR looks clean.
Also, please fill the PR template. It would be nice to indicate some QA steps so we can make sure everything works flawlessly.
@pranshuchittora Can you fix the conflicts and run |
I have updated the PR |
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.
Thanks for updating, lots of little comments here, please ask if you have any questions!
src/components/OptionsList.js
Outdated
<View> | ||
{this.props.headerMessage ? ( | ||
<View style={[styles.ph5]}> | ||
<Text style={[styles.textLabel, styles.colorMuted]}> | ||
{this.props.headerMessage} | ||
</Text> | ||
</View> | ||
) : null} | ||
</View> |
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.
Was this change necessary? If yes, can you explain? I tested without the new View
you added and it seems to be working fine
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.
Removing this
src/styles/styles.js
Outdated
textMicroGTA: { | ||
fontSize: variables.fontSizeSmall, | ||
fontFamily: fontFamily.GTA, | ||
}, | ||
|
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.
Please delete if you're not using anymore
src/components/OptionsSelector.js
Outdated
<View style={[styles.ph5, styles.pv3]}> | ||
<View style={[ | ||
styles.ph5, | ||
styles.pt3, |
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 none of the changes in this file are needed, the only difference I can see that your changes make is they reduce the padding below the following TextInputWithFocusStyles
, but I think it looks find with the original padding. Is there any other change you were trying to make with these style updates?
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.
Reverting back
src/pages/SearchPage.js
Outdated
userToInvite, | ||
} = getSearchOptions( | ||
this.validateInput = _.debounce(this.validateInput.bind(this), 300); | ||
const {recentReports, personalDetails, userToInvite} = getSearchOptions( |
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.
This change isn't necessary - please try to keep lines the same as before, unless you're changing something in the line(s).
const headerMessage = getHeaderMessage( | ||
this.state.personalDetails.length !== 0, | ||
false, | ||
searchValue, | ||
); |
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.
In this function, it looks like the only time we're using this headerMessage
is if the the phone number is invalid, so I think it would be better if we just do headerMessage: translate(preferredLocale, 'messages.noPhoneNumber')
directly in the else
statement below - since this will only be displayed if the modifiedSearchValue
is an invalid phone number - we shouldn't need to call getHeaderMessage
right?
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 am keeping the call to getHeaderMessage
because if we want to make any change in the underlying messaging part then we have only one place to change. Or a single source of truth.
this.setState({ | ||
recentReports: [], | ||
userToInvite: null, | ||
headerMessage, |
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.
As mentioned above, let's do something like headerMessage: translate(preferredLocale, 'messages.noPhoneNumber')
here
userToInvite, | ||
recentReports, | ||
personalDetails, | ||
headerMessage: recentReports.length + personalDetails.length |
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 it could be cleaner to just make this else
an else if (Str.isValidEmail(searchValue) && !Str.isDomainEmail(searchValue))
, where headerMessage
should always be ''
, then add an else
which displays the this.props.translate('messages.noEmailOrPhone')
error message, 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.
This validation is not required as it is done internally by getSearchOptions
@Beamanator I have updated the PR |
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.
The work you're doing so far is great for the Search Page, but we also need it to be used in all pages that have account-search functionality (+ new chat, new group, some IOU pages)
* @param {String} searchValue | ||
* @returns {void} | ||
*/ | ||
validateInput(searchValue) { |
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 believe we're going to have to move this into OptionsListUtils
since the validation you're adding is going to apply to all pages that have account-search functionality. Can you figure out how we can reuse getSearchOptions
here (by editing getOptions
)? I'm thinking we can have getOptions
also return headerMessage
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 discussed this with you earlier. That my initial approach was to add the changes in getOptions
only but it's not flexible enough and might require good amount of refactoring.
Because there are a lot of things happening internally and the code is a bit messy and adding more code will increase the complexity and maintainability efforts.
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.
Woah you did? I'm sorry I don't remember you bringing up that approach, maybe I misunderstood :O
Hmm I don't see why we can't refactor getHeaderMessage
just a bit, and make getOptions
also return something like headerMessage: getMeaderMessage(...)
. Here's why I'm thinking this will work (please let me know if you disagree on these points):
getHeaderMessage
takes only a few parameters, and all of the params should be able to be calculated from other variables insidegetOptions
getOptions
is only used inOptionsListUtils
, which hasget...Options
functions for specific pages, all of those pages will need this type of functionality (the same type of logic forheaderMessage
)
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.
Hi @Beamanator
I tried merging these changes into utils. So getSearchOptions
& getHeaderMessage
are independent of each other. They both take the searchValue
as one of the input. With this, we might end up hitting the phone number validation API twice.
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.
Hmm once you push your latest changes I can check and see if I can help come up with a way to only hit that validation API once 👍
@pranshuchittora Can you give an update when you think you'll be able to get to the requested changes above? |
@pranshuchittora a requirement that you promptly reply to comments on issues and PRs in order to avoid receiving negative reviews internally which could affect the future hiring. Can you please respond to @Beamanator above and also check all other issues and PRs that you're working on to make sure you're caught up? |
Pardon the delayed reply, I have completed this task and able to get the required output but need to migrate the logic inside utils. Will update the PR as soon as possible. |
@Beamanator here's the demo for the integration of search validation API inside utils. Peek.2021-07-02.02-31.mp4Here are the changes -> pranshuchittora@86d635e Few insights while implementing these changes.
Correct me if I am wrong or missing anything here. |
@pranshuchittora Ok i see that the API is being called twice - once in
You're right that we'd have to asynchronous chain (promises) down a bit, but I don't see this being a huge effort - maybe that's because I have lots of experience doing that. Are you comfortable making those promise chains? Also if you don't feel this is a good implementation can you ask for recommendations in #expensify-open-source?
True that if you keep them separate we could have the api called twice when we only want to call it once. However, I don't see how combining them will be difficult since |
@pranshuchittora The solution you're proposing is breaking the React rule related to triggering side-effects in the render() function (the this.getHeader() call). Also, I don't see the need for calling the IsValidPhoneNumber function inside the other API call, we could show the What do you think? |
I agree. I have done this to reduce the possibility of any breaking change. Because right now getHeaderMessage gives pretty deterministic output for the given input (search value etc). But introducing the validation API for showing the header message is a breaking change.
We need to call the API that the goal of this ticket. To disable creating chats with invalid phone numbers. |
Of course, it's just that we would only do it in one place. The const apiSaysPhoneIsInvalid = Str.isValidPhone(searchValue) && this.state.userToInvite === null; |
Right now the |
You added the API call inside Also, you're already treating To be clear: All I'm saying is related to the changes you linked in this comment: #3124 (comment) Could you upload those changes to this branch? It would be easier for us to review. |
I haven't uploaded them to this branch because I am not sure of them as they are breaking changes. As the methods have async call then we need to change the consumption everywhere which is out of scope for this ticket. |
Could we move the asynchronous code inside the getSearchOptions function so the getOptions doesn't need to return a promise and we only need to worry about the usages of getSearchOptions in the codebase? |
Hi @pranshuchittora, can we get an update here please? |
No, moving the async code from getOptions would require copying/migrating the validation logic from getOptions to getSearchOptions as well. Anyway, this will come with a breaking change because
|
|
Migrating the logic inside utils will be a breaking change considering consumption (i.e. inside constructor) therefore some good amount of refactoring is required. No worries, it was really nice working with you all. Looking forward to working collaborating with you in future :) |
Details
Fixed Issues
Closes #2936
Closes #2934
Tests
QA Steps
Tested On
Screenshots
Web
Peek.2021-05-25.23-26.mp4
Mobile Web
Desktop
iOS
Android