forked from Expensify/App
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathPriorityModeController.tsx
More file actions
98 lines (85 loc) · 4.58 KB
/
Copy pathPriorityModeController.tsx
File metadata and controls
98 lines (85 loc) · 4.58 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
import {useNavigation} from '@react-navigation/native';
import React, {useCallback, useEffect, useMemo, useRef, useState} from 'react';
import {useOnyx} from 'react-native-onyx';
import useReportDataLoading from '@hooks/useReportDataLoading';
import {updateChatPriorityMode} from '@libs/actions/User';
import getIsNarrowLayout from '@libs/getIsNarrowLayout';
import Log from '@libs/Log';
import navigationRef from '@libs/Navigation/navigationRef';
import {isReportParticipant, isValidReport} from '@libs/ReportUtils';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import SCREENS from '@src/SCREENS';
import FocusModeNotification from './FocusModeNotification';
/**
* This component is used to automatically switch a user into #focus mode when they exceed a certain number of reports.
* We do this primarily for performance reasons. Similar to the "Welcome action" we must wait for a number of things to
* happen when the user signs in or refreshes the page:
*
* - NVP that tracks whether they have already been switched over. We only do this once.
* - Priority mode NVP (that dictates the ordering/filtering logic of the LHN)
* - Reports to load (in ReconnectApp or OpenApp). As we check the count of the reports to determine whether the
* user is eligible to be automatically switched.
*
*/
export default function PriorityModeController() {
const [accountID] = useOnyx(ONYXKEYS.SESSION, {selector: (session) => session?.accountID, canBeMissing: true});
const isLoadingReportData = useReportDataLoading();
const [isInFocusMode] = useOnyx(ONYXKEYS.NVP_PRIORITY_MODE, {selector: (priorityMode) => priorityMode === CONST.PRIORITY_MODE.GSD, canBeMissing: true});
const [hasTriedFocusMode] = useOnyx(ONYXKEYS.NVP_TRY_FOCUS_MODE, {canBeMissing: true});
const [allReports] = useOnyx(ONYXKEYS.COLLECTION.REPORT, {canBeMissing: true});
const currentRouteName = useCurrentRouteName();
const [shouldShowModal, setShouldShowModal] = useState(false);
const closeModal = useCallback(() => setShouldShowModal(false), []);
const validReportCount = useMemo(() => {
let count = 0;
Object.values(allReports ?? {}).forEach((report) => {
if (!isValidReport(report) || !isReportParticipant(accountID ?? CONST.DEFAULT_NUMBER_ID, report)) {
return;
}
count++;
});
return count;
}, [accountID, allReports]);
// We set this when we have finally auto-switched the user of #focus mode to prevent duplication.
const hasSwitched = useRef(false);
// Listen for state changes and trigger the #focus mode when appropriate
useEffect(() => {
// Wait for Onyx state to fully load
if (isLoadingReportData || isInFocusMode === undefined || hasTriedFocusMode === undefined || !accountID) {
return;
}
if (hasSwitched.current || isInFocusMode || hasTriedFocusMode) {
return;
}
if (validReportCount < CONST.REPORT.MAX_COUNT_BEFORE_FOCUS_UPDATE) {
Log.info('[PriorityModeController] Not switching user to focus mode as they do not have enough reports', false, {validReportCount});
return;
}
// We wait for the user to navigate back to the home screen before triggering this switch
const isNarrowLayout = getIsNarrowLayout();
if ((isNarrowLayout && currentRouteName !== SCREENS.HOME) || (!isNarrowLayout && currentRouteName !== SCREENS.REPORT)) {
Log.info("[PriorityModeController] Not switching user to focus mode as they aren't on the home screen", false, {validReportCount, currentRouteName});
return;
}
Log.info('[PriorityModeController] Switching user to focus mode', false, {validReportCount, hasTriedFocusMode, isInFocusMode, currentRouteName});
updateChatPriorityMode(CONST.PRIORITY_MODE.GSD, true);
setShouldShowModal(true);
hasSwitched.current = true;
}, [accountID, currentRouteName, hasTriedFocusMode, isInFocusMode, isLoadingReportData, validReportCount]);
return shouldShowModal ? <FocusModeNotification onClose={closeModal} /> : null;
}
/**
* A funky but reliable way to subscribe to screen changes.
*/
function useCurrentRouteName() {
const navigation = useNavigation();
const [currentRouteName, setCurrentRouteName] = useState<string | undefined>('');
useEffect(() => {
const unsubscribe = navigation.addListener('state', () => {
setCurrentRouteName(navigationRef.getCurrentRoute()?.name);
});
return () => unsubscribe();
}, [navigation]);
return currentRouteName;
}