57 lines
2.0 KiB
Vue
57 lines
2.0 KiB
Vue
|
|
<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>
|