HarmonyOS IMKit 组件 API
本页汇总 10 个 IMKit 组件的 props / events / behaviors 与各端公开符号,便于按组件查阅;每一节都可从侧边栏「组件」进入独立页面。
契约预留
本平台为 reserved:绑定符号来自已冻结契约。
概要表
| 组件 | 职责 | Props | Events | 数据源 | 锚点 |
|---|---|---|---|---|---|
ConversationListView | 会话列表 | 4 | 3 | IMLib.getConversationList / CONVERSATION 事件增量更新 | 查看 |
ChatView | 会话详情(消息流 + 输入区) | 8 | 12 | — | 查看 |
MessageBubble | 消息气泡(按内容类型渲染) | 9 | 8 | — | 查看 |
MessageInput | 输入区 | 5 | 7 | — | 查看 |
Avatar | 头像 | 4 | 0 | — | 查看 |
UnreadBadge | 未读/提及角标 | 3 | 0 | — | 查看 |
TimeSeparator | 时间分隔/格式化 | 2 | 0 | — | 查看 |
MessageStatusIndicator | 发送状态 | 3 | 0 | — | 查看 |
Theme | 主题令牌 | 2 | 0 | — | 查看 |
IMKitFacade | 组件门面/挂载入口 | 1 | 2 | — | 查看 |
ConversationListView
会话列表
Props
| 属性 | 类型 | 必填 | 说明 |
|---|---|---|---|
conversations | Conversation[] | 是 | 会话数组(来自 IMLib.getConversationList / CONVERSATION 事件) |
activeTargetId | string | 否 | 当前高亮会话的 targetId |
theme | Theme | 否 | 主题对象(mode + 9 个颜色令牌) |
options | {showPinned:bool,showUnread:bool,showDraft:bool,showMention:bool} | 否 | 显示选项(置顶 / 未读 / 草稿 / @ 提及):{ showPinned:bool, showUnread:bool, showDraft:bool, showMention:bool } |
Events
| 事件 | 参数 | 说明 |
|---|---|---|
select | conversation | 点击会话,宿主负责跳转到 ChatView |
longpress | conversation | 长按会话,宿主展示操作菜单(置顶 / 免打扰 / 删除) |
refresh | — | 下拉刷新,宿主重新拉取会话列表 |
Behaviors
- 排序:置顶优先,其余按 updatedAt 倒序
- 未读角标:unreadCount>0 显示;>99 显示 99+;mention count 独立角标
- 免打扰(notificationLevel=2)显示静音图标且不显示红点(保留数字可选)
- 空闲(无会话)显示空态;加载中显示骨架
- 点击会话触发 select,宿主负责跳转 ChatView
各端公开符号
| 平台 | 符号 / 签名 |
|---|---|
| Android | io.nipaas.imkit.conversationlist.ConversationListFragment |
| Web | IMKit.mount(container, 'ConversationListView', props) |
| Electron | ConversationListView(props: {conversations: Conversation[]; activeTargetId?: string; theme?: Theme; options?: … |
| macOS | 宿主自渲染(SDK 不导出该组件) |
| Flutter | ConversationListView(...) |
| Native (C ABI) | im_kit_conversation_model_new(im_client_t*) |
| iOS | IMPConversationListView |
| HarmonyOS(预留) | struct ConversationListView |
ChatView
会话详情(消息流 + 输入区)
Props
| 属性 | 类型 | 必填 | 说明 |
|---|---|---|---|
conversationType | ConversationType | 是 | 会话类型枚举(ConversationType) |
targetId | string | 是 | 目标会话 ID(单聊为 userId,群聊为 groupId) |
messages | Message[] | 是 | 消息数组(来自 IMLib getHistoryMessages / MESSAGES 事件) |
currentUserId | string | 是 | 当前登录用户 ID(用于区分气泡方向与已读) |
hasMore | bool | 是 | 是否还有更早历史(决定是否展示「加载更多」) |
showReadCount | bool | 否 | 是否显示已读人数(群聊 n/m) |
onReactionClick | (reactionId:string)=>void | 否 | — |
onReactionLongPress | (message:Message)=>void | 否 | — |
Events
| 事件 | 参数 | 说明 |
|---|---|---|
loadMore | — | 加载更多历史消息 |
sendText | text,extras? | 发送文本(可选带 @ 提及 / 引用) |
sendImage | image | 发送图片 |
sendFile | file | 发送文件 |
sendVoice | voice | 发送语音 |
sendLocation | location | 发送位置 |
recall | messageId | 撤回消息 |
resend | clientMsgId | 重发发送失败的消息 |
typing | bool | 输入状态变化(true / false) |
readReceipt | messageIds | 上报已读回执 |
reaction_click | reactionId | 宿主回调(参数见 IDL 事件定义) |
reaction_longpress | message | 宿主回调(参数见 IDL 事件定义) |
Behaviors
- 倒序渲染(最新在底部);新消息到达自动滚底(用户上翻时给出“有新消息”提示)
- 按 messageId 去重;本地先显示 pending 气泡,ack 后替换为服务端消息
- 时间分隔:同一会话间隔 >5 分钟显示时间条
- 撤回消息渲染为占位文案“消息已撤回”,不显示原文
- 引用消息渲染引用块;@提及在文本中高亮
- 已读回执:发送者可见已读人数/状态(群聊按 readCounts/totalMembers)
- 翻页加载历史,beforeSeq 游标,hasMore=false 时显示“没有更多”
- 向每个消息气泡透传 message.reactions / message.expansion,并转发 onReactionClick / onReactionLongPress(setMessages / appendMessages / 宿主变更消息后始终取最新值)
各端公开符号
| 平台 | 符号 / 签名 |
|---|---|
| Android | io.nipaas.imkit.conversation.ChatFragment |
| Web | IMKit.mount(container, 'ChatView', props) |
| Electron | ChatView(props: {conversationType: ConversationType; targetId: string; messages: Message[]; currentUserId: str… |
| macOS | 宿主自渲染(SDK 不导出该组件) |
| Flutter | ChatView(...) |
| Native (C ABI) | im_kit_message_model_new(im_client_t*, int conversation_type, const char* target_id) |
| iOS | IMPChatView |
| HarmonyOS(预留) | struct ChatView |
MessageBubble
消息气泡(按内容类型渲染)
Props
| 属性 | 类型 | 必填 | 说明 |
|---|---|---|---|
message | Message | 是 | 消息实体(IDL Message) |
isMine | bool | 是 | 是否为当前用户发送 |
showStatus | bool | 否 | 是否显示发送状态 |
showReadCount | bool | 否 | 是否显示已读人数(群聊 n/m) |
reactions | MessageReactionSummary[] | 否 | — |
expansion | Record<string,string> | 否 | — |
onReactionClick | (reactionId:string)=>void | 否 | — |
onReactionLongPress | (message:Message)=>void | 否 | — |
streaming | bool | 否 | — |
Events
| 事件 | 参数 | 说明 |
|---|---|---|
longpress | message | 长按会话,宿主展示操作菜单(置顶 / 免打扰 / 删除) |
reaction_click | reactionId | 宿主回调(参数见 IDL 事件定义) |
reaction_longpress | message | 宿主回调(参数见 IDL 事件定义) |
tapImage | url | 点击图片消息 |
tapFile | url,name | 点击文件消息 |
tapVoice | url,duration | 点击语音消息 |
tapLocation | latitude,longitude | 点击位置消息 |
stream_chunk | streamId, text, complete | 宿主回调(参数见 IDL 事件定义) |
Behaviors
- 回应 chip 按 reactionTime 升序排列(同值保持输入顺序)
- hasCurrentUserReacted=true 的 chip 高亮为 active 态(主题色描边 + aria-pressed=true)
- chip 计数 >99 显示 99+;计数<=0 或 reactionId 空的 chip 不渲染
- 消息扩展徽标按 key:value 渲染,最多 3 对,超出部分显示 +N(N=未展示对数)
- 气泡长按(pointerdown >=500ms)或右键触发 reaction_longpress(message) / onReactionLongPress,由宿主打开回应选择器
- streaming=true 时 content.type=stream 渲染增量文本 + 生成中光标;complete 后收敛为普通文本气泡(streaming:false 可关闭)
各端公开符号
| 平台 | 符号 / 签名 |
|---|---|
| Android | io.nipaas.imkit.conversation.provider.MessageItemProvider |
| Web | IMKit.mount(container, 'MessageBubble', props) |
| Electron | MessageBubble(props: {message: Message; isMine: boolean; showStatus?: boolean; showReadCount?: boolean; onLong… |
| macOS | 宿主自渲染(SDK 不导出该组件) |
| Flutter | MessageBubble(...) |
| Native (C ABI) | im_kit_message_render_descriptor(const char* message_json, char** out_json) |
| iOS | IMPMessageBubble |
| HarmonyOS(预留) | struct MessageBubble |
MessageInput
输入区
Props
| 属性 | 类型 | 必填 | 说明 |
|---|---|---|---|
draft | string | 是 | 草稿文本 |
disabled | bool | 是 | 是否禁用输入 |
muted | bool | 是 | 是否被禁言(禁言时禁用发送并提示) |
mentionCandidates | UserProfile[] | 否 | @ 候选成员列表 |
maxLength | int | 否 | 最大输入长度(默认 5000) |
Events
| 事件 | 参数 | 说明 |
|---|---|---|
send | text,extras? | 输入区发送文本 |
typing | bool | 输入状态变化(true / false) |
pickImage | — | 选择图片 |
pickFile | — | 选择文件 |
startRecord | — | 宿主回调(参数见 IDL 事件定义) |
pickLocation | — | 选择位置 |
draftChanged | draft | 草稿变化 |
Behaviors
- 输入时 500ms 防抖触发 typing(true),3s 无输入触发 typing(false)
- 被禁言(muted=true)禁用发送并提示;仍可查看
- 草稿自动保存(IMLib.saveTextMessageDraft),发送成功后清空
- 群聊支持 @ 选择器(全员/指定成员),生成 mentionedInfo
各端公开符号
| 平台 | 符号 / 签名 |
|---|---|
| Android | io.nipaas.imkit.conversation.input.MessageInputBar |
| Web | IMKit.mount(container, 'MessageInput', props) |
| Electron | MessageInput(props: {draft: string; disabled: boolean; muted: boolean; mentionCandidates?: UserProfile[]; maxL… |
| macOS | 宿主自渲染(SDK 不导出该组件) |
| Flutter | MessageInput(...) |
| Native (C ABI) | im_kit_message_model_add_pending |
| iOS | IMPMessageInput |
| HarmonyOS(预留) | struct MessageInput |
Avatar
头像
Props
| 属性 | 类型 | 必填 | 说明 |
|---|---|---|---|
userId | string | 是 | 用户 ID(用于生成首字与稳定背景色) |
name | string | 否 | 显示名称(可选,缺省取 userId) |
url | string | 否 | 头像 URL(加载失败回退首字) |
size | int | 否 | 头像尺寸(像素) |
Events
未声明事件。
Behaviors
- url 缺失或加载失败时显示姓名首字/末字,背景色由 userId 哈希稳定生成
各端公开符号
| 平台 | 符号 / 签名 |
|---|---|
| Android | io.nipaas.imkit.widget.AvatarView |
| Web | IMKit.mount(container, 'Avatar', props) |
| Electron | Avatar(props: {userId: string; name?: string; url?: string; size?: number}) |
| macOS | 宿主自渲染(SDK 不导出该组件) |
| Flutter | AvatarWidget(...) |
| Native (C ABI) | im_kit_avatar_initials(const char* user_id, const char* name, char* out, size_t out_len) |
| iOS | IMPAvatar |
| HarmonyOS(预留) | struct Avatar |
UnreadBadge
未读/提及角标
Props
| 属性 | 类型 | 必填 | 说明 |
|---|---|---|---|
count | int | 是 | 未读数量(0 隐藏,>99 显示 99+) |
mentionedCount | int | 否 | @ 提及数量(独立角标) |
muted | bool | 否 | 是否被禁言(禁言时禁用发送并提示) |
Events
未声明事件。
Behaviors
- 0 隐藏;>99 显示 99+;muted 用灰点;提及用 @ 角标
各端公开符号
| 平台 | 符号 / 签名 |
|---|---|
| Android | io.nipaas.imkit.widget.UnreadBadgeView |
| Web | IMKit.mount(container, 'UnreadBadge', props) |
| Electron | UnreadBadge(props: {count: number; mentionedCount?: number; muted?: boolean}) |
| macOS | 宿主自渲染(SDK 不导出该组件) |
| Flutter | UnreadBadge(...) |
| Native (C ABI) | im_kit_unread_badge_text(int count, char* out, size_t out_len) |
| iOS | IMPUnreadBadge |
| HarmonyOS(预留) | struct UnreadBadge |
TimeSeparator
时间分隔/格式化
Props
| 属性 | 类型 | 必填 | 说明 |
|---|---|---|---|
timestamp | int64 | 是 | 时间戳(epoch 毫秒) |
now | int64 | 否 | 参照时间(便于测试注入;默认当前时间) |
Events
未声明事件。
Behaviors
- 当天 HH:mm;昨天“昨天 HH:mm”;7 天内“周X HH:mm”;更早 YYYY-MM-DD HH:mm
各端公开符号
| 平台 | 符号 / 签名 |
|---|---|
| Android | io.nipaas.imkit.widget.TimeSeparatorView |
| Web | IMKit.mount(container, 'TimeSeparator', props) |
| Electron | TimeSeparator(props: {timestamp: number; now?: number}) |
| macOS | 宿主自渲染(SDK 不导出该组件) |
| Flutter | TimeSeparator(...) |
| Native (C ABI) | im_kit_format_time(int64_t timestamp_ms, int64_t now_ms, char* out, size_t out_len) |
| iOS | IMPTimeSeparator |
| HarmonyOS(预留) | struct TimeSeparator |
MessageStatusIndicator
发送状态
Props
| 属性 | 类型 | 必填 | 说明 |
|---|---|---|---|
status | 'sending'|'sent'|'delivered'|'read'|'failed' | 是 | 发送状态:sending / sent / delivered / read / failed |
readCount | int | 否 | 已读人数 |
totalMembers | int | 否 | 群成员总数(n/m 分母) |
Events
未声明事件。
Behaviors
- sending 转圈;failed 显示重发;单聊显示已读/未读;群聊显示 n/m
各端公开符号
| 平台 | 符号 / 签名 |
|---|---|
| Android | io.nipaas.imkit.widget.MessageStatusView |
| Web | IMKit.mount(container, 'MessageStatusIndicator', props) |
| Electron | MessageStatusIndicator(props: {status: 'queued' | 'sending' | 'sent' | 'delivered' | 'read' | 'failed'; readCo… |
| macOS | 宿主自渲染(SDK 不导出该组件) |
| Flutter | MessageStatusIndicator(...) |
| Native (C ABI) | im_kit_message_status_text(const char* message_json, int read_count, int total_members, char* out, size_t out_… |
| iOS | IMPMessageStatusIndicator |
| HarmonyOS(预留) | struct MessageStatusIndicator |
Theme
主题令牌
Props
| 属性 | 类型 | 必填 | 说明 |
|---|---|---|---|
mode | 'light'|'dark' | 是 | light / dark |
colors | {primary,background,surface,text,textSecondary,bubbleMine,bubbleOther,danger,mention} | 是 | 主题颜色令牌集合:{ primary:, background:, surface:, text:, textSecondary:, bubbleMine:, bubbleOther:, danger:, mention: } |
Events
未声明事件。
Behaviors
- 默认跟随系统;宿主可覆盖令牌;暗色对比度满足可读性
各端公开符号
| 平台 | 符号 / 签名 |
|---|---|
| Android | io.nipaas.imkit.theme.IMKitTheme |
| Web | IMKit.mount(container, 'Theme', props) |
| Electron | Theme(props: {mode: 'light' | 'dark'; colors: {primary: string; background: string; surface: string; text: str… |
| macOS | 宿主自渲染(SDK 不导出该组件) |
| Flutter | ImkitTheme(...) |
| Native (C ABI) | im_kit_theme_load(const char* json, im_kit_theme_t** out) |
| iOS | IMPTheme |
| HarmonyOS(预留) | class Theme |
IMKitFacade
组件门面/挂载入口
Props
| 属性 | 类型 | 必填 | 说明 |
|---|---|---|---|
options | {container:any, appkey:string, serverUrl?:string, locale?:string, theme?:Theme, renderers?:map<string,function>} | 是 | 显示选项(置顶 / 未读 / 草稿 / @ 提及):{ container:any, appkey:string, serverUrl?:string, locale?:string, theme?:Theme, renderers?:map<string,function> } |
Events
| 事件 | 参数 | 说明 |
|---|---|---|
ready | — | 宿主回调(参数见 IDL 事件定义) |
error | err | 宿主回调(参数见 IDL 事件定义) |
Behaviors
- mount/update/destroy 生命周期幂等;同一容器重复 mount 复用实例;组件销毁释放监听
各端公开符号
| 平台 | 符号 / 签名 |
|---|---|
| Android | io.nipaas.imkit.IMKit |
| Web | IMKit.mount(container, 'IMKit', props) |
| Electron | IMKit.mount(container: HTMLElement, component: ComponentType, props: object): {update(props: object): void; de… |
| macOS | 宿主自渲染(SDK 不导出该组件) |
| Flutter | IMKit.start(...) |
| Native (C ABI) | im_kit_version |
| iOS | IMKitFacade |
| HarmonyOS(预留) | class IMKitFacade:options: IMKitOptions{container,appkey,serverUrl?,locale?,theme?,renderers?};方法 mount(contai… |