228 lines
6.9 KiB
Vue
228 lines
6.9 KiB
Vue
<script setup>
|
|
import { ref, onMounted } from 'vue'
|
|
import { useChatStore
|
|
|
|
} from '../stores/chatstore';
|
|
const chatStore = useChatStore()
|
|
|
|
// Variáveis de controle do Drawer e do Mini Variant
|
|
const isDrawerOpen = ref(true)
|
|
const isMiniVariant = ref(false)
|
|
const inputMessage = ref('')
|
|
|
|
// Funções de controle do Drawer
|
|
const toggleDrawer = () => {
|
|
isDrawerOpen.value = !isDrawerOpen.value
|
|
isMiniVariant.value = !isMiniVariant.value
|
|
}
|
|
|
|
// Selecionar um chat da lista
|
|
const selectChat = (index) => {
|
|
chatStore.selectedChatIndex = index
|
|
}
|
|
|
|
// Criar um novo chat
|
|
const createNewChat = () => {
|
|
const newChatName = `Chat ${chatStore.chatList.length + 1}`
|
|
chatStore.chatList.push({ id: `chat${chatStore.chatList.length + 1}`, name: newChatName, messages: [] })
|
|
chatStore.selectedChatIndex = chatStore.chatList.length - 1
|
|
}
|
|
|
|
// Salvar nome do chat
|
|
const saveChatName = (index) => {
|
|
if (chatStore.chatList[index].name.trim() !== '') {
|
|
chatStore.chatList[index].name = chatStore.chatList[index].name.trim()
|
|
}
|
|
}
|
|
|
|
// Enviar uma mensagem
|
|
const sendMessage = () => {
|
|
if (inputMessage.value.trim() !== '') {
|
|
chatStore.chatList[chatStore.selectedChatIndex].messages.push({ text: inputMessage.value, isUser: true })
|
|
inputMessage.value = ''
|
|
|
|
setTimeout(() => {
|
|
chatStore.chatList[chatStore.selectedChatIndex].messages.push({
|
|
text: 'Esta é uma resposta automática.',
|
|
isUser: false
|
|
})
|
|
}, 1000)
|
|
}
|
|
}
|
|
|
|
// Carregar os chats do usuário no onMounted
|
|
onMounted(async () => {
|
|
const userId = 'user123' // Esse id viria do sistema de autenticação
|
|
await chatStore.loadChats(userId)
|
|
})
|
|
|
|
</script>
|
|
|
|
<template>
|
|
<v-container fluid no-gutters class="chat">
|
|
<!-- Drawer Lateral -->
|
|
<v-navigation-drawer v-model="isDrawerOpen" :mini-variant="isMiniVariant" app permanent>
|
|
<v-list>
|
|
<v-list-item v-if="!isMiniVariant">
|
|
<v-row align="center" justify="space-between" style="width: 100%">
|
|
<v-col cols="auto">
|
|
<v-list-item-title class="text-h6">Chats</v-list-item-title>
|
|
</v-col>
|
|
<v-col cols="auto">
|
|
<v-icon @click="createNewChat" style="padding-left: 25pt;">mdi-chat-plus-outline</v-icon>
|
|
</v-col>
|
|
</v-row>
|
|
</v-list-item>
|
|
|
|
<!-- Lista de chats -->
|
|
<v-list-item v-for="(chat, index) in chatStore.chatList" :key="chat.id" @click="selectChat(index)"
|
|
:class="{ 'chat-selected': chatStore.selectedChatIndex === index }" v-if="!isMiniVariant">
|
|
<v-list-item-content>
|
|
<v-list-item-title>
|
|
<v-textarea v-model="chat.name" @focus="chat.isUnderlined = true" @blur="chat.isUnderlined = false"
|
|
hide-details variant="plain" class="mr-2" :class="{ 'underline': chat.isUnderlined }"
|
|
@keyup.enter="saveChatName(index)" placeholder="Novo nome" auto-grow rows="1" max-rows="5" />
|
|
</v-list-item-title>
|
|
</v-list-item-content>
|
|
</v-list-item>
|
|
</v-list>
|
|
</v-navigation-drawer>
|
|
|
|
<!-- Barra de aplicação com o título do chat selecionado -->
|
|
<v-app-bar app flat>
|
|
<template v-if="isMiniVariant">
|
|
<v-btn @click="createNewChat" icon>
|
|
<v-icon>mdi-chat-plus-outline</v-icon>
|
|
</v-btn>
|
|
<v-btn @click="toggleDrawer" icon>
|
|
<v-icon>mdi-menu</v-icon>
|
|
</v-btn>
|
|
<h2 class="text-h5 ml-2">{{ chatStore.chatList[chatStore.selectedChatIndex]?.name }}</h2>
|
|
</template>
|
|
<template v-else>
|
|
<v-btn @click="toggleDrawer" icon>
|
|
<v-icon>mdi-menu</v-icon>
|
|
</v-btn>
|
|
<h2 class="text-h5 ml-2">{{ chatStore.chatList[chatStore.selectedChatIndex]?.name }}</h2>
|
|
</template>
|
|
</v-app-bar>
|
|
|
|
<!-- Conteúdo do chat -->
|
|
<v-col cols="12" lg="6" xs="10" offset-lg="3" offset-xs="1" class="chat-container">
|
|
<div class="chat-messages flex-grow-1 overflow-y-auto">
|
|
<v-list>
|
|
<v-list-item-group>
|
|
<v-list-item v-for="(message, index) in chatStore.chatList[chatStore.selectedChatIndex]?.messages" :key="index">
|
|
<v-list-item-content>
|
|
<v-row>
|
|
<v-col cols="12" v-if="message.isUser">
|
|
<v-row justify="end">
|
|
<v-col cols="8">
|
|
<v-card class="user-message" outlined>
|
|
<v-card-text>{{ message.text }}</v-card-text>
|
|
</v-card>
|
|
</v-col>
|
|
</v-row>
|
|
</v-col>
|
|
|
|
<v-col cols="12" v-else>
|
|
<v-row justify="start">
|
|
<v-col cols="8">
|
|
<v-card class="received-message" outlined>
|
|
<v-card-text>{{ message.text }}</v-card-text>
|
|
</v-card>
|
|
</v-col>
|
|
</v-row>
|
|
</v-col>
|
|
</v-row>
|
|
</v-list-item-content>
|
|
</v-list-item>
|
|
</v-list-item-group>
|
|
</v-list>
|
|
</div>
|
|
</v-col>
|
|
|
|
<!-- Barra de entrada para nova mensagem -->
|
|
<v-app-bar location="bottom" flat>
|
|
<v-row align="center">
|
|
<v-col cols="10" lg="6" offset="1" offset-lg="3">
|
|
<v-textarea class="input-message" v-model="inputMessage" @keyup.enter="sendMessage"
|
|
label="Digite sua mensagem" outlined hide-details prepend-inner-icon="mdi-send"
|
|
@click:append-outer="sendMessage" rows="1" />
|
|
</v-col>
|
|
</v-row>
|
|
</v-app-bar>
|
|
</v-container>
|
|
</template>
|
|
|
|
|
|
<style scoped>
|
|
/* Estilo para as mensagens recebidas */
|
|
.input-message {
|
|
background-color: #f1f1f1;
|
|
border-top-left-radius: 16px;
|
|
border-bottom-left-radius: 0px;
|
|
border-top-right-radius: 16px;
|
|
border-bottom-right-radius: 0px;
|
|
text-align: center;
|
|
margin-bottom: 15pt;
|
|
max-width: 100%;
|
|
/* Limita para que o texto não ocupe toda a linha */
|
|
box-shadow: none;
|
|
/* Remove a sombra */
|
|
}
|
|
|
|
/* Estilo para as mensagens do usuário */
|
|
.user-message {
|
|
background-color: #e3f2fd;
|
|
border-top-left-radius: 16px;
|
|
border-bottom-left-radius: 16px;
|
|
border-top-right-radius: 16px;
|
|
border-bottom-right-radius: 0px;
|
|
text-align: end;
|
|
max-width: 100%;
|
|
/* Limita para que o texto não ocupe toda a linha */
|
|
box-shadow: none;
|
|
/* Remove a sombra */
|
|
}
|
|
|
|
/* Estilo para as mensagens recebidas */
|
|
.received-message {
|
|
background-color: #f1f1f1;
|
|
border-top-left-radius: 16px;
|
|
border-bottom-left-radius: 0px;
|
|
border-top-right-radius: 16px;
|
|
border-bottom-right-radius: 16px;
|
|
text-align: start;
|
|
max-width: 100%;
|
|
/* Limita para que o texto não ocupe toda a linha */
|
|
box-shadow: none;
|
|
/* Remove a sombra */
|
|
}
|
|
|
|
.chat-selected {
|
|
background-color: #e0f7fa;
|
|
}
|
|
|
|
.v-navigation-drawer {
|
|
max-width: 250px;
|
|
}
|
|
|
|
.chat {
|
|
padding: 0 !important;
|
|
}
|
|
|
|
.chat-container {
|
|
height: calc(80vh - 70px);
|
|
}
|
|
|
|
.chat-messages {
|
|
flex-grow: 1;
|
|
overflow-y: auto;
|
|
}
|
|
|
|
.underline {
|
|
text-decoration: underline;
|
|
}
|
|
</style>
|