1. A primeira coisa que vamos fazer é criar o nosso chatService.ts, e nele, iremos criar nossos métodos de pegar todos os chats, iniciar um chat e também de mandar alguma mensagem

    import api from "./api";
    import * as SecureStore from "expo-secure-store";
    
    interface startChat {
      product: string;
      seller: string;
      initialMessage: string;
    }
    
    interface sendMessage {
      _id: string;
      content: string;
      reciver: string;
      sender: string;
    }
    
    const chatService = {
      getChats: async () => {
        const token = await SecureStore.getItemAsync("onebitshop-token");
    
        const res = await api.get("/conversations", {
          headers: {
            Authorization: `Bearer ${token}`,
          },
        });
    
        return res;
      },
      startChat: async (params: startChat) => {
        const token = await SecureStore.getItemAsync("onebitshop-token");
    
        const res = await api.post("/conversations", params, {
          headers: {
            Authorization: `Bearer ${token}`,
          },
        });
    
        return res;
      },
      sendMessage: async (params: sendMessage) => {
        const token = await SecureStore.getItemAsync("onebitshop-token");
    
        const res = await api.post(`/conversations/${params._id}/send`, params, {
          headers: {
            Authorization: `Bearer ${token}`,
          },
        });
    
        return res;
      },
    };
    
    export default chatService;
    
  2. Com isso feito, nós vamos agora criar uma entidade chamada messages, e nela nós iremos colocar a tipagem das mensagens trocadas pelos usuários

    export interface Messages {
    	_id?: string;
      content: string;
      receiver: string;
      sender: string;
    }
    
  3. E agora vamos fazer a tipagem lá nas rotas

    Chat: {
    	_id?: string;
      product: Product;
      sellerName: string;
      sellerId: string;
    	buyerId: string;
      messages: Messages[];
    };
    
  4. Com essa tipagem, a gente vai conseguir navegar para a tela de chat individual tranquilamente quando iniciarmos uma conversa. Nós vamos agora fazer isso, então iremos para a nossa tela de “Product” para poder criar aqui o nosso handleChatSeller

    const handleChatSeller = async () => {
      const user = await AsyncStorage.getItem("user");
      const { _id } = JSON.parse(user || "");
    
      const initialMessage = `Olá, quero saber mais sobre o seu produto, ${route.params.seller.name}`;
    
      const params = {
        product: route.params._id,
        seller: route.params.seller._id,
        initialMessage,
      };
    
      const res = await chatService.startChat(params);
    
      if (res.status === 201) {
        navigation.navigate("Chat", {
          product: route.params,
          sellerName: route.params.seller.name,
          sellerId: route.params.seller._id,
    			buyerId: _id,
          messages: [
            {
              content: initialMessage,
              receiver: route.params.seller._id,
              sender: _id,
            },
          ],
        });
      }
    };
    
  5. Dessa forma, ao iniciar um chat, a gente será enviado para a sua tela individual e faremos o envio da primeira mensagem

  6. Agora, precisamos ir lá para o nosso Chat modificar as informações recebidas

    const Chat = ({ route }: Props) => {
      return (
        <Container>
          <ChatHeader
            sellerName={route.params.sellerName}
            product={route.params.product}
          />
    
          <MessagesList messages={route.params.messages} />
    
          <InputContainer>
            <Input
              placeholder="Digite sua mensagem"
              placeholderTextColor="white"
              multiline
            />
            <SendButton onPress={() => {}}>
              <SendIcon source={chatImage} />
            </SendButton>
          </InputContainer>
    
          <NavBar />
        </Container>
      );
    };
    
  7. Com isso feito, vamos em ChatHeader e lá iremos colocar as informações recebidas. Primeiro, criando a tipagem para as informações base

    interface Props {
      sellerId: string;
      sellerName: string;
      product: Product;
    }
    
    const ChatHeader = ({ sellerName, product, sellerId }: Props) => {
    
  8. Depois, modificando o nosso handle de navegação para o perfil do vendedor

    const handleSellerProfile = () => {
      navigation.navigate("SellerProfile", {
        sellerId,
      });
    };
    
  9. E por fim, modificar aqui as coisas dentro do nosso componente

    <Container>
      <Row>
        <BackArrow marginLeft={0} />
        <SellerName>{sellerName}</SellerName>
        <ModalButton onPress={handleToggleModal}>
          <ModalImage source={modalImg} />
        </ModalButton>
        <Modal animationType="fade" transparent={true} visible={modalVisible}>
          <ModalOverlay onPress={handleToggleModal} activeOpacity={1}>
            <ModalContainer>
              <ModalText onPress={handleSellerProfile}>Ver Perfil</ModalText>
              <ModalText>Deletar Conversa</ModalText>
              <ModalText onPress={handleFeedback}>Avaliar</ModalText>
              <ModalText onPress={handleDenounce}>Denunciar</ModalText>
            </ModalContainer>
          </ModalOverlay>
        </Modal>
      </Row>
      <AdCard product={product} />
    </Container>
    
  10. Por último, vamos para o nosso AdCard, e aqui dentro de AdCard vamos receber o product

    interface Props {
      product: Product;
    }
    
    const AdCard = ({ product }: Props) => {
      const navigation = useNavigation<PropsStack>();
    
      return (
        <Container
          onPress={() => {
            navigation.navigate("Product", {
              ...product,
            });
          }}
        >
    
  11. E já podemos testar o nosso envio. Agora, faremos que o botão do perfil de vendedor para falar com ele também funcione, nós vamos copiar esse handle para usar ele lá, vamos fazer algumas modificações no handle, mas será a mesma base

    if (!userInfo || loading) {
      return <Loader />;
    }
    
    const handleChatSeller = async () => {
      if (userInfo.products.length <= 0) {
        Alert.alert(
          "Esse vendedor não vende nada, então você não pode falar com ele!"
        );
        return;
      }
    
      const user = await AsyncStorage.getItem("user");
      const { _id } = JSON.parse(user || "");
    
      const initialMessage = `Olá, quero saber mais sobre o seu produto, ${userInfo.name}`;
    
      const params = {
        product: userInfo.products[0]._id,
        seller: userInfo._id,
        initialMessage,
      };
    
      const res = await chatService.startChat(params);
    
      if (res.status === 201) {
        navigation.navigate("Chat", {
          product: userInfo.products[0],
          sellerName: userInfo.name,
          sellerId: userInfo._id,
          messages: [
            {
              content: initialMessage,
              receiver: userInfo._id,
              sender: _id,
            },
          ],
        });
      }
    };
    
    return
    
  12. Agora já temos o início do chat funcionando corretamente