# 对话消息元信息

## 使用方法

`ChatMessageMetadata` 放在消息下面，或者放进最后一条气泡的元信息插槽，用来显示时间、页脚内容和送达状态。这三样都是可选的。传空字符串这种「什么都不渲染」的值，不会多出一个分隔点；插槽里传数字 0 会照常显示。页脚里放什么由调用方决定，组件不接管。

`timestamp`、`footer`、`status` 三样都没有时，整行什么都不渲染。中间的小圆点只挨着真正有内容的那一段出现，所以两段是「2:30 PM · 已读」，三段是「2:30 PM · GPT-4o · 已读」。

```vue
<script setup lang="ts">
import { ChatMessageMetadata } from '@astryx-vue/core/Chat'
</script>

<template>
  <ChatMessageMetadata status="read" timestamp="2:30 PM" />
</template>
```

### 结构

- **元信息行**: 一行跟着发送者走的说明文字，装着所有可见的元信息。
- **时间**: 调用方给的时间内容，排在最前面。
- **页脚**: 时间和状态之间的信息或操作，内容由调用方给。
- **状态**: 传了状态时显示的本地化送达图标和文字。

## 建议

| 建议 | 做法 |
| --- | --- |
| 推荐 | 消息用了气泡时，元信息放进最后一条气泡的元信息插槽，它就会跟气泡内容走。 |
| 推荐 | 时间和页脚分开传。值是「什么都不渲染」的类型时，分隔点会跟着省掉。插槽内容原样使用，组件不改。 |
| 避免 | 页脚里放按钮，却不给可读名字和交互行为。这些控件不归元信息这一行管。 |
| 避免 | 同一份元信息既放在气泡上，又放在外层消息上。 |

## 示例

常见的用法和不同的状态。

### 页脚操作

助手消息的页脚放一排操作：复制、重试、点赞、点踩，再加模型名。适合需要反馈或小工具的 AI 回复。

```vue
<script setup lang="ts">
import { ChatMessage, ChatMessageBubble, ChatMessageList, ChatMessageMetadata } from '@astryx-vue/core/Chat'
import { IconButton } from '@astryx-vue/core/IconButton'
</script>

<template>
  <ChatMessageList>
    <ChatMessage sender="user">
      <ChatMessageBubble>
        {{ 'Summarize the Q1 revenue report.' }}
        <template #metadata>
          <ChatMessageMetadata status="read" timestamp="9:41 AM" />
        </template>
      </ChatMessageBubble>
    </ChatMessage>
    <ChatMessage sender="assistant">
      <ChatMessageBubble variant="ghost">
        {{ 'Q1 revenue reached $2.4B, up 18% year-over-year. Enterprise subscriptions drove 62% of the growth, while ad revenue held steady at $890M.' }}
        <template #metadata>
          <ChatMessageMetadata timestamp="9:42 AM">
            <template #footer>
              <span class="chat-preview__actions">
                <IconButton label="Copy" variant="ghost" size="sm">
                  <span class="i-carbon-copy" />
                </IconButton>
                <IconButton label="Retry" variant="ghost" size="sm">
                  <span class="i-carbon-renew" />
                </IconButton>
                <IconButton label="Thumbs up" variant="ghost" size="sm">
                  <span class="i-carbon-thumbs-up" />
                </IconButton>
                <IconButton label="Thumbs down" variant="ghost" size="sm">
                  <span class="i-carbon-thumbs-down" />
                </IconButton>
                <span>GPT-4o</span>
              </span>
            </template>
          </ChatMessageMetadata>
        </template>
      </ChatMessageBubble>
    </ChatMessage>
  </ChatMessageList>
</template>
```

### 送达状态

五种送达状态全放一遍（发送中、已发送、已送达、已读、失败），每条都带时间。用来显示投递进度，或者把失败摆出来。

```vue
<script setup lang="ts">
import type { ChatMessageStatus } from '@astryx-vue/core/Chat'
import { ChatMessage, ChatMessageBubble, ChatMessageList, ChatMessageMetadata } from '@astryx-vue/core/Chat'

const rows: { status: ChatMessageStatus, text: string }[] = [
  { status: 'sending', text: 'Deploying the update now…' },
  { status: 'sent', text: 'Config pushed to staging.' },
  { status: 'delivered', text: 'Verified on the staging cluster.' },
  { status: 'read', text: 'Looks good — promoting to prod.' },
  { status: 'error', text: 'Rollback triggered, checking logs.' },
]
</script>

<template>
  <ChatMessageList>
    <ChatMessage v-for="row in rows" :key="row.status" sender="user">
      <ChatMessageBubble>
        {{ row.text }}
        <template #metadata>
          <ChatMessageMetadata :status="row.status" timestamp="10:15 AM" />
        </template>
      </ChatMessageBubble>
    </ChatMessage>
  </ChatMessageList>
</template>
```

### 时间

用户和助手消息都只显示时间。可以是绝对时间，也可以是「5 个月前」这种相对说法。

```vue
<script setup lang="ts">
import { ChatMessage, ChatMessageBubble, ChatMessageList, ChatMessageMetadata } from '@astryx-vue/core/Chat'
</script>

<template>
  <ChatMessageList>
    <ChatMessage sender="user">
      <ChatMessageBubble>
        {{ 'Thanks — any blockers I should know about?' }}
        <template #metadata>
          <ChatMessageMetadata timestamp="2:30 PM" />
        </template>
      </ChatMessageBubble>
    </ChatMessage>
    <ChatMessage sender="assistant">
      <ChatMessageBubble variant="ghost">
        {{ 'Relative timestamps work too — helpful for older messages where the exact time matters less than recency.' }}
        <template #metadata>
          <ChatMessageMetadata timestamp="5 months ago" />
        </template>
      </ChatMessageBubble>
    </ChatMessage>
  </ChatMessageList>
</template>
```

## 属性

| 属性 | 类型 | 默认值 | 说明 |
| --- | --- | --- | --- |
| `timestamp` | `string` | — | 时间，或者别的短文本。排在这一行的最前面。 |
| `footer` | `string` | — | 时间和状态之间的次要文字，例如模型名。 |
| `status` | `'sending' \| 'sent' \| 'delivered' \| 'read' \| 'error'` | — | 送达状态，会显示本地化的图标和文字。`timestamp`、`footer`、`status` 三样都没有时，整行不渲染。 |

## 插槽

- `timestamp`：替代 `timestamp` 属性。想把纯文本换成 `Timestamp` 组件时用它。
- `footer`：替代 `footer` 属性。放复制、重试、表情这类按钮用它；每个按钮都要有自己的可读名字。
