Skip to content

Commit c28e46c

Browse files
committedMar 7, 2025·
fix: Conversation keyboard filler
1 parent e24b5c3 commit c28e46c

8 files changed

+50
-38
lines changed
 

‎features/conversation/conversation-chat/conversation-keyboard-filler.tsx

+20-30
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { AnimatedVStack } from "@design-system/VStack"
22
import { memo, useEffect, useRef } from "react"
33
import { Keyboard, TextInput } from "react-native"
4-
import { useAnimatedStyle, useSharedValue } from "react-native-reanimated"
4+
import { useAnimatedStyle } from "react-native-reanimated"
55
import { useSafeAreaInsets } from "react-native-safe-area-context"
66
import { useConversationMessageContextMenuEmojiPickerStore } from "@/features/conversation/conversation-chat/conversation-chat-message/conversation-message-context-menu/conversation-message-context-menu-emoji-picker/conversation-message-context-menu-emoji-picker.store"
77
import { useConversationMessageContextMenuStoreContext } from "@/features/conversation/conversation-chat/conversation-chat-message/conversation-message-context-menu/conversation-message-context-menu.store-context"
@@ -13,11 +13,10 @@ type IConversationKeyboardFillerProps = {}
1313
export const ConversationKeyboardFiller = memo(function ConversationKeyboardFiller(
1414
props: IConversationKeyboardFillerProps,
1515
) {
16-
const { height: keyboardHeightAV } = useAnimatedKeyboard()
16+
const { keyboardHeightAV, progressAV, previousOpenKeyboardHeightAV } = useAnimatedKeyboard()
1717
const insets = useSafeAreaInsets()
18-
const lastKeyboardHeight = useSharedValue(0)
18+
const wasKeyboardOpenRef = useRef(false)
1919
const textInputRef = useRef<TextInput>(null)
20-
const keyboardWasOpenRef = useRef(false)
2120
const isKeyboardShown = useKeyboardIsShown()
2221

2322
const messageContextMenuData = useConversationMessageContextMenuStoreContext(
@@ -33,51 +32,42 @@ export const ConversationKeyboardFiller = memo(function ConversationKeyboardFill
3332
return
3433
}
3534

36-
if (!!messageContextMenuData) {
37-
// If the keyboard is open, keep track of where it was because we need to open it again when the context menu is dismissed
35+
if (messageContextMenuData) {
36+
// Store keyboard state when emoji picker opens
3837
if (isKeyboardShown) {
3938
Keyboard.dismiss()
40-
lastKeyboardHeight.value = keyboardHeightAV.value
41-
keyboardWasOpenRef.current = true
39+
wasKeyboardOpenRef.current = true
4240
}
4341
}
4442
// Context menu is hidden
4543
else {
46-
// Reopen keyboard if it was open before context menu was shown
47-
if (keyboardWasOpenRef.current) {
44+
// Restore keyboard state when emoji picker closes
45+
if (wasKeyboardOpenRef.current) {
4846
textInputRef.current?.focus()
49-
keyboardWasOpenRef.current = false
47+
wasKeyboardOpenRef.current = false
5048
}
5149
}
52-
}, [
53-
isEmojiPickerOpen,
54-
messageContextMenuData,
55-
isKeyboardShown,
56-
keyboardHeightAV,
57-
lastKeyboardHeight,
58-
])
50+
}, [isEmojiPickerOpen, messageContextMenuData, isKeyboardShown])
5951

60-
// Reset the last height when context menu is dismissed
61-
// And make sure to wait until the keyboard is open to that the height animates back to what it was before
62-
useEffect(() => {
63-
if (!messageContextMenuData && isKeyboardShown) {
64-
lastKeyboardHeight.value = 0
52+
const fillerAnimatedStyle = useAnimatedStyle(() => {
53+
if (messageContextMenuData) {
54+
return {
55+
height: previousOpenKeyboardHeightAV.value - insets.bottom,
56+
}
6557
}
66-
}, [messageContextMenuData, isKeyboardShown, keyboardHeightAV, lastKeyboardHeight])
6758

68-
const fillerAnimatedStyle = useAnimatedStyle(() => {
59+
const baseHeight = typeof keyboardHeightAV.value === "number" ? keyboardHeightAV.value : 0
60+
const currentHeight = baseHeight * progressAV.value
61+
6962
return {
70-
height: Math.max(
71-
Math.max(lastKeyboardHeight.value, keyboardHeightAV.value) - insets.bottom,
72-
0,
73-
),
63+
height: Math.max(currentHeight - insets.bottom, 0),
7464
}
7565
})
7666

7767
return (
7868
<>
7969
<AnimatedVStack style={fillerAnimatedStyle} />
80-
{/* Need for focus on keyboard */}
70+
{/* Hidden TextInput for keyboard focus management */}
8171
<TextInput
8272
ref={textInputRef}
8373
style={{ height: 0, width: 0, opacity: 0, position: "absolute" }}

‎features/conversation/conversation-create/conversation-create-list-results.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -430,7 +430,7 @@ const Container = memo(function Container(props: { children: React.ReactNode })
430430
const { children } = props
431431

432432
const { theme } = useAppTheme()
433-
const { height: keyboardHeightAV } = useAnimatedKeyboard()
433+
const { keyboardHeightAV } = useAnimatedKeyboard()
434434

435435
const searchQuery = useConversationStoreContext((state) => state.searchTextValue)
436436

‎features/groups/group-details/group-details.screen-header.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ export function useGroupDetailsScreenHeader() {
3535
title: "Info",
3636
leftIcon: "chevron.left",
3737
onLeftPress: handleBackPress,
38+
backgroundColor: theme.colors.background.surface,
3839
// RightActionComponent: (
3940
// <HStack>
4041
// <HeaderAction icon="square.and.arrow.up" onPress={handleSharePress} />

‎features/groups/group-details/group-details.screen.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ export const GroupDetailsScreen = memo(function GroupDetailsScreen(
7575
<Pressable
7676
style={{
7777
alignItems: "center",
78+
backgroundColor: theme.colors.background.surface,
7879
}}
7980
onPress={() => alert("Exit pressed")}
8081
>

‎features/onboarding/screens/onboarding-contact-card.screen.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ export function OnboardingContactCardScreen() {
3636

3737
const { user: privyUser } = usePrivy()
3838

39-
const { progress: keyboardProgressAV } = useAnimatedKeyboard()
39+
const { progressAV: keyboardProgressAV } = useAnimatedKeyboard()
4040

4141
const handleRealContinue = useCallback(async () => {
4242
try {

‎hooks/use-animated-keyboard.ts

+22-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,26 @@
11
import { useReanimatedKeyboardAnimation } from "react-native-keyboard-controller"
2+
import { useDerivedValue, useSharedValue } from "react-native-reanimated"
23

34
export function useAnimatedKeyboard() {
4-
const { height, progress } = useReanimatedKeyboardAnimation()
5-
return { height, progress }
5+
const { height, progress: progressAV } = useReanimatedKeyboardAnimation()
6+
7+
const previousOpenKeyboardHeightAV = useSharedValue(0)
8+
9+
// Because when it's open it's like -346
10+
const keyboardHeightAV = useDerivedValue(() => {
11+
const currentHeight = height.value * -1
12+
13+
// Store previous height when keyboard is fully open
14+
if (progressAV.value === 1) {
15+
previousOpenKeyboardHeightAV.value = currentHeight
16+
}
17+
18+
return currentHeight
19+
})
20+
21+
return {
22+
keyboardHeightAV,
23+
progressAV,
24+
previousOpenKeyboardHeightAV,
25+
}
626
}

‎hooks/use-keyboard-handlers.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ type IKeyboardHandlersArgs = {
77
}
88

99
export function useKeyboardHandlers(args: IKeyboardHandlersArgs) {
10-
const { progress } = useAnimatedKeyboard()
10+
const { progressAV } = useAnimatedKeyboard()
1111

1212
useAnimatedReaction(
13-
() => progress.value,
13+
() => progressAV.value,
1414
(progress) => {
1515
if (progress === 1) {
1616
runOnJS(args.onKeyboardOpen)()

‎hooks/use-keyboard-is-shown.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@ import { useAnimatedKeyboard } from "@/hooks/use-animated-keyboard"
55
export function useKeyboardIsShown() {
66
const [isKeyboardShown, setIsKeyboardShown] = useState(false)
77

8-
const { progress } = useAnimatedKeyboard()
8+
const { progressAV } = useAnimatedKeyboard()
99

1010
useAnimatedReaction(
11-
() => progress.value,
11+
() => progressAV.value,
1212
(progress) => {
1313
if (progress === 1) {
1414
runOnJS(setIsKeyboardShown)(true)

0 commit comments

Comments
 (0)
Please sign in to comment.