k2-im 0.1.19 → 0.1.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +36 -0
- package/dist/browser.js +1 -1
- package/dist/chat-kit-pinia.d.ts +349 -24
- package/dist/chat-kit-pinia.js +1 -1
- package/dist/chat-kit-vue.d.ts +92 -6
- package/dist/chat-kit-vue.js +1 -1
- package/dist/chat-kit.d.ts +429 -30
- package/dist/chat-kit.js +1 -1
- package/dist/chunk-2GZMQCIP.js +1 -0
- package/dist/chunk-4X7RCGEV.js +1 -0
- package/dist/chunk-5I7S6LWE.js +2 -0
- package/dist/chunk-A2BLOVZ5.js +2 -0
- package/dist/chunk-DN4H5C7G.js +2 -0
- package/dist/chunk-P4HOR4XO.js +1 -0
- package/dist/chunk-YAM4YHKF.js +7 -0
- package/dist/i18n.d.ts +140 -7
- package/dist/i18n.js +1 -1
- package/dist/index.d.ts +574 -38
- package/dist/index.js +1 -1
- package/dist/sdk.d.ts +377 -24
- package/dist/sdk.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-CD5SF7WI.js +0 -1
- package/dist/chunk-KLEMN4CG.js +0 -1
- package/dist/chunk-NBLASAT2.js +0 -2
- package/dist/chunk-NVF5RDHB.js +0 -2
- package/dist/chunk-ULJD6ZA3.js +0 -7
- package/dist/chunk-W2FKET4Z.js +0 -1
- package/dist/chunk-YPS6Y5ZY.js +0 -1
package/README.md
CHANGED
|
@@ -79,3 +79,39 @@ import { createImClient } from '@k2/im/sdk';
|
|
|
79
79
|
import { createImI18n } from '@k2/im/i18n';
|
|
80
80
|
import { createChatRuntime } from '@k2/im/chat-kit';
|
|
81
81
|
```
|
|
82
|
+
|
|
83
|
+
### Web Push 绑定
|
|
84
|
+
|
|
85
|
+
`client.push` 负责当前设备订阅上报、ACK 确认与连接恢复后的同步。浏览器授权、
|
|
86
|
+
`ServiceWorkerRegistration`、`PushManager`、系统通知展示和点击路由由宿主负责。
|
|
87
|
+
共享消息提醒规则可从 `chat-kit` 或已加载的 `chat-kit/pinia` 入口导入
|
|
88
|
+
`resolveMessageNotificationDecision`,输入事实由宿主提供。
|
|
89
|
+
|
|
90
|
+
```ts
|
|
91
|
+
const stop = client.push.subscribe((snapshot) => {
|
|
92
|
+
// 只有 synced 表示服务端确认,浏览器创建订阅不等于绑定成功。
|
|
93
|
+
renderPushStatus(snapshot)
|
|
94
|
+
})
|
|
95
|
+
client.push.setWebSubscription({ userId, subscription: subscription.toJSON() })
|
|
96
|
+
// 注销、关闭通知或切换账号:先停止上报,再解除浏览器订阅。
|
|
97
|
+
client.push.clear()
|
|
98
|
+
await subscription.unsubscribe()
|
|
99
|
+
stop()
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
绑定数据只在当前账号 runtime 的内存中保存,不持久化登录凭据或订阅密钥。
|
|
103
|
+
账号 logout 会销毁旧 push 对象,新账号需要重新提供浏览器真实订阅。
|
|
104
|
+
`clear()` 不代表服务端解绑,不能用它替代浏览器 `unsubscribe()`。
|
|
105
|
+
|
|
106
|
+
协议使用已有 `CM_PUSHTOKENSYNC` / `CM_PUSHTOKENSYNC_ACK`、Web Push 类型 20、
|
|
107
|
+
普通 token 类型 0。SDK 按后端回显的帧 MsgSeq 配对,只有正确账号和 `NON_ERR` 才视为绑定成功。
|
|
108
|
+
旧后端默认 0 回复进入 `unconfirmed`,其它错误码显示失败;超时或解析失败后等待正常重连,
|
|
109
|
+
不会为了推送主动重连。
|
|
110
|
+
|
|
111
|
+
目前未确认关闭页面时可用的后端 HTTP 续订及解绑合同。Worker 可以续订并通知打开的宿主,
|
|
112
|
+
没有页面时需等下次启动由 SDK 上报;这不等于已经实现关闭期间的可靠后台同步。
|
|
113
|
+
|
|
114
|
+
Web Push 绑定通过 `client.push` 同步浏览器订阅。`synced` 只表示收到账号与 MsgSeq 匹配的成功 ACK;
|
|
115
|
+
`unconfirmed` 表示旧后端已回复默认错误码,绑定结果不能确认,宿主可保留浏览器订阅并显示本机已授权、
|
|
116
|
+
服务端未确认。SDK 不把默认 0 当成功,也不因该旧回复自动反复上报相同订阅;正常重连会重新同步。
|
|
117
|
+
后端当前每账号只有一个 Web 槽,不保证多浏览器独立收推送,`clear()` 也不代表服务端解绑。
|
package/dist/browser.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export{A as createLazyBrowserApiProtocolClient}from'./chunk-
|
|
1
|
+
export{A as createLazyBrowserApiProtocolClient}from'./chunk-YAM4YHKF.js';import'./chunk-A2BLOVZ5.js';import'./chunk-WOT6VMZA.js';
|
package/dist/chat-kit-pinia.d.ts
CHANGED
|
@@ -43,7 +43,7 @@ interface ConversationDraft$1 {
|
|
|
43
43
|
updatedAt: number;
|
|
44
44
|
}
|
|
45
45
|
/** 消息内容类型。sticker=表情/贴图(BMessage contentType=7);call=单聊通话记录(contentType=10);transfer=转账(contentType=16);miniProgram=小程序分享卡(contentType=22);redPacket=红包卡(contentType=25);game=小游戏(contentType=27);未知 wire 正文统一归一为 unknown。 */
|
|
46
|
-
type MessageContentType = 'text' | 'system' | 'image' | 'video' | 'voice' | 'file' | 'sticker' | 'contact' | 'miniProgram' | 'game' | 'transfer' | 'call' | 'redPacket' | 'unknown';
|
|
46
|
+
type MessageContentType = 'text' | 'system' | 'image' | 'video' | 'voice' | 'file' | 'sticker' | 'contact' | 'miniProgram' | 'game' | 'transfer' | 'call' | 'redPacket' | 'mediaAlbum' | 'unknown';
|
|
47
47
|
/**
|
|
48
48
|
* 发送态(客户端态):消息从本地创建到服务端确认的生命周期。
|
|
49
49
|
* `uploading` 仅媒体消息使用:文件上传阶段(uploading→pending→sending→sent);
|
|
@@ -53,7 +53,7 @@ type MessageSendStatus = 'pending' | 'uploading' | 'sending' | 'sent' | 'failed'
|
|
|
53
53
|
/** 送达/已读态(服务端态):消息在对端的回执状态。 */
|
|
54
54
|
type MessageReceipt = 'unread' | 'delivered' | 'read';
|
|
55
55
|
/** 群系统提示事件类型(结构化语义;UI/i18n 层据此渲染文案,**不在 mapper 写死中文**)。 */
|
|
56
|
-
type ImSystemEventType = 'direct_contact_established' | 'direct_contact_required' | 'direct_message_refused' | 'group_info_changed' | 'group_activated' | 'group_member_joined' | 'group_member_invited' | 'group_member_left' | 'group_member_removed' | 'group_master_changed' | 'group_dismissed' | 'group_member_renamed' | 'group_message_pinned' | 'group_message_unpinned' | 'channel_name_changed' | 'channel_avatar_changed' | 'channel_announcement_changed' | 'channel_member_joined' | 'channel_member_invited' | 'channel_member_left' | 'channel_member_removed' | 'channel_owner_transferred' | 'channel_admin_added' | 'channel_admin_removed' | 'channel_dismissed' | 'channel_all_muted' | 'channel_all_unmuted' | 'channel_created' | 'channel_private_chat_disabled' | 'channel_private_chat_enabled' | 'channel_member_renamed' | 'channel_member_muted' | 'channel_member_unmuted' | 'channel_message_pinned' | 'channel_message_unpinned' | 'channel_unknown' | 'red_packet_claimed' | 'red_packet_claimed_thunder' | 'unknown';
|
|
56
|
+
type ImSystemEventType = 'direct_contact_established' | 'direct_contact_required' | 'direct_message_refused' | 'group_info_changed' | 'group_activated' | 'group_member_joined' | 'group_member_invited' | 'group_member_left' | 'group_member_removed' | 'group_master_changed' | 'group_dismissed' | 'group_member_renamed' | 'group_message_pinned' | 'group_message_unpinned' | 'group_call_started' | 'group_call_ended' | 'group_call_missed' | 'channel_name_changed' | 'channel_avatar_changed' | 'channel_announcement_changed' | 'channel_member_joined' | 'channel_member_invited' | 'channel_member_left' | 'channel_member_removed' | 'channel_owner_transferred' | 'channel_admin_added' | 'channel_admin_removed' | 'channel_dismissed' | 'channel_all_muted' | 'channel_all_unmuted' | 'channel_created' | 'channel_private_chat_disabled' | 'channel_private_chat_enabled' | 'channel_member_renamed' | 'channel_member_muted' | 'channel_member_unmuted' | 'channel_message_pinned' | 'channel_message_unpinned' | 'channel_unknown' | 'red_packet_claimed' | 'red_packet_claimed_thunder' | 'unknown';
|
|
57
57
|
/** 系统提示结构化内容(contentType==='system'):存语义,不把最终中文句子当主数据源(UI/composable 据 eventType + 资料生成文案)。 */
|
|
58
58
|
interface ImSystemMessageBody {
|
|
59
59
|
eventType: ImSystemEventType;
|
|
@@ -120,6 +120,23 @@ type LastMessageSummary = {
|
|
|
120
120
|
} | {
|
|
121
121
|
kind: 'voice';
|
|
122
122
|
durationMs?: number;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* 媒体合集(contentType 28)。
|
|
126
|
+
*
|
|
127
|
+
* 只给结构化计数与配文,**不在这里拼「2 张照片, 1 个视频」这种文案**——中英文的量词、复数与
|
|
128
|
+
* 连接符各不相同,必须由 im-i18n 按 locale 组装。`caption` 非空时宿主优先显示配文(对齐三端)。
|
|
129
|
+
*
|
|
130
|
+
* `firstItemKind` 是第一项是照片还是视频。有配文时列表显示的是配文,光看计数无法决定该配
|
|
131
|
+
* 照片图标还是视频图标,三端统一按第一项取(对齐 iOS `IMMediaAlbumMessageBody`)。
|
|
132
|
+
* 入站解析后所有项都被丢弃时缺省,宿主据此不显示类型图标。
|
|
133
|
+
*/
|
|
134
|
+
| {
|
|
135
|
+
kind: 'mediaAlbum';
|
|
136
|
+
imageCount: number;
|
|
137
|
+
videoCount: number;
|
|
138
|
+
caption?: string;
|
|
139
|
+
firstItemKind?: 'image' | 'video';
|
|
123
140
|
} | {
|
|
124
141
|
kind: 'encrypted';
|
|
125
142
|
} | {
|
|
@@ -422,6 +439,59 @@ interface UnknownMessageBody {
|
|
|
422
439
|
reason: 'unsupported-content-type' | 'malformed-content';
|
|
423
440
|
}
|
|
424
441
|
/** 按 contentType 的结构化内容体。 */
|
|
442
|
+
/**
|
|
443
|
+
* 媒体合集单项:一张图片或一个视频。
|
|
444
|
+
*
|
|
445
|
+
* 对应协议 `content` JSON 里 `items[]` 的一个元素(wire `mediaType` 1=图片 2=视频)。
|
|
446
|
+
* 与 `ImImageBody` / `ImVideoBody` 的区别是它**不是**独立的一条消息——同一条合集消息里的
|
|
447
|
+
* 若干项共享消息级的撤回、已读、引用与转发语义。
|
|
448
|
+
*/
|
|
449
|
+
interface ImMediaAlbumItem {
|
|
450
|
+
/** 该项是图片还是视频;由协议 `mediaType` 归一而来,未知取值的项在解析阶段已被丢弃。 */
|
|
451
|
+
kind: 'image' | 'video';
|
|
452
|
+
/** 远端地址。加密项也是这个地址,解密用本项自己的 `teaKey`。 */
|
|
453
|
+
url: string;
|
|
454
|
+
/** 原始像素宽。宫格按它判定朝向,为 0 时宿主用兜底几何。 */
|
|
455
|
+
width: number;
|
|
456
|
+
/** 原始像素高。 */
|
|
457
|
+
height: number;
|
|
458
|
+
/**
|
|
459
|
+
* 视频时长,**毫秒**。
|
|
460
|
+
*
|
|
461
|
+
* 协议 `items[].duration` 本身就是毫秒,这里不做换算——注意这与单视频消息
|
|
462
|
+
* `ImVideoBody.duration`(秒)单位不同,所以刻意用 `durationMs` 命名区分。图片项没有此字段。
|
|
463
|
+
*/
|
|
464
|
+
durationMs?: number;
|
|
465
|
+
/** 远端缩略图地址;可能缺省,此时只能用 `thumbData`。 */
|
|
466
|
+
thumbUrl?: string;
|
|
467
|
+
/** 内嵌缩略图/封面 JPEG 字节。加密消息服务端出不了封面,宫格首屏只能靠它。 */
|
|
468
|
+
thumbData?: Uint8Array;
|
|
469
|
+
/** 原文件 MD5。 */
|
|
470
|
+
md5?: string;
|
|
471
|
+
/** 原文件大小(字节)。 */
|
|
472
|
+
size?: number;
|
|
473
|
+
/** 本项的文件解密 TEA key;`fileEncryptType` 为 0/2/3 时必有。 */
|
|
474
|
+
teaKey?: Uint8Array;
|
|
475
|
+
/** 文件加密类型:0=跟随消息 1=不加密 2=前 32 字节 TEA 3=完整 TEA。 */
|
|
476
|
+
fileEncryptType?: number;
|
|
477
|
+
/** 发送方勾选了「原图」。仅作展示角标,不影响下载与解密。 */
|
|
478
|
+
hd?: boolean;
|
|
479
|
+
}
|
|
480
|
+
/**
|
|
481
|
+
* 媒体合集正文(`contentType === 'mediaAlbum'`,协议 28)。
|
|
482
|
+
*
|
|
483
|
+
* 一条消息同时承载一段可选配文和 1–9 个图片/视频项。产品上的「图文消息」就是
|
|
484
|
+
* `items.length === 1 && caption` 非空的情形,所以**分档判断一律看 `items.length`,不要看 contentType**。
|
|
485
|
+
*
|
|
486
|
+
* `items` 为空数组只会出现在入站解析残缺时(所有项的 `mediaType` 都不认识,或都无法解密);
|
|
487
|
+
* 这种正文不可出站——出站编码会显式拒绝,避免把坏消息转发出去。
|
|
488
|
+
*/
|
|
489
|
+
interface ImMediaAlbumBody {
|
|
490
|
+
/** 配文;缺省与空串等价,出站不写空串。 */
|
|
491
|
+
caption?: string;
|
|
492
|
+
/** 媒体项,顺序即用户选择顺序(决定宫格 index 与首项朝向)。 */
|
|
493
|
+
items: readonly ImMediaAlbumItem[];
|
|
494
|
+
}
|
|
425
495
|
interface ImMessageBody {
|
|
426
496
|
/** P0 文本内容(明文,解密后的结果)。 */
|
|
427
497
|
text?: string;
|
|
@@ -449,6 +519,8 @@ interface ImMessageBody {
|
|
|
449
519
|
call?: ImCallRecordBody;
|
|
450
520
|
/** contentType==='redPacket' 时的红包卡片。 */
|
|
451
521
|
redPacket?: ImRedPacketBody;
|
|
522
|
+
/** contentType==='mediaAlbum' 时的媒体合集正文(配文 + 1~9 个图片/视频项)。 */
|
|
523
|
+
mediaAlbum?: ImMediaAlbumBody;
|
|
452
524
|
/** contentType==='unknown' 时的稳定未知正文,不含原始 wire type。 */
|
|
453
525
|
unknown?: UnknownMessageBody;
|
|
454
526
|
}
|
|
@@ -483,7 +555,7 @@ type ImMessageFailureReason = 'timeout' | 'rejected' | 'encrypt_failed' | 'netwo
|
|
|
483
555
|
* 失败**展示语义**码(强类型枚举,非裸串):供 im-i18n 按 locale 渲染失败气泡文案。
|
|
484
556
|
* 由 `reason` / `SendMediaFailReason` / ACK errcode 穷尽映射而来,与 im-i18n failure catalog 键一一对应(media.* 带 mediaKind 参数)。
|
|
485
557
|
*/
|
|
486
|
-
type ImFailureDisplayCode = 'media.empty' | 'media.noCrypto' | 'media.previewFailed' | 'media.encryptFailed' | 'media.uploadFailed' | 'media.cancelled' | 'media.invalidDuration' | 'media.uploadInterrupted' | 'contactRequired' | 'messageRefused' | 'forbiddenOrLeft' | 'contentRejected' | 'groupDismissed' | 'groupUnavailable' | 'channelDismissed' | 'channelMuted' | 'channelNotMember' | 'channelAdminRequired' | 'conversationUnsupported' | 'sendCanceled' | 'sessionLoggedOut' | 'timeout' | 'network' | 'unknown';
|
|
558
|
+
type ImFailureDisplayCode = 'media.empty' | 'media.noCrypto' | 'media.previewFailed' | 'media.encryptFailed' | 'media.uploadFailed' | 'media.cancelled' | 'media.invalidDuration' | 'media.uploadInterrupted' | 'media.contentTooLarge' | 'contactRequired' | 'messageRefused' | 'forbiddenOrLeft' | 'contentRejected' | 'groupDismissed' | 'groupUnavailable' | 'channelDismissed' | 'channelMuted' | 'channelNotMember' | 'channelAdminRequired' | 'conversationUnsupported' | 'sendCanceled' | 'sessionLoggedOut' | 'timeout' | 'network' | 'unknown';
|
|
487
559
|
interface ImMessageFailure {
|
|
488
560
|
/** 归一后的错误码(来自 MESChatAck.errcode 或本地失败码,本地码用负值)。 */
|
|
489
561
|
code: number;
|
|
@@ -511,7 +583,12 @@ interface MediaTaskUpdate {
|
|
|
511
583
|
direction: 'upload' | 'download';
|
|
512
584
|
state: 'queued' | 'running' | 'completed' | 'failed' | 'canceled';
|
|
513
585
|
percent: number;
|
|
514
|
-
/**
|
|
586
|
+
/**
|
|
587
|
+
* upload 任务子阶段。
|
|
588
|
+
*
|
|
589
|
+
* `waiting-upload-slot` 与 `state: 'queued'` 同时出现,表示还没开始传字节(在生成缩略图或在等上传槽位),
|
|
590
|
+
* 此时 percent 恒为 0;`transferring` 正在传字节;`finalizing` 是等待远端 URL 最终确认。
|
|
591
|
+
*/
|
|
515
592
|
phase?: 'waiting-upload-slot' | 'transferring' | 'finalizing';
|
|
516
593
|
failure?: ImMessageFailure;
|
|
517
594
|
}
|
|
@@ -1612,9 +1689,23 @@ interface MediaAssetCacheKey {
|
|
|
1612
1689
|
messageId: string;
|
|
1613
1690
|
resourceVersion: string;
|
|
1614
1691
|
}
|
|
1615
|
-
/**
|
|
1692
|
+
/**
|
|
1693
|
+
* 已解密的真实媒体资产。
|
|
1694
|
+
*
|
|
1695
|
+
* 内容用 `Blob` 承载而不是 `Uint8Array`:图片、尤其视频可达上百 MB,读成 `Uint8Array` 就等于把整份
|
|
1696
|
+
* 媒体搬进 JS 堆;`Blob` 的字节由浏览器自己托管,写缓存、读缓存和交给 `<img>` / `<video>` 全程都不需要
|
|
1697
|
+
* 整读一遍。字段名从 `bytes` 改成 `blob` 是刻意的——改名让编译器强制每个读写点重新被检查,也不会留下
|
|
1698
|
+
* 「有时是字节、有时是 Blob」两条内存表现完全不同的路径。
|
|
1699
|
+
*
|
|
1700
|
+
* `Blob` 可结构化克隆,因此 IndexedDB 能直接存,未来跨 Worker 传递也不需要改形状。
|
|
1701
|
+
*/
|
|
1616
1702
|
interface MediaAssetCacheEntry extends MediaAssetCacheKey {
|
|
1617
|
-
|
|
1703
|
+
/** 解密后的真实媒体内容;字节量一律按 `blob.size` 核算(LRU、单条上限、诊断都用它)。 */
|
|
1704
|
+
blob: Blob;
|
|
1705
|
+
/**
|
|
1706
|
+
* 消息体声明的 MIME。保留该字段而不是依赖 `blob.type`:解密产物的 Blob 可能没有类型,也可能带的是
|
|
1707
|
+
* 下载响应的类型,与消息声明不一定一致;读缓存时要以消息声明为准。
|
|
1708
|
+
*/
|
|
1618
1709
|
mimeType?: string;
|
|
1619
1710
|
}
|
|
1620
1711
|
/** 单种媒体的 sibling 缓存策略。 */
|
|
@@ -1632,7 +1723,7 @@ interface MediaAssetCacheStrategyRegistry {
|
|
|
1632
1723
|
/**
|
|
1633
1724
|
* 明文媒体资产缓存 Port。
|
|
1634
1725
|
*
|
|
1635
|
-
* Core/SDK
|
|
1726
|
+
* Core/SDK 只通过该端口读写真实媒体内容(以 Blob 承载);IndexedDB、配额与 LRU 由浏览器实现负责。
|
|
1636
1727
|
*/
|
|
1637
1728
|
interface MediaAssetCachePort {
|
|
1638
1729
|
get: (key: MediaAssetCacheKey) => Promise<MediaAssetCacheEntry | null>;
|
|
@@ -1652,8 +1743,14 @@ interface ImProfilePort {
|
|
|
1652
1743
|
clearCache?: () => void;
|
|
1653
1744
|
}
|
|
1654
1745
|
|
|
1655
|
-
/**
|
|
1656
|
-
|
|
1746
|
+
/**
|
|
1747
|
+
* 会话收藏可展示的内容类型;与 iOS `isSupportCollectionMsgType` 对齐。
|
|
1748
|
+
*
|
|
1749
|
+
* @remarks 这些值与收藏接口的 `content_type` 数值一一对应,而那个数值就是消息自己的 contentType
|
|
1750
|
+
* (1=文本 2=图片 3=视频 4=语音 5=位置 11=文件 **28=媒体合集**),不是另一套收藏专用枚举。
|
|
1751
|
+
* Android `MessageCollectExecute` 直接写 `message.getContentType()`,iOS 写 `msg.msgType`,两端一致。
|
|
1752
|
+
*/
|
|
1753
|
+
type ImSessionFavoriteKind = 'text' | 'image' | 'video' | 'voice' | 'location' | 'file' | 'mediaAlbum';
|
|
1657
1754
|
/** 服务端一条会话收藏快照;列表以 HTTP 为准,不回写原消息。 */
|
|
1658
1755
|
interface ImSessionFavoriteItem$1 {
|
|
1659
1756
|
readonly collectId: string;
|
|
@@ -2325,6 +2422,38 @@ type EditFailReason = 'not-found' | 'not-own' | 'not-sent' | 'recalled' | 'delet
|
|
|
2325
2422
|
|
|
2326
2423
|
type RecallFailReason = 'not-found' | 'not-own' | 'not-sent' | 'expired' | 'unsupported' | 'timeout' | 'server-expired' | 'failed' | 'disconnected';
|
|
2327
2424
|
|
|
2425
|
+
/** 浏览器 PushSubscription.toJSON() 的可移植数据;不依赖 DOM 或浏览器全局。 */
|
|
2426
|
+
interface ImWebPushSubscription {
|
|
2427
|
+
endpoint?: string;
|
|
2428
|
+
expirationTime?: number | null;
|
|
2429
|
+
keys?: Record<string, string>;
|
|
2430
|
+
}
|
|
2431
|
+
/** 状态不包含 endpoint、加密密钥或登录凭据,可安全用于设置页。 */
|
|
2432
|
+
interface ImPushSnapshot {
|
|
2433
|
+
status: 'idle' | 'pending' | 'syncing' | 'synced' | 'unconfirmed' | 'error' | 'disposed';
|
|
2434
|
+
error?: 'timeout' | 'invalid-ack' | 'server-rejected' | 'send-failed';
|
|
2435
|
+
/** unconfirmed 表示已收到旧后端默认错误码 ACK,不能据此证明绑定成功或失败。 */
|
|
2436
|
+
serverCode?: number;
|
|
2437
|
+
/** 超时等失败后等下一条连接恢复;不主动反复重报或制造重连。 */
|
|
2438
|
+
requiresReconnect?: boolean;
|
|
2439
|
+
}
|
|
2440
|
+
/**
|
|
2441
|
+
* 当前账号的推送绑定。浏览器授权、订阅和取消订阅由宿主拥有。
|
|
2442
|
+
* setWebSubscription 只提交同步意图;只有 snapshot.status === 'synced' 表示收到服务端成功 ACK。
|
|
2443
|
+
*/
|
|
2444
|
+
interface ImPushApi {
|
|
2445
|
+
/** 必须携带创建订阅时的账号,防止异步结果被交给另一个账号。离线时保留最新意图。 */
|
|
2446
|
+
setWebSubscription: (input: {
|
|
2447
|
+
userId: string;
|
|
2448
|
+
subscription: ImWebPushSubscription;
|
|
2449
|
+
}) => void;
|
|
2450
|
+
/** 停止本地同步并释放订阅数据;不宣称服务端解绑,宿主仍须调用 PushSubscription.unsubscribe()。 */
|
|
2451
|
+
clear: () => void;
|
|
2452
|
+
snapshot: () => ImPushSnapshot;
|
|
2453
|
+
/** 立即提供快照,返回退订函数;监听器的异常经宿主错误端口报告。 */
|
|
2454
|
+
subscribe: (listener: (snapshot: ImPushSnapshot) => void) => () => void;
|
|
2455
|
+
}
|
|
2456
|
+
|
|
2328
2457
|
/**
|
|
2329
2458
|
* 后端协议的目标服务命名。
|
|
2330
2459
|
*
|
|
@@ -2563,9 +2692,19 @@ interface MediaTransferAdapterConfig {
|
|
|
2563
2692
|
rangeDownload?: boolean;
|
|
2564
2693
|
/**
|
|
2565
2694
|
* 媒体发送阶段的并发上限;由 im-core 消费,adapter 本身仍只负责单个上传任务。
|
|
2566
|
-
*
|
|
2695
|
+
*
|
|
2696
|
+
* 并发按媒体体积分两档:图片与不超过分片阈值(16 MiB)的小文件走单次 PutObject、不占分片缓冲,
|
|
2697
|
+
* 缺省 5;视频与超过阈值(或字节数未知)的文件走分片,每路各带分片缓冲,缺省 3。
|
|
2698
|
+
* 两档都只接受 1-6 的整数,超出范围由 core 显式报错。
|
|
2699
|
+
* - 传一个数字:所有媒体共用这一个并发数,与分档前的语义一致。
|
|
2700
|
+
* - 传 `{ total, largeFiles }`:显式分档,`largeFiles` 不得超过 `total`。
|
|
2567
2701
|
*/
|
|
2568
|
-
maxConcurrentUploads?: number
|
|
2702
|
+
maxConcurrentUploads?: number | {
|
|
2703
|
+
/** 在途上传总数上限(两档合计);缺省 5。 */
|
|
2704
|
+
total?: number;
|
|
2705
|
+
/** 其中大文件档的上限(视频、超过分片阈值或字节数未知的内容);缺省 min(3, total)。 */
|
|
2706
|
+
largeFiles?: number;
|
|
2707
|
+
};
|
|
2569
2708
|
}
|
|
2570
2709
|
|
|
2571
2710
|
interface NetworkEventTarget {
|
|
@@ -2711,12 +2850,16 @@ interface ImMessageReactions {
|
|
|
2711
2850
|
aggregates: readonly ImMessageReactionAggregate[];
|
|
2712
2851
|
}
|
|
2713
2852
|
/** 可渲染媒体正文;密钥和底层文件加密策略只允许留在 SDK/Core。 */
|
|
2714
|
-
interface ImMessageViewBody extends Omit<ImMessageBody, 'image' | 'video' | 'voice' | 'file' | 'sticker'> {
|
|
2853
|
+
interface ImMessageViewBody extends Omit<ImMessageBody, 'image' | 'video' | 'voice' | 'file' | 'sticker' | 'mediaAlbum'> {
|
|
2715
2854
|
image?: Readonly<Omit<NonNullable<ImMessageBody['image']>, 'teaKey' | 'fileEncryptType'>>;
|
|
2716
2855
|
video?: Readonly<Omit<NonNullable<ImMessageBody['video']>, 'teaKey' | 'fileEncryptType'>>;
|
|
2717
2856
|
voice?: Readonly<Omit<NonNullable<ImMessageBody['voice']>, 'teaKey' | 'fileEncryptType'>>;
|
|
2718
2857
|
file?: Readonly<Omit<NonNullable<ImMessageBody['file']>, 'teaKey' | 'fileEncryptType'>>;
|
|
2719
2858
|
sticker?: Readonly<NonNullable<ImMessageBody['sticker']>>;
|
|
2859
|
+
/** 合集的每一项都带自己的密钥材料,逐项剥离后才交给产品层;按项下载走 SDK handle,不需要这些字段。 */
|
|
2860
|
+
mediaAlbum?: Readonly<Omit<NonNullable<ImMessageBody['mediaAlbum']>, 'items'> & {
|
|
2861
|
+
items: readonly Readonly<Omit<ImMediaAlbumItem, 'teaKey' | 'fileEncryptType'>>[];
|
|
2862
|
+
}>;
|
|
2720
2863
|
}
|
|
2721
2864
|
/**
|
|
2722
2865
|
* 官方 Chat Kit 与宿主消息线程使用的完整稳定消息 DTO。
|
|
@@ -2792,6 +2935,44 @@ interface MiniProgramMessageOptions {
|
|
|
2792
2935
|
interface TransferMessageOptions {
|
|
2793
2936
|
replyToMessageId?: string;
|
|
2794
2937
|
}
|
|
2938
|
+
/**
|
|
2939
|
+
* 媒体合集里的一项:一张图片或一个视频。
|
|
2940
|
+
*
|
|
2941
|
+
* @remarks `kind` 由**调用方**按 MIME 分类,SDK 不嗅探文件内容——宿主的文件选择器本来就要按类型分流
|
|
2942
|
+
* (GIF 得走 `sendGif`),再让 SDK 猜一次只会多一处口径不一致。
|
|
2943
|
+
*/
|
|
2944
|
+
interface MediaAlbumItemInput {
|
|
2945
|
+
/** 这一项是图片还是视频。 */
|
|
2946
|
+
kind: 'image' | 'video';
|
|
2947
|
+
/** 原文件;`File` 可直接传,`Blob` 需调用方保证 `type` 可判定。 */
|
|
2948
|
+
file: File | Blob;
|
|
2949
|
+
/** 宿主创建的本地 object URL,仅供上传中的宫格显示这一格;URL 释放由宿主生命周期负责。 */
|
|
2950
|
+
localPreviewUrl?: string;
|
|
2951
|
+
/**
|
|
2952
|
+
* 这一项的本地宽高(视频再带时长与首帧)。
|
|
2953
|
+
*
|
|
2954
|
+
* 不传时 SDK 会自己读一次(与单图/单视频同一条预览路径)。宫格的格子几何按原始宽高算,
|
|
2955
|
+
* 缺了它整条消息的格子比例会在上传完成时跳变。
|
|
2956
|
+
*/
|
|
2957
|
+
localPreviewMetadata?: ImagePreviewMetadata | VideoPreviewMetadata;
|
|
2958
|
+
}
|
|
2959
|
+
/**
|
|
2960
|
+
* 媒体合集发送选项。
|
|
2961
|
+
*
|
|
2962
|
+
* @remarks 恰好 1 项且没有配文时,SDK 内部会回落成普通图片/视频消息(与 Android / iOS / 旧 H5 一致),
|
|
2963
|
+
* 此时返回的仍是同样的 `SendMessageResult`,调用方不需要区分。
|
|
2964
|
+
*/
|
|
2965
|
+
interface MediaAlbumMessageOptions {
|
|
2966
|
+
/** 配文,最长 1024 字符;纯空白等同于没有配文。超长由 SDK 明确拒绝,**不静默截断**。 */
|
|
2967
|
+
caption?: string;
|
|
2968
|
+
replyToMessageId?: string;
|
|
2969
|
+
/**
|
|
2970
|
+
* 发送方勾选了「原图」,写进每一项的 `hd` 标记。
|
|
2971
|
+
*
|
|
2972
|
+
* 本期不做任何图片/视频压缩,勾与不勾都发原文件,这个字段只让接收端显示「原图」角标。
|
|
2973
|
+
*/
|
|
2974
|
+
hd?: boolean;
|
|
2975
|
+
}
|
|
2795
2976
|
/**
|
|
2796
2977
|
* 本地视频的固有尺寸、时长与首帧封面。
|
|
2797
2978
|
*
|
|
@@ -3854,6 +4035,22 @@ type ConversationLastMessageSummary = {
|
|
|
3854
4035
|
} | {
|
|
3855
4036
|
kind: 'voice';
|
|
3856
4037
|
durationMs?: number;
|
|
4038
|
+
}
|
|
4039
|
+
/**
|
|
4040
|
+
* 媒体合集(一条消息内 1~9 个图片/视频 + 可选配文)。
|
|
4041
|
+
*
|
|
4042
|
+
* 只给计数与配文,数量文案由宿主经 im-i18n 按 locale 组装;有配文时优先显示配文。
|
|
4043
|
+
* 两个计数都为 0 表示入站正文残缺(所有项都无法解析),宿主应按未知正文处理。
|
|
4044
|
+
*
|
|
4045
|
+
* `firstItemKind` 是第一项是照片还是视频。有配文时列表显示的是配文,光看计数决定不了该配
|
|
4046
|
+
* 照片图标还是视频图标,三端统一按第一项取;正文残缺时缺省,宿主据此不显示类型图标。
|
|
4047
|
+
*/
|
|
4048
|
+
| {
|
|
4049
|
+
kind: 'mediaAlbum';
|
|
4050
|
+
imageCount: number;
|
|
4051
|
+
videoCount: number;
|
|
4052
|
+
caption?: string;
|
|
4053
|
+
firstItemKind?: 'image' | 'video';
|
|
3857
4054
|
} | {
|
|
3858
4055
|
kind: 'encrypted';
|
|
3859
4056
|
} | {
|
|
@@ -4306,6 +4503,16 @@ interface ConversationMessageApi {
|
|
|
4306
4503
|
sendFile: (file: File | Blob, options?: FileMessageOptions) => Promise<SendMessageResult>;
|
|
4307
4504
|
/** 发送 GIF 贴图;原文件明文上传 sticker bucket,消息固定 EXPRESSION/LINK/GIF。 */
|
|
4308
4505
|
sendGif: (file: File | Blob, options?: GifMessageOptions) => Promise<SendMessageResult>;
|
|
4506
|
+
/**
|
|
4507
|
+
* 发送媒体合集:1~9 个图片/视频合成**一条**消息,可带一段配文。
|
|
4508
|
+
*
|
|
4509
|
+
* @remarks 全部项上传成功才发出;任一项失败整条失败,不发半条消息。恰好 1 项且没有配文时
|
|
4510
|
+
* SDK 内部回落成普通图片/视频消息(三端一致)。**校验是整条的**——某一项超限会拒绝整条,
|
|
4511
|
+
* 因为协议上它就是一条消息,没有「发一半」这种状态。
|
|
4512
|
+
*
|
|
4513
|
+
* GIF 不能进合集(三端一致),调用方要先按 MIME 把它拆出去走 `sendGif`。
|
|
4514
|
+
*/
|
|
4515
|
+
sendMediaAlbum: (items: readonly MediaAlbumItemInput[], options?: MediaAlbumMessageOptions) => Promise<SendMessageResult>;
|
|
4309
4516
|
/** 发送已经托管在远端的静态贴图;资源和贴图包身份均为必填合同。 */
|
|
4310
4517
|
sendSticker: (asset: ImStickerAssetInput, options?: ExpressionMessageOptions) => Promise<SendMessageResult>;
|
|
4311
4518
|
/** 发送已经托管在远端的 GIF;Giphy 没有 package identity,输入不得提供 packageId。 */
|
|
@@ -4386,6 +4593,43 @@ interface ConversationMessageApi {
|
|
|
4386
4593
|
* ```
|
|
4387
4594
|
*/
|
|
4388
4595
|
forward: (messageIds: readonly string[], targets: readonly ConversationRef<ProductHandleConversationType>[]) => Promise<ForwardMessagesResult>;
|
|
4596
|
+
/**
|
|
4597
|
+
* 把媒体合集里的第 `itemIndex` 项,当成**一条独立的图片或视频消息**转发到多个目标会话。
|
|
4598
|
+
*
|
|
4599
|
+
* 用途:全屏预览里点转发时,用户要转的是当前正在看的这一格,而不是整条合集。
|
|
4600
|
+
*
|
|
4601
|
+
* @remarks
|
|
4602
|
+
* 与 `forward` 的区别是产出的消息类型变了(合集 → 图片/视频),所以是独立方法而不是给 `forward`
|
|
4603
|
+
* 放宽入参。与 `forward` 相同的是:复用该项已有的远端地址与解密 key,**不重新上传**;目标会话仍由
|
|
4604
|
+
* direct/GROUP/CHANNEL 各自的 SendStrategy 组帧入 Outbox。
|
|
4605
|
+
*
|
|
4606
|
+
* 视频项在合集里的时长是毫秒,转成单视频消息时 SDK 会换算成协议要求的秒,调用方不需要处理。
|
|
4607
|
+
* 合集项上的「原图」角标与远端缩略图地址不会带到单媒体消息上——单图/单视频正文没有这两个字段。
|
|
4608
|
+
*
|
|
4609
|
+
* 三种情况进 `failed`:源消息不是媒体合集(`IM_SDK_FORWARD_CONTENT_UNSUPPORTED`)、
|
|
4610
|
+
* `itemIndex` 越界或该项已不存在(`IM_SDK_MEDIA_ALBUM_ITEM_INVALID`)、该项还没有可复用的远端地址
|
|
4611
|
+
* (还在上传或入站残缺,`IM_SDK_FORWARD_MEDIA_NOT_READY`,可重试)。
|
|
4612
|
+
*
|
|
4613
|
+
* **还有一类结果三个数组会全空**:源消息已撤回、已被双删、解密失败、在本地已经查不到,
|
|
4614
|
+
* 或它的类型本身就不可转发时,这条消息在预检阶段就被剔除,只出现在 `skippedSourceMessageIds` 里。
|
|
4615
|
+
* 这与 `forward` 的批量语义一致(批量转发本来就要把不可转的源剔掉再发其余的),
|
|
4616
|
+
* 但单条调用时它意味着**什么都没发出去**。所以调用方判成功要看 `sent`,
|
|
4617
|
+
* 不要只判 `failed.length > 0`——那样在「预览期间原消息被撤回」这种竞态下会既不发送也不提示。
|
|
4618
|
+
*
|
|
4619
|
+
* @param messageId 当前 handle 中的合集消息 id。
|
|
4620
|
+
* @param itemIndex 宫格里的项下标,从 0 起;必须是非负整数。
|
|
4621
|
+
* @param targets 目标会话,最多 9 个。
|
|
4622
|
+
* @example
|
|
4623
|
+
* ```ts
|
|
4624
|
+
* const result = await handle.messages.forwardMediaAlbumItem('message-42', 2, [
|
|
4625
|
+
* { conversationType: 'direct', conversationId: '1001' },
|
|
4626
|
+
* ])
|
|
4627
|
+
* // 一条都没发出去就要提示:失败原因在 failed 里,源消息被剔除时 failed 也是空的。
|
|
4628
|
+
* if (result.sent.length === 0)
|
|
4629
|
+
* showError(result.failed[0]?.error.code ?? 'IM_SDK_FORWARD_CONTENT_UNSUPPORTED')
|
|
4630
|
+
* ```
|
|
4631
|
+
*/
|
|
4632
|
+
forwardMediaAlbumItem: (messageId: string, itemIndex: number, targets: readonly ConversationRef<ProductHandleConversationType>[]) => Promise<ForwardMessagesResult>;
|
|
4389
4633
|
/**
|
|
4390
4634
|
* 按 id 向服务端取回本地没有的消息,并回填进本地历史。
|
|
4391
4635
|
*
|
|
@@ -4595,6 +4839,14 @@ interface ImMessageRef {
|
|
|
4595
4839
|
conversation: ConversationRef<ProductHandleConversationType>;
|
|
4596
4840
|
/** 当前会话内的稳定消息 id。 */
|
|
4597
4841
|
messageId: string;
|
|
4842
|
+
/**
|
|
4843
|
+
* 媒体合集里的第几项(从 0 起)。
|
|
4844
|
+
*
|
|
4845
|
+
* **只有合集消息需要它,也只有合集消息接受它**:一条合集是一条消息、多个文件,光靠 messageId
|
|
4846
|
+
* 指不到具体某一项。给单媒体消息传这个字段会被显式拒绝,而不是忽略——忽略的话调用方以为自己
|
|
4847
|
+
* 在下载第 3 项,实际拿到的是整条消息的唯一媒体。
|
|
4848
|
+
*/
|
|
4849
|
+
itemIndex?: number;
|
|
4598
4850
|
}
|
|
4599
4851
|
/**
|
|
4600
4852
|
* 可观察媒体上传/下载任务的只读产品投影。
|
|
@@ -4609,13 +4861,27 @@ interface ImMediaTask {
|
|
|
4609
4861
|
messageId: string;
|
|
4610
4862
|
/** 关联消息的精确会话 sibling。 */
|
|
4611
4863
|
ref: ConversationRef<ProductHandleConversationType>;
|
|
4864
|
+
/**
|
|
4865
|
+
* 媒体合集的项下标;单媒体消息与全部上传任务为 undefined。
|
|
4866
|
+
*
|
|
4867
|
+
* 一条合集的多项共用同一个 messageId,各自是独立的下载任务。调用方按 messageId 找任务时
|
|
4868
|
+
* 必须连这个字段一起比,否则并发下载两项时会把另一项的进度读成自己的。
|
|
4869
|
+
* 上传任务不带下标:一条合集整体只有一条上传进度(所有项都传完才算这条消息发出去)。
|
|
4870
|
+
*/
|
|
4871
|
+
itemIndex?: number;
|
|
4612
4872
|
/** upload 来自发送链路,download 来自本产品 API。 */
|
|
4613
4873
|
direction: 'upload' | 'download';
|
|
4614
4874
|
/** 终态 completed/failed/canceled 不会被同一尝试的迟到 progress 回退。 */
|
|
4615
4875
|
state: 'queued' | 'running' | 'completed' | 'failed' | 'canceled';
|
|
4616
4876
|
/** 0-100 的归一化整数。 */
|
|
4617
4877
|
percent: number;
|
|
4618
|
-
/**
|
|
4878
|
+
/**
|
|
4879
|
+
* upload 子阶段。
|
|
4880
|
+
*
|
|
4881
|
+
* `waiting-upload-slot` 与 `state: 'queued'` 同时出现,表示这条媒体还没开始传字节(在生成缩略图或在
|
|
4882
|
+
* 等上传槽位),此时 `percent` 恒为 0——宿主应显示「等待中」而不是把 0 当成停住的进度。
|
|
4883
|
+
* `transferring` 是正在传字节,`finalizing` 是字节已传完、在等对象存储确认。
|
|
4884
|
+
*/
|
|
4619
4885
|
phase?: 'waiting-upload-slot' | 'transferring' | 'finalizing';
|
|
4620
4886
|
/** 可供产品按 code/category 决策的稳定错误;不含底层 URL、密钥或响应正文。 */
|
|
4621
4887
|
error?: ImSdkErrorShape;
|
|
@@ -4671,6 +4937,31 @@ interface ImMediaTasksApi {
|
|
|
4671
4937
|
* @throws 持久缓存读取失败时抛 `IM_SDK_MEDIA_CACHE_READ_FAILED`,不能把存储故障伪装成 cache miss。
|
|
4672
4938
|
*/
|
|
4673
4939
|
getCached: (message: ImMessageRef) => Promise<Blob | null>;
|
|
4940
|
+
/**
|
|
4941
|
+
* 为宿主手里的**本地**图片/视频文件预读展示元信息:尺寸、视频时长、视频首帧封面的 JPEG 字节。
|
|
4942
|
+
*
|
|
4943
|
+
* 给「发送前预览」这类场景用:宿主要在用户还没点发送时就把缩略图画出来,而浏览器读不出视频的
|
|
4944
|
+
* 首帧——`<video preload="metadata">` 在 iOS Safari 上只加载元信息、**不解码任何一帧**,
|
|
4945
|
+
* 拿它当缩略图会得到一个空白格子(还会白占一路解码)。
|
|
4946
|
+
*
|
|
4947
|
+
* 返回的对象可以**原样**作为 `localPreviewMetadata` 交给 `sendImage` / `sendVideo` /
|
|
4948
|
+
* `sendMediaAlbum`:发送链路会跳过重复解码,上传中的气泡也从第一帧就有封面。
|
|
4949
|
+
* 视频封面用的就是发送链路那套规格(长边 320、JPEG),所以弹层里看到的与最终发出去的是同一张。
|
|
4950
|
+
*
|
|
4951
|
+
* @param input.kind 按文件类型选解码路径;`'video'` 才会抽首帧与读时长。
|
|
4952
|
+
* @param input.file 本地文件;不会被上传,也不会进任何缓存。
|
|
4953
|
+
* @param input.signal 宿主放弃时中止解码(例如预览弹层被关掉)。
|
|
4954
|
+
* @returns 解码成功返回元信息;**浏览器确实读不出这个文件**(格式不支持、解码超时)时返回 `null`,
|
|
4955
|
+
* 调用方应当显式呈现「这个文件读不出来」,不要拿空白格子糊过去。失败原因会记入 SDK 结构化诊断。
|
|
4956
|
+
* @throws 宿主通过 `signal` 中止时抛 `AbortError`——那是调用方自己的取消,不能和「读不出来」混为一谈。
|
|
4957
|
+
* @throws runtime 已 logout/dispose 时抛 `IM_SDK_MEDIA_RUNTIME_INACTIVE`;
|
|
4958
|
+
* 未装配预览端口时抛 `IM_SDK_MEDIA_PREVIEW_UNAVAILABLE`,不静默返回 `null`。
|
|
4959
|
+
*/
|
|
4960
|
+
prepareLocalPreview: <TKind extends 'image' | 'video'>(input: {
|
|
4961
|
+
kind: TKind;
|
|
4962
|
+
file: Blob;
|
|
4963
|
+
signal?: AbortSignal;
|
|
4964
|
+
}) => Promise<(TKind extends 'video' ? VideoPreviewMetadata : ImagePreviewMetadata) | null>;
|
|
4674
4965
|
}
|
|
4675
4966
|
|
|
4676
4967
|
/**
|
|
@@ -5119,14 +5410,8 @@ interface ImSearchApi {
|
|
|
5119
5410
|
readonly messages: ImMessageSearchApi;
|
|
5120
5411
|
}
|
|
5121
5412
|
|
|
5122
|
-
/**
|
|
5123
|
-
* 会话收藏稳定产品门面。
|
|
5124
|
-
*
|
|
5125
|
-
* 本模块不缓存服务端列表;每次 list/add/delete 都以当前账号 provider 为准。
|
|
5126
|
-
* 收藏快照与原聊天消息解耦:原消息删除、撤回或编辑不会回写收藏。
|
|
5127
|
-
*/
|
|
5128
|
-
|
|
5129
5413
|
type ImSessionFavoriteItem = Readonly<ImSessionFavoriteItem$1>;
|
|
5414
|
+
|
|
5130
5415
|
/** 产品层会话收藏 API。 */
|
|
5131
5416
|
interface ImSessionFavoritesApi {
|
|
5132
5417
|
list: () => Promise<readonly ImSessionFavoriteItem[]>;
|
|
@@ -5638,6 +5923,8 @@ interface AdvancedConversationsApi extends ImConversationsApi, ImConversationBac
|
|
|
5638
5923
|
* ```
|
|
5639
5924
|
*/
|
|
5640
5925
|
interface ImProductClient {
|
|
5926
|
+
/** 当前设备推送订阅的服务端绑定与同步状态。 */
|
|
5927
|
+
readonly push: ImPushApi;
|
|
5641
5928
|
readonly session: ImSessionApi;
|
|
5642
5929
|
readonly capabilities: ImConversationCapabilitiesApi;
|
|
5643
5930
|
readonly conversations: ImConversationListApi;
|
|
@@ -5843,7 +6130,7 @@ declare function useImApplicationsStore(pinia?: Pinia): ImApplicationsStore;
|
|
|
5843
6130
|
* 二期收敛:kit 框架无关层不再直接产中文,改产本联合里的码 + 参数(如 {reason}/{label}/{size}),由宿主经 im-i18n 渲染。
|
|
5844
6131
|
* 动态原始报错(error.message)作为 `{reason}` 参数拼接,不入 catalog(属诊断,不翻译)。
|
|
5845
6132
|
*/
|
|
5846
|
-
type ImServiceTextKey = 'common.notConnected' | 'common.selectOrOpenConversation' | 'common.conversationTypeNotReady' | 'common.conversationNotReady' | `recall.${RecallFailReason}` | `edit.${EditFailReason}` | 'localDelete.done' | 'localDelete.notFound' | 'localDelete.inFlight' | 'localDelete.failed' | 'channelDelete.notFound' | 'channelDelete.unsupported' | 'channelDelete.notSent' | 'channelDelete.unavailable' | 'channelDelete.forbidden' | 'channelDelete.timeout' | 'channelDelete.failed' | 'channelDelete.disconnected' | 'directBlock.contactRequired' | 'groupBlock.left' | 'groupBlock.removed' | 'groupBlock.dismissed' | 'groupBlock.unknownRestricted' | 'channelBlock.guest' | 'channelBlock.left' | 'channelBlock.removed' | 'channelBlock.dismissed' | 'channelBlock.muted' | 'channelBlock.allMembersMuted' | 'channelBlock.currentUserMuted' | 'channelBlock.blacklisted' | 'channelBlock.unknownRestricted' | 'channelProfile.loadFailed' | 'channelProfile.notFound' | 'channelProfile.retryAction' | 'channelMembers.title' | 'channelMembers.searchPlaceholder' | 'channelMembers.loading' | 'channelMembers.loadFailed' | 'channelMembers.retryAction' | 'channelMembers.empty' | 'channelMembers.loadingMore' | 'channelMembers.loadMoreFailed' | 'channelMembers.exhausted' | 'channelMembers.loadMoreAction' | 'label.image' | 'label.video' | 'label.file' | 'label.sticker' | 'send.failed' | 'send.retryFailed' | 'send.cancelFailed' | 'send.mediaFailed' | 'send.mediaEmpty' | 'send.mediaCancelled' | 'send.mediaCountLimit' | 'send.mediaTooLarge' | 'send.videoTooLong' | 'send.videoDurationUnavailable' | 'send.voiceEmpty' | 'send.voiceStorageNotConfigured' | 'send.voiceCancelled' | 'send.voiceFailed' | 'media.voiceNotReady' | 'media.voiceLoadEmpty' | 'media.voiceLoadFailed' | 'media.videoOpenEmpty' | 'media.videoLoadFailed' | 'media.imageInvalid' | 'media.imageLoadFailed' | 'media.fileDownloadEmpty' | 'media.fileDownloadFailed' | 'conversation.muteEnableFailed' | 'conversation.muteDisableFailed' | 'read.markReadFailed' | 'pinned.forbidden' | 'pinned.network' | 'pinned.contract' | 'pinned.unsupported' | 'pinned.failed' | 'pinned.previewUnavailable' | 'pinned.locateFailed' | 'pinned.recalled' | 'pinned.deleted' | 'pinned.protected' | 'pinned.pinAction' | 'pinned.unpinAction' | 'pinned.unpinConfirm' | 'pinned.cancelAction' | 'lifecycle.missingLoginState' | 'lifecycle.prepareFailed' | 'lifecycle.missingConnectParams' | 'lifecycle.connectFailed' | 'lifecycle.disposed' | 'forward.emptyInput' | 'forward.allSkipped' | 'forward.partialSkipped' | 'forward.done' | 'forward.failed';
|
|
6133
|
+
type ImServiceTextKey = 'common.notConnected' | 'common.selectOrOpenConversation' | 'common.conversationTypeNotReady' | 'common.conversationNotReady' | `recall.${RecallFailReason}` | `edit.${EditFailReason}` | 'localDelete.done' | 'localDelete.notFound' | 'localDelete.inFlight' | 'localDelete.failed' | 'channelDelete.notFound' | 'channelDelete.unsupported' | 'channelDelete.notSent' | 'channelDelete.unavailable' | 'channelDelete.forbidden' | 'channelDelete.timeout' | 'channelDelete.failed' | 'channelDelete.disconnected' | 'directBlock.contactRequired' | 'groupBlock.left' | 'groupBlock.removed' | 'groupBlock.dismissed' | 'groupBlock.unknownRestricted' | 'channelBlock.guest' | 'channelBlock.left' | 'channelBlock.removed' | 'channelBlock.dismissed' | 'channelBlock.muted' | 'channelBlock.allMembersMuted' | 'channelBlock.currentUserMuted' | 'channelBlock.blacklisted' | 'channelBlock.unknownRestricted' | 'channelProfile.loadFailed' | 'channelProfile.notFound' | 'channelProfile.retryAction' | 'channelMembers.title' | 'channelMembers.searchPlaceholder' | 'channelMembers.loading' | 'channelMembers.loadFailed' | 'channelMembers.retryAction' | 'channelMembers.empty' | 'channelMembers.loadingMore' | 'channelMembers.loadMoreFailed' | 'channelMembers.exhausted' | 'channelMembers.loadMoreAction' | 'label.image' | 'label.video' | 'label.file' | 'label.sticker' | 'send.failed' | 'send.retryFailed' | 'send.cancelFailed' | 'send.mediaFailed' | 'send.mediaEmpty' | 'send.mediaCancelled' | 'send.mediaCountLimit' | 'send.mediaTooLarge' | 'send.mediaFormatMismatch' | 'send.videoTooLong' | 'send.videoDurationUnavailable' | 'send.voiceEmpty' | 'send.voiceStorageNotConfigured' | 'send.voiceCancelled' | 'send.voiceFailed' | 'media.uploadWaiting' | 'media.voiceNotReady' | 'media.voiceLoadEmpty' | 'media.voiceLoadFailed' | 'media.videoOpenEmpty' | 'media.videoLoadFailed' | 'media.imageInvalid' | 'media.imageLoadFailed' | 'media.fileDownloadEmpty' | 'media.fileDownloadFailed' | 'conversation.muteEnableFailed' | 'conversation.muteDisableFailed' | 'conversation.backgroundLoadFailed' | 'read.markReadFailed' | 'storage.failed' | 'sync.failed' | 'draft.saveFailed' | 'history.returnLatestFailed' | 'pinned.forbidden' | 'pinned.network' | 'pinned.contract' | 'pinned.unsupported' | 'pinned.failed' | 'pinned.previewUnavailable' | 'pinned.locateFailed' | 'pinned.recalled' | 'pinned.deleted' | 'pinned.protected' | 'pinned.pinAction' | 'pinned.unpinAction' | 'pinned.unpinConfirm' | 'pinned.cancelAction' | 'lifecycle.missingLoginState' | 'lifecycle.prepareFailed' | 'lifecycle.missingConnectParams' | 'lifecycle.connectFailed' | 'lifecycle.disposed' | 'forward.emptyInput' | 'forward.allSkipped' | 'forward.partialSkipped' | 'forward.done' | 'forward.failed';
|
|
5847
6134
|
|
|
5848
6135
|
/**
|
|
5849
6136
|
* 本文件管理图片和视频本地预览地址的完整生命周期。
|
|
@@ -5999,6 +6286,13 @@ interface ChatMediaMessageRef {
|
|
|
5999
6286
|
conversationId: string;
|
|
6000
6287
|
/** 需要查找本地媒体预览的消息 ID。 */
|
|
6001
6288
|
messageId: string;
|
|
6289
|
+
/**
|
|
6290
|
+
* 媒体合集的项下标(第几格)。
|
|
6291
|
+
*
|
|
6292
|
+
* 一条合集的 9 格共用同一个 messageId,各自是独立资源;不带下标会让它们落到同一个注册表键上,
|
|
6293
|
+
* 后绑定的一格把先绑定的挤掉并撤销其地址。单媒体消息不传这个字段。
|
|
6294
|
+
*/
|
|
6295
|
+
itemIndex?: number;
|
|
6002
6296
|
}
|
|
6003
6297
|
/**
|
|
6004
6298
|
* Chat Kit 提供给共享 Store 和业务 Service 的账号运行接口。
|
|
@@ -6802,14 +7096,17 @@ declare function useImHistoryReturnAfterSendCoordinator(pinia?: Pinia): ImHistor
|
|
|
6802
7096
|
* 为页面展示当前账号的媒体上传/下载进度,并提供取消、重试和重新选择原文件入口。
|
|
6803
7097
|
*
|
|
6804
7098
|
* 【状态从哪里来】
|
|
6805
|
-
* Store 订阅 SDK
|
|
6806
|
-
*
|
|
7099
|
+
* Store 订阅 SDK 的完整媒体任务列表,向页面提供任务、当前线程每条消息的上传百分比、是否还在排队等
|
|
7100
|
+
* 上传槽位、是否正在完成最后处理以及稳定错误。传输、任务状态、消息状态、取消和重试都由 SDK 维护;Store 不模拟进度,也不
|
|
6807
7101
|
* 创建第二套上传队列。
|
|
6808
7102
|
*
|
|
6809
7103
|
* 【提供的能力】
|
|
6810
7104
|
* - `start` / `reset`:开始监听当前 SDK Client,或切账号时退订并清空旧任务。
|
|
6811
7105
|
* - `cancel` / `retry`:按 SDK 给出的任务 ID 取消或重试。
|
|
6812
7106
|
* - `cancelUpload`:根据当前会话类型、会话 ID 和消息 ID 找到唯一上传任务后取消。
|
|
7107
|
+
* - `cancelDownload`:按消息身份取消在途下载;合集要带项下标,因为一条合集的每一项是独立任务。
|
|
7108
|
+
* 与 `cancelUpload` 不同,它定位任务时不看当前会话——切会话正是关闭预览的路径之一。
|
|
7109
|
+
* 取消是任务级的,同一下载的所有等待方都会一起收到取消,只有唯一消费者才该调它。
|
|
6813
7110
|
* - `requestReplacement` / `takeReplacementRequest`:视频或文件刷新后失去本地源时,生成一次重新选择请求;
|
|
6814
7111
|
* 宿主取走意图后自行打开平台文件选择器,File 本身不会写入 Store。
|
|
6815
7112
|
*
|
|
@@ -6845,6 +7142,14 @@ type ImMediaOperationResult = Readonly<{
|
|
|
6845
7142
|
reason: 'not-ready' | 'not-found' | 'failed' | 'stale';
|
|
6846
7143
|
error?: ImMediaStoreError;
|
|
6847
7144
|
}>;
|
|
7145
|
+
/**
|
|
7146
|
+
* 下载任务在 `downloadTasks` / `downloadProgress` 里的键。
|
|
7147
|
+
*
|
|
7148
|
+
* 一条媒体合集的每一项是各自独立的下载任务,却共用同一个 messageId;只用 messageId 做键的话
|
|
7149
|
+
* 后一项会把前一项整条覆盖掉,宿主读到的进度属于另一格。单媒体消息不带下标,键与历史保持一致,
|
|
7150
|
+
* 宿主既有的 `downloadProgress[message.id]` 读法不受影响。
|
|
7151
|
+
*/
|
|
7152
|
+
declare function imMediaDownloadKey(messageId: string, itemIndex?: number): string;
|
|
6848
7153
|
/** 取得当前 Vue setup 或显式 Pinia 的媒体任务 Store;不会隐式创建 Runtime。 */
|
|
6849
7154
|
declare function useImMediaStore(pinia?: Pinia): any;
|
|
6850
7155
|
|
|
@@ -8326,5 +8631,25 @@ type ImThreadStore = Store<'k2-im-thread', ImThreadStoreState, Record<string, ne
|
|
|
8326
8631
|
/** 取得当前 Vue setup 或显式 Pinia 的消息线程 Store;每个实例只管理一个当前会话。 */
|
|
8327
8632
|
declare function useImThreadStore(pinia?: Pinia): ImThreadStore;
|
|
8328
8633
|
|
|
8329
|
-
|
|
8634
|
+
/** 新消息提醒所需的领域与宿主事实;本模块不读取浏览器、路由或全局设置。 */
|
|
8635
|
+
interface MessageNotificationInput {
|
|
8636
|
+
source: 'live' | 'offline';
|
|
8637
|
+
senderId: string;
|
|
8638
|
+
accountId: string;
|
|
8639
|
+
contentType: string;
|
|
8640
|
+
muted: boolean;
|
|
8641
|
+
globallyEnabled: boolean;
|
|
8642
|
+
visibilityState: 'visible' | 'hidden';
|
|
8643
|
+
permission: 'default' | 'denied' | 'granted' | null;
|
|
8644
|
+
}
|
|
8645
|
+
type MessageNotificationDecision = {
|
|
8646
|
+
show: true;
|
|
8647
|
+
} | {
|
|
8648
|
+
show: false;
|
|
8649
|
+
reason: 'not-live' | 'unsupported' | 'permission-denied' | 'page-visible' | 'self-message' | 'system-message' | 'conversation-muted' | 'globally-disabled';
|
|
8650
|
+
};
|
|
8651
|
+
/** PC/H5 共用的实时消息提醒规则;离线历史回放不逐条弹通知。 */
|
|
8652
|
+
declare function resolveMessageNotificationDecision(input: MessageNotificationInput): MessageNotificationDecision;
|
|
8653
|
+
|
|
8654
|
+
export { applicationKey, createAndInstallImChatKit, createImChatKitContext, disposeImChatKit, ensureImChatKitSelfProfile, getImChatKitContext, imMediaDownloadKey, installImChatKit, resolveMessageNotificationDecision, useImApplicationsStore, useImCapabilitiesStore, useImComposerStore, useImConversationActivationCoordinator, useImConversationDeletionCoordinator, useImConversationListStore, useImExpressionStore, useImHistoryReturnAfterSendCoordinator, useImMediaStore, useImMessageOperationsStore, useImProfileDirectoryStore, useImQuotedMessageStore, useImReactionStore, useImSearchStore, useImSessionFavoritesStore, useImSessionStore, useImThreadPagingStore, useImThreadReturnToLatestCoordinator, useImThreadStore };
|
|
8330
8655
|
export type { ApplyImSessionInput, ChatRuntimeFactories, ChatRuntimeHostDeps, ImApplicationDomainCounts, ImApplicationReviewOperation, ImApplicationReviewResult, ImApplicationsReloadResult, ImApplicationsStoreError, ImCapabilitiesStore, ImChannelManagementMemberTarget, ImChannelMemberManagementOperation, ImChannelMemberManagementResult, ImChannelMemberManagementResultFor, ImChannelProfileActionResult, ImChannelProfileActionResultFor, ImChannelProfileOperation, ImChatKitContext, ImChatKitInstallation, ImComposerStore, ImComposerStoreActions, ImComposerStoreState, ImComposerSubmitResult, ImConversationActivationCoordinator, ImConversationActivationError, ImConversationActivationResult, ImConversationDeletionCoordinator, ImConversationDeletionError, ImConversationDeletionResult, ImConversationListActionError, ImConversationListMutationOperation, ImConversationListMutationResult, ImConversationListRefreshResult, ImConversationListStore, ImDirectContactActionResult, ImDirectContactActionResultFor, ImDirectContactOperation, ImDirectoryState, ImEmojiPanelRecentEntry, ImEmojiRecentEntry, ImExpressionLoadStatus, ImExpressionOperation, ImExpressionOperationResult, ImExpressionRecentPersistencePort, ImExpressionRecentPersistenceSnapshot, ImExpressionRecentViewItem, ImExpressionResetOptions, ImExpressionSendResult, ImExpressionStore, ImExpressionStoreActions, ImExpressionStoreError, ImExpressionStoreGetters, ImExpressionStoreState, ImForwardPreparationResult, ImGameRecentEntry, ImGroupMemberManagementOperation, ImGroupMemberManagementResult, ImGroupMemberManagementResultFor, ImGroupProfileActionResult, ImGroupProfileActionResultFor, ImGroupProfileOperation, ImHistoryReturnAfterSendCoordinator, ImHistoryReturnError, ImHistoryReturnExecution, ImHistoryReturnResult, ImMediaOperationResult, ImMediaReplacementRequest, ImMediaStoreError, ImMediaTaskPresentation, ImMembershipJoinActionResult, ImMembershipJoinOperation, ImMessageOperationsStore, ImMessageOperationsStoreActions, ImMessageOperationsStoreState, ImMessageSelectionResult, ImPersistedEmojiPanelRecentEntry, ImPersistedEmojiRecentEntry, ImPersistedExpressionAssetRecentEntry, ImPersistedGameRecentEntry, ImProfileAccessDestination, ImProfileAccessResult, ImProfileDirectoryResult, ImQuotedMessageState, ImQuotedMessageStore, ImQuotedMessageStoreActions, ImQuotedMessageStoreState, ImReactionOperationResult, ImReactionStore, ImReactionStoreActions, ImReactionStoreError, ImReactionStoreState, ImSearchOperationResult, ImSessionFavoritesReloadResult, ImSessionFavoritesStoreError, ImSessionFavoritesWriteResult, ImSessionPhase, ImSessionStore, ImThreadPagingActions, ImThreadPagingState, ImThreadPagingStore, ImThreadReturnToLatestCoordinator, ImThreadStore, ImThreadStoreActions, ImThreadStoreState };
|