| ... | ... | @@ -17,7 +17,11 @@ import type { |
| 17 | 17 | import * as Haptics from "expo-haptics"; |
| 18 | 18 | import { memo, useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react"; |
| 19 | 19 | import { Platform, View, type GestureResponderEvent } from "react-native"; |
| 20 | | import { KeyboardController, KeyboardStickyView } from "react-native-keyboard-controller"; |
| 20 | import { |
| 21 | KeyboardController, |
| 22 | KeyboardStickyView, |
| 23 | useKeyboardState, |
| 24 | } from "react-native-keyboard-controller"; |
| 21 | 25 | import Animated, { FadeInDown, FadeOut } from "react-native-reanimated"; |
| 22 | 26 | import { useSafeAreaInsets } from "react-native-safe-area-context"; |
| 23 | 27 | |
| ... | ... | @@ -183,7 +187,11 @@ export const ThreadDetailScreen = memo(function ThreadDetailScreen(props: Thread |
| 183 | 187 | const lastScrolledAnchorMessageIdRef = useRef<MessageId | null>(null); |
| 184 | 188 | const [composerExpanded, setComposerExpanded] = useState(false); |
| 185 | 189 | const [anchorMessageId, setAnchorMessageId] = useState<MessageId | null>(null); |
| 186 | | const composerBottomInset = composerExpanded ? 0 : Math.max(insets.bottom, 12); |
| 190 | // Key the safe-area padding on keyboard visibility, not focus: on Android |
| 191 | // the back gesture closes the keyboard while the editor stays focused, and |
| 192 | // a focus-keyed inset would leave the toolbar under the gesture bar. |
| 193 | const isKeyboardVisible = useKeyboardState((state) => state.isVisible); |
| 194 | const composerBottomInset = isKeyboardVisible ? 0 : Math.max(insets.bottom, 12); |
| 187 | 195 | const contentPresentationKind = props.contentPresentation.kind; |
| 188 | 196 | // The raw sync status enters "synchronizing" on every full fetch, cached or |
| 189 | 197 | // not. Whether messages are already on screen decides the pill label: no |