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 - Mark the chat as "read" immediately upon switching to the tab #34537

Merged
7 changes: 6 additions & 1 deletion src/libs/actions/Report.ts
Original file line number Diff line number Diff line change
Expand Up @@ -933,7 +933,7 @@ function expandURLPreview(reportID: string, reportActionID: string) {
}

/** Marks the new report actions as read */
function readNewestAction(reportID: string) {
function readNewestAction(reportID: string, shouldEmitEvent = true) {
const lastReadTime = DateUtils.getDBTime();

const optimisticData: OnyxUpdate[] = [
Expand All @@ -957,6 +957,11 @@ function readNewestAction(reportID: string) {
};

API.write('ReadNewestAction', parameters, {optimisticData});

if (!shouldEmitEvent) {
return;
}

DeviceEventEmitter.emit(`readNewestAction_${reportID}`, lastReadTime);
}

Expand Down
46 changes: 44 additions & 2 deletions src/pages/home/report/ReportActionsList.js
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ function ReportActionsList({
const route = useRoute();
const opacity = useSharedValue(0);
const userActiveSince = useRef(null);
const userInactiveSince = useRef(null);

const markerInit = () => {
if (!cacheUnreadMarkers.has(report.reportID)) {
Expand Down Expand Up @@ -387,7 +388,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 @@ -405,7 +406,48 @@ function ReportActionsList({
if (!markerFound) {
setCurrentUnreadMarker(null);
}
}, [sortedVisibleReportActions, report.lastReadTime, report.reportID, messageManuallyMarkedUnread, shouldDisplayNewMarker, currentUnreadMarker]);
}, [sortedVisibleReportActions, shouldDisplayNewMarker, currentUnreadMarker, report.reportID]);

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

const onVisibilityChange = useCallback(() => {
if (!Visibility.isVisible()) {
userInactiveSince.current = DateUtils.getDBTime();
return;
}
// In case the user read new messages (after being inactive) with other device we should
// show marker based on report.lastReadTime
const newMessageTimeReference = userInactiveSince.current > report.lastReadTime ? userActiveSince.current : report.lastReadTime;
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, false);
userActiveSince.current = DateUtils.getDBTime();
lastReadTimeRef.current = newMessageTimeReference;
setCurrentUnreadMarker(null);
cacheUnreadMarkers.delete(report.reportID);
calculateUnreadMarker();
}, [calculateUnreadMarker, report, sortedVisibleReportActions]);

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

return unsubscribeVisibilityListener;
}, [onVisibilityChange]);

const renderItem = useCallback(
({item: reportAction, index}) => (
Expand Down
Loading