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: use focus listeners for message read status #35004

Closed
wants to merge 11 commits into from

Conversation

jeremy-croff
Copy link
Contributor

@jeremy-croff jeremy-croff commented Jan 23, 2024

Details

Implement the correct isVisible and isFocus methods for the electron Visibility Util.
When this util was originally implemented, electron did not have win.isVisible yet. original implementation for reference:
e7150f9

Fixed Issues

$ #34829
PROPOSAL: #34829 (comment)

Tests

QA steps;

Given two logged in users, atleast one the electron app

  1. Open Desktop App
  2. Login as User A
  3. Open Web App/Device
  4. Login as User B

Given created chat
5. Click the green plus icon in the bottom left
6. press Start Chat
7. type the email from person you want to chat with
8. hit add to group to create the chat

Scenario receives notifications and marks as read when clicking on it

When chat is not focused
9. From User A select a chat of Concierge or another one that's not user B
10. From User B sent a message to User A
11. User A received Notification, wait until it docks
12. Open Notification center and click on this received notification
13. Verify the chat is marked as read

When chat is focused and desktop app is minimized
14. From User A select a chat of user B
15. Minimize Desktop App of User A
15. From User B sent a message to User A
16. User A received Notification, wait until it docks
17. Open Notification center and click on this received notification
18. Verify the chat is marked as read

When chat is not focused and desktop app is already visibile
19. Open Desktop App of User A to front view ( visible state on monitor )
20. From User A select a chat of Concierge or another one that's not user B
21. From User B sent a message to User A
22. User A received Notification, wait until it docks
23. Open Notification center and click on this received notification
24. Verify the chat is marked as read

Scenario: chat doesn't receive notifications, but chat marks as read

When: chat is focused and desktop app is visibile
25. Open Desktop App of User A to front view ( visible state on monitor )
26. From User A select a chat of user B
27. From User B sent a message to User A
28. User A doesnt receive notification
29. Verify the chat is marked as read

When: chat is focused and desktop app is occluded but not minimized
30. Open Desktop App of User A to front view ( visible state on monitor )
31. From User Aselect a chat of user B
32. From User B sent a message to User A
33. User A doesnt receive notification
34. Verify the chat is marked as read

  • Verify that no errors appear in the JS console

Offline tests

  1. Disconnect the internet on user B
  2. Send messages from User A to B
  3. Connect the internet on User B
  4. Verify notifications come through

QA Steps

Given the
Scenario: two logged in users, atleast one the electron app
and
Scenario: created chat between the users
( or see steps above on how to create)

When user A is on another chat like Concierge, or has the electron app minimized:
-Send a message from User B to user A
-User A received Notification

  • Wait until Notification goes to the Notification center dock
    -Open Notification center and click on this received notification

  • Verify the chat is marked as read

  • 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: mWeb Chrome
    • iOS: Native
    • iOS: mWeb 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 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(theme.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 the PR modifies a component or page that can be accessed by a direct deeplink, I verified that the code functions as expected when the deeplink is used - from a logged in and logged out account.
  • If the PR modifies the form input styles:
    • I verified that all the inputs inside a form are aligned with each other.
    • I added Design label so the design team can review the changes.
  • 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.

Screenshots/Videos

Android: Native
Android.Native.mp4
Android: mWeb Chrome
AndroidWeb.mp4
iOS: Native
IOS.Native.test.mp4
iOS: mWeb Safari
IosMweb.mp4
MacOS: Chrome / Safari
macOsWeb.mp4
MacOS: Desktop
macOs.Electron.mp4

@jeremy-croff jeremy-croff requested a review from a team as a code owner January 23, 2024 20:45
Copy link
Contributor

github-actions bot commented Jan 23, 2024

CLA Assistant Lite bot All contributors have signed the CLA ✍️ ✅

@melvin-bot melvin-bot bot requested review from Julesssss and removed request for a team January 23, 2024 20:46
Copy link

melvin-bot bot commented Jan 23, 2024

@Julesssss Please 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]

@jeremy-croff jeremy-croff reopened this Jan 23, 2024
@jeremy-croff jeremy-croff reopened this Jan 24, 2024
@jeremy-croff jeremy-croff changed the title fix: uses visibility api from electron to determine visibility, imple… fix: implement electron visibility apis Jan 24, 2024
@jeremy-croff
Copy link
Contributor Author

jeremy-croff commented Jan 24, 2024

@Julesssss I want to make a special note on this test case I ran:

Scenario: chat is focused and desktop app is occluded but not minimized
When
- Open Desktop App of User A to front view ( visible state on monitor )
- From User A select a chat of user B
- From User B sent a message to User A

Then
- User A doesnt receive notification
- Verify the chat is marked as read

When the screen is occluded, but the chat is open on the report it receives a message from - The customer does not receive an notification because the app thinks it's still visible. This seems to be a recent bug with electron visibility returning as true even when occluded on certain devices electron/electron#38955 .

This is a regression because the previous electron isFocus would have still sent a notification.

I have added additional code in a draft PR to address this:
https://github.com/jeremy-croff/App/pull/2/files
This additional code relies on focus of the report to decide whether to notify and or mark as read. And will recheck on focus change. Not visibility which is problematic with it's edge cases and lack of guarantee the user is viewing it such as when the web the browser is 99% occluded and it would still mark it as read.

There's also another benefit of that change:
It will mark the existing active report as read once the user focuses on it.
This is an existing defect where

  1. if you receive a message on your active chat while it's minimized
  2. you open your tab
  3. It gets a unread state - it does not mark the report as read unless you leave the chat and come back.

I believe the additional PR is the best customer experience, and addresses all use cases.

Since the additional change were out of scope of the original proposal, I am seeking guidance on whether I can include them or not.

@Julesssss
Copy link
Contributor

I was incorrectly assigned here. Reassigning to @blimpich, and manually assigning @ishpaul777 for the C+ review

@ishpaul777
Copy link
Contributor

@jeremy-croff Can you please record a video scenario explained, with and without the additional changes

For future reference: please make sure to add full link to issue, before opening PR for review so automation can work properly

Fixed Issues
$ https://github.com/Expensify/App/issues/<issueid>

@ishpaul777
Copy link
Contributor

Also can you please update test Steps with a numbered list with expected result on each step (if any), see any of the other PRs like: #34560, #34563 etc.

@jeremy-croff
Copy link
Contributor Author

jeremy-croff commented Jan 24, 2024

@jeremy-croff Can you please record a video scenario explained, with and without the additional changes

For future reference: please make sure to add full link to issue, before opening PR for review so automation can work properly

Fixed Issues
$ https://github.com/Expensify/App/issues/<issueid>

Thank you for all the tips! Will be sure to do so.

Vids have audio with context

Before:

  1. bug with visibility and occlusion on electron ( regression )
  2. bug with mark existing open chat as read (existing)

Uploading Before additional changes.mp4…

After

  1. fixes both bugs
With.additional.changes.mov

@jeremy-croff
Copy link
Contributor Author

Also can you please update test Steps with a numbered list with expected result on each step (if any), see any of the other PRs like: #34560, #34563 etc.

updated

@ishpaul777
Copy link
Contributor

ishpaul777 commented Jan 24, 2024

Thanks!
Bug 1, seems like a bug caused by the changes with the PR, will so should be fixed Please push a fix.
Bug 2, If this is a existing bug and will be fixed with additional changes, please note that there is no additional compensation for this and comes with the risk of causing a regression which will cause a "-50%" if found during regression period

@jeremy-croff
Copy link
Contributor Author

jeremy-croff commented Jan 24, 2024

Thanks! Bug 1, seems like a bug caused by the changes with the PR, will so should be fixed Please push a fix. Bug 2, If this is a existing bug and will be fixed with additional changes, please note that there is no additional compensation for this and comes with the risk of causing a regression which will cause a "-50%" if found during regression period

Because the regression is caused by the usage of isVisible per electron/electron#38955 with no known workarounds. Reverting back to isFocus undoes my proposal.

In order to leverage isFocus as a solution, the onfocus listener must be utilized and Bug 2 comes free out of the box!

I think my hands are tied here.

I have merged in the additional proposed changed as this is both defect free and fixes other issues.

FIxes #33680 #34537

and possibly #34698 will have to test later. Heading into office now!

Comment on lines 206 to 215
const readNewestReportActionOnFocus = () => {
if(!ReportUtils.isUnread(report)){
return
}
if (Visibility.hasFocus() && scrollingVerticalOffset.current < MSG_VISIBLE_THRESHOLD) {
Report.readNewestAction(report.reportID);
} else {
readActionSkipped.current = true;
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we rewrite this like so?

diff --git a/src/pages/home/report/ReportActionsList.js b/src/pages/home/report/ReportActionsList.js
index 05f73032d7..b2ea93da28 100644
@@ -204,10 +204,7 @@ function ReportActionsList({
     }, [report.reportID]);
 
     const readNewestReportActionOnFocus = () => {
-        if(!ReportUtils.isUnread(report)){
-            return
-        }
-        if (Visibility.hasFocus() && scrollingVerticalOffset.current < MSG_VISIBLE_THRESHOLD) {
+        if (ReportUtils.isUnread(report) && Visibility.hasFocus() && scrollingVerticalOffset.current < MSG_VISIBLE_THRESHOLD) {
             Report.readNewestAction(report.reportID);
         } else {
             readActionSkipped.current = true;

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Makes sense, updated.
Thanks!

@ishpaul777
Copy link
Contributor

Hey @jeremy-croff, Changes seems to be causing regressions
Steps:

  1. start a chat between account A and account B
  2. with account A, open any other chat, for example, Concierge Chat, open any other window
  3. Send message to account A from B
  4. manually focus on to Desktop App (not from notification)

expected result, chat with B is unread
Actual result, chat with B is marked as read

And Honestly I am not confident with changes applied, the ideal solution is to hold for a upstream fix for electron/electron#38955 then revisit this issue instead of workaroud, @blimpich any thoughts ?

@blimpich
Copy link
Contributor

@ishpaul777 Yeah ideally we should fix the bug in Electron since it is the root cause. It doesn't look like there is much movement there though so having this sit here seems like not a great option either. I just posted a comment there asking a maintainer who seemed close to fixing it whether they will end up fixing it anytime soon. Lets see if they respond. If we don't think that it'll get fixed upstream anytime soon then I think we should try to make this PR work

@ishpaul777
Copy link
Contributor

Thanks for your thoughts! @blimpich, Lets put this for hold for response and revisit the issue next week.

@jeremy-croff
Copy link
Contributor Author

Hey @jeremy-croff, Changes seems to be causing regressions Steps:

  1. start a chat between account A and account B
  2. with account A, open any other chat, for example, Concierge Chat, open any other window
  3. Send message to account A from B
  4. manually focus on to Desktop App (not from notification)

expected result, chat with B is unread Actual result, chat with B is marked as read

And Honestly I am not confident with changes applied, the ideal solution is to hold for a upstream fix for electron/electron#38955 then revisit this issue instead of workaroud, @blimpich any thoughts ?

I've moved the logic that only reads the active report to be also used in the onfocus hook to address this. Good catch.

I'm still pending a full regression and can do so to have this ready while waiting on clarification if we should go with an upstream fix.

A case to make for not going with an upstream fix is because I believe visibility is not the right trigger for marking things as read. I currently believe focus is.

@blimpich
Copy link
Contributor

So far no response from upstream repo. I just emailed the engineer in case the GH comment didn't get through to them. I say we give that a day or two and if no response then lets go ahead with this.

@ishpaul777
Copy link
Contributor

Agree 👍 @jeremy-croff Can you please prepare your PR just incase we don't recieve any response

desktop/main.js Outdated
Comment on lines 560 to 564
// eslint-disable-next-line no-param-reassign
event.returnValue = browserWindow && !browserWindow.isDestroyed() && browserWindow.isVisible();
});

ipcMain.on(ELECTRON_EVENTS.REQUEST_HAS_FOCUS, (event) => {
Copy link
Contributor

Choose a reason for hiding this comment

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

The change is not required if we are checking for focus instead of visibilty right ?

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 believe this change is desired, this implements the correct focus logic for electron. Before it defaulted to true.

Copy link
Contributor

Choose a reason for hiding this comment

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

browserWindow.isVisible() is not yet bug free right, this may introduce another unidentified regression somewhere else, so i'd say if not necessary for this solution we remove it, as before we are already checking focus when we check for visibility. we continue using it and keep an eye until electron/electron#38982 is merged upstream, does that makes sense ?

Copy link
Contributor Author

@jeremy-croff jeremy-croff Jan 31, 2024

Choose a reason for hiding this comment

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

This makes sense

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@ishpaul777 Updated PR. thanks for the suggestion.
It's indeed not necessary for this solution. The initial thought that moving other logic over to focus would be more consistent in cases where windows are occluded and are still marking it as read. But it's out of this issues scope.

@iwiznia
Copy link
Contributor

iwiznia commented Mar 13, 2024

What's the deal with this PR? More than a month without an update and this is blocking #35085

The issue says this but I think that PR has been already deployed.

@ishpaul777
Copy link
Contributor

We were told that this PR #33680 will resolve the issue, when the i last checked PR it was not staging.

the issue was weekly so it got lost in my K2 sorry..

I retested the issue is still reproducable so we should move forward here

@blimpich
Copy link
Contributor

blimpich commented Mar 13, 2024

@iwiznia this issue is logistically messy. We originally were waiting for an upstream maintainer of Electron to patch Electron, and eventually they did but then the fix got reverted, then we also thought #33680 might fix this issue's root cause.

@ishpaul777 all good! It got lost in my k2 as well, I should have been keeping a closer eye on the issue we were holding on. I've lost faith that the upstream maintainers of Electron are going to fix this for us, so lets move forward with this PR.

cc: @jeremy-croff

@ishpaul777
Copy link
Contributor

ishpaul777 commented Mar 13, 2024

Yes, i retested still reproducable. but i'd like to see a updated proposal from @jeremy-croff as this PR dont have the approved changes initially. Lets move the conv. in the issue..

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