Osas nathaniel
Osas nathaniel

Reputation: 5

Screen flickers when on navigated page

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

Answers (0)

Related Questions