Skip to content

Commit 93ce153

Browse files
committed
fix: offscreen PortalWhileClosingViews
1 parent 7992186 commit 93ce153

File tree

1 file changed

+50
-34
lines changed

1 file changed

+50
-34
lines changed

package/src/components/UIComponents/PortalWhileClosingView.tsx

Lines changed: 50 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { ReactNode, useEffect, useRef } from 'react';
1+
import React, { ReactNode, useEffect, useMemo, useRef } from 'react';
22
import { Platform, View } from 'react-native';
33

44
import Animated, { useAnimatedStyle, useSharedValue } from 'react-native-reanimated';
@@ -11,6 +11,7 @@ import {
1111
createClosingPortalLayoutRegistrationId,
1212
setClosingPortalLayout,
1313
useShouldTeleportToClosingPortal,
14+
useOverlayController,
1415
} from '../../state-store';
1516

1617
type PortalWhileClosingViewProps = {
@@ -31,6 +32,49 @@ type PortalWhileClosingViewProps = {
3132
portalName: string;
3233
};
3334

35+
const useSyncingApi = (portalHostName: string, registrationId: string) => {
36+
const containerRef = useRef<View | null>(null);
37+
const placeholderLayout = useSharedValue({ h: 0, w: 0 });
38+
const insets = useSafeAreaInsets();
39+
const { id } = useOverlayController();
40+
41+
const syncPortalLayout = useStableCallback(() => {
42+
if (!id) {
43+
return;
44+
}
45+
46+
containerRef.current?.measureInWindow((x, y, width, height) => {
47+
const absolute = {
48+
x,
49+
y: y + (Platform.OS === 'android' ? insets.top : 0),
50+
};
51+
52+
if (!width || !height) {
53+
return;
54+
}
55+
56+
placeholderLayout.value = { h: height, w: width };
57+
58+
setClosingPortalLayout(portalHostName, registrationId, {
59+
...absolute,
60+
h: height,
61+
w: width,
62+
});
63+
});
64+
});
65+
66+
useEffect(() => {
67+
if (id) {
68+
syncPortalLayout();
69+
}
70+
}, [insets.bottom, id, syncPortalLayout]);
71+
72+
return useMemo(
73+
() => ({ syncPortalLayout, containerRef, placeholderLayout }),
74+
[placeholderLayout, syncPortalLayout],
75+
);
76+
};
77+
3478
/**
3579
* Keeps wrapped UI above the message overlay during close animation by teleporting it to a closing portal host.
3680
*
@@ -67,54 +111,26 @@ export const PortalWhileClosingView = ({
67111
portalHostName,
68112
portalName,
69113
}: PortalWhileClosingViewProps) => {
70-
const containerRef = useRef<View | null>(null);
71114
const registrationIdRef = useRef<string | null>(null);
72-
const placeholderLayout = useSharedValue({ h: 0, w: 0 });
73-
const insets = useSafeAreaInsets();
74115

75116
if (!registrationIdRef.current) {
76117
registrationIdRef.current = createClosingPortalLayoutRegistrationId();
77118
}
78119

79120
const registrationId = registrationIdRef.current;
80-
const shouldTeleport = useShouldTeleportToClosingPortal(portalHostName, registrationId);
81-
82-
const syncPortalLayout = useStableCallback(() => {
83-
containerRef.current?.measureInWindow((x, y, width, height) => {
84-
const absolute = {
85-
x,
86-
y: y + (Platform.OS === 'android' ? insets.top : 0),
87-
};
88-
89-
if (!width || !height) {
90-
return;
91-
}
92121

93-
placeholderLayout.value = { h: height, w: width };
94-
95-
setClosingPortalLayout(portalHostName, registrationId, {
96-
...absolute,
97-
h: height,
98-
w: width,
99-
});
100-
});
101-
});
122+
const { syncPortalLayout, containerRef, placeholderLayout } = useSyncingApi(
123+
portalHostName,
124+
registrationId,
125+
);
126+
const shouldTeleport = useShouldTeleportToClosingPortal(portalHostName, registrationId);
102127

103128
useEffect(() => {
104129
return () => {
105130
clearClosingPortalLayout(portalHostName, registrationId);
106131
};
107132
}, [portalHostName, registrationId]);
108133

109-
useEffect(() => {
110-
// Measure once after mount and layout settle.
111-
requestAnimationFrame(() => {
112-
requestAnimationFrame(() => {
113-
syncPortalLayout();
114-
});
115-
});
116-
}, [insets.top, portalHostName, syncPortalLayout]);
117-
118134
const placeholderStyle = useAnimatedStyle(() => ({
119135
height: placeholderLayout.value.h,
120136
width: placeholderLayout.value.w > 0 ? placeholderLayout.value.w : '100%',

0 commit comments

Comments
 (0)