44 lines
1.3 KiB
Vue
44 lines
1.3 KiB
Vue
<template>
|
|||
|
|
<div
|
||
|
|
class="flex animate-fade-up"
|
||
|
|
:class="isUser ? 'justify-end' : 'justify-start'"
|
||
|
|
:style="{ animationDelay: `${index * 30}ms` }"
|
||
|
|
>
|
||
|
|
<div
|
||
|
|
class="max-w-[85%] md:max-w-[70%] rounded-2xl px-4 py-3 transition-all duration-200"
|
||
|
|
:class="bubbleClasses"
|
||
|
|
>
|
||
|
|
<p class="text-sm leading-relaxed whitespace-pre-wrap break-words">{{ message.content }}</p>
|
||
|
|
<div class="flex items-center gap-2 mt-1.5">
|
||
|
|
<span class="text-[10px] opacity-40 select-none">{{ formattedTime }}</span>
|
||
|
|
<span v-if="isUser && message.status" class="text-[10px] opacity-30">
|
||
|
|
{{ message.status === 'sent' ? '✓' : message.status === 'delivered' ? '✓✓' : '' }}
|
||
|
|
</span>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</template>
|
||
|
|
|
||
|
|
<script setup lang="ts">
|
||
|
|
import { computed } from 'vue'
|
||
|
|
import type { Message } from '@aiui/core/types/message'
|
||
|
|
|
||
|
|
const props = defineProps<{
|
||
|
|
message: Message
|
||
|
|
index: number
|
||
|
|
}>()
|
||
|
|
|
||
|
|
const isUser = computed(() => props.message.role === 'user')
|
||
|
|
|
||
|
|
const bubbleClasses = computed(() =>
|
||
|
|
isUser.value
|
||
|
|
? 'glass-strong text-white rounded-br-md'
|
||
|
|
: 'glass-dark text-gray-100 rounded-bl-md'
|
||
|
|
)
|
||
|
|
|
||
|
|
const formattedTime = computed(() => {
|
||
|
|
const d = new Date(props.message.timestamp)
|
||
|
|
return d.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })
|
||
|
|
})
|
||
|
|
</script>
|