Reputation: 5
I am having an issue with my component i created a message card which when clicked goes to a chat page that displays messages using react-native-gifted-chat which works fine but when i wrap the message card which goes to the chat page with swipeable to make it swipeable using react native gesture handler when i now click on it to navigate to the chat page thechat page flickers continiously and doesn't stop till maybe i click on the input to type a text message to send how do i fiex this
code index.tsx
import {
View,
Text,
Image,
FlatList,
TouchableOpacity,
} from "react-native";
import React, { useState } from "react";
import {
SafeAreaView,
useSafeAreaInsets,
} from "react-native-safe-area-context";
import { fontStyles } from "~/lib/constants";
import { Feather } from "@expo/vector-icons";
import { Mail, Search } from "lucide-react-native";
import { Input } from "~/components/ui/input";
import { cn } from "~/lib/utils";
import MessageCard from "~/components/professional/MessageCard";
import { Button } from "~/components/ui/button";
import all from "~/utils/data/messages/all.json";
import { Link, useRouter } from "expo-router";
import SwipeableComponent from "~/components/ui/SwipeableComponent";
const Messages = () => {
const insets = useSafeAreaInsets();
const [isFocused, setIsFocused] = useState(false);
const router = useRouter();
const goToChat = (id: number) => {
router.push(`/professional/messages/${id}`);
};
return (
<SafeAreaView className="flex-1">
<View className="px-6 pt-6">
<View className="flex-row justify-between items-center pb-3">
<Text style={{ ...fontStyles.h2 }}>Messages</Text>
<View className="flex-row items-center gap-4">
<Mail size={24} color="black" />
<Feather name="edit" size={24} color="black" />
</View>
</View>
<View className="py-4">
<View
className={cn(
"flex flex-row px-3 h-12 rounded-full bg-gray-200 items-center border",
isFocused ? "border-black" : "border-gray-200"
)}
>
<Search size={24} color={isFocused ? "black" : "#6b7280"} />
<Input
placeholder="Search"
className="flex-1 border-0 bg-gray-200 py-2 -mb-1.5 rounded-full"
style={{ height: "auto", ...fontStyles.body }}
onFocus={() => setIsFocused(true)}
onBlur={() => setIsFocused(false)}
/>
</View>
</View>
</View>
<View>
<View className="py-2 items-center">
<FlatList
data={all}
contentContainerStyle={{ paddingBottom: insets.bottom * 8 }}
keyExtractor={(item) => item.id.toString()}
renderItem={({ item, index }) => (
<SwipeableComponent>
<TouchableOpacity onPress={() => goToChat(index)}>
<MessageCard data={item} />
</TouchableOpacity>
</SwipeableComponent>
)}
ListEmptyComponent={
<View className="p-10 justify-center items-center">
<View className="pt-3">
<Image
className="w-44 h-56"
source={require("../../../../../assets/images/no-messages.png")}
/>
</View>
<Text style={{ ...fontStyles.body }}>No messages yet..</Text>
<Button
variant="teal"
className="flex-row gap-2 items-center mt-5"
>
<Text className="text-white" style={{ ...fontStyles.p }}>
Start Conversation
</Text>
<Feather name="plus" size={20} color="white" />
</Button>
</View>
}
/>
</View>
</View>
</SafeAreaView>
);
};
export default Messages;
swipeablecomponent.tsx
import { Ionicons } from "@expo/vector-icons";
import React from "react";
import { TouchableOpacity } from "react-native";
import { Text } from "react-native";
import { GestureHandlerRootView } from "react-native-gesture-handler";
import ReanimatedSwipeable from "react-native-gesture-handler/ReanimatedSwipeable";
import Reanimated, {
SharedValue,
useAnimatedStyle,
} from "react-native-reanimated";
import { fontStyles } from "~/lib/constants";
type Props = {
children: React.ReactNode;
};
function RightAction(prog: SharedValue<number>, drag: SharedValue<number>) {
const styleAnimation = useAnimatedStyle(() => {
return {
transform: [{ translateX: drag.value + 177 }],
};
});
return (
<Reanimated.View
className="flex-row justify-between items-center w-1/2"
style={styleAnimation}
>
<TouchableOpacity
className="h-full flex-1 gap-1 justify-center items-center p-4 bg-gray-400"
onPress={() => console.log("More action")}
>
<Ionicons name="ellipsis-horizontal-sharp" size={24} color="#FFFFFF" />
<Text className="text-white" style={{ ...fontStyles.p }}>
More
</Text>
</TouchableOpacity>
<TouchableOpacity
className="h-full flex-1 gap-1 justify-center items-center p-4 bg-red-500"
onPress={() => console.log("Delete action")}
>
<Ionicons name="trash-outline" size={24} color="#FFFFFF" />
<Text className="text-white" style={{ ...fontStyles.p }}>
Delete
</Text>
</TouchableOpacity>
</Reanimated.View>
);
}
export default function Example({ children }: Props) {
return (
<GestureHandlerRootView>
<ReanimatedSwipeable
containerStyle={{ alignItems: "center" }}
friction={2}
overshootFriction={10}
enableTrackpadTwoFingerGesture
rightThreshold={40}
renderRightActions={RightAction}
>
{children}
</ReanimatedSwipeable>
</GestureHandlerRootView>
);
}
[id].tsx
import { View, Text, ImageBackground } from "react-native";
import React, { useCallback, useEffect, useRef, useState } from "react";
import {
Bubble,
GiftedChat,
IMessage,
InputToolbar,
Send,
} from "react-native-gifted-chat";
import messagesData from "~/utils/data/messages/messages.json";
import {
SafeAreaView,
useSafeAreaInsets,
} from "react-native-safe-area-context";
import { fontStyles } from "~/lib/constants";
import { Feather, Ionicons } from "@expo/vector-icons";
import { SwipeableMethods } from "react-native-gesture-handler/lib/typescript/components/ReanimatedSwipeable";
import ChatMessageBox from "~/components/professional/ChatMessageBox";
import ReplyMessageBar from "~/components/professional/ReplyMessageBar";
import Animated from "react-native-reanimated";
const MessageId = () => {
const [messages, setMessages] = useState<IMessage[]>([]);
const [replyMessage, setReplyMessage] = useState<IMessage | null>();
const [text, setText] = useState("");
const insets = useSafeAreaInsets();
const swipeableRowRef = useRef<SwipeableMethods | null>(null)
useEffect(() => {
setMessages([
...messagesData.map((message) => {
return {
_id: message.id,
text: message.msg,
createdAt: new Date(message.date),
user: {
_id: message.from,
name: message.from ? "You" : "Bob",
},
};
}),
{
_id: 0,
text: "This is a system message",
createdAt: new Date(),
system: true,
user: {
_id: 0,
name: "Hustle Link",
},
},
]);
}, []);
const onSend = useCallback((messages = []) => {
setMessages((previousMessages) =>
GiftedChat.append(previousMessages, messages)
);
}, []);
const updateRowRef = useCallback(
(ref: any) => {
if (
ref &&
replyMessage &&
ref.props.children.props.currentMessage?._id === replyMessage._id
) {
swipeableRowRef.current = ref;
}
},
[replyMessage]
);
useEffect(() => {
if (replyMessage && swipeableRowRef.current) {
swipeableRowRef.current.close();
swipeableRowRef.current = null;
}
}, [replyMessage]);
return (
<View className="flex-1 bg-gray-50" style={{ paddingBottom: insets.bottom }}>
<GiftedChat
messages={messages}
onSend={(messages: any) => onSend(messages)}
user={{
_id: 1,
}}
onInputTextChanged={setText}
renderAvatar={null}
renderBubble={(props) => {
return (
<Bubble
{...props}
textStyle={{
right: {
...fontStyles.p,
},
left: {
...fontStyles.p,
},
}}
wrapperStyle={{
right: {
backgroundColor: "#0d9488",
},
}}
/>
);
}}
renderSend={(props) => {
return (
<View style={{}}>
{text.length > 0 && (
<Send
{...props}
containerStyle={{
justifyContent: "center",
marginRight: 15,
marginLeft: 10,
}}
>
<Feather name="send" size={28} color="#0d9488" />
</Send>
)}
{text.length === 0 && (
<View className="flex-row gap-2 justify-center items-center my-3 px-2">
<Ionicons name="camera-outline" size={28} color="#0d9488" />
<Ionicons name="mic-outline" size={28} color="#0d9488" />
</View>
)}
</View>
);
}}
textInputProps={{
...fontStyles.body,
backgroundColor: 'white',
marginBottom: 8,
borderRadius: 20,
paddingHorizontal: 10,
paddingTop: 7,
borderWidth: 1,
borderColor: '#d1d5db'
}}
renderInputToolbar={(props) => {
return (
<InputToolbar
containerStyle={{
backgroundColor: '#f9fafb',
}}
{...props}
renderActions={(props) => (
<View className="my-3 ml-1">
<Ionicons name="add" size={28} color="#0d9488" />
</View>
)}
/>
);
}}
renderMessage={(props) => (
<ChatMessageBox {...props} updateRowRef={updateRowRef} setReplyOnSwipeOpen={setReplyMessage} />
)}
renderChatFooter={() => (
<ReplyMessageBar clearReply={() => setReplyMessage(null)} message={replyMessage} />
)}
/>
</View>
);
};
export default MessageId;
Upvotes: 0
Views: 78