Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

90
Visualizações
Scroll down on VUEJS application not working

I'm creating a chatbot application that streams content from a REST API and it works perfectly fine, but scrolling down doesn't do what I expected, a scroll bar is generated and I have to manually scroll to see the streaming response.

 async sendMsg() {
 const messageToSend = this.newMessage.trim();
 this.newMessage = '';
 
 const botName = "Prometheus";
 const usermessagePayload = {
 content: messageToSend,
 sender: 'user',
 receiver: botName,
 time: util.formatDate.format(new Date(), 'hh:mm:ss'),
 sources: []
 };
 
 this.$store.commit('SEND_MESSAGE', usermessagePayload);
 
 try {
 const path = `https://<url>/privategptstream?prompt=${messageToSend}`;
 console.log("Sending message:", messageToSend);

 const response = await fetch(path);
 const reader = response.body.getReader();

 const initialanswerPayload = {
 content: '',
 sender: botName,
 receiver: 'user',
 time: util.formatDate.format(new Date(), 'hh:mm:ss'),
 isNewMessage: true
 }
 
 this.$store.commit('APPEND_MESSAGE_CHUNK', initialanswerPayload);
 
 while (true) {
 const { done, value } = await reader.read();
 if (done) break;
 
 const chunk = new TextDecoder("utf-8").decode(value);
 const answerPayload = {
 content: chunk,
 sender: botName,
 receiver: 'user',
 time: util.formatDate.format(new Date(), 'hh:mm:ss'),
 isNewMessage: false
 }
 
 // Append the chunk to the last message in the conversation
 this.$store.commit('APPEND_MESSAGE_CHUNK', answerPayload);
 this.$nextTick(() => {
 setTimeout(() => {
 this.scrollToBottom();
 }, 100); // Adjust the delay as needed
 });
 }
 
 console.log("Streaming complete");
 } catch (error) {
 console.error("Error streaming the answer:", error);
 this.showSnackbar('Failed to get an answer from the server.');
 }
 },

 scrollToBottom() {
 const chatContainer = this.$refs.chatContainer;
 chatContainer.scrollTop = chatContainer.scrollHeight;
 console.log("chatcontainer scrollTop:" + chatContainer.scrollTop );
 console.log("chatcontainer scrollHeight:" + chatContainer.scrollHeight );

 },


<template>
 <!-- Main container for the entire chat interface -->
 <v-container>
 <!-- Container for displaying chat messages -->
 <v-row class="messages-container" >
 <v-col cols="14">
 <!-- Styling for the messages -->
 <div class="pa-4 messages" ref="chatContainer" >
 <!-- Loop through messages in reverse order to display newest at the bottom -->
 <div v-for="(message, index) in reversedChats" :key="index" class="my-2 d-flex flex-column">
 <!-- Conditional styling for user and bot messages -->
 <div :class="['message-chip', message.sender === 'user' ? 'question' : 'response']">
 <!-- Display avatar for user message -->
 <img v-if="message.sender === 'user'" src="../../assets/user.png" class="avatar user-avatar">
 <!-- Display avatar for bot response -->
 <img v-if="message.sender !== 'user'" src="../../assets/bot.png" class="avatar bot-avatar">
 <!-- Display message content -->
 <pre v-if="message.sender === 'user'">{{ message.content }}</pre>
 <div v-else>
 <!-- Display image if message is an image -->
 <pre v-if="!message.isImage">{{ message.content }}</pre>
 <img v-else :src="message.content" alt="Generated Image" class="generated-image">
 <!-- Display source buttons if sources are available -->
 <div v-if="message.sources && message.sources.length" class="source-buttons">
 <!-- Loop through sources and display buttons for each -->
 <v-btn
 v-for="(source, sIndex) in message.sources"
 :key="`source-${sIndex}`"
 small
 class="source-button"
 @click="sourceAction(source.url)"
 >
 {{ source.title }}
 </v-btn>
 </div>
 </div>
 </div>
 </div>
 </div>
 </v-col>
 </v-row>

 <!-- Container for user input and predefined options -->
 <v-row class="input-row" no-gutters>
 <v-col cols="12">
 <!-- Display bot description before user input -->
 <div class="bot-description" v-if="showPredefinedCards">
 <img src="../../assets/logo.png" alt="Logo" class="e61-logo">
 <!-- Bot introduction message -->
 <p>This bot can help you with a variety of tasks, such as answering questions, providing information, and more.</p>
 <p>Try one of the options below and type in your question or make use of the predefined prompts.</p>
 </div>
 <!-- Display predefined text options if available -->
 <div class="predefined-text-cards" v-if="showPredefinedCards">
 <v-row>
 <!-- Loop through predefined text options and display as cards -->
 <v-col cols="12" sm="3" v-for="(item, index) in actionButtons" :key="index">
 <v-card outlined @click="selectCard(index)" :class="{ 'selected': selectedCard === index }" class="pa-2">
 <v-card-title class="justify-center">
 <!-- Display icon and title for each predefined option -->
 <v-icon left>{{ item.icon }}</v-icon>
 {{ item.title }}
 </v-card-title>
 <!-- Display summary text for each predefined option -->
 <v-card-text>{{ item.summary }}</v-card-text>
 </v-card>
 </v-col>
 </v-row>
 </div>
 <!-- Form and other elements remain unchanged -->
 </v-col>
 <v-col cols="12">
 <!-- Display predefined prompts based on selected card -->
 <v-row class="predefined-prompts-container" justify="center" v-if="selectedCard !==null">
 <!-- Loop through predefined prompts and display as buttons -->
 <v-btn small outlined v-for="(prompt, index) in predefinedPrompts" :key="index" @click="setPredefinedText(prompt.prompt)" class="ma-1">
 {{ prompt.text }}
 </v-btn>
 </v-row>
 <!-- Form for user input -->
 <v-form @submit.prevent="sendMsg" class="d-flex align-center" v-if="selectedCard !==null">
 <!-- Button to clear conversation -->
 <v-btn
 :class="{'expand-btn': hoverClearButton}" 
 icon 
 @click="clearMessages"
 @mouseover="hoverClearButton = true"
 @mouseleave="hoverClearButton = false" 
 class="my-auto">
 <v-icon v-if="!hoverClearButton">mdi-delete</v-icon>
 <span v-if="hoverClearButton">Clear Conversation</span>
 </v-btn>
 
 <!-- Textarea for user input -->
 <v-textarea
 outlined
 counter
 label="Ask me anything..."
 auto-grow
 :rows="1"
 :rules="rules"
 v-model="newMessage"
 class="mr-2 flex-grow-1"
 no-resize
 @keyup.enter.prevent="sendMsg"
 ></v-textarea>
 <!-- Button to send user message -->
 <v-btn type="submit" color="primary" class="my-auto" icon>
 <v-icon>mdi-send</v-icon>
 </v-btn>
 </v-form>
 </v-col>
 </v-row>
 <!-- Snackbar for displaying messages -->
 <v-snackbar v-model="snackbar.show">
 {{ snackbar.message }}
 <!-- Button to close snackbar -->
 <v-btn color="red" text @click="snackbar.show = false">Close</v-btn>
 </v-snackbar>
 </v-container>
</template>

<script src="./ChatList.js"></script>
<style src="./ChatList.css" scoped></style>
over 2 years ago · Carlos Garzón Colorado
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda