
Compartilhar:
Educador de tecnologia com um jeito amigável, pai de família, defensor da diversidade, provavelmente discuto um pouco demais. Ex-engenheiro de backend. Fale comigo sobre JavaScript (front-end ou back-end), o incrível Vue.js, DevOps, DevSecOps e tudo relacionado ao JamStack. Escritor no DEV.to
Paginação do chat com rolagem infinita
Tempo de leitura: 25 minutos
Observação: algumas das ferramentas ou métodos descritos neste artigo podem não ter mais suporte ou estar desatualizados. Para obter conteúdo atualizado ou suporte, consulte nossas postagens mais recentes ou nossa Documentação
Dando continuidade ao post anterior Crie uma interface de usuário simples para mensagens com o Bootstrap, este artigo mostrará como carregar mensagens mais antigas da conversa usando o Vonage Client SDK, que agora é fornecido de forma paginada pela Conversation API.
Pré-requisitos
Node e NPM
Para começar, você precisará ter o Node e o NPM instalados. Este guia utiliza o Node 8 e o NPM 6. Verifique se eles estão instalados e atualizados.
Tanto o Node quanto o NPM precisam estar instalados e na versão correta. Acesse o site nodejs.org e instale a versão correta, caso ainda não a tenha.
CLI da Vonage
Para configurar seu aplicativo, você precisará instalar o Vonage CLI. Instale-o usando o NPM no terminal.
Você pode encontrar sua chave e seu segredo da API no Painel , que são usados para configurar a CLI da Vonage.
O CLI da Vonage possui plug-ins que, quando instalados, oferecem recursos adicionais. Neste tutorial, você trabalhará com o Conversations; portanto, eis o comando para instalar o plug-in correspondente:
Git (opcional)
Você pode usar o git para clonar o aplicativo de demonstração do GitHub.
Para quem não se sente à vontade com os comandos do Git, não se preocupe, eu te ajudo. Este guia traz instruções sobre como baixar o projeto como um arquivo ZIP.
Siga este guia para instalar o git.
Introdução
Com base no aplicativo finalizado do último tutorial, há um novo aplicativo de demonstração inicial. Clone-o e instale-o seguindo estas etapas.
Baixe o aplicativo de demonstração
Para quem não se sente à vontade com os comandos do Git, é possível baixar o aplicativo de demonstração como um arquivo zip e descompactá-lo localmente.
Depois de clonada ou descompactada, acesse o novo diretório do aplicativo de demonstração.
Instale as dependências do npm.
Configure a porta do aplicativo usando um arquivo de ambiente. Copie o arquivo de exemplo:
Agora, edite o arquivo de ambiente .env e defina a porta como 3000 (ou qualquer outra porta que você precisar).
Entre os outros pacotes instalados pelo seu último comando, há um chamado nodemon, que permite que você recarregue seu aplicativo automaticamente caso edite algum arquivo.
Para iniciar o aplicativo da maneira padrão, execute:
Para iniciar o aplicativo, mas usando o nodemon, execute:
Dica: Se você estiver executando o aplicativo com
nodemonpelo restante deste tutorial, sempre que eu sugerir reiniciar o aplicativo, você não precisará fazer isso, poisnodemono sistema já faz isso por você. No entanto, se precisar se autenticar novamente no aplicativo, ainda será necessário fazer isso, já que as informações da sessão são armazenadas na memória e não estão configuradas para usar nenhum outro tipo de armazenamento.
Configurar o aplicativo de demonstração
Para se conectar ao Vonage e enviar ou receber mensagens pelo serviço, é necessário configurar o aplicativo de demonstração.
Criar uma aplicação da Vonage
Primeiro, crie uma Application da Vonage com recursos de RTC (comunicação em tempo real). A URL do evento será um registro em tempo real dos eventos que ocorrem no serviço da Vonage, como usuários entrando ou saindo, enviando mensagens e ativando o áudio (caso você queira ativá-lo).
Criar uma conversa no Vonage
Em segundo lugar, crie uma “Conversação” do Vonage, que funciona como uma sala de bate-papo. Ou seja, um espaço para mensagens e eventos.
Crie sua conta
Agora, crie uma conta para você mesmo.
Observação: Nesta demonstração, não haverá bate-papo entre dois usuários. Outros guias mostram como criar conversas entre vários usuários. Este guia se concentra em definir o estilo da interface de usuário das mensagens de maneira simples, mas atraente.
Adicionar o usuário a uma conversa
Em seguida, adicione seu novo usuário à conversa. Um usuário pode ser membro de uma Application, mas ainda assim precisa participar da conversa.
Gerar um token de usuário
Por fim, gere um token para o seu novo usuário. Esse token representa o usuário ao acessar o aplicativo. Esse token de acesso identifica o usuário; portanto, qualquer pessoa que o utilizar será considerada o usuário correto.
Na prática, você configurará o aplicativo com esse token. Em ambiente de produção, esses tokens devem ser protegidos, mantidos em sigilo e divulgados com muito cuidado ao aplicativo cliente, se for o caso.
Configurar o aplicativo
Depois de gerar todas as partes necessárias, edite o views/layout.hbs arquivo e localize o código JavaScript mostrado aqui.
<script>
var userName = '';
var displayName = '';
var conversationId = '';
var clientToken = '';
</script>Edite o arquivo de configuração com os valores que você gerou nos comandos acima.
<script>
var userName = 'luke'; // <USER_NAME>
var displayName = 'Luke Oliff'; // <DISPLAY_NAME>
var conversationId = 'CON-123...y6346'; // <CONVERSATION_ID>
var clientToken = 'eyJhbG9.eyJzdWIiO.Sfl5c'; // this will be much much longer
</script>Agora que está configurado, inicie o aplicativo e acesse-o usando o URL padrão do aplicativo.
Observação: Esta é apenas uma demonstração e você não deve codificar credenciais de forma estática em nenhuma aplicação, especialmente em uma que as exponha ao cliente.
Vonage Chat Simple Messaging UI
Preparar um histórico de mensagens
Como você precisa de mais mensagens para percorrer o histórico, crie um histórico de mensagens enviando várias mensagens ao cliente. O tamanho padrão da página é de 20 itens; portanto, crie mais de 20 mensagens. Recomendo criar 60 mensagens de teste para que você possa carregar duas páginas inteiras do histórico.
Adicionando paginação ao aplicativo
As configurações padrão do aplicativo exibem apenas 20 itens dos eventos anteriores da conversa. Agora, é hora de adicionar paginação ao aplicativo para que os usuários possam carregar eventos mais antigos.
O que é paginação?
A paginação é a forma como um aplicativo divide o conteúdo em várias páginas. Quando implementada no projeto de uma API, ela permite a entrega de conjuntos de resultados gerenciáveis, que geralmente podem ser navegados programaticamente. SDKs como o Vonage Client SDK não são diferentes, muitas vezes ampliando a funcionalidade de paginação das APIs por meio de métodos intuitivos que tornam a paginação mais simples.
A Experiência do Usuário
Alguns aplicativos oferecem links como “próximo” ou “anterior”, ou números de página. Mas não é isso que você vai implementar aqui. Como as mensagens em um canal de bate-papo são um fluxo contínuo de conversa, este aplicativo permitirá que os usuários simplesmente continuem rolando pelas mensagens anteriores. Isso é feito por meio de um conceito conhecido como rolagem infinita. À medida que você rola pelas mensagens mais antigas e chega ao fim, o aplicativo solicitará a próxima página do histórico e as inserirá na exibição. Em canais mais antigos com muito histórico, isso dará a sensação de poder rolar para sempre, ou seja, a rolagem infinita.
O Código
Agora, você vai escrever um pouco de código. Aqui, você fará alterações para detectar a posição de rolagem da sua lista de mensagens e carregar mais mensagens quando chegar à mensagem mais antiga. A mensagem mais antiga será exibida bem no topo da janela.
Rolar até o topo
Para detectar quando você rola a tela até o topo, é preciso adicionar um novo evento. Edite o public/javascripts/chat.js arquivo e adicione o código a seguir abaixo do setupUserEvents() método.
// public/javascripts/chat.js
// ...
setupUserEvents() {
// ...
this.messageFeed.addEventListener("scroll", () => {
alert('scrolling!');
}
}
// ...
Você pode testar isso no navegador, onde logo descobrirá por que isso não é muito útil. Esse código adiciona um ouvinte de evento ao elemento messageFeed elemento, o que significa que toda vez que você tentar rolar a página, ele aciona um pop-up. Não é isso que você quer!
Então, faça uma pequena alteração. Adicione o código a seguir acima do setupUserEvents() método e modifique seu novo ouvinte de eventos conforme mostrado.
// public/javascripts/chat.js
// ...
isFeedAtTop() {
return 0 === this.messageFeed.scrollTop;
}
setupUserEvents() {
// ...
this.messageFeed.addEventListener("scroll", () => {
if (this.isFeedAtTop()) {
alert('scrolling!');
}
}
}
// ...
Essa nova alteração cria um novo método que detecta onde está a posição de rolagem do messageFeed está 0, zero ou exatamente no início, na parte superior do histórico de mensagens. Muito mais útil! Agora, você sabe quando alguém chega à mensagem mais antiga, no topo da lista de mensagens.
Vonage Chat Alert When Scrolling to the Top
Quem é você?
Para atribuir novas mensagens a um usuário quando elas forem carregadas do histórico de conversas, você deve armazená-las. Ao editar o public/javascripts/chat.js arquivo, adicione a seguinte linha após a linha this.conversation = conversation;.
// public/javascripts/chat.js
// ...
setupConversationEvents(conversation, user) {
// ...
this.user = user;
// ...
}
// ... Armazenar o contexto da página
Para carregar mais mensagens do histórico de mensagens, é preciso saber qual foi a última página carregada. Para isso, ainda na edição do public/javascripts/chat.js arquivo, altere o código existente showConversationHistory conforme mostrado abaixo para armazenar a página do evento mais recente no aplicativo.
// public/javascripts/chat.js
// ...
showConversationHistory(conversation, user) {
// ...
.then((eventsPage) => {
this.lastPage = eventsPage;
var eventsHistory = "";
// ...
}
// ...
Se não estiver claro como o showConversationHistory método deve ficar após a alteração, aqui está o método completo com a alteração aplicada.
// public/javascripts/chat.js
// ...
showConversationHistory(conversation, user) {
conversation
.getEvents({ page_size: 20, order: 'desc' })
.then((eventsPage) => {
this.lastPage = eventsPage;
var eventsHistory = "";
eventsPage.items.forEach((value, key) => {
if (conversation.members.get(value.from)) {
switch (value.type) {
case 'text':
eventsHistory = this.senderMessage(user, conversation.members.get(value.from), value) + eventsHistory;
break;
case 'member:joined':
eventsHistory = this.memberJoined(conversation.members.get(value.from), value) + eventsHistory;
break;
}
}
});
this.messageFeed.innerHTML = eventsHistory + this.messageFeed.innerHTML;
this.scrollFeedToBottom();
})
.catch(this.errorLogger);
}
// ...
A ideia desse método é armazenar o EventsPage resultado retornado pela chamada getEvents, para que o aplicativo possa usá-lo novamente mais tarde.
Com essa alteração em vigor, o aplicativo agora reconhece qual é a página mais recente.
Evite solicitações desnecessárias
Um método do EventsPage objeto é hasNext, que retorna “true” se houver mais eventos para carregar.
Com o hasNext método, edite o evento de rolagem que você adicionou anteriormente para incluir this.lastPage.hasNext() à condição em torno do nosso alert.
// public/javascripts/chat.js
// ...
setupUserEvents() {
// ...
this.messageFeed.addEventListener("scroll", () => {
if (this.isFeedAtTop() && this.lastPage.hasNext()) {
alert('scrolling!');
}
}
}
// ...
Agora, você só receberá um alerta se houver outra página de eventos para carregar.
Carregar a próxima página
Para carregar a próxima página, substitua o alert no seu ouvinte de eventos pelo código mostrado abaixo:
// public/javascripts/chat.js
// ...
this.lastPage
.getNext()
.then((eventsPage) => {
this.lastPage = eventsPage;
var moreEvents = "";
eventsPage.items.forEach((value, key) => {
if (this.conversation.members.get(value.from)) {
switch (value.type) {
case 'text':
moreEvents = this.senderMessage(this.user, this.conversation.members.get(value.from), value) + moreEvents;
break;
case 'member:joined':
moreEvents = this.memberJoined(this.conversation.members.get(value.from), value) + moreEvents;
break;
}
}
});
this.messageFeed.innerHTML = moreEvents + this.messageFeed.innerHTML;
})
.catch(this.errorLogger);
// ...
Este código utiliza this.lastPage que foi armazenado no aplicativo anteriormente neste artigo e solicita getNext que retorna um novo EventsPage.
O restante do código apresentado aqui sobrescreve this.LastPage pela página mais recente e executa praticamente a mesma função do showConversationHistory método que exibe mensagens históricas quando a página é carregada, adicionando-as ao topo da messageFeed.
Fixar a posição de rolagem
Com a rolagem infinita ativada, você vai perceber que as novas mensagens são adicionadas no topo, mas você continua vendo a parte superior do messageFeed, perdendo a posição em que você estava no histórico de mensagens do canal. Para resolver isso, você vai reutilizar o scrollTo método que já está no public/javascripts/chat.js arquivo.
Anteriormente, scrollTo era usado para rolar até o final das mensagens, o que é feito com qualquer número maior que a altura da messageFeed. Nesta equipe, você precisa rolar até um ponto específico na messageFeed.
Se a posição, no momento em que o aplicativo carregou novas mensagens, estivesse 0 na parte superior, então faria sentido rolar a tela até a diferença entre a altura antes e depois da messageFeed fosse atualizada.
Dentro da condição que verifica a posição da rolagem e hasNext, mas antes que o the.lastPage.getNext() código ser executado, adicione o código para armazenar o scrollHeight, conforme mostrado aqui:
// public/javascripts/chat.js
// ...
if (this.isFeedAtTop() && this.lastPage.hasNext()) {
this.scrollHeight = this.messageFeed.scrollHeight;
// ...
// ...
Agora, nessa mesma função, após a linha que atualiza o messageFeed.innerHTML com moreEvents, adicione também esta linha:
// public/javascripts/chat.js
// ...
// ...
this.scrollTo(this.messageFeed.scrollHeight-this.scrollHeight);
// ...Se não estiver claro como o "scroll" ouvinte de eventos deve se comportar após a alteração, aqui está o código na íntegra:
// public/javascripts/chat.js
// ...
// ...
this.messageFeed.addEventListener("scroll", () => {
if (this.isFeedAtTop() && this.lastPage.hasNext()) {
this.scrollHeight = this.messageFeed.scrollHeight;
this.lastPage
.getNext()
.then((eventsPage) => {
this.lastPage = eventsPage;
var moreEvents = "";
eventsPage.items.forEach((value, key) => {
if (this.conversation.members.get(value.from)) {
switch (value.type) {
case 'text':
moreEvents = this.senderMessage(this.user, this.conversation.members.get(value.from), value) + moreEvents;
break;
case 'member:joined':
moreEvents = this.memberJoined(this.conversation.members.get(value.from), value) + moreEvents;
break;
}
}
});
this.messageFeed.innerHTML = moreEvents + this.messageFeed.innerHTML;
this.scrollTo(this.messageFeed.scrollHeight-this.scrollHeight);
})
.catch(this.errorLogger);
}
});
// ...
Com um pouco de sorte, quando você experimentar, vai perceber que as mensagens parecem carregar acima da sua posição de rolagem, permitindo que você role “até o infinito” ou até o topo.
Vonage Chat Infinite Scrolling to the Top
Fim
Este artigo é a continuação da postagem anterior Crie uma interface de usuário simples para mensagens com o Bootstrap, mostrando como carregar mensagens mais antigas à medida que você percorre o histórico de mensagens.
Não se esqueça: se tiver alguma dúvida, comentário, sugestão ou ideia que gostaria de compartilhar com a comunidade em geral, sinta-se à vontade para participar do nosso espaço de trabalho da Comunidade no Slack ou deixar uma resposta aqui embaixo 👇.
Compartilhar:
Educador de tecnologia com um jeito amigável, pai de família, defensor da diversidade, provavelmente discuto um pouco demais. Ex-engenheiro de backend. Fale comigo sobre JavaScript (front-end ou back-end), o incrível Vue.js, DevOps, DevSecOps e tudo relacionado ao JamStack. Escritor no DEV.to