Added linting and enforced code styling.
This commit is contained in:
parent
8655eae39c
commit
86967b26cd
37 changed files with 3356 additions and 1875 deletions
|
@ -1,51 +1,62 @@
|
|||
<template>
|
||||
<div class="q-pa-md column full-height">
|
||||
<q-scroll-area
|
||||
ref="scrollAreaRef"
|
||||
class="col"
|
||||
style="flex-grow: 1; overflow-x: visible; overflow-y: auto;"
|
||||
<div class="q-pa-md column full-height">
|
||||
<q-scroll-area
|
||||
ref="scrollAreaRef"
|
||||
class="col"
|
||||
style="flex-grow: 1; overflow-x: visible; overflow-y: auto;"
|
||||
>
|
||||
<div
|
||||
v-for="(message, index) in messages"
|
||||
:key="index"
|
||||
class="q-mb-sm q-mx-md"
|
||||
>
|
||||
<q-chat-message
|
||||
:name="message.sender.toUpperCase()"
|
||||
:sent="message.sender === 'user'"
|
||||
:bg-color="message.sender === 'user' ? 'primary' : 'grey-4'"
|
||||
:text-color="message.sender === 'user' ? 'white' : 'black'"
|
||||
>
|
||||
<div v-for="(message, index) in messages" :key="index" class="q-mb-sm q-mx-md">
|
||||
<q-chat-message
|
||||
:name="message.sender.toUpperCase()"
|
||||
:sent="message.sender === 'user'"
|
||||
:bg-color="message.sender === 'user' ? 'primary' : 'grey-4'"
|
||||
:text-color="message.sender === 'user' ? 'white' : 'black'"
|
||||
>
|
||||
<!-- Use v-html to render parsed markdown -->
|
||||
<div v-if="!message.loading" v-html="parseMarkdown(message.content)" class="message-content"></div>
|
||||
<!-- Optional: Add a spinner for a better loading visual -->
|
||||
<template v-if="message.loading" v-slot:default>
|
||||
<q-spinner-dots size="2em" />
|
||||
</template>
|
||||
</q-chat-message>
|
||||
</div>
|
||||
</q-scroll-area>
|
||||
<!-- Use v-html to render parsed markdown -->
|
||||
<div
|
||||
v-if="!message.loading"
|
||||
v-html="parseMarkdown(message.content)"
|
||||
class="message-content"
|
||||
/>
|
||||
<!-- Optional: Add a spinner for a better loading visual -->
|
||||
<template
|
||||
v-if="message.loading"
|
||||
#default
|
||||
>
|
||||
<q-spinner-dots size="2em" />
|
||||
</template>
|
||||
</q-chat-message>
|
||||
</div>
|
||||
</q-scroll-area>
|
||||
|
||||
<q-separator />
|
||||
<q-separator />
|
||||
|
||||
<div class="q-pa-sm row items-center">
|
||||
<q-input
|
||||
v-model="newMessage"
|
||||
outlined
|
||||
dense
|
||||
placeholder="Type a message..."
|
||||
class="col"
|
||||
@keyup.enter="sendMessage"
|
||||
autogrow
|
||||
/>
|
||||
<q-btn
|
||||
round
|
||||
dense
|
||||
flat
|
||||
icon="send"
|
||||
color="primary"
|
||||
class="q-ml-sm"
|
||||
@click="sendMessage"
|
||||
:disable="!newMessage.trim()"
|
||||
/>
|
||||
</div>
|
||||
<div class="q-pa-sm row items-center">
|
||||
<q-input
|
||||
v-model="newMessage"
|
||||
outlined
|
||||
dense
|
||||
placeholder="Type a message..."
|
||||
class="col"
|
||||
@keyup.enter="sendMessage"
|
||||
autogrow
|
||||
/>
|
||||
<q-btn
|
||||
round
|
||||
dense
|
||||
flat
|
||||
icon="send"
|
||||
color="primary"
|
||||
class="q-ml-sm"
|
||||
@click="sendMessage"
|
||||
:disable="!newMessage.trim()"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
|
@ -54,14 +65,14 @@ import { QScrollArea, QChatMessage, QSpinnerDots } from 'quasar'; // Import QSpi
|
|||
import { marked } from 'marked'; // Import marked
|
||||
|
||||
const props = defineProps({
|
||||
messages: {
|
||||
type: Array,
|
||||
required: true,
|
||||
default: () => [],
|
||||
// Example message structure:
|
||||
// { sender: 'Bot', content: 'Hello!', loading: false }
|
||||
// { sender: 'You', content: 'Thinking...', loading: true }
|
||||
},
|
||||
messages: {
|
||||
type: Array,
|
||||
required: true,
|
||||
'default': () => [],
|
||||
// Example message structure:
|
||||
// { sender: 'Bot', content: 'Hello!', loading: false }
|
||||
// { sender: 'You', content: 'Thinking...', loading: true }
|
||||
},
|
||||
});
|
||||
|
||||
const emit = defineEmits(['send-message']);
|
||||
|
@ -69,30 +80,37 @@ const emit = defineEmits(['send-message']);
|
|||
const newMessage = ref('');
|
||||
const scrollAreaRef = ref(null);
|
||||
|
||||
const scrollToBottom = () => {
|
||||
if (scrollAreaRef.value) {
|
||||
const scrollTarget = scrollAreaRef.value.getScrollTarget();
|
||||
const duration = 300; // Optional: animation duration
|
||||
// Use getScrollTarget().scrollHeight for accurate height
|
||||
scrollAreaRef.value.setScrollPosition('vertical', scrollTarget.scrollHeight, duration);
|
||||
}
|
||||
const scrollToBottom = () =>
|
||||
{
|
||||
if (scrollAreaRef.value)
|
||||
{
|
||||
const scrollTarget = scrollAreaRef.value.getScrollTarget();
|
||||
const duration = 300; // Optional: animation duration
|
||||
// Use getScrollTarget().scrollHeight for accurate height
|
||||
scrollAreaRef.value.setScrollPosition('vertical', scrollTarget.scrollHeight, duration);
|
||||
}
|
||||
};
|
||||
|
||||
const sendMessage = () => {
|
||||
const trimmedMessage = newMessage.value.trim();
|
||||
if (trimmedMessage) {
|
||||
emit('send-message', trimmedMessage);
|
||||
newMessage.value = '';
|
||||
// Ensure the scroll happens after the message is potentially added to the list
|
||||
nextTick(() => {
|
||||
scrollToBottom();
|
||||
});
|
||||
}
|
||||
const sendMessage = () =>
|
||||
{
|
||||
const trimmedMessage = newMessage.value.trim();
|
||||
if (trimmedMessage)
|
||||
{
|
||||
emit('send-message', trimmedMessage);
|
||||
newMessage.value = '';
|
||||
// Ensure the scroll happens after the message is potentially added to the list
|
||||
nextTick(() =>
|
||||
{
|
||||
scrollToBottom();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const parseMarkdown = (content) => {
|
||||
const parseMarkdown = (content) =>
|
||||
{
|
||||
// Basic check to prevent errors if content is not a string
|
||||
if (typeof content !== 'string') {
|
||||
if (typeof content !== 'string')
|
||||
{
|
||||
return '';
|
||||
}
|
||||
// Configure marked options if needed (e.g., sanitization)
|
||||
|
@ -101,10 +119,12 @@ const parseMarkdown = (content) => {
|
|||
};
|
||||
|
||||
// Scroll to bottom when messages change or component mounts
|
||||
watch(() => props.messages, () => {
|
||||
nextTick(() => {
|
||||
scrollToBottom();
|
||||
});
|
||||
watch(() => props.messages, () =>
|
||||
{
|
||||
nextTick(() =>
|
||||
{
|
||||
scrollToBottom();
|
||||
});
|
||||
}, { deep: true, immediate: true });
|
||||
|
||||
</script>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue