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] User can unpin a report and mark it as unread/read simultaneously. #26917

Closed
1 of 6 tasks
kavimuru opened this issue Sep 6, 2023 · 50 comments
Closed
1 of 6 tasks
Assignees
Labels
Bug Something is broken. Auto assigns a BugZero manager. Daily KSv2 Design Engineering Internal Requires API changes or must be handled by Expensify staff

Comments

@kavimuru
Copy link

kavimuru commented Sep 6, 2023

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


Action Performed:

  1. Right click on any report in LHS
  2. Unpin/pin & Mark as read/unread quickly

Expected Result:

User should be able to select one at a time.

Actual Result:

User is able to select both at a time.

Workaround:

Can the user still use Expensify without this being fixed? Have you informed them of the workaround?

Platforms:

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

  • Android / native
  • Android / Chrome
  • iOS / native
  • iOS / Safari
  • MacOS / Chrome / Safari
  • MacOS / Desktop

Version Number: 1.3.65-0
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
Notes/Photos/Videos: Any additional supporting documentation

bug_demo.mp4
web.mov

Expensify/Expensify Issue URL:
Issue reported by: @Krishna2323
Slack conversation: https://expensify.slack.com/archives/C049HHMV9SM/p1692160684023549

View all open jobs on GitHub

Upwork Automation - Do Not Edit
  • Upwork Job URL: https://www.upwork.com/jobs/~01c0f25974eee0955c
  • Upwork Job ID: 1699841676339986432
  • Last Price Increase: 2023-09-28
@kavimuru kavimuru added Daily KSv2 Bug Something is broken. Auto assigns a BugZero manager. labels Sep 6, 2023
@melvin-bot
Copy link

melvin-bot bot commented Sep 6, 2023

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

@melvin-bot
Copy link

melvin-bot bot commented Sep 6, 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

@akinwale
Copy link
Contributor

akinwale commented Sep 6, 2023

Proposal

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

User can unpin a report and mark it as unread/read simultaneously.

What is the root cause of that problem?

The shouldDelay parameter passed to the closePopover is set to true, which results in a delay when closing the popover.

hideContextMenu(true, ReportActionComposeFocusManager.focus);

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

Solution 1
Set the shouldDelay parameter to false for the closePopover method. This should also be done for the "Mark as read" and "Pin" / "Unpin" menu items.

However, it looks like the delay may be required when the context menu is displayed elsewhere.

  1. So we should add a new parameter for the onPress handler of the menu items in the ContextMenuActions file for the corresponding menu items that need to be displayed in the LHN. This parameter can be called shouldDelayClose.

  2. Add an optional parameter to the ReportActionContextMenu#showContextMenu method called shouldDelayClose with its default value set to true to maintain backward compatibility. When calling this method in OptionRowLHN, set the value for this parameter to false, and then pass the value to onPress event handler for each of the corresponding items.

ReportActionContextMenu.showContextMenu(

  1. Add the shouldDelayClose prop to BaseReportActionContextMenu and the corresponding prop type. Pass the prop as a member of the payload object when rendering the context menu actions.
shouldDelayClose: props.shouldDelayClose,
  1. Update PopoverReportActionContextMenu with shouldDelayClose set in the state. Add the parameter to the showContextMenu method with a default value set to true. Pass the state value as a prop to BaseReportActionContextMenu.

Solution 2
Use a boolean ref to track if a menu item has been clicked in BaseReportActionContextMenu and handle accordingly.

Why not a useState hook here? It is possible for a user to click faster than React updates the state, so two actions will still end up being registered in that scenario.

  1. Add the itemPressed ref.
const itemPressed = useRef(false);
  1. Update the onPress prop for the ContextMenuItem.
onPress={() => interceptAnonymousUser(() => {
    if (itemPressed.current) {
        return;
    }
    if (closePopup) {
        // only one menu item should register for a press if the popup should close afterwards
        itemPressed.current = true;
    }
    contextAction.onPress(closePopup, payload);
}, contextAction.isAnonymousAction)}

Solution 3 (not working)
Use the useSingleExecution hook to prevent multiple taps/clicks from registering meaning only one click will be executed at a time. This hook will be available once this PR is merged into main. Explanation.

To achieve this, the following changes will be made in BaseReportActionContextMenu.

  1. Add the useSingleExecution hook.
const {singleExecution} = useSingleExecution();
  1. Update the onPress prop for ContextMenuItem.
-onPress={() => interceptAnonymousUser(() => contextAction.onPress(closePopup, payload), contextAction.isAnonymousAction)}
+onPress={singleExecution(() => interceptAnonymousUser(() => contextAction.onPress(closePopup, payload), contextAction.isAnonymousAction))}

After testing this approach, it does not work as intended. While it works on native platforms, there seems to be no latency on web and the internal isExecuting state of the hook returns false before the next user click is registered.

What alternative solutions did you explore? (Optional)

None.

@DylanDylann
Copy link
Contributor

DylanDylann commented Sep 7, 2023

Proposal

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

User can unpin a report and mark it as unread/read simultaneously.

What is the root cause of that problem?

  • Currently, when clicking on the "Mark as unread" (or "Mark as read") button in the context menu, it will delay for 800ms before hiding the context menu, like below:
    hideContextMenu(true, ReportActionComposeFocusManager.focus);
  • The hideContextMenu with the first params called "shouldDelay":
    function hideContextMenu(shouldDelay, onHideCallback = () => {}) {
    if (!contextMenuRef.current) {
    return;
    }
    if (!shouldDelay) {
    contextMenuRef.current.hideContextMenu(onHideCallback);
    return;
    }
    // Save the active instanceID for which hide action was called.
    // If menu is being closed with a delay, check that whether the same instance exists or a new was created.
    // If instance is not same, cancel the hide action
    const instanceID = contextMenuRef.current.instanceID;
    setTimeout(() => {
    if (contextMenuRef.current.instanceID !== instanceID) {
    return;
    }
    contextMenuRef.current.hideContextMenu(onHideCallback);
    }, 800);
    }

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

  • We clicking on "Mark as unread" button, we can call the hideContextMenu with shouldDelay param is false like:
   hideContextMenu(false, ReportActionComposeFocusManager.focus);

What alternative solutions did you explore? (Optional)

  • We can just disable the others button after clicking on "Mark as unread" button to make sure that others' logic is not broken by creating a state disableClickOnContextMenuItem in PopoverReportActionContextMenu that used to decide if we should disable context button item or not
  • The hideContextMenu function will become:
function hideContextMenu(shouldDelay, onHideCallback = () => {}) {
  ...
    contextMenuRef.current.disableClickOnContextMenuItem();
    setTimeout(() => {
        if (contextMenuRef.current.instanceID !== instanceID) {
            return;
        }
        contextMenuRef.current.hideContextMenu(onHideCallback);
    }, 800);
}
  • In there, the disableClickOnContextMenuItem is:
  disableClickOnContextMenuItem() {
        this.setState({
            disableClickOnContextMenuItem: true,
        });
    }

Result

  • Solution 1:
Screencast.from.24-08-2023.22.59.14.webm
  • Solution 2:
Screencast.from.25-08-2023.02.26.25.webm

@abekkala abekkala added the External Added to denote the issue can be worked on by a contributor label Sep 7, 2023
@melvin-bot melvin-bot bot changed the title User can unpin a report and mark it as unread/read simultaneously. [$500] User can unpin a report and mark it as unread/read simultaneously. Sep 7, 2023
@melvin-bot
Copy link

melvin-bot bot commented Sep 7, 2023

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

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

melvin-bot bot commented Sep 7, 2023

Current assignee @abekkala is eligible for the External assigner, not assigning anyone new.

@melvin-bot
Copy link

melvin-bot bot commented Sep 7, 2023

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

@parasharrajat
Copy link
Member

Why is this an issue?

Does one action prevent the other? or Does one action create issues for the other?

@DylanDylann
Copy link
Contributor

@parasharrajat I think the expected is: User cannot click two items at once

@parasharrajat
Copy link
Member

Technically, they are being clicked one by one, not at a time.

@DylanDylann
Copy link
Contributor

@parasharrajat Yeah, I mean that once the ContextMenu is open, user can click on one item

@parasharrajat
Copy link
Member

Ok. It might be but IMO, it is fine.

@abekkala
Copy link
Contributor

abekkala commented Sep 7, 2023

It was decided in the Slack discussion that we should ensure the modal is closed when a context item is selected. Rather than staying open after the first selection

@melvin-bot
Copy link

melvin-bot bot commented Sep 11, 2023

@abekkala, @abdulrahuman5196 Whoops! This issue is 2 days overdue. Let's get this updated quick!

@melvin-bot melvin-bot bot added the Overdue label Sep 11, 2023
@melvin-bot
Copy link

melvin-bot bot commented Sep 11, 2023

@abekkala, @abdulrahuman5196 Whoops! This issue is 2 days overdue. Let's get this updated quick!

@abekkala
Copy link
Contributor

@abdulrahuman5196 have you had a chance to review the proposals that have been provided?

@melvin-bot melvin-bot bot added Overdue and removed Overdue labels Sep 11, 2023
@melvin-bot
Copy link

melvin-bot bot commented Sep 14, 2023

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

@abekkala
Copy link
Contributor

@abdulrahuman5196 have you reviewed the proposals for the fix?

@melvin-bot melvin-bot bot removed the Overdue label Sep 14, 2023
@DylanDylann
Copy link
Contributor

@abekkala @abdulrahuman5196 Currently, we are using the animation when selecting Mark as unread or Pin so I think we should not close the modal immediately after selecting item

Screencast.from.15-09-2023.11.57.21.webm

@melvin-bot
Copy link

melvin-bot bot commented Sep 27, 2023

@abekkala @abdulrahuman5196 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!

@abdulrahuman5196
Copy link
Contributor

Reviewing now

@melvin-bot melvin-bot bot removed the Overdue label Sep 27, 2023
@abdulrahuman5196
Copy link
Contributor

@abekkala Sorry for the delay.

Currently, we are using the animation when selecting Mark as unread or Pin so I think we should not close the modal immediately after selecting item

I agree on this. We can't close immediately.

What should be the expected behaviour here? Do we make the other options not clickable?

@DylanDylann
Copy link
Contributor

@abdulrahuman5196 my proposal will make other options not clickable #26917 (comment)

@melvin-bot
Copy link

melvin-bot bot commented Sep 28, 2023

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

@abdulrahuman5196
Copy link
Contributor

@abdulrahuman5196 my proposal will make other options not clickable #26917 (comment)

But I am doubtful if we want it. Because if its not clickable how can the UI be? It would be better to confirm what exact behaviour we want? Like I have asked here #26917 (comment)

cc: @abekkala

@DylanDylann
Copy link
Contributor

@abdulrahuman5196 Yeah we need to confirm. In my opinion, my proposal will disable other options, and when hovering over these options, it will display as {cursor: not-allowed} and the color will change to any "none-actvie" color

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

melvin-bot bot commented Oct 2, 2023

@abekkala, @abdulrahuman5196 Whoops! This issue is 2 days overdue. Let's get this updated quick!

@abdulrahuman5196
Copy link
Contributor

@abdulrahuman5196 my proposal will make other options not clickable #26917 (comment)

But I am doubtful if we want it. Because if its not clickable how can the UI be? It would be better to confirm what exact behaviour we want? Like I have asked here #26917 (comment)

cc: @abekkala

@abekkala Gentle ping on this.

And another point is, I am also skeptical about changing this behaviour. Because there are multiple other popovers using the same behaviour and we would end up changing others as well.

@melvin-bot melvin-bot bot removed the Overdue label Oct 3, 2023
@abekkala
Copy link
Contributor

abekkala commented Oct 3, 2023

@Julesssss pulling you in here as you were on the Slack conversation.

Should the modal close and not keep open to click back and forth both options?

@Julesssss Julesssss self-assigned this Oct 4, 2023
@Julesssss
Copy link
Contributor

Currently, we are using the animation when selecting Mark as unread or Pin so I think we should not close the modal immediately after selecting item

I don't think the animation is necessary tbh. The user doesn't need to see the state change to understand that it has occurred, plus it is causing this bug and looks like UI lag. Having said that, if the animation is desired then let's just do nothing here.

Let's ask @Expensify/design for their thoughts.

@melvin-bot
Copy link

melvin-bot bot commented Oct 4, 2023

Triggered auto assignment to @dannymcclain (Design), see these Stack Overflow questions for more details.

@shawnborton
Copy link
Contributor

I'm actually curious why we think this is a bug? I mean if the menu is open, and the options are selectable, why can't the user select either one as quickly as they want?

I mean obviously this is an edge case and we try to close the popover menu after one is selected. But I don't know that this is a "bug" personally.

@DylanDylann
Copy link
Contributor

@shawnborton You can check this one #24261. In that, we also prevent users from selecting two emojis at once

@shawnborton
Copy link
Contributor

Sure, but this is different - these aren't the same action (adding an emoji) - they are two distinct actions.

@melvin-bot
Copy link

melvin-bot bot commented Oct 4, 2023

@dannymcclain @Julesssss @abekkala @abdulrahuman5196 this issue is now 4 weeks old and preventing us from maintaining WAQ, can you:

  • Decide whether any proposals currently meet our guidelines and can be approved as-is today
  • If no proposals meet that standard, please take this issue internal and treat it as one of your highest priorities
  • If you have any questions, don't hesitate to start a discussion in #expensify-open-source

Thanks!

@melvin-bot melvin-bot bot added Internal Requires API changes or must be handled by Expensify staff and removed 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 labels Oct 4, 2023
@melvin-bot
Copy link

melvin-bot bot commented Oct 4, 2023

Current assignee @abdulrahuman5196 is eligible for the Internal assigner, not assigning anyone new.

@abekkala
Copy link
Contributor

abekkala commented Oct 4, 2023

Ok, so it sounds like initially in the slack thread we decided this was something to "fix" and now after further reflection we decided this is not a bug. @Julesssss we good to just close this then?

@Julesssss
Copy link
Contributor

Yeah, I agree. While not ideal let's not fix something that isn't broken

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 Design Engineering Internal Requires API changes or must be handled by Expensify staff
Projects
None yet
Development

No branches or pull requests

9 participants