聊天气泡状态(发送中/失败/已读)

气泡状态由 MessageBubble 的 status、showStatus、showReadCount、readCount、totalMembers 决定;文本由 messageStatusText 统一生成。状态流转(pending → sent/failed、已读回执)由 ChatView 监听 SDK 事件后驱动,宿主只需处理 resend/tapReadDetail 等交互。

概念​

状态气泡显示触发/来源
sending“发送中”本地乐观消息,等待 send_ack
sent无额外文案(群聊可显示已读 n/m)收到 send_ack
failed“发送失败”,点击重发超时/网络失败/服务端错误
read(群聊 n/m)messageStatusText(status,readCount,totalMembers)已读回执事件
  • 单聊 conversationType=1 不显示 n/m;群聊显示 已读 n/m。
  • 点击“已读 n/m”触发 tapReadDetail,宿主打开已读成员列表。
  • 点击失败状态触发 resend,宿主应重发同内容并更新原气泡。
  • MessageStatusIndicator 可单独用于自定义列表/通知栏。

前置条件​

  • 已按 快速开始 完成 init 与 connect,页面能收发消息。
  • 使用 @ni-paas/im-web/imkit(浏览器原生 ESM,无第三方依赖);自定义代码只调用 IMKit/IMLib 公开入口。
  • 已引入默认样式:调用 ensureStyles(),或自行加载 IMKit 样式表。
  • 自托管版无“UI 主题商店/付费皮肤”;所有自定义均为本地代码(不适用项)。

步骤​

  1. 乐观插入 pending 消息

    发送时先用 clientMsgId 插入 status="sending" 的气泡;ChatView.appendMessage 会自动处理 pending。

  2. 收到 ACK 更新状态

    SDK 收到 send_ack 后以 messageId 替换 pending;失败则标 failed 并 emit sendFailed。

  3. 接线重发

    监听气泡 resend 或 ChatView sendFailed,重发后把状态改回 sending。

  4. 接线已读

    群聊设置 showReadCount:true 与 totalMembers;收到 read_receipt 后更新 readCount;tapReadDetail 打开明细。

参数表​

Props / 事件 / 函数类型说明
statussending|sent|failed气泡状态
showStatusboolean是否显示发送状态
showReadCountboolean群聊是否显示 n/m
readCount / totalMembersnumber已读人数/群成员数
conversationTypenumber1 单聊不显示 n/m
messageStatusText(status,read,total)函数统一文案
resend / tapReadDetail事件重发 / 已读明细

示例​

自定义消息列表里的状态气泡​

JavaScript
import { MessageBubble, messageStatusText, ensureStyles } from '@ni-paas/im-web/imkit';

ensureStyles();

function renderMessage(message, { isMine, readCount, totalMembers }) {
  const bubble = new MessageBubble({
    message,
    isMine,
    status: message.status || 'sent',
    showStatus: isMine,
    showReadCount: isMine && message.conversationType !== 1,
    readCount,
    totalMembers,
    conversationType: message.conversationType,
  });

  bubble.on('resend', ({ clientMsgId, message: current }) => {
    current.status = 'sending';
    bubble.update({ message: current, status: 'sending' });
    client.sendMessage({
      conversationType: current.conversationType,
      targetId: current.targetId,
      content: current.content,
      clientMsgId,
    });
  });

  bubble.on('tapReadDetail', ({ messageId }) => openReadList(messageId));
  return bubble;
}

ChatView 的 pending / sendFailed / readReceipt​

JavaScript
const chat = new ChatView({
  conversationType: 2,
  targetId: 'g_demo',
  currentUserId: 'alice',
  showReadCount: true,
});

chat.on('pending', ({ message }) => {
  // 乐观气泡已插入,可在这里做“发送中”动画
  console.log('pending', message.clientMsgId);
});

chat.on('sendFailed', ({ message, result }) => {
  console.warn('发送失败', result && result.code, result && result.msg, message.clientMsgId);
  // 气泡已是 failed;用户点击会触发 resend
});

chat.on('readReceipt', ({ messageIds, result }) => {
  if (result && result.code === 0) console.log('已读回执已提交', messageIds.length);
});

// 群聊 n/m 的总人数由 ChatView 在收到回执/刷新时通过
// client.getMessageReadCount(messageId) 返回的 totalMembers 自动维护;
// 如需完全自定义,使用上面的 MessageBubble 示例并自行传入 totalMembers。

常见问题​

发送中/失败文案能改吗?​

内置文案固定为“发送中/发送失败”;需要自定义请关掉 showStatus,用自己的节点渲染,并复用 messageStatusText 的规则。

失败后重发为什么还是失败?​

检查连接是否在线、服务是否开通、是否被禁言;result.code 会给出 1009/1010/1021 等具体原因。

单聊能显示“已读”吗?​

气泡默认不显示单聊 n/m;可用 messageStatusText("read") 在自定义节点中展示“已读/未读”。

已读人数不更新?​

确认群成员数 totalMembers 已传入,且收到 read_receipt 后更新了 readCount。

相关链接​