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

[$500] Edit message, save/cancel and visiting different report removes focus from composer #29919

Closed
2 of 6 tasks
m-natarajan opened this issue Oct 18, 2023 · 40 comments
Closed
2 of 6 tasks
Assignees
Labels
Bug Something is broken. Auto assigns a BugZero manager. Daily KSv2 Engineering External Added to denote the issue can be worked on by a contributor Help Wanted Apply this label when an issue is open to proposals by contributors

Comments

@m-natarajan
Copy link

m-natarajan commented Oct 18, 2023

If you haven’t already, check out our contributing guidelines for onboarding and email [email protected] to request to join our Slack channel!


Version Number: 1.3.86-1
Reproducible in staging?: y
Reproducible in production?: y
If this was caught during regression testing, add the test name, ID and link from TestRail:
Email or phone of affected tester (no customers):
Logs: https://stackoverflow.com/c/expensify/questions/4856
Expensify/Expensify Issue URL:
Issue reported by: @dhanashree-sawant
Slack conversation: https://expensify.slack.com/archives/C049HHMV9SM/p1697650111645879

Action Performed:

  1. Open the app
  2. Open any report
  3. Send any message
  4. Edit the message
  5. Save or cancel the edit message
  6. Visit another report and observe that app does not focus on composer

Expected Result:

App should focus on composer whenever we visit any report

Actual Result:

App does not focus on composer when we edit any message, save/cancel the mesage and visit any other report

Workaround:

unknown

Platforms:

Which of our officially supported platforms is this issue occurring on?

  • Android: Native
  • Android: mWeb Chrome
  • iOS: Native
  • iOS: mWeb Safari
  • MacOS: Chrome / Safari
  • MacOS: Desktop

Screenshots/Videos

Android: Native
Android.chrome.no.focus.on.composer.mp4
Android: mWeb Chrome
Android.app.no.focus.composer.mp4
iOS: Native
ios.native.no.focus.on.composer.mov
iOS: mWeb Safari
MacOS: Chrome / Safari
mac.chrome.no.focus.on.composer.mov
Recording.124.mp4
MacOS: Desktop
mac.desktop.no.focus.on.composer.mov

View all open jobs on GitHub

Upwork Automation - Do Not Edit
  • Upwork Job URL: https://www.upwork.com/jobs/~01e2dccea0afb54c13
  • Upwork Job ID: 1714761073301872640
  • Last Price Increase: 2023-11-08
@m-natarajan m-natarajan added External Added to denote the issue can be worked on by a contributor Daily KSv2 Bug Something is broken. Auto assigns a BugZero manager. labels Oct 18, 2023
@melvin-bot
Copy link

melvin-bot bot commented Oct 18, 2023

Triggered auto assignment to @peterdbarkerUK (Bug), see https://stackoverflow.com/c/expensify/questions/14418 for more details.

@melvin-bot melvin-bot bot changed the title Edit message, save/cancel and visiting different report removes focus from composer [$500] Edit message, save/cancel and visiting different report removes focus from composer Oct 18, 2023
@melvin-bot
Copy link

melvin-bot bot commented Oct 18, 2023

Job added to Upwork: https://www.upwork.com/jobs/~01e2dccea0afb54c13

@melvin-bot
Copy link

melvin-bot bot commented Oct 18, 2023

Bug0 Triage Checklist (Main S/O)

  • This "bug" occurs on a supported platform (ensure Platforms in OP are ✅)
  • This bug is not a duplicate report (check E/App issues and #expensify-bugs)
    • If it is, comment with a link to the original report, close the issue and add any novel details to the original issue instead
  • This bug is reproducible using the reproduction steps in the OP. S/O
    • If the reproduction steps are clear and you're unable to reproduce the bug, check with the reporter and QA first, then close the issue.
    • If the reproduction steps aren't clear and you determine the correct steps, please update the OP.
  • This issue is filled out as thoroughly and clearly as possible
    • Pay special attention to the title, results, platforms where the bug occurs, and if the bug happens on staging/production.
  • I have reviewed and subscribed to the linked Slack conversation to ensure Slack/Github stay in sync

@melvin-bot melvin-bot bot added the Help Wanted Apply this label when an issue is open to proposals by contributors label Oct 18, 2023
@melvin-bot
Copy link

melvin-bot bot commented Oct 18, 2023

Triggered auto assignment to Contributor-plus team member for initial proposal review - @hoangzinh (External)

@zukilover
Copy link
Contributor

Proposal

Please re-state the problem that we are trying to solve in this issue.

Composer is not focused when user has edited a chat from different report

What is the root cause of that problem?

Within deleteDraft which is called in the triggerSaveOrCancel method, composer focused is set to false thus loses its focus state:

const deleteDraft = useCallback(() => {
InputFocus.callback(() => setIsFocused(false));

isFocused triggers composerFocusKeepFocusOn on an effect that then read from the state value to remove the focus ref.

useEffect(() => {
InputFocus.composerFocusKeepFocusOn(textInputRef.current, isFocused, modal, onyxFocused);
}, [isFocused, modal, onyxFocused]);

What changes do you think we should make in order to solve the problem?

Remove the offending line that triggers the focus state change:

const deleteDraft = useCallback(() => {
        // InputFocus.callback(() => setIsFocused(false)); << remove this line
        InputFocus.inputFocusChange(false);

What alternative solutions did you explore? (Optional)

N/A

@abzokhattab
Copy link
Contributor

is it a regression from #29073 ?

@ayazalavi
Copy link
Contributor

@narefyev91 please take a look

@hoangzinh
Copy link
Contributor

@ayazalavi can you confirm that it's a regression from your PR #29073?

@ayazalavi
Copy link
Contributor

I am not sure, let me take a look.

@melvin-bot melvin-bot bot added the Overdue label Oct 23, 2023
@hoangzinh
Copy link
Contributor

@ayazalavi is there any luck so far? If I comment out the line as mentioned in @zukilover's proposal, this issue will no longer be reproducible.

@melvin-bot melvin-bot bot removed the Overdue label Oct 24, 2023
@peterdbarkerUK
Copy link
Contributor

Is this intended behaviour? From here:

On small devices the auto focus will bring up the keyboard which may be annoying. Reports are optimized for reading. Ref: https://expensify.slack.com/archives/C01GTK53T8Q/p1617201995245400

@hoangzinh
Copy link
Contributor

@peterdbarkerUK Yes, it's true on small-screen devices. But we still maintain auto-focus on Web/Desktop.

@melvin-bot
Copy link

melvin-bot bot commented Oct 25, 2023

📣 It's been a week! Do we have any satisfactory proposals yet? Do we need to adjust the bounty for this issue? 💸

@melvin-bot melvin-bot bot added the Overdue label Oct 26, 2023
@melvin-bot
Copy link

melvin-bot bot commented Oct 30, 2023

@hoangzinh, @peterdbarkerUK Eep! 4 days overdue now. Issues have feelings too...

@hoangzinh
Copy link
Contributor

hoangzinh commented Oct 30, 2023

@peterdbarkerUK the Prod regression period is over on issue #26527. Do you agree to accept new proposals to fix this issue here?

@melvin-bot melvin-bot bot removed the Overdue label Oct 30, 2023
@peterdbarkerUK
Copy link
Contributor

Yes, please. If @zukilover's proposal still works to your liking? Looks like an extremely easy one.

@ayazalavi
Copy link
Contributor

Let me please write down the proposal as well. Since apparently my PR is connected with this bug.

Copy link

melvin-bot bot commented Nov 1, 2023

@hoangzinh @peterdbarkerUK this issue was created 2 weeks ago. Are we close to approving a proposal? If not, what's blocking us from getting this issue assigned? Don't hesitate to create a thread in #expensify-open-source to align faster in real time. Thanks!

Copy link

melvin-bot bot commented Nov 1, 2023

📣 It's been a week! Do we have any satisfactory proposals yet? Do we need to adjust the bounty for this issue? 💸

@hoangzinh
Copy link
Contributor

@zukilover Thanks for your proposal #29919 (comment). I think you pointed out the correct place that causes this issue. But you haven't explained why we need that line from the beginning and if we remove this line, will it cause any regression bug?

@zukilover
Copy link
Contributor

That specific line was added from #26527 to fix a glitch of the focus states (race condition).

It should be fixed with the new inputFocusChange, and thus the focus callback is a redundant line here that should be removed.

@ayazalavi
Copy link
Contributor

ayazalavi commented Nov 2, 2023 via email

@ayazalavi
Copy link
Contributor

ayazalavi commented Nov 2, 2023 via email

@hoangzinh
Copy link
Contributor

It should be fixed with the new inputFocusChange, and thus the focus callback is a redundant line here that should be removed.

@zukilover, because both InputFocus.callback(() => setIsFocused(false)) and inputFocusChange are added in the same PR #29073. Could you elaborate on why you think it's a redundant line? Thanks

@zukilover
Copy link
Contributor

If we take a look at how composerFocusKeepFocusOn is implemented, especially these lines:

if (isFocused) {
refSave = ref;
}
if (!isFocused && !onyxFocused && !modal.willAlertModalBecomeVisible && !modal.isVisible && refSave) {
if (!ReportActionComposeFocusManager.isFocused()) {
refSave.focus();
} else {
refSave = undefined;
}
}
}

It tries to focus on refSave but refSave will be defined if isFocused is truthy, but the focusing is executed only when isFocused is falsy. This seems to be counterintuitive.

@ayazalavi
Copy link
Contributor

Proposal

Restating the Problem

The problem we are addressing is that when a user edits a message in a chat and then switches to another chat, the main composer does not receive focus.

Identifying the Root Cause

The root cause of this issue is that the focus on the compose field is triggered programmatically in ComposerWithSuggestions at this location:

.

The issue arises when the edit compose box loses focus after closing the edit input field. As a result, the main compose box in the same chat where the message was edited regains focus. When we switch to another chat, this line

if (!(willBlurTextInputOnTapOutside && !isNextModalWillOpenRef.current && !modal.isVisible && isFocused && (prevIsModalVisible || !prevIsFocused))) {

evaluates prevIsFocused===true, causing it to skip the focus() method call at

.

Consequently, the main compose box loses focus in the new chat.

Proposed Solution

To solve this problem, we suggest calling the focus method at

onLayout={(e) => {
const composerLayoutHeight = e.nativeEvent.layout.height;
if (composerHeight === composerLayoutHeight) {
return;
}
setComposerHeight(composerLayoutHeight);
}}
.

This will ensure that the main compose box receives focus as soon as it's layout'd, preventing the issue from occurring.

Result:

91588771-ee1c-49e9-8e01-db48b37709cd.mp4

Alternative Solutions

No alternative solutions were explored or mentioned in the proposal.

@melvin-bot melvin-bot bot added the Overdue label Nov 6, 2023
@bernhardoj
Copy link
Contributor

Proposal

Please re-state the problem that we are trying to solve in this issue.

Visiting another report after saving/canceling an edit message composer does not auto-focus the main composer.

What is the root cause of that problem?

We have a condition here to decide whether we should auto-focus the composer or not.

const shouldAutoFocus = !modal.isVisible && (shouldFocusInputOnScreenFocus || (isEmptyChat && !ReportActionsUtils.isTransactionThread(parentAction))) && shouldShowComposeInput;

The problem is with the shouldShowComposeInput. One of the purposes of shouldShowComposeInput is to hide the main composer when an edit composer is focused, on a small screen

When we start editing a message, the edit composer will be focused, and shouldShowComposeInput is set to false.

onFocus={() => {
setIsFocused(true);
reportScrollManager.scrollToIndex(props.index, true);
setShouldShowComposeInputKeyboardAware(false);

When we save/cancel it, it will be unmounted, and it is supposed to reset shouldShowComposeInput back to true.

return () => {
// Skip if the current report action is not active
if (!isActive()) {
return;
}
if (EmojiPickerAction.isActive(props.action.reportActionID)) {
EmojiPickerAction.clearActive();
}
if (ReportActionContextMenu.isActiveReportAction(props.action.reportActionID)) {
ReportActionContextMenu.clearActiveReportAction();
}
// Show the main composer when the focused message is deleted from another client
// to prevent the main composer stays hidden until we swtich to another chat.
setShouldShowComposeInputKeyboardAware(true);
};
// eslint-disable-next-line react-hooks/exhaustive-deps -- this cleanup needs to be called only on unmount
}, [props.action.reportActionID]);

The problem is, isActive() is always false because isFocusedRef is false
https://github.com/Expensify/App/blob/d75acafec3e24cfa6bc48a20822f9d36763b71a0/src/pages/home/report/ReportActionItemMessageEdit.js#L166-L168R

and that is because we set it to false every time we call deleteDraft (both saving/canceling draft will call this) which is added by this PR

const deleteDraft = useCallback(() => {
InputFocus.callback(() => setIsFocused(false));

So, shouldShowComposeInput is still false even after we close the edit composer. When we switch to another report, autoFocus is now false because shouldShowComposeInput is false.

We actually have a logic to always reset shouldShowComposeInput to true here

useEffect(() => {
fetchReportIfNeeded();
ComposerActions.setShouldShowComposeInput(true);

but as you know, it takes time to update the Onyx.

What changes do you think we should make in order to solve the problem?

IMO, the offending PR (#29073) solution that is trying to solve this issue is a bit hard to read. The behavior that the PR wants to achieve is to refocus back to the last focused composer, in that issue case is the edit composer.

We already have a utility for that called ReportActionComposeFocusManager which we can reuse in our case. So, my suggestion is:

  1. "Revert" the code from added composer focus glitch fix #29073
  2. When a modal closes or the screen regains focused, call ReportActionComposeFocusManager.focus(); instead of the local focus() function.
if (!(willBlurTextInputOnTapOutside && !isNextModalWillOpenRef.current && !modal.isVisible && isFocused && (prevIsModalVisible || !prevIsFocused))) {
    return;
}

-focus();
+ReportActionComposeFocusManager.focus();

Super simple!

Copy link

melvin-bot bot commented Nov 7, 2023

@hoangzinh, @peterdbarkerUK Uh oh! This issue is overdue by 2 days. Don't forget to update your issues!

@peterdbarkerUK
Copy link
Contributor

Not overdue, just waiting on proposal review

@melvin-bot melvin-bot bot removed the Overdue label Nov 7, 2023
Copy link

melvin-bot bot commented Nov 8, 2023

@hoangzinh @peterdbarkerUK this issue is now 3 weeks old. There is one more week left before this issue breaks WAQ and will need to go internal. What needs to happen to get a PR in review this week? Please create a thread in #expensify-open-source to discuss. Thanks!

Copy link

melvin-bot bot commented Nov 8, 2023

📣 It's been a week! Do we have any satisfactory proposals yet? Do we need to adjust the bounty for this issue? 💸

@hoangzinh
Copy link
Contributor

On my list to review today

@hoangzinh
Copy link
Contributor

Update: still reading the previous issue #26527 to understand their changes.

@ayazalavi
Copy link
Contributor

ayazalavi commented Nov 13, 2023 via email

@hoangzinh
Copy link
Contributor

Somehow I couldn't reproduce the issue in dev/staging. Is there anyone able to reproduce the issue now?

Screen.Recording.2023-11-13.at.14.39.49.mov

@bernhardoj
Copy link
Contributor

Looks like it's no longer reproducible after the rn-web upgrade.

@peterdbarkerUK
Copy link
Contributor

+1 I can no longer reproduce. I'm checking how compensation works in this scenario (personal paper trial)

@ayazalavi
Copy link
Contributor

ayazalavi commented Nov 13, 2023 via email

@peterdbarkerUK
Copy link
Contributor

@ayazalavi I'm not sure I understand your question, could you clarify? Thanks!

@peterdbarkerUK
Copy link
Contributor

Hey folks - first up, I really appreciate all your work making and reviewing proposals for this.

As this has been resolved by the rn-web update, I'm going to close it out without paying bounties. The reason being that this issue was solved "in the course of things" unrelated to this issue, without work needing to be done. I understand this can be frustrating, though with the issues that are quick and easy to resolve I hope it is, on balance, not too painful.

Please let me know if you have any questions or disagree!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug Something is broken. Auto assigns a BugZero manager. Daily KSv2 Engineering External Added to denote the issue can be worked on by a contributor Help Wanted Apply this label when an issue is open to proposals by contributors
Projects
None yet
Development

No branches or pull requests

7 participants