Keep settled mobile sidebars hidden under UI load

The earlier ghost-open fix gated re-commits on a settle counter, but on
Fabric that doesn't hold: Reanimated re-applies its own (stale) animated
props over React's committed props on every commit, so a settled-closed
sidebar still reappears after a heavy commit (e.g. a long thread mounting
or a message send) — reanimated#9635. No committed transform/opacity
value can win while a useAnimatedStyle is attached.

Split ownership instead: React owns whether the overlay exists, the
worklet owns its motion. display lives on the plain wrapper View that
Reanimated never touches, so a hidden overlay stays hidden regardless of
what the animated props revert to. An open gesture flips an overlayPeek
flag to reveal the panel before the store updates; a short close grace
keeps it displayed until the close animation finishes.

Residual: a heavy commit landing mid-close-animation can still flash the
panel until the animation settles — transient, not the previous permanent
wedge.
This commit is contained in:
Mohamed Boudra
2026-06-13 08:34:52 +07:00
parent 04a985bf23
commit e0463ad17f
6 changed files with 112 additions and 132 deletions
@@ -20,6 +20,7 @@ export function useExplorerOpenGesture({ enabled, onOpen }: UseExplorerOpenGestu
windowWidth,
animateToOpen,
animateToClose,
setOverlayPeek,
isGesturing,
gestureAnimatingRef,
openGestureRef,
@@ -93,6 +94,8 @@ export function useExplorerOpenGesture({ enabled, onOpen }: UseExplorerOpenGestu
})
.onStart(() => {
isGesturing.value = true;
// The overlay is display:none while closed; reveal it for the drag.
runOnJS(setOverlayPeek)(true);
})
.onUpdate((event) => {
// Right sidebar: start from closed position (+windowWidth) and move towards 0.
@@ -122,6 +125,7 @@ export function useExplorerOpenGesture({ enabled, onOpen }: UseExplorerOpenGestu
})
.onFinalize(() => {
isGesturing.value = false;
runOnJS(setOverlayPeek)(false);
}),
[
enabled,
@@ -131,6 +135,7 @@ export function useExplorerOpenGesture({ enabled, onOpen }: UseExplorerOpenGestu
mobilePanelState,
animateToOpen,
animateToClose,
setOverlayPeek,
isGesturing,
openGestureRef,
leftOpenGestureRef,