Criando um aplicativo de bate-papo nativo do React – Parte 2: Histórico de mensagens | PubNub

Krissanawat Kaewsanmuang Blocked Desbloquear Seguir Seguindo 1º de julho

Em nossa parte anterior de nossa série de tutoriais em andamento sobre a criação de um aplicativo de bate-papo React Native, configuramos mensagens básicas e nossa interface de usuário de bate-papo. Nesta parte, vamos adicionar o histórico de mensagens, que permitirá armazenar e buscar mensagens históricas. Quando um usuário reinicia o aplicativo de bate-papo, ele poderá ver as mensagens enviadas anteriormente.

Note que você precisará concluir a Parte Um antes de passar por este tutorial, já que também abordamos a configuração nessa parte.

Nesta parte, vamos cobrir duas áreas principais do histórico de mensagens:

  • Buscando o histórico de mensagens
  • Exibindo visualmente qual usuário enviou uma mensagem

Buscando Histórico de Mensagens

Atualmente, nosso aplicativo de bate-papo tem uma interface de bate-papo global. Mensagens de bate-papo aparecem no log global para todos os usuários conectados quando alguém envia uma mensagem. Mas quando fechamos o aplicativo, todas as mensagens desaparecem. Quando reabrirmos o aplicativo, o log de mensagens estará vazio. Isso ocorre porque o histórico de mensagens não está armazenado no dispositivo.

Isso é o que vamos resolver nesta parte – armazenar e buscar o histórico de mensagens. Usaremos o PubNub Storage & Playback (às vezes chamado de History ou History API ) para fazer isso.

Navegue até o seu painel do PubNub Admin e ative o recurso.

Quando o armazenamento e a reprodução estiverem ativados, precisaremos buscar a mensagem armazenada quando o aplicativo for atualizado ou retomado. Para isso, precisamos retornar ao arquivo App.js e buscar as mensagens armazenadas quando o aplicativo for iniciado, usando a função de retorno de chamada do ComponentDidmount () React.

O trecho de código a seguir busca o histórico de mensagens de um canal PubNub:

 this.pubnub.history( 
{ channel: "MainChat", reverse: true, count: 15 },
(status, res) => {
console.log(newmessage);
}
);

Esta função funciona simplesmente buscando 15 mensagens de um canal chamado MainChat. As mensagens buscadas podem ser vistas no console do desenvolvedor do JavaScript.

Você pode ver que funciona como um encanto. Mas quando observamos a estrutura padrão da mensagem do Gifted Chat, ela não corresponde ao nosso design. Portanto, precisamos reconstruir a mensagem antes de anexarmos as novas mensagens ao estado Reagir. Você pode usar o código do snippet a seguir para construir uma nova matriz de mensagens que corresponderá à estrutura da mensagem do Bate-papo Gifted:

 componentDidMount() { 
this.pubnub.history(
{ channel: "MainChat", reverse: true, count: 15 },
(status, res) => {
let newmessage = [];
res.messages.forEach(function(element, index) {
newmessage[index] = element.entry[0];
});
console.log(newmessage);
}
);
}

Você pode ver que as estruturas de mensagens estão alinhadas na captura de tela a seguir.

Agora, precisamos anexar a nova matriz de mensagens ao Bate-papo Gifted. Para isso, você pode usar o seguinte trecho de código:

 componentDidMount() { 
this.pubnub.history(
{ channel: "MainChat", reverse: true, count: 15 },
(status, res) => {
let newmessage = [];
res.messages.forEach(function(element, index) {
newmessage[index] = element.entry[0];
});
console.log(newmessage);
this.setState(previousState => ({
messages: GiftedChat.append(
previousState.messages,
newmessage
)
}));
}
);
}

Agora o histórico de mensagens será carregado mesmo quando o aplicativo for atualizado.

No entanto, as mensagens são ordenadas na direção oposta. Então, precisamos reverter o array antes de adicionarmos o array ao Gifted Chat. Você pode fazer isso usando o seguinte trecho de código:

 componentDidMount() { 
this.pubnub.history(
{ channel: "MainChat", reverse: true, count: 15 },
(status, res) => {
let newmessage = [];
res.messages.forEach(function(element, index) {
newmessage[index] = element.entry[0];
});
console.log(newmessage);
this.setState(previousState => ({
messages: GiftedChat.append(
previousState.messages,
newmessage.reverse()
)
}));
}
);
}

E com isso, as mensagens de bate-papo agora são recuperadas e exibidas na ordem cronológica correta em que foram enviadas.

Associando Usuários a Mensagens na IU do Chat

Você pode observar que, quando você envia uma mensagem e atualiza o aplicativo, todas as mensagens são exibidas no lado do destinatário. Por que isso acontece? Criamos aleatoriamente um ID de usuário quando carregamos o aplicativo para simular vários usuários.

Precisamos adicionar um pouco de autenticação de usuário para que possamos identificar os usuários no bate-papo. Isso nos permitirá mostrar as mensagens no lado correto da interface de bate-papo. Em seguida, os usuários poderão diferenciar visualmente suas mensagens de bate-papo das mensagens de bate-papo de seus amigos.

Primeiro, precisamos criar alguns arquivos em nosso diretório de aplicativos.

Precisamos mover o código de nosso arquivo App.js para MainChat.js e alterar o nome da classe de App para MainChat, conforme mostrado no snippet de código abaixo:

 import React, { Component } from "react"; 
import {
View,
Text,
StyleSheet,
TextInput,
TouchableOpacity,
Image
} from "react-native";
export default class App extends Component {
render() {
return (
<View style={styles.container}>
<View style={styles.logo}>
<Image
source={require("../img/react.jpg")}
style={{ width: 66, height: 58 }}
/>
<Image
source={require("../img/pubnublogo.png")}
style={{ width: 60, height: 60 }}
/>
</View>
<Text style={styles.welcome}>Chat with Pubnub</Text>
<TextInput
style={styles.input}
placeholder="Username"
autoCapitalize="none"
autoCorrect={false}
onChangeText={username => this.setState({ username })}
/>
<TextInput
style={styles.input}
secureTextEntry={true}
placeholder="Password"
onChangeText={password => this.setState({ password })}
/>
<View style={styles.btnContiner}>
<TouchableOpacity style={styles.btn} onPress={() => this.login()}>
<Text style={styles.btntext}>Login</Text>
</TouchableOpacity>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
alignItems: "center",
bottom: 66
},
welcome: {
fontSize: 30,
textAlign: "center",
margin: 10,
fontWeight: "300"
},
input: {
width: "90%",
backgroundColor: "skyblue",
padding: 15,
marginBottom: 10
},
btnContiner: {
flexDirection: "row",
justifyContent: "center",
width: "80%"
},
btn: {
backgroundColor: "orange",
padding: 15,
width: "45%"
},
btntext: { fontSize: 16, textAlign: "center" },
logo: {
flexDirection: "row"
}
});

Agora você pode ver o resultado do nosso estilo de formulário de login.

Em seguida, adicionaremos a funcionalidade de autenticação do usuário. Para fazer isso, primeiro criamos um objeto de estado com duas variáveis nome de usuário e senha, como no snippet de código abaixo:

 state = { username: "", password: "" }; 

Quando um usuário digita no campo de entrada de texto, adicionamos os dados de texto às variáveis de estado, conforme mostrado no snippet de código abaixo:

 <View style={styles.container}> 
<Text style={styles.welcome}>Chat with Pubnub</Text>
<TextInput
style={styles.input}
placeholder="Username"
autoCapitalize="none"
autoCorrect={false}
onChangeText={username => this.setState({ username })}
/>
<TextInput
style={styles.input}
secureTextEntry={true}
placeholder="Password"
onChangeText={password => this.setState({ password })}
/>
<View style={styles.btnContiner}>
<TouchableOpacity style={styles.btn} >
<Text style={styles.btntext}>Login</Text>
</TouchableOpacity>
</View>
</View>

Quando o usuário clica no botão de login, ele acionará a função de login.

Para uma configuração simples e rápida, criamos uma variável const chamada user, que contém nome de usuário e senha , conforme mostrado no exemplo de código abaixo.

Isto é puramente para fins de demonstração. Não faça isso na sua aplicação de produção! Faça um sistema de autenticação seguro e de empacotamento de servidor.

 const user = { 
0: { username: "user1", password: 1111 },
1: { username: "user2", password: 1111 }
};

Agora, usamos essa variável para representar um banco de dados e criar uma função de login, conforme mostrado no snippet de código abaixo.

 login() { 
if (
(user[0].username == this.state.username &&
user[0].password == this.state.password) ||
(user[1].username == this.state.username &&
user[1].password == this.state.password)
) {
this.props.navigation.navigate("MainChat", {
username: this.state.username
});
} else {
console.log(this.state);
alert("username or password is incorrect");
}
}

Uma vez feito, você terá algo parecido com isso.

Podemos ver que nossa autenticação de login foi bem-sucedida. Agora, precisamos redirecionar o usuário para a sala de bate-papo após o login bem-sucedido.

Redirecionamento após o sucesso do login

Em seguida, precisamos usar o pacote react-navigation para manipular rotas e redirecionamentos, como páginas da web. Primeiro, você precisa seguir as instruções de instalação do React Navigation aqui. Então, precisamos mover todo o código do App.js para o Login.js e alterar o nome da classe. Então, precisamos tornar o App.js compatível com o gerenciamento de rotas com a navegação por reação.

 import { createStackNavigator, createAppContainer } from "react-navigation"; 
import Login from "./src/components/Login";
import MainChat from "./src/components/MainChat";
const AppNavigator = createStackNavigator(
{
Login: {
screen: Login
},
MainChat: {
screen: MainChat
}
},
{
initialRouteName: "Login"
}
);
export default createAppContainer(AppNavigator);

Agora podemos redirecionar os usuários para a tela de bate-papo principal após o login. A funcionalidade funcionará depois que adicionarmos a função de navegação.

 login() { 
if (
(user[0].username == this.state.username &&
user[0].password == this.state.password) ||
(user[1].username == this.state.username &&
user[1].password == this.state.password)
) {
this.props.navigation.navigate("MainChat", {
username: this.state.username
});
} else {
console.log(this.state);
alert("username or password is incorrect");
}
}

Aqui, precisamos especificar o nome da tela (ou seja, MainChat) e o parâmetro (ou seja, nome de usuário) que você deseja usar na próxima página.

Nós configuramos o MainChat.js substituindo o ID aleatório por um valor de parâmetro, conforme mostrado no seguinte trecho de código:

 render() { 
return (
<GiftedChat
messages={this.state.messages}
onSend={messages => this.onSend(messages)}
user={{
_id: this.props.navigation.getParam("username")
}}
/>
);
}

Vamos experimentar tudo!

Você pode ver o login pelo usuário1 e, em seguida, o envio de uma nova mensagem. O usuário1 verá a mensagem do Usuário2 no lado correto da interface do usuário.

Empacotando

Neste tutorial, aprendemos a armazenar e buscar mensagens de bate-papo históricas e exibi-las na ordem em que foram recebidas.

Seu aplicativo de bate-papo está crescendo em recursos, mas há muito mais que podemos fazer. Fique de olho nos posts subsequentes sobre indicadores de digitação, contagem de mensagens não lidas, presença de usuários e muito mais.