Skip to content

Commit

Permalink
implement new freeze wrapper
Browse files Browse the repository at this point in the history
  • Loading branch information
adamgrzybowski committed Nov 8, 2024
1 parent 6fc9f27 commit c52cbaa
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import type {NavigationState} from '@react-navigation/native';
import {isFullScreenName} from '@libs/NavigationUtils';

function getIsScreenBlurred(state: NavigationState, currentRouteKey: string) {
const lastFullScreenRoute = state.routes.findLast((route) => isFullScreenName(route.name));
return lastFullScreenRoute?.key !== currentRouteKey;
}

export default getIsScreenBlurred;
28 changes: 28 additions & 0 deletions src/libs/Navigation/AppNavigator/FreezeWrapper/index.native.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import {useNavigation, useRoute} from '@react-navigation/native';
import React, {useEffect, useState} from 'react';
import {Freeze} from 'react-freeze';
import type ChildrenProps from '@src/types/utils/ChildrenProps';
import getIsScreenBlurred from './getIsScreenBlurred';

type FreezeWrapperProps = ChildrenProps & {
/** Prop to disable freeze */
keepVisible?: boolean;
};

function FreezeWrapper({keepVisible = false, children}: FreezeWrapperProps) {
const navigation = useNavigation();
const currentRoute = useRoute();

const [isScreenBlurred, setIsScreenBlurred] = useState(false);

useEffect(() => {
const unsubscribe = navigation.addListener('state', (e) => setIsScreenBlurred(getIsScreenBlurred(e.data.state, currentRoute.key)));
return () => unsubscribe();
}, [currentRoute.key, navigation]);

return <Freeze freeze={isScreenBlurred && !keepVisible}>{children}</Freeze>;
}

FreezeWrapper.displayName = 'FreezeWrapper';

export default FreezeWrapper;
35 changes: 35 additions & 0 deletions src/libs/Navigation/AppNavigator/FreezeWrapper/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import {useNavigation, useRoute} from '@react-navigation/native';
import React, {useEffect, useLayoutEffect, useState} from 'react';
import {Freeze} from 'react-freeze';
import type ChildrenProps from '@src/types/utils/ChildrenProps';
import getIsScreenBlurred from './getIsScreenBlurred';

type FreezeWrapperProps = ChildrenProps & {
/** Prop to disable freeze */
keepVisible?: boolean;
};

function FreezeWrapper({keepVisible = false, children}: FreezeWrapperProps) {
const navigation = useNavigation();
const currentRoute = useRoute();

const [isScreenBlurred, setIsScreenBlurred] = useState(false);
const [freezed, setFreezed] = useState(false);

useEffect(() => {
const unsubscribe = navigation.addListener('state', (e) => setIsScreenBlurred(getIsScreenBlurred(e.data.state, currentRoute.key)));
return () => unsubscribe();
}, [currentRoute.key, navigation]);

// Decouple the Suspense render task so it won't be interrupted by React's concurrent mode
// and stuck in an infinite loop
useLayoutEffect(() => {
setFreezed(isScreenBlurred && !keepVisible);
}, [isScreenBlurred, keepVisible]);

return <Freeze freeze={freezed}>{children}</Freeze>;
}

FreezeWrapper.displayName = 'FreezeWrapper';

export default FreezeWrapper;

0 comments on commit c52cbaa

Please sign in to comment.