Skip to content

Commit 3a6e7c7

Browse files
authored
Merge pull request #65 from ansari-project/fix/keyboard-handling
Fix keyboard handling using KeyboardController
2 parents b27aa89 + d107731 commit 3a6e7c7

File tree

9 files changed

+39
-27
lines changed

9 files changed

+39
-27
lines changed

app.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"name": "Ansari Chat",
44
"owner": "ansari-project",
55
"slug": "ansari-chat",
6-
"version": "1.2.0",
6+
"version": "1.3.0",
77
"scheme": "ansarichat",
88
"userInterfaceStyle": "automatic",
99
"orientation": "portrait",

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "ansari-chat-app",
33
"main": "expo-router/entry",
4-
"version": "1.2.0",
4+
"version": "1.3.0",
55
"private": true,
66
"dependencies": {
77
"@babel/plugin-proposal-export-namespace-from": "^7.18.9",

src/app/(public)/forgot-password.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@ import { RootState } from '@/store'
55
import { createGeneralThemedStyles } from '@/utils'
66
import React, { useState } from 'react'
77
import { useTranslation } from 'react-i18next'
8-
import { NativeSyntheticEvent, Platform, Pressable, TextInput, View, Text, Keyboard } from 'react-native'
8+
import { NativeSyntheticEvent, Platform, Pressable, TextInput, View, Text } from 'react-native'
9+
import { KeyboardAwareScrollView, KeyboardController } from 'react-native-keyboard-controller'
910
import { useSelector } from 'react-redux'
1011
import { useRouter } from 'expo-router'
1112
import * as Yup from 'yup'
1213
import StyledText from '@/components/StyledText'
13-
import { KeyboardAwareScrollView } from 'react-native-keyboard-controller'
1414

1515
// TypeScript interface for the initial state
1616
interface EmailState {
@@ -40,7 +40,7 @@ const ForgetPasswordScreen: React.FC = () => {
4040
try {
4141
await validateEmail(emailState.email)
4242
if (emailState.email.trim().length !== 0 && Object.keys(errors).length === 0) {
43-
Keyboard.dismiss()
43+
KeyboardController.dismiss()
4444
await UserService.requestPasswordReset(emailState.email)
4545
setEmailState({ ...emailState, submitted: true })
4646
}

src/app/(public)/login.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@ import { useLoginSchema } from '@/validation'
77
import { Formik, FormikHelpers } from 'formik'
88
import React, { useState } from 'react'
99
import { useTranslation } from 'react-i18next'
10-
import { Keyboard, NativeSyntheticEvent, Platform, Pressable, StyleSheet, Text, TextInput, View } from 'react-native'
10+
import { NativeSyntheticEvent, Platform, Pressable, StyleSheet, Text, TextInput, View } from 'react-native'
1111
import { useDispatch, useSelector } from 'react-redux'
1212
import { useRouter, useLocalSearchParams } from 'expo-router'
1313
import * as Yup from 'yup'
1414
import StyledText from '@/components/StyledText'
15-
import { KeyboardAwareScrollView } from 'react-native-keyboard-controller'
15+
import { KeyboardAwareScrollView, KeyboardController } from 'react-native-keyboard-controller'
1616

1717
const LoginScreen: React.FC = () => {
1818
const router = useRouter()
@@ -38,7 +38,7 @@ const LoginScreen: React.FC = () => {
3838
})
3939

4040
const handleSubmit = (values: LoginRequest, formikHelpers: FormikHelpers<LoginRequest>) => {
41-
Keyboard.dismiss()
41+
KeyboardController.dismiss()
4242
formikHelpers.setSubmitting(true)
4343
setErrorMessage(null)
4444
dispatch(login(values))

src/app/(public)/register.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,13 @@ import { useRegisterSchema } from '@/validation'
77
import { Formik, FormikHelpers } from 'formik'
88
import React, { useState } from 'react'
99
import { useTranslation } from 'react-i18next'
10-
import { Keyboard, NativeSyntheticEvent, Platform, Pressable, Text, TextInput, View } from 'react-native'
10+
import { NativeSyntheticEvent, Platform, Pressable, Text, TextInput, View } from 'react-native'
1111
import Checkbox from 'expo-checkbox'
1212
import { useDispatch, useSelector } from 'react-redux'
1313
import { useRouter } from 'expo-router'
1414
import * as Yup from 'yup'
1515
import StyledText from '@/components/StyledText'
16-
import { KeyboardAwareScrollView } from 'react-native-keyboard-controller'
16+
import { KeyboardAwareScrollView, KeyboardController } from 'react-native-keyboard-controller'
1717

1818
interface RegisterFormValues {
1919
email: string
@@ -47,7 +47,7 @@ const RegisterScreen: React.FC = () => {
4747
}
4848

4949
const handleSubmit = (values: RegisterFormValues, formikHelpers: FormikHelpers<RegisterFormValues>) => {
50-
Keyboard.dismiss()
50+
KeyboardController.dismiss()
5151
formikHelpers.setSubmitting(true)
5252
setErrorMessage(null)
5353
const registerRequest: RegisterRequest = {

src/app/(public)/reset-password.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@ import { createGeneralThemedStyles } from '@/utils'
77
import { useRegisterSchema } from '@/validation'
88
import React, { useState } from 'react'
99
import { useTranslation } from 'react-i18next'
10-
import { Keyboard, Platform, Pressable, StyleSheet, Text, TextInput, View } from 'react-native'
10+
import { Platform, Pressable, StyleSheet, Text, TextInput, View } from 'react-native'
1111
import { useSelector } from 'react-redux'
1212
import { useRouter } from 'expo-router'
1313
import * as Yup from 'yup'
14-
import { KeyboardAwareScrollView } from 'react-native-keyboard-controller'
14+
import { KeyboardAwareScrollView, KeyboardController } from 'react-native-keyboard-controller'
1515
import StyledText from '@/components/StyledText'
1616

1717
// TypeScript interface for the component's state
@@ -46,7 +46,7 @@ const ResetPasswordScreen: React.FC = () => {
4646

4747
// Submits the form after validation
4848
const handleSubmit = async () => {
49-
Keyboard.dismiss()
49+
KeyboardController.dismiss()
5050
setIsSubmitting(true)
5151
try {
5252
await validatePassword()

src/components/KeyboardHandler.tsx

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,36 +2,48 @@ import React from 'react'
22
import { useKeyboardHandler } from 'react-native-keyboard-controller'
33
import Animated, { useAnimatedStyle, useSharedValue } from 'react-native-reanimated'
44

5-
const PADDING_BOTTOM = 0
5+
const LOG_KEYBOARD_EVENTS = false
66

77
const useGradualAnimation = () => {
8-
const height = useSharedValue(PADDING_BOTTOM)
8+
const height = useSharedValue(0)
9+
const progress = useSharedValue(0)
910

1011
useKeyboardHandler(
1112
{
13+
onStart: (event) => {
14+
'worklet'
15+
if (LOG_KEYBOARD_EVENTS) console.log('[KeyboardHandler] onStart', event)
16+
},
1217
onMove: (event) => {
1318
'worklet'
14-
height.value = Math.max(event.height, PADDING_BOTTOM)
19+
if (LOG_KEYBOARD_EVENTS) console.log('[KeyboardHandler] onMove', event)
20+
height.value = event.height
21+
progress.value = event.progress
22+
},
23+
onEnd: (event) => {
24+
'worklet'
25+
if (LOG_KEYBOARD_EVENTS) console.log('[KeyboardHandler] onEnd', event)
26+
progress.value = event.progress
27+
height.value = event.height
1528
},
1629
},
1730
[],
1831
)
1932

20-
return { height }
33+
return { height, progress }
2134
}
2235

2336
const KeyboardHandler: React.FC = () => {
24-
const { height } = useGradualAnimation()
37+
const { height, progress } = useGradualAnimation()
2538

2639
const animatedStyle = useAnimatedStyle(() => {
2740
return {
28-
height: Math.abs(height.value),
29-
marginBottom: height.value > 0 ? 0 : PADDING_BOTTOM,
30-
width: 'auto',
41+
// Use height as-is, but fallback to 0 if progress indicates keyboard is hidden
42+
height: progress.value === 0 ? 0 : height.value,
3143
}
3244
})
3345

34-
return <Animated.View style={animatedStyle}></Animated.View>
46+
return <Animated.View style={animatedStyle} />
3547
}
3648

3749
export default KeyboardHandler

src/components/chat/ChatInput.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@ import { AppDispatch, RootState, tootleInputFullMode } from '@/store'
44
import React, { useRef, useState } from 'react'
55
import { useTranslation } from 'react-i18next'
66
import {
7-
Keyboard,
87
KeyboardEvent,
98
NativeSyntheticEvent,
109
Pressable,
1110
TextInput,
1211
TextInputContentSizeChangeEventData,
1312
View,
1413
} from 'react-native'
14+
import { KeyboardController } from 'react-native-keyboard-controller'
1515
import { useDispatch, useSelector } from 'react-redux'
1616

1717
interface ChatInputProps {
@@ -57,7 +57,7 @@ const ChatInput: React.FC<ChatInputProps> = ({ value, onSendPress, onInputChange
5757
}
5858

5959
const submit = () => {
60-
Keyboard.dismiss()
60+
KeyboardController.dismiss()
6161
dispatch(tootleInputFullMode(false))
6262
onSendPress()
6363
}

0 commit comments

Comments
 (0)