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

[HOLD for payment 2024-03-14] [HOLD for payment 2024-02-07] [$500] HIGH: Mark the chat as "read" immediately upon switching to the tab #33680

Closed
quinthar opened this issue Dec 28, 2023 · 105 comments
Assignees
Labels
Awaiting Payment Auto-added when associated PR is deployed to production Bug Something is broken. Auto assigns a BugZero manager. Engineering External Added to denote the issue can be worked on by a contributor Internal Requires API changes or must be handled by Expensify staff Weekly KSv2

Comments

@quinthar
Copy link
Contributor

quinthar commented Dec 28, 2023

Current behaviour:

  1. User is viewing a chat A and opens new tab.
  2. User receives messages in chat A and comes back to the tab with chat A being open.
  3. Currently the LHN shows as bold, but there is no Unread green line marker.
  4. If the user switches to another chat and comes back to the chat A, now chat A behaves as showing a new unread chat. The LHN bold is gone and unread green marker is shown.

Expected behaviour:

In step 3, LHN shouldn't be bold, though it should have the green unread marker should be shown to symbolize the new messages received.

When the user switches away, the green unread marker should be removed.

Upwork Automation - Do Not Edit
  • Upwork Job URL: https://www.upwork.com/jobs/~012a54894c108d9212
  • Upwork Job ID: 1745132109856296960
  • Last Price Increase: 2024-01-10
  • Automatic offers:
    • abdulrahuman5196 | Reviewer | 28093546
    • FitseTLT | Contributor | 28093547
@quinthar quinthar converted this from a draft issue Dec 28, 2023
@slafortune slafortune 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 Dec 28, 2023
Copy link

melvin-bot bot commented Dec 28, 2023

Job added to Upwork: https://www.upwork.com/jobs/~01962a536f7d747895

@melvin-bot melvin-bot bot changed the title CRITICAL: Mark the chat as "read" immediately upon switching to the tab [$500] CRITICAL: Mark the chat as "read" immediately upon switching to the tab Dec 28, 2023
Copy link

melvin-bot bot commented Dec 28, 2023

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

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

melvin-bot bot commented Dec 28, 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

Copy link

melvin-bot bot commented Dec 28, 2023

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

@rayane-djouah
Copy link
Contributor

rayane-djouah commented Dec 28, 2023

Proposal

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

chats are not marked as "read" immediately when a user switches to the chat tab.

What is the root cause of that problem?

the read status of a chat is not updated in real-time as the user views it. Instead, the status update appears to be dependent on a state change triggered by navigating away from and back to the report

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

React Native's AppState can be used to determine if the app is in the foreground or background, and the useEffect hook can be employed to run side effects based on state changes. Here's a proposed solution:

Import AppState from React Native: This module helps to determine the current state of the app.

Add AppState Listener in useEffect: We will add a listener to AppState to detect when the app is brought to the foreground.

Update Read Status: When the app comes to the foreground and the relevant chat tab is active, we trigger the action to mark the chat as read.

import { AppState } from 'react-native';
useEffect(() => {
    const handleAppStateChange = (nextAppState) => {
        // Check if the app is coming to the foreground 
        if (nextAppState === 'active') {
                if (Visibility.isVisible() && Visibility.hasFocus() && ReportUtils.isUnread(report)) {
                    // mark the chat as read
                    Report.readNewestAction(report.reportID);
                }
        }
    };

    AppState.addEventListener('change', handleAppStateChange);

    return () => {
        AppState.removeEventListener('change', handleAppStateChange);
    };
}, [report.reportID]);

What alternative solutions did you explore? (Optional)

@tienifr
Copy link
Contributor

tienifr commented Dec 28, 2023

Proposal

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

This is new feature, we want to mark chat as read when the chat gains focus.

What is the root cause of that problem?

This is new feature.

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

  1. First we want to listen to the screen visibility in order to run things like reseting marker, mark as read, ...
    We can define a new useEffect like below (we can add the Visibility.hasFocus as well if we want to, because even if the app is visible but it doesn't have focus, we might not want to consider it as "read")
const useScreenVisibility = () => {
    const [isVisible, setIsVisible] = useState(Visibility.isVisible());

    useEffect(() => {
        const unsubscribeVisibilityListener = Visibility.onVisibilityChange(() => {
            setIsVisible(Visibility.isVisible());
        });

        return unsubscribeVisibilityListener;
    }, []);

    return isVisible;
}

This can be reused for various use case in the app

  1. We want to read the report right after the user comes back to view the screen, so can add this to here
useEffect(() => {
        if (!isScreenVisible || scrollingVerticalOffset.current >= MSG_VISIBLE_THRESHOLD) {
            return;
        }
                    
        Report.readNewestAction(report.reportID);
        
        if (!currentUnreadMarker) {
            userActiveSince.current = DateUtils.getDBTime();
        }
    }, [report.reportID, isScreenVisible]);

Basically if the user comes back to the screen and the user is viewing the latest messages, then call Report.readNewestAction to read the report. We'll also set userActiveSince.current if the currentUnreadMarker is not present, to acknowledge that the user gets active in the page at that time, this will be used for step 3 below

  1. In here, we should add isScreenVisible to the dependency list so that the marker will be recalculated if the user becomes active in the page again, this will make sure the green marker shows correctly (because the userActiveSince.current needs to be correct for this condition to work, we already set userActiveSince.current to the correct value in step 2)

We can optionally add

if (!isScreenVisible) {
    return;
}

To here because we don't need to recalculate the green marker if the screen is not visible.

Inside readNewestAction we can optionally early return if the report is already read.

Note:

  • scrollingVerticalOffset.current < MSG_VISIBLE_THRESHOLD (If the user is scrolled out of view, the user didn't see the new message yet so we can't consider it as read, this is the same condition as in here).

What alternative solutions did you explore? (Optional)

We can modify this existing logic to handle the above cases, and we need to make sure to add screen visibility to the dependency list here

@tienifr
Copy link
Contributor

tienifr commented Dec 28, 2023

Proposal updated to clarify and add example code changes

@FitseTLT
Copy link
Contributor

FitseTLT commented Dec 28, 2023

@quinthar I have some suggestions

  1. Alice is viewing the Bob chat in her NewDot tab, but switches to a different tab to do something else. She gets a message from Bob, and switches back to the tab to view it.

Nope. Now unread marker will only display if you open the report while it has unread messages. If you are already on the report and you receive message while you 're on another tab and switch it back it will not display the marker.

  1. Mark chats as read immediately upon becoming visible in the foreground.

Then what is the reason to display the marker if we remove it immediately, in any other social media apps (e.g. telegram) the marker will exist until you open other chat and I think the current behaviour is correct.

@bfitzexpensify
Copy link
Contributor

@abdulrahuman5196 this is one marked as critical, so please prioritise reviewing the proposals here - thanks!

@quinthar
Copy link
Contributor Author

Nope. Now unread marker will only display if you open the report while it has unread messages. If you are already on the report and you receive message while you 're on another tab and switch it back it will not display the marker.

Ah, good questions! To clarify, I'm not referring to the "unread marker" (eg, the horizontal line across the chat that designates new from old messages). I'm referring to it being marked as unread (bold) in the LHN. I'm sorry for being ambiguous in the original description, does that clarify things?

@FitseTLT
Copy link
Contributor

FitseTLT commented Dec 28, 2023

Proposal

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

Mark the chat as "read" immediately upon switching to the tab

What is the root cause of that problem?

New Feature:
We already have the logic here

if (ReportUtils.isUnread(report)) {
if (Visibility.isVisible() && scrollingVerticalOffset.current < MSG_VISIBLE_THRESHOLD) {
Report.readNewestAction(report.reportID);

but it only marks the report read if it is Visibility.isVisible so once we return from other tab the useEffect will not be invoked as it only depends on report.lastVisibleActionCreated and report.reportID not visibility state

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

We should add visibility change listener and should Report.readNewestAction when Visibility.isVisible
and the scroll is below the MSG_VISIBLE_THRESHOLD

CAUTION: we should not reset currentUnreadMarker as that will remove the new message green unread marker line which should not be removed until we open another report (we only want the report to be read i.e. remove the boldness in LHN)

So inside ReportActionsList we add this code

useEffect(() => {
    const unsubscribeVisibilityListener = Visibility.onVisibilityChange(() => {

        InteractionManager.runAfterInteractions(() => {
            if (!Visibility.isVisible() || scrollingVerticalOffset.current >= MSG_VISIBLE_THRESHOLD) {
                return;
            }
           if (!currentUnreadMarker) {
                    userActiveSince.current = DateUtils.getDBTime();

                    _.each(sortedReportActions, (reportAction, index) => {
                        if (!shouldDisplayNewMarker(reportAction, index)) {
                            return;
                        }

                        if (!currentUnreadMarker && currentUnreadMarker !== reportAction.reportActionID) {
                            cacheUnreadMarkers.set(report.reportID, reportAction.reportActionID);
                            setCurrentUnreadMarker(reportAction.reportActionID);
                        }
                    });
                }
            Report.readNewestAction(report.reportID);
        });
        
    })

    return unsubscribeVisibilityListener;
}, [report.reportID]);

or We can also use this code

if (ReportUtils.isUnread(report)) {
if (Visibility.isVisible() && scrollingVerticalOffset.current < MSG_VISIBLE_THRESHOLD) {
Report.readNewestAction(report.reportID);

but we should add visibility state as a dependency here

}, [report.lastVisibleActionCreated, report.reportID]);

What alternative solutions did you explore? (Optional)

@bfitzexpensify
Copy link
Contributor

Bump @abdulrahuman5196 - please review these proposals, thank you!

@tienifr
Copy link
Contributor

tienifr commented Dec 29, 2023

Proposal updated with minor change, based on the requirement update

@FitseTLT
Copy link
Contributor

Proposal updated with minor change, based on the requirement update

       // put this if we want to clear the unread green marker as well after coming back, if not then ignore it

@abdulrahuman5196 please take a note that this is not a minor change but the main point of the new feature we are implementing. As only making the report unread and not resetting currentUnreadMarker is the critical and main point; and resetting currentUnreadMarker will make the unread marker useless as it will make it disappear as soon as the user opens the chat (as the visibility will be focused then) although it should be displayed until the user moves to other report or chat

@melvin-bot melvin-bot bot added the Overdue label Jan 1, 2024
@abdulrahuman5196
Copy link
Contributor

Reviewing now

@melvin-bot melvin-bot bot removed the Overdue label Jan 1, 2024
@abdulrahuman5196
Copy link
Contributor

Current Experience:

Screen.Recording.2024-01-01.at.11.33.07.PM.mov
  1. User is viewing a chat A and opens new tab.
  2. User receives messages in chat A and comes back to the tab with chat A being open.
  3. Currently the LHN shows as bold, but there is no Unread green line marker.
  4. If the user switches to another chat and comes back to the chat A, now chat A behaves as showing a new unread chat. Like the LHN bold is gone and unread green marker is shown.

I think there are 2 issues here regarding the LHN and unread marker here

I think in the step 3, we should change the experience like.
LHN shouldn't be bold, but green marker should be shown to symbolize the new messages received
(which is like a user going to new unread chat)

If we fix step 3, in step 4 the chat would automatically act as already read chat.

Kindly let me if we should change the unread marker as suggested or just have the LHN issue as mentioned in OP.

Copy link

melvin-bot bot commented Jan 1, 2024

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

@bfitzexpensify
Copy link
Contributor

@abdulrahuman5196 in step 4, when the user switches away, that would remove the green unread marker?

@abdulrahuman5196
Copy link
Contributor

@abdulrahuman5196 in step 4, when the user switches away, that would remove the green unread marker?

That should be the case IMO, but not happening right now. Atleast in this case if we switch to chat B and come back to chat A after step 3, we are seeing unread marker.
@bfitzexpensify

@bfitzexpensify
Copy link
Contributor

Sweet. Looks like you're up on reviewing the fix @abdulrahuman5196

@alexpensify alexpensify removed their assignment Feb 8, 2024
@alexpensify
Copy link
Contributor

Whoops, I missed that @bfitzexpensify is back online:

#33680 (comment)

I'm stepping away here and Ben will deal with the BZ next steps when that time comes.

@bfitzexpensify
Copy link
Contributor

Mind taking a look at the PR @abdulrahuman5196?

@abdulrahuman5196
Copy link
Contributor

Hi @bfitzexpensify Sorry for the delay. Will check on it today.

@bfitzexpensify
Copy link
Contributor

@abdulrahuman5196 what's the latest with this issue?

@abdulrahuman5196
Copy link
Contributor

@bfitzexpensify new changes have been merged yesterday

@hayata-suenaga
Copy link
Contributor

yep the pr was merged

@melvin-bot melvin-bot bot added Weekly KSv2 and removed Weekly KSv2 labels Mar 7, 2024
@melvin-bot melvin-bot bot changed the title [HOLD for payment 2024-02-07] [$500] CRITICAL: Mark the chat as "read" immediately upon switching to the tab [HOLD for payment 2024-03-14] [HOLD for payment 2024-02-07] [$500] CRITICAL: Mark the chat as "read" immediately upon switching to the tab Mar 7, 2024
Copy link

melvin-bot bot commented Mar 7, 2024

Reviewing label has been removed, please complete the "BugZero Checklist".

@melvin-bot melvin-bot bot removed the Reviewing Has a PR in review label Mar 7, 2024
Copy link

melvin-bot bot commented Mar 7, 2024

The solution for this issue has been 🚀 deployed to production 🚀 in version 1.4.48-0 and is now subject to a 7-day regression period 📆. Here is the list of pull requests that resolve this issue:

If no regressions arise, payment will be issued on 2024-03-14. 🎊

For reference, here are some details about the assignees on this issue:

Copy link

melvin-bot bot commented Mar 7, 2024

BugZero Checklist: The PR fixing this issue has been merged! The following checklist (instructions) will need to be completed before the issue can be closed:

  • [@abdulrahuman5196] The PR that introduced the bug has been identified. Link to the PR:
  • [@abdulrahuman5196] The offending PR has been commented on, pointing out the bug it caused and why, so the author and reviewers can learn from the mistake. Link to comment:
  • [@abdulrahuman5196] A discussion in #expensify-bugs has been started about whether any other steps should be taken (e.g. updating the PR review checklist) in order to catch this type of bug sooner. Link to discussion:
  • [@abdulrahuman5196] Determine if we should create a regression test for this bug.
  • [@abdulrahuman5196] If we decide to create a regression test for the bug, please propose the regression test steps to ensure the same bug will not reach production again.
  • [@bfitzexpensify] Link the GH issue for creating/updating the regression test once above steps have been agreed upon:

@bfitzexpensify
Copy link
Contributor

Payments complete, please complete the BZ checklist when you get a moment @abdulrahuman5196 - thank you!

@abdulrahuman5196
Copy link
Contributor

The PR that introduced the bug has been identified. Link to the PR:
The offending PR has been commented on, pointing out the bug it caused and why, so the author and reviewers can learn from the mistake. Link to comment:
A discussion in #expensify-bugs has been started about whether any other steps should be taken (e.g. updating the PR review checklist) in order to catch this type of bug sooner. Link to discussion:

Not a regression. New implementation.

Determine if we should create a regression test for this bug.

Yes.

If we decide to create a regression test for the bug, please propose the regression test steps to ensure the same bug will not reach production again.

  1. Login with User B and open a chat with User A and change to another tab on web
  2. Now Send a message as User A to User B
  3. Wait until the message arrives at User B and now as User B switch back to the tab you were chatting in (1)
  4. Check that the LHN is not bold
  5. verify that unread marker indicates on the new message you sent in (2)

@bfitzexpensify

@quinthar quinthar changed the title [HOLD for payment 2024-03-14] [HOLD for payment 2024-02-07] [$500] CRITICAL: Mark the chat as "read" immediately upon switching to the tab [HOLD for payment 2024-03-14] [HOLD for payment 2024-02-07] [$500] HIGH: Mark the chat as "read" immediately upon switching to the tab Mar 25, 2024
@abdulrahuman5196
Copy link
Contributor

I think we can close this @bfitzexpensify

@github-project-automation github-project-automation bot moved this from HIGH to CRITICAL in [#whatsnext] #vip-vsb Mar 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Awaiting Payment Auto-added when associated PR is deployed to production Bug Something is broken. Auto assigns a BugZero manager. Engineering External Added to denote the issue can be worked on by a contributor Internal Requires API changes or must be handled by Expensify staff Weekly KSv2
Projects
No open projects
Status: CRITICAL
Development

No branches or pull requests