Skip to content

Commit

Permalink
Merge pull request #37021 from FitseTLT/fix-mark-as-read-switching-be…
Browse files Browse the repository at this point in the history
…tween-tabs

Fix - Mark the chat as "read" immediately upon switching to the tab
  • Loading branch information
Hayata Suenaga authored Mar 5, 2024
2 parents 5199604 + f12d925 commit b921221
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 3 deletions.
67 changes: 64 additions & 3 deletions src/pages/home/report/ReportActionsList.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {useRoute} from '@react-navigation/native';
import {useIsFocused, useRoute} from '@react-navigation/native';
import lodashGet from 'lodash/get';
import PropTypes from 'prop-types';
import React, {memo, useCallback, useEffect, useMemo, useRef, useState} from 'react';
Expand Down Expand Up @@ -149,6 +149,18 @@ function ReportActionsList({
const route = useRoute();
const opacity = useSharedValue(0);
const userActiveSince = useRef(null);
const lastMessageTime = useRef(null);

const [isVisible, setIsVisible] = useState(false);
const isFocused = useIsFocused();

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

return unsubscriber;
}, []);

const markerInit = () => {
if (!cacheUnreadMarkers.has(report.reportID)) {
Expand Down Expand Up @@ -393,7 +405,7 @@ function ReportActionsList({
[currentUnreadMarker, sortedVisibleReportActions, report.reportID, messageManuallyMarkedUnread],
);

useEffect(() => {
const calculateUnreadMarker = useCallback(() => {
// Iterate through the report actions and set appropriate unread marker.
// This is to avoid a warning of:
// Cannot update a component (ReportActionsList) while rendering a different component (CellRenderer).
Expand All @@ -411,7 +423,56 @@ function ReportActionsList({
if (!markerFound) {
setCurrentUnreadMarker(null);
}
}, [sortedVisibleReportActions, report.lastReadTime, report.reportID, messageManuallyMarkedUnread, shouldDisplayNewMarker, currentUnreadMarker]);
}, [sortedVisibleReportActions, report.reportID, shouldDisplayNewMarker, currentUnreadMarker]);

useEffect(() => {
calculateUnreadMarker();
}, [calculateUnreadMarker, report.lastReadTime, messageManuallyMarkedUnread]);

useEffect(() => {
if (!userActiveSince.current || report.reportID !== prevReportID) {
return;
}

if (!isVisible || !isFocused) {
if (!lastMessageTime.current) {
lastMessageTime.current = lodashGet(sortedVisibleReportActions, '[0].created', '');
}
return;
}

// In case the user read new messages (after being inactive) with other device we should
// show marker based on report.lastReadTime
const newMessageTimeReference = lastMessageTime.current > report.lastReadTime ? userActiveSince.current : report.lastReadTime;
lastMessageTime.current = null;
if (
scrollingVerticalOffset.current >= MSG_VISIBLE_THRESHOLD ||
!(
sortedVisibleReportActions &&
_.some(
sortedVisibleReportActions,
(reportAction) =>
newMessageTimeReference < reportAction.created &&
(ReportActionsUtils.isReportPreviewAction(reportAction) ? reportAction.childLastActorAccountID : reportAction.actorAccountID) !== Report.getCurrentUserAccountID(),
)
)
) {
return;
}

Report.readNewestAction(report.reportID);
userActiveSince.current = DateUtils.getDBTime();
lastReadTimeRef.current = newMessageTimeReference;
setCurrentUnreadMarker(null);
cacheUnreadMarkers.delete(report.reportID);
calculateUnreadMarker();

// This effect logic to `mark as read` will only run when the report focused has new messages and the App visibility
// is changed to visible(meaning user switched to app/web, while user was previously using different tab or application).
// We will mark the report as read in the above case which marks the LHN report item as read while showing the new message
// marker for the chat messages received while the user wasn't focused on the report or on another browser tab for web.
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [isFocused, isVisible]);

const renderItem = useCallback(
({item: reportAction, index}) => (
Expand Down
1 change: 1 addition & 0 deletions tests/perf-test/ReportActionsList.perf-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ jest.mock('@react-navigation/native', () => {
return {
...actualNav,
useRoute: () => mockedNavigate,
useIsFocused: () => true,
};
});

Expand Down

0 comments on commit b921221

Please sign in to comment.