WebAgent/src/components/ChatBubble.vue

57 lines
2.0 KiB
Vue
Raw Normal View History

<script setup lang="ts">
import type { ChatBubbleProps } from '@/types/chat'
const props = defineProps<ChatBubbleProps>()
const messageClasses = computed(() => {
const base = 'rounded-2xl p-3 max-w-80'
const sender = props.message.sender === 'user'
? 'bg-blue-100 dark:bg-blue-900 ml-auto text-right'
: 'bg-gray-100 dark:bg-gray-800 mr-auto text-left'
return `${base} ${sender}`
})
const formattedTime = computed(() => {
if (!props.message.timestamp) return ''
const date = typeof props.message.timestamp === 'string'
? new Date(props.message.timestamp)
: props.message.timestamp
return date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })
})
</script>
<template>
<div class="flex items-end gap-2 mb-4" :class="{ 'flex-row-reverse': message.sender === 'user' }">
<!-- Avatar -->
<van-image
v-if="avatar"
:src="avatar"
class="w-8 h-8 rounded-full flex-shrink-0"
round
/>
<div v-else class="w-8 h-8 rounded-full flex-shrink-0 flex items-center justify-center"
:class="message.sender === 'user' ? 'bg-blue-100 dark:bg-blue-900' : 'bg-gray-100 dark:bg-gray-800'">
<van-icon :name="message.sender === 'user' ? 'user-circle-o' : 'robot-o'" />
</div>
<!-- Message bubble -->
<div class="flex flex-col" :class="{ 'items-end': message.sender === 'user', 'items-start': message.sender === 'ai' }">
<div :class="messageClasses">
<p class="text-sm">{{ message.content }}</p>
<!-- Status indicator -->
<div v-if="message.status === 'sending'" class="mt-1">
<van-icon name="clock-o" class="animate-pulse" />
</div>
<div v-else-if="message.status === 'error'" class="mt-1 text-red-500">
<van-icon name="warning-o" />
</div>
</div>
<!-- Timestamp -->
<div v-if="showTimestamp && formattedTime" class="mt-1 text-xs text-gray-500 dark:text-gray-400">
{{ formattedTime }}
</div>
</div>
</div>
</template>