import {
Dimensions,
Keyboard,
Platform,
Pressable,
StyleSheet,
Text,
TextInput,
View,
} from "react-native";
import React, {useEffect, useRef, useState} from "react";
import {useNavigation, useRoute} from "@react-navigation/native";
import {Color, FontFamily} from "../../Styles/Colors";
import {useSafeAreaInsets} from "react-native-safe-area-context";
import BackButton from "../../Assets/SVGs/BackButton";
import {
responsiveFontSize,
responsiveHeight,
} from "react-native-responsive-dimensions";
import {useFoldableDevice} from "../../Constant/foldPhone/FoldableDeviceProvider";
import {GetUserConversation} from "../../Services/chats";
import FastImage from "@d11/react-native-fast-image";
import Animated, {
useAnimatedStyle,
useSharedValue,
} from "react-native-reanimated";
import {
useKeyboardHandler,
useKeyboardAnimation,
} from "react-native-keyboard-controller";
import SendBtn from "../../Assets/SVGs/SendBtn";
const useGradualAnimation = () => {
const height = useSharedValue(0);
useKeyboardHandler(
{
onMove: e => {
"worklet";
height.set(e.height);
},
// onEnd: e => {
// "worklet";
// height.set(e.height);
// },
},
[],
);
return {height};
};
const {width, height} = Dimensions.get("screen");
const ParticularChatsScreen = () => {
const routes = useRoute();
const {conversationId, othersUserId} = routes.params;
const insets = useSafeAreaInsets();
const navigation = useNavigation();
const {isUnfolded} = useFoldableDevice();
const flatListRef = useRef(null);
// const {height: keyboardHeight} = useKeyboardAnimation();
// const keyboardHeight = useSharedValue(0);
const [data, setData] = useState([
{
_id: "685a43b8335b4f21bb7a716d",
conversationId: "conv_RidBd7fH2QxR",
senderId: "user_123",
receiverId: "U15281858739",
content: "Hello",
messageType: "text",
isRead: false,
isDelivered: false,
messageId: "msg_rXiyMEgtVAPT",
timestamp: "2025-06-24T06:20:40.744Z",
createdAt: "2025-06-24T06:20:40.745Z",
updatedAt: "2025-06-24T06:20:40.745Z",
},
{
_id: "685a43b8335b4f21bb7a716d",
conversationId: "conv_RidBd7fH2QxR",
senderId: "user_123",
receiverId: "U15281858739",
content: "Hello",
messageType: "text",
isRead: false,
isDelivered: false,
messageId: "msg_rXiyMEgtVAPT",
timestamp: "2025-06-24T06:20:40.744Z",
createdAt: "2025-06-24T06:20:40.745Z",
updatedAt: "2025-06-24T06:20:40.745Z",
},
{
_id: "685a43b8335b4f21bb7a716d",
conversationId: "conv_RidBd7fH2QxR",
senderId: "user_123",
receiverId: "U15281858739",
content: "Hello",
messageType: "text",
isRead: false,
isDelivered: false,
messageId: "msg_rXiyMEgtVAPT",
timestamp: "2025-06-24T06:20:40.744Z",
createdAt: "2025-06-24T06:20:40.745Z",
updatedAt: "2025-06-24T06:20:40.745Z",
},
{
_id: "685a43b8335b4f21bb7a716d",
conversationId: "conv_RidBd7fH2QxR",
senderId: "user_123",
receiverId: "U15281858739",
content: "Hello",
messageType: "text",
isRead: false,
isDelivered: false,
messageId: "msg_rXiyMEgtVAPT",
timestamp: "2025-06-24T06:20:40.744Z",
createdAt: "2025-06-24T06:20:40.745Z",
updatedAt: "2025-06-24T06:20:40.745Z",
},
{
_id: "685a43b8335b4f21bb7a716d",
conversationId: "conv_RidBd7fH2QxR",
senderId: "user_123",
receiverId: "U15281858739",
content: "Hello",
messageType: "text",
isRead: false,
isDelivered: false,
messageId: "msg_rXiyMEgtVAPT",
timestamp: "2025-06-24T06:20:40.744Z",
createdAt: "2025-06-24T06:20:40.745Z",
updatedAt: "2025-06-24T06:20:40.745Z",
},
{
_id: "685a43b8335b4f21bb7a716d",
conversationId: "conv_RidBd7fH2QxR",
senderId: "user_123",
receiverId: "U15281858739",
content: "Hello",
messageType: "text",
isRead: false,
isDelivered: false,
messageId: "msg_rXiyMEgtVAPT",
timestamp: "2025-06-24T06:20:40.744Z",
createdAt: "2025-06-24T06:20:40.745Z",
updatedAt: "2025-06-24T06:20:40.745Z",
},
{
_id: "685a43b8335b4f21bb7a716d",
conversationId: "conv_RidBd7fH2QxR",
senderId: "user_123",
receiverId: "U15281858739",
content: "Hello",
messageType: "text",
isRead: false,
isDelivered: false,
messageId: "msg_rXiyMEgtVAPT",
timestamp: "2025-06-24T06:20:40.744Z",
createdAt: "2025-06-24T06:20:40.745Z",
updatedAt: "2025-06-24T06:20:40.745Z",
},
{
_id: "685a43b8335b4f21bb7a716d",
conversationId: "conv_RidBd7fH2QxR",
senderId: "user_123",
receiverId: "U15281858739",
content: "Hello",
messageType: "text",
isRead: false,
isDelivered: false,
messageId: "msg_rXiyMEgtVAPT",
timestamp: "2025-06-24T06:20:40.744Z",
createdAt: "2025-06-24T06:20:40.745Z",
updatedAt: "2025-06-24T06:20:40.745Z",
},
{
_id: "685a43b8335b4f21bb7a716d",
conversationId: "conv_RidBd7fH2QxR",
senderId: "user_123",
receiverId: "U15281858739",
content: "Hello",
messageType: "text",
isRead: false,
isDelivered: false,
messageId: "msg_rXiyMEgtVAPT",
timestamp: "2025-06-24T06:20:40.744Z",
createdAt: "2025-06-24T06:20:40.745Z",
updatedAt: "2025-06-24T06:20:40.745Z",
},
{
_id: "685a43b8335b4f21bb7a716d",
conversationId: "conv_RidBd7fH2QxR",
senderId: "user_123",
receiverId: "U15281858739",
content: "Hello",
messageType: "text",
isRead: false,
isDelivered: false,
messageId: "msg_rXiyMEgtVAPT",
timestamp: "2025-06-24T06:20:40.744Z",
createdAt: "2025-06-24T06:20:40.745Z",
updatedAt: "2025-06-24T06:20:40.745Z",
},
{
_id: "685a43b8335b4f21bb7a716d",
conversationId: "conv_RidBd7fH2QxR",
senderId: "user_123",
receiverId: "U15281858739",
content: "Hello",
messageType: "text",
isRead: false,
isDelivered: false,
messageId: "msg_rXiyMEgtVAPT",
timestamp: "2025-06-24T06:20:40.744Z",
createdAt: "2025-06-24T06:20:40.745Z",
updatedAt: "2025-06-24T06:20:40.745Z",
},
{
_id: "685a43b8335b4f21bb7a716d",
conversationId: "conv_RidBd7fH2QxR",
senderId: "user_123",
receiverId: "U15281858739",
content: "Hello",
messageType: "text",
isRead: false,
isDelivered: false,
messageId: "msg_rXiyMEgtVAPT",
timestamp: "2025-06-24T06:20:40.744Z",
createdAt: "2025-06-24T06:20:40.745Z",
updatedAt: "2025-06-24T06:20:40.745Z",
},
{
_id: "685a43b8335b4f21bb7a716d",
conversationId: "conv_RidBd7fH2QxR",
senderId: "user_123",
receiverId: "U15281858739",
content: "Hello",
messageType: "text",
isRead: false,
isDelivered: false,
messageId: "msg_rXiyMEgtVAPT",
timestamp: "2025-06-24T06:20:40.744Z",
createdAt: "2025-06-24T06:20:40.745Z",
updatedAt: "2025-06-24T06:20:40.745Z",
},
{
_id: "685a43b8335b4f21bb7a716d",
conversationId: "conv_RidBd7fH2QxR",
senderId: "user_123",
receiverId: "U15281858739",
content: "Hello",
messageType: "text",
isRead: false,
isDelivered: false,
messageId: "msg_rXiyMEgtVAPT",
timestamp: "2025-06-24T06:20:40.744Z",
createdAt: "2025-06-24T06:20:40.745Z",
updatedAt: "2025-06-24T06:20:40.745Z",
},
{
_id: "685a43b8335b4f21bb7a716d",
conversationId: "conv_RidBd7fH2QxR",
senderId: "user_123",
receiverId: "U15281858739",
content: "Hello",
messageType: "text",
isRead: false,
isDelivered: false,
messageId: "msg_rXiyMEgtVAPT",
timestamp: "2025-06-24T06:20:40.744Z",
createdAt: "2025-06-24T06:20:40.745Z",
updatedAt: "2025-06-24T06:20:40.745Z",
},
{
_id: "685a43b8335b4f21bb7a716d",
conversationId: "conv_RidBd7fH2QxR",
senderId: "user_123",
receiverId: "U15281858739",
content: "Hello",
messageType: "text",
isRead: false,
isDelivered: false,
messageId: "msg_rXiyMEgtVAPT",
timestamp: "2025-06-24T06:20:40.744Z",
createdAt: "2025-06-24T06:20:40.745Z",
updatedAt: "2025-06-24T06:20:40.745Z",
},
]);
const getChatsData = async () => {
try {
const {result} = await GetUserConversation(conversationId, 1, 20);
console.log(result);
// setData(`${JSON.stringify(result?.data?.messages[0]?.content)}`);
} catch (error) {
console.error(error.message);
// setData(`${error.message}`);
}
};
useEffect(() => {
// const keyboardDidShowListener = Keyboard.addListener(
// "keyboardDidShow",
// e => {
// setHeightValue(e.endCoordinates.height);
// keyboardHeight.set(e.endCoordinates.height);
// },
// );
// const keyboardDidHideListener = Keyboard.addListener(
// "keyboardDidHide",
// () => {
// setHeightValue(0);
// keyboardHeight.set(0);
// },
// );
getChatsData();
flatListRef.current.scrollToEnd({animated: false});
// return () => {
// keyboardDidShowListener.remove();
// keyboardDidHideListener.remove();
// };
}, []);
const handleBackButton = () => {
navigation.goBack();
};
const onContentSizeChange = () => {
flatListRef.current.scrollToEnd({animated: false});
};
const ITEM_HEIGHT = responsiveHeight(10);
const {height} = useGradualAnimation();
const fakeViewStyles = useAnimatedStyle(() => {
return {
height: Math.abs(height),
};
}, []);
return (
<>
<View style={[styles.topBar, {paddingTop: insets.top}]}>
<Pressable
onPress={handleBackButton}
style={styles.backButtonContainer}>
<BackButton
color="black"
width={
Platform.OS === "ios"
? isUnfolded
? responsiveFontSize(2.5)
: responsiveFontSize(4)
: isUnfolded
? responsiveFontSize(2)
: responsiveFontSize(4)
}
height={
Platform.OS === "ios"
? isUnfolded
? responsiveFontSize(3)
: responsiveFontSize(5)
: isUnfolded
? responsiveFontSize(2)
: responsiveFontSize(5)
}
/>
</Pressable>
<Pressable
onPress={() => {
navigation.navigate("UserProfileScreen", {id: othersUserId});
}}
style={styles.profile}>
<FastImage
source={{
uri: `https://rentlog-test.s3.ap-south-1.amazonaws.com/Profile_Pictures/${othersUserId}_profile_pic.jpeg`,
priority: FastImage.priority.normal,
}}
resizeMode={FastImage.resizeMode.cover}
style={styles.topImage}
/>
<Text style={styles.name}>Shivam</Text>
</Pressable>
</View>
<View style={{flex: 1, position: "relative"}}>
{/* chats */}
<Animated.FlatList
getItemLayout={(data, index) => ({
length: ITEM_HEIGHT,
offset: ITEM_HEIGHT * index,
index,
})}
CellRendererComponent={({children}) => children}
removeClippedSubviews={false}
ref={flatListRef}
bounces={false}
horizontal={false}
contentContainerStyle={{
// minHeight: height * 0.6,
justifyContent: "flex-end",
alignItems: "flex-end",
paddingBottom:
insets.bottom + responsiveFontSize(Platform.OS === "ios" ? 0 : 4),
width: width,
paddingHorizontal: responsiveFontSize(2),
}}
onContentSizeChange={onContentSizeChange}
data={data}
renderItem={({item, index}) => {
return (
<View key={item._id}>
<Text>{item.content}</Text>
</View>
);
}}
/>
{/* input box */}
<View
style={{
marginTop: responsiveFontSize(2),
width: width * 0.92,
height: responsiveHeight(7),
justifyContent: "center",
alignItems: "center",
borderRadius: width,
overflow: "hidden",
padding: width * 0.003,
marginHorizontal: "auto",
marginBottom:
insets.bottom + responsiveFontSize(Platform.OS === "ios" ? 0 : 4),
}}>
<View
style={{
width: "100%",
height: "100%",
borderRadius: width,
borderWidth: width * 0.001,
borderColor: "rgba(0, 0, 0, 0.46)",
backgroundColor: Color.light_bg,
elevation: 2,
flexDirection: "row",
overflow: "hidden",
padding: width * 0.01,
shadowColor: "#000",
shadowOffset: {width: 0, height: 2},
shadowOpacity: 0.2,
shadowRadius: 1.41,
}}>
<TextInput
placeholder="Message"
style={{
flex: 2,
borderRadius: width,
paddingHorizontal: responsiveFontSize(2),
color: "rgba(0, 0, 0, 0.81)",
height: "100%",
fontFamily: FontFamily.GilroyBold,
fontSize: responsiveFontSize(1.7),
}}
placeholderTextColor={"rgba(0, 0, 0, 0.49)"}
/>
<Pressable
style={{
backgroundColor: Color.L1_red,
justifyContent: "center",
alignItems: "center",
width: "13%",
borderRadius: width,
marginRight: width * 0.01,
}}>
<SendBtn
height={responsiveFontSize(3)}
width={responsiveFontSize(3)}
/>
</Pressable>
</View>
</View>
<Animated.View style={fakeViewStyles} />
</View>
</>
);
};
export default ParticularChatsScreen;
const styles = StyleSheet.create({
topBar: {
flexDirection: "row",
justifyContent: "flex-start",
height: height * 0.1,
alignItems: "center",
paddingVertical: responsiveFontSize(1),
gap: responsiveFontSize(1),
width: width,
borderBottomWidth: width * 0.001,
borderColor: "rgba(0,0,0,0.3)",
},
backButtonContainer: {
justifyContent: "center",
alignItems: "center",
width: width * 0.15,
height: "100%",
},
profile: {
flexDirection: "row",
justifyContent: "center",
alignItems: "center",
gap: responsiveFontSize(2),
marginBottom: width * 0.01,
},
topImage: {
width: responsiveFontSize(4.5),
borderRadius: width,
height: responsiveFontSize(4.5),
},
name: {
fontFamily: FontFamily.GilroyBold,
fontSize: responsiveFontSize(2),
color: Color.black,
},
});
Describe the bug
On iOS devices, the keyboard height is not updating correctly when using react-native-keyboard-controller with useKeyboardHandler. The same implementation works perfectly on Android, but fails to respond consistently or at all on iOS when trying to animate a view based on keyboard height.
Code snippet
Repo for reproducing
sorry i cant provide the repo yet .
To Reproduce
Steps to reproduce the behavior:
Expected behavior
The Animated.View should adjust its height according to the keyboardHeight on both Android and iOS, based on useSharedValue updates from the keyboard events.
Screenshots
issue.mov
Smartphone (please complete the following information):