Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 16 additions & 8 deletions src/hooks/useMarkAsRead.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import type * as OnyxTypes from '@src/types/onyx';
import type {OnyxEntry} from 'react-native-onyx';

import {useIsFocused, useRoute} from '@react-navigation/native';
import {useEffect, useRef, useState} from 'react';
import {useEffect, useEffectEvent, useRef, useState} from 'react';
import {DeviceEventEmitter} from 'react-native';

import useCurrentUserPersonalDetails from './useCurrentUserPersonalDetails';
Expand Down Expand Up @@ -98,7 +98,7 @@ function useMarkAsRead({reportID, report, transactionThreadReport, sortedVisible

const didMarkOnReportChangeRef = useRef(false);

useEffect(() => {
const handleReportChangeMarkAsRead = useEffectEvent(() => {
didMarkOnReportChangeRef.current = false;
if (reportID !== prevReportID) {
return;
Expand All @@ -121,11 +121,16 @@ function useMarkAsRead({reportID, report, transactionThreadReport, sortedVisible
}

readActionSkippedRef.current = true;
// This effect should only run when the newest visible action changes, otherwise every action/report object update can prematurely consume unread state.
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [report?.lastVisibleActionCreated, transactionThreadReport?.lastVisibleActionCreated, reportID, isVisible, isReportActionsLoaded]);
});

// Only re-run on newest-action changes; otherwise any report update can prematurely consume unread state.
useEffect(() => {
handleReportChangeMarkAsRead();
}, [report?.lastVisibleActionCreated, transactionThreadReport?.lastVisibleActionCreated, reportID, isVisible, isReportActionsLoaded]);

// isFocused is passed as an arg because the Effect Event closure can be stale (stuck true) on frozen screens,
// re-marking a just-unread report as read on report switch
const handleAppVisibilityMarkAsRead = useEffectEvent((isFocusedArg: boolean) => {
if (didMarkOnReportChangeRef.current) {
didMarkOnReportChangeRef.current = false;
return;
Expand All @@ -134,7 +139,7 @@ function useMarkAsRead({reportID, report, transactionThreadReport, sortedVisible
return;
}

if (!isVisible || !Visibility.hasFocus() || !isFocused) {
if (!isVisible || !Visibility.hasFocus() || !isFocusedArg) {
if (!lastMessageTime.current) {
lastMessageTime.current = lastAction?.created ?? '';
}
Expand All @@ -159,8 +164,11 @@ function useMarkAsRead({reportID, report, transactionThreadReport, sortedVisible

readNewestAction(reportID, true);
userActiveSince.current = DateUtils.getDBTime();
// This effect should only run when app visibility/focus changes; the helper reads the latest report/action values without making every action update mark the report as read.
// eslint-disable-next-line react-hooks/exhaustive-deps
});

// Only re-run when app visibility/focus changes, so action updates don't keep marking the report as read.
useEffect(() => {
handleAppVisibilityMarkAsRead(isFocused);
}, [isVisible, isFocused]);

const markNewestActionAsRead = () => {
Expand Down
Loading