fix(app): keep iOS fullscreen composer above the keyboard (#7170)

Keep keyboard translation attached to the native animation graph when fullscreen resizes the dock. Apply the enabled mode on the native animation frame so Fabric does not restore the previous transform during layout.
This commit is contained in:
Mohamed Boudra
2026-10-17 00:38:15 +07:00
committed by GitHub
parent df82edd218
commit a1c6e8dfaf
2 changed files with 36 additions and 4 deletions
@@ -0,0 +1,18 @@
context platform=ios timeout=60000 retries=0
# Start with an empty composer in an idle chat or new-agent draft on an iPhone with the software keyboard enabled.
# Expand a long draft with the keyboard open; Exit fullscreen must remain reachable.
open sh.paseo.debug
wait "editable=true" 60000
fill "editable=true" "iOS fullscreen composer smoke.\n\nLine 1: Check that the composer keeps this draft when expanded and collapsed.\nLine 2: Check that the composer keeps this draft when expanded and collapsed.\nLine 3: Check that the composer keeps this draft when expanded and collapsed.\nLine 4: Check that the composer keeps this draft when expanded and collapsed.\nLine 5: Check that the composer keeps this draft when expanded and collapsed.\nLine 6: Check that the composer keeps this draft when expanded and collapsed.\nLine 7: Check that the composer keeps this draft when expanded and collapsed.\nLine 8: Check that the composer keeps this draft when expanded and collapsed.\nLine 9: Check that the composer keeps this draft when expanded and collapsed.\nLine 10: Check that the composer keeps this draft when expanded and collapsed.\nLine 11: Check that the composer keeps this draft when expanded and collapsed.\nLine 12: Check that the composer keeps this draft when expanded and collapsed.\nLine 13: Check that the composer keeps this draft when expanded and collapsed.\nLine 14: Check that the composer keeps this draft when expanded and collapsed."
press "label=\"Fullscreen\""
wait "label=\"Exit fullscreen\" role=button" 5000
is visible "label=\"Exit fullscreen\" role=button"
press "label=\"Exit fullscreen\" role=button"
wait "label=\"Fullscreen\" role=button" 5000
is visible "label=\"Fullscreen\" role=button"
press "label=\"Fullscreen\""
wait "label=\"Exit fullscreen\" role=button" 5000
is visible "label=\"Exit fullscreen\" role=button"
press "label=\"Exit fullscreen\" role=button"
wait "label=\"Fullscreen\" role=button" 5000
is visible "label=\"Fullscreen\" role=button"
@@ -1,5 +1,5 @@
import { useMemo, type ReactNode } from "react";
import { Animated, type ViewProps } from "react-native";
import { useMemo, useEffect, type ReactNode } from "react";
import { Animated, useAnimatedValue, type ViewProps } from "react-native";
import { useKeyboardAnimation } from "react-native-keyboard-controller";
import { useSafeAreaInsets } from "react-native-safe-area-context";
@@ -32,9 +32,23 @@ export function KeyboardTranslateView({
}),
[bottomClearance, height, insets.bottom, progress],
);
// Fullscreen resizes this view while disabling translation. iOS Fabric can
// reapply its previous transform during that layout commit. Keep the graph
// attached and apply the mode on the native animation frame; a static zero or
// setValue during the React commit gets overwritten by the resize.
const enabledValue = useAnimatedValue(enabled ? 1 : 0);
useEffect(() => {
const animation = Animated.timing(enabledValue, {
toValue: enabled ? 1 : 0,
duration: 0,
useNativeDriver: true,
});
animation.start();
return () => animation.stop();
}, [enabled, enabledValue]);
const keyboardStyle = useMemo(
() => ({ transform: [{ translateY: enabled ? translateY : 0 }] }),
[enabled, translateY],
() => ({ transform: [{ translateY: Animated.multiply(translateY, enabledValue) }] }),
[enabledValue, translateY],
);
return (