forked from Expensify/App
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathFreezeWrapper.tsx
39 lines (32 loc) · 1.56 KB
/
FreezeWrapper.tsx
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
import {useIsFocused, useNavigation, useRoute} from '@react-navigation/native';
import React, {useEffect, useRef, useState} from 'react';
import {Freeze} from 'react-freeze';
import type ChildrenProps from '@src/types/utils/ChildrenProps';
import shouldSetScreenBlurred from './shouldSetScreenBlurred';
type FreezeWrapperProps = ChildrenProps & {
/** Prop to disable freeze */
keepVisible?: boolean;
};
function FreezeWrapper({keepVisible = false, children}: FreezeWrapperProps) {
const [isScreenBlurred, setIsScreenBlurred] = useState(false);
// we need to know the screen index to determine if the screen can be frozen
const screenIndexRef = useRef<number | null>(null);
const isFocused = useIsFocused();
const navigation = useNavigation();
const currentRoute = useRoute();
useEffect(() => {
const index = navigation.getState()?.routes.findIndex((route) => route.key === currentRoute.key) ?? 0;
screenIndexRef.current = index;
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
useEffect(() => {
const unsubscribe = navigation.addListener('state', () => {
const navigationIndex = (navigation.getState()?.index ?? 0) - (screenIndexRef.current ?? 0);
setIsScreenBlurred(shouldSetScreenBlurred(navigationIndex));
});
return () => unsubscribe();
}, [isFocused, isScreenBlurred, navigation]);
return <Freeze freeze={!isFocused && isScreenBlurred && !keepVisible}>{children}</Freeze>;
}
FreezeWrapper.displayName = 'FreezeWrapper';
export default FreezeWrapper;