Initial commit
This commit is contained in:
107
resources/js/pages/apps/components/MessageItem.vue
Normal file
107
resources/js/pages/apps/components/MessageItem.vue
Normal file
@@ -0,0 +1,107 @@
|
||||
<script setup>
|
||||
import { computed } from 'vue';
|
||||
import { useTheme } from 'vuetify';
|
||||
import { themes } from '@/plugins/vuetify/theme';
|
||||
|
||||
const props = defineProps({
|
||||
message: Object,
|
||||
activeModelColor: String,
|
||||
activeModelBgColor: String,
|
||||
models: Array,
|
||||
selectedModelIdentifier: String,
|
||||
});
|
||||
|
||||
const getFileIcon = (fileType) => {
|
||||
if (fileType.startsWith('image/')) return 'tabler-photo';
|
||||
if (fileType.includes('pdf')) return 'tabler-file-type-pdf';
|
||||
if (fileType.includes('word')) return 'tabler-file-type-doc';
|
||||
if (fileType.includes('text')) return 'tabler-file-text';
|
||||
return 'tabler-file';
|
||||
};
|
||||
|
||||
const getFileSize = (size) => {
|
||||
if (size < 1024) return `${size} B`;
|
||||
if (size < 1024 * 1024) return `${(size / 1024).toFixed(1)} KB`;
|
||||
return `${(size / (1024 * 1024)).toFixed(1)} MB`;
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<li
|
||||
class="my-3 d-flex"
|
||||
:class="[
|
||||
message.sender === 'user' ? 'justify-end' : 'justify-start',
|
||||
message.isAnimating ? 'is-animating' : '',
|
||||
message.sender === 'user' ? 'user-message' : 'bot-message',
|
||||
message.isSystemMessage ? 'system-message' : '',
|
||||
]"
|
||||
>
|
||||
<template v-if="message.sender !== 'user'">
|
||||
<VAvatar
|
||||
size="32"
|
||||
:color="message.isSystemMessage ? 'grey' : activeModelColor"
|
||||
variant="tonal"
|
||||
class="me-2 message-avatar"
|
||||
>
|
||||
<VIcon
|
||||
:icon="message.isSystemMessage ? 'tabler-info-circle' : 'tabler-robot'"
|
||||
/>
|
||||
</VAvatar>
|
||||
</template>
|
||||
|
||||
<div
|
||||
class="pa-3 rounded-lg message-bubble"
|
||||
:class="[
|
||||
message.sender === 'user'
|
||||
? 'bg-primary text-white'
|
||||
: message.isSystemMessage
|
||||
? 'bg-grey-lighten-3 text-grey-darken-3'
|
||||
: `bg-${activeModelBgColor} text-white`,
|
||||
message.isAnimating ? 'animate-message' : '',
|
||||
]"
|
||||
>
|
||||
<div v-if="!message.form && !message.multiForm && !message.type">
|
||||
{{ message.text }}
|
||||
</div>
|
||||
|
||||
<div v-if="message.isAttachment && message.files" class="attachment-preview mt-2">
|
||||
<div
|
||||
v-for="(file, fileIndex) in message.files"
|
||||
:key="fileIndex"
|
||||
class="d-flex align-center mb-1"
|
||||
>
|
||||
<VIcon :icon="getFileIcon(file.type)" size="small" class="me-1"></VIcon>
|
||||
<span class="text-caption">{{ file.name }} ({{ getFileSize(file.size) }})</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<template v-if="message.sender === 'user'">
|
||||
<VAvatar size="32" color="grey" variant="tonal" class="ms-2 message-avatar">
|
||||
<VIcon icon="tabler-user" />
|
||||
</VAvatar>
|
||||
</template>
|
||||
</li>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.message-avatar {
|
||||
opacity: 0;
|
||||
animation: fade-in 0.3s ease forwards;
|
||||
animation-delay: 0.15s;
|
||||
}
|
||||
|
||||
@keyframes fade-in {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.attachment-preview {
|
||||
font-size: 0.85rem;
|
||||
opacity: 0.9;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user