-
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
[Chat] [IOU] Mobile keyboard should not be displayed at IOUConfirm step #1855
Comments
This looks to have been introduced with the new React Navigation changes and unrelated to the IOU screens, you can set any route or simply close the menu and it will still cause the keyboard to show. Proposal
In the
Which will allow us to check if the page is focused before focusing the input which resolves the keyboard issue:
Android Back Issue
|
Hi @Maftalion, thanks for sharing the detailed solution. We would love for you to take on this issue via UpWork if you're interested. |
@Julesssss thanks, just submitted a proposal! Also just want to make sure, but you're fine with the |
That's a great point @Maftalion . I'm not sure about this so please hold while I confirm this internally. I'll get back to you ASAP. |
Okay, we’re not quite ready to start using Hooks as this requires a bit more internal discussion and we’d prefer to spend a bit more time exploring alternatives (or reverse engineering Hooks) for now. But we'd love to hear any other thoughts you had regarding the issue. |
@Julesssss @jliexpensify I am posting a proposal now as I thought it was assigned to the @Maftalion. Proposal
// When any modal goes from visible to hidden, bring focus to the compose field
if (prevProps.modal.isVisible && !this.props.modal.isVisible) {
this.setIsFocused(true);
} This is code is forcing the focus on the input when we close the CreateMenu Modal. But report screen was never unmounted thus this is triggered and resulted in focus being set on the input.
ReportActionCompose.contextType = NavigationContext; which allows us to listen for the focus event on the navigation instance. then we can attach listeners like this. componentDidMount() {
this.unsubscribeFocus = this.context.addListener('focus', () => this.setState({
isScreenFocused: true,
}));
this.unsubscribeBlur = this.context.addListener('blur', () => this.setState({
isScreenFocused: false,
}));
}
// eslint-disable-next-line react/sort-comp
componentWillUnmount() {
this.unsubscribeFocus();
this.unsubscribeBlur();
}
componentDidUpdate(prevProps) {
const valueToReturn = this.context.isFocused();
if (this.state.isScreenFocused !== valueToReturn) {
// If the value has changed since the last render, we need to update it.
// This could happen if we missed an update from the event listeners during re-render.
// eslint-disable-next-line react/no-did-update-set-state
this.setState({
isScreenFocused: valueToReturn,
});
}
// The first time the component loads the props is empty and the next time it may contain value.
// If it does let's update this.comment so that it matches the defaultValue that we show in textInput.
if (this.props.comment && prevProps.comment === '' && prevProps.comment !== this.props.comment) {
this.comment = this.props.comment;
}
// When any modal goes from visible to hidden, bring focus to the compose field
if (this.state.isScreenFocused && prevProps.modal.isVisible && !this.props.modal.isVisible) {
this.setIsFocused(true);
}
} which will fix this issue. If it's already assigned, feel free to take a look at the proposal. Maybe it will help. |
@Julesssss I'm fine with deferring this task to @parasharrajat since he took the time to figure out how to do it without using the hook. My only suggestion would be to set it up as a HOC so this can used on other screens as well without needing all the boilerplate. I also found another way to fix this as well, if we just use |
Interesting Hack @Maftalion . Will try this one as well. Thanks for sharing. |
Hi @parasharrajat and @Maftalion - thanks for both sharing potential solutions. So that I'm 100% clear on things, was it decided that Rajat was going to take this on instead? If so, please let me know and I'll look into changing this in Upwork. @parasharrajat if you are taking this on, do you mind submitting a proposal in Upwork as well? cc @Julesssss re: the discussion on not using hooks |
@jliexpensify yeah, that's right. Thanks to both of you for figuring this issue out. |
Awesome, as discussed - I've hired @parasharrajat via Upworks. Thanks for all your help @Maftalion ! |
Hey guys the selected approach is good and will greatly reduce side effects caused by I just want to mention something that you might consider for the future: My observations:The
With the new functionality brought in this ticket - a HOC providing focus awareness we can do the following. Instead of anticipating and reacting inside
Pseudo Implementation (in ReportScreen)<ScreenWrapper>
<HeaderView />
{
isFocused
? <ReportView reportID={activeReportID} />
: <PlaceholderView reportID={activeReportID} />
}
</ScreenWrapper> The purpose of the Alternatively There's one benefit I see in the
I think the fast response when you open the same chat will be preserved even if you start from unmounted state
There might be something already baked in react-navigation regarding such cases - A view outside the visible area causing side effects, or they might have a suggestion in their docs Most of this is from the top of my head. I haven't studied this project entirely so I might come up with something better (Do chime in if you're interested), but usually side effects causing logic tend to cause issues like these and patching it with more conditional statements works only to a certain extent. |
@kidroca Thanks for bringing in this and suggesting an approach. I am well aware of the issue you mentioned. That's the only reason to Introduce the HOC approach. With this, we can manage the focus more accurately. I have some thoughts on fixing the mentioned issue with much simplicity. |
Thanks for that suggestion @kidroca. Would you like to create an Expensify.cash issue to continue this discussion? We might need to discuss a bit further with other colleagues, but I think that could be a great further improvement and I would be happy to get an UpWork issue set up for that investigation/implementation. |
Yes, I'd like that. Definitely needs more discussion and I don't want to spam the current ticket. I'll open a new ticket when I'm done with my current work. |
The only caveat to this approach is that I think @marcaaron started setting up the Right Docked Modals as screens, so on web/desktop it would render the PlaceholderView when those modals open on top of the report. But the |
I think it would be sufficient to just unmount the input field ReportActionCompose.render{
chatHasFocus
? <TextInputFocusable />
: <FakeInput>Write something...</FakeInput>
} When there's no text input mounted it won't be able to accidentally steal focus There's something similar already: const inputDisable = this.props.isSmallScreenWidth && Navigation.isDrawerOpen(); But it's re-evaluated when "something" triggers a new render - props need to change |
I left a similar comment on @parasharrajat's PR, but wondering if another solution here is to be more selective about when we are focusing this input instead of assuming we always want to do it when "any modal closes and the screen is focused". I like the HOC idea and there is a good chance knowing whether a screen is focused will be useful in the future, but perhaps not yet. If we know the specific situations where we want to focus the input and can find a way to focus explicitly perhaps we won't need to know if "modal is visible" or "screen has focus". But maybe this is easier said than done. |
@marcaaron true, if the experience should be to focus only when the report changes (and not re-focus when a modal closes) then the conditional can probably just be simplified to |
@Maftalion this is exactly what I did here: 0395526 ReportActionCompose.componentDidUpdate// When the report ID changes bring focus to the compose field
if (prevProps.reportID !== this.props.reportID) {
this.setIsFocused(true);
} And this is the result: 2021-03-26.21-51-26.mp4There's still a place for improvement - the slight jitter that happens when you transition from modal to modal - its react native trying to return focus to the view that was focused before opening the modal, only to open another modal. It's not that prominent on a real device, but perhaps we can disable the field to try make it "unfocusable" when the 2nd modal is selected to appear (openPicker()) and restore enabled state on Edit: I found out that this behavior is not intended for mobile while I was creating #2129
This is a comment inside TextInputFocusable On native focusing would also bring the keyboard, so autofocusing should probably be avoided - more details in the new issue Much better experience when the keyboard does not try to appear between modals 2021-03-29.13-56-42.mp4 |
@parasharrajat We are currently discussing whether to just get rid of auto focusing the input altogether on native platforms. This should fix this issue and a couple of others if we decide this is the best way forward. |
@marcaaron Yup sure. There is a couple of ongoing PR and opinions(including yours) that would change the objective. Thus I am waiting as per my update here. Thanks for the update info. |
Here's what I am thinking a complete fix for this should be:
We should only want to "autoFocus" on web/desktop (see rules of step 1). So, we require a custom implementation for this anyway instead of just passing |
If you haven’t already, check out our contributing guidelines for onboarding!
Problem
The mobile alphabetic keyboard is being displayed on physical devices when the IOUAmount page is displayed. It isn't always consistent but occurs most of the time with no obvious pattern. This occurs on both Android and iOS physical devices.
To reproduce this issue, apply the following diff so that 'New chat' and 'New group' launches the IOUModal:
Make sure you include the final new line!
iouAmountKeyboard.mp4
Desired Solution
The alphabetic keyboard should not be displayed, as we are not rendering an Input field on mobile:
Upwork Link: https://www.upwork.com/ab/applicants/1372398296191315968/job-details
The text was updated successfully, but these errors were encountered: