123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206 |
- import { TUINotification } from "../../../TUIPlugin";
- import Message from "../../../TUICore/tim/index";
- import IComponentServer from "../IComponentServer";
- import { JSONToObject } from "./utils/utils";
- /**
- * class TUIChatServer
- *
- * TUIChat 逻辑主体
- */
- export default class TUIChatServer extends IComponentServer {
- public TUICore: any;
- public store: any;
- public currentStore: any = {};
- constructor(TUICore: any) {
- super();
- this.TUICore = TUICore;
- this.bindTIMEvent();
- this.store = TUICore.setComponentStore("TUIChat", {}, this.updateStore.bind(this));
- }
- /**
- * 组件销毁
- * destroy
- */
- public destroyed() {
- this.unbindTIMEvent();
- }
- /**
- * 数据监听回调
- * data listener callback
- *
- * @param {any} newValue 新数据
- * @param {any} oldValue 旧数据
- *
- */
- updateStore(newValue: any, oldValue: any) {
- Object.assign(this.currentStore, newValue);
- if (!newValue.conversation.conversationID) {
- this.currentStore.messageList = [];
- return;
- }
- if (newValue.conversation.conversationID && newValue.conversation.conversationID !== oldValue.conversation.conversationID) {
- this.render(newValue.conversation);
- }
- }
- public render(conversation: any) {
- const len = 15;
- this.currentStore.isFirstRender = true;
- this.currentStore.messageList = [];
- this.currentStore.readSet.clear();
- this.getMessageList({
- conversationID: conversation.conversationID,
- count: len,
- });
- if (conversation.type === this.TUICore.TIM.TYPES.CONV_GROUP) {
- this.currentStore.userInfo.isGroup = true;
- const options = {
- groupID: conversation.groupProfile.groupID,
- userIDList: [conversation.groupProfile.selfInfo.userID],
- };
- this.getGroupProfile({ groupID: conversation.groupProfile.groupID });
- this.getGroupMemberProfile(options).then((res: any) => {
- const { memberList } = res.data;
- const [selfInfo] = memberList;
- this.currentStore.selfInfo = selfInfo;
- });
- this?.TUICore?.TUIServer?.TUIGroup?.getGroupMemberList({
- groupID: conversation.groupProfile.groupID,
- count: 100,
- offset: 0,
- }).then((res: any) => {
- this.currentStore.allMemberList = res.data?.memberList;
- });
- } else {
- this.currentStore.userInfo.isGroup = false;
- this.currentStore.userInfo.list = [conversation?.userProfile];
- }
- }
- /**
- * /////////////////////////////////////////////////////////////////////////////////
- * //
- * // TIM 事件监听注册接口
- * // TIM Event listener registration interface
- * //
- * /////////////////////////////////////////////////////////////////////////////////
- */
- private bindTIMEvent() {
- this.TUICore.tim.on(this.TUICore.TIM.EVENT.MESSAGE_RECEIVED, this.handleMessageReceived, this);
- this.TUICore.tim.on(this.TUICore.TIM.EVENT.MESSAGE_MODIFIED, this.handleMessageModified, this);
- this.TUICore.tim.on(this.TUICore.TIM.EVENT.MESSAGE_REVOKED, this.handleMessageRevoked, this);
- this.TUICore.tim.on(this.TUICore.TIM.EVENT.MESSAGE_READ_BY_PEER, this.handleMessageReadByPeer, this);
- this.TUICore.tim.on(this.TUICore.TIM.EVENT.GROUP_LIST_UPDATED, this.handleGroupListUpdated, this);
- this.TUICore.tim.on(this.TUICore.TIM.EVENT.MESSAGE_READ_RECEIPT_RECEIVED, this.handleMessageReadReceiptReceived, this);
- }
- private unbindTIMEvent() {
- this.TUICore.tim.off(this.TUICore.TIM.EVENT.MESSAGE_RECEIVED, this.handleMessageReceived);
- this.TUICore.tim.off(this.TUICore.TIM.EVENT.MESSAGE_MODIFIED, this.handleMessageModified);
- this.TUICore.tim.off(this.TUICore.TIM.EVENT.MESSAGE_REVOKED, this.handleMessageRevoked);
- this.TUICore.tim.off(this.TUICore.TIM.EVENT.MESSAGE_READ_BY_PEER, this.handleMessageReadByPeer);
- this.TUICore.tim.off(this.TUICore.TIM.EVENT.GROUP_LIST_UPDATED, this.handleGroupListUpdated);
- this.TUICore.tim.off(this.TUICore.TIM.EVENT.MESSAGE_READ_RECEIPT_RECEIVED, this.handleMessageReadReceiptReceived);
- }
- private handleMessageReceived(event: any) {
- event?.data?.forEach((message: Message) => {
- if (message?.conversationID === this?.store?.conversation?.conversationID) {
- this.currentStore.messageList = [...this.currentStore.messageList, message];
- }
- TUINotification.getInstance().notify(message);
- });
- }
- private handleMessageModified(event: any) {
- const middleData = this.currentStore.messageList;
- this.currentStore.messageList = [];
- this.currentStore.messageList = middleData;
- }
- private handleMessageRevoked(event: any) {
- const middleData = this.currentStore.messageList;
- this.currentStore.messageList = [];
- this.currentStore.messageList = middleData;
- }
- private handleMessageReadByPeer(event: any) {
- const middleData = this.currentStore.messageList;
- this.currentStore.messageList = [];
- this.currentStore.messageList = middleData;
- }
- private handleGroupListUpdated(event: any) {
- event?.data.map((item: any) => {
- if (item?.groupID === this?.store?.conversation?.groupProfile?.groupID) {
- this.store.conversation.groupProfile = item;
- this.currentStore.conversation = {};
- this.currentStore.conversation = this.store.conversation;
- }
- return item;
- });
- }
- private handleMessageReadReceiptReceived(event: any) {
- const middleData = this.currentStore.messageList;
- this.currentStore.messageList = [];
- this.currentStore.messageList = middleData;
- }
- /**
- * /////////////////////////////////////////////////////////////////////////////////
- * //
- * // 处理 TIM 接口参数及回调
- * // Handling TIM interface parameters and callbacks
- * //
- * /////////////////////////////////////////////////////////////////////////////////
- */
- /**
- * 创建消息生成参数
- * Create message generation parameters
- *
- * @param {Object} content 消息体
- * @param {String} type 消息类型 text: 文本类型 file: 文件类型 face: 表情 location: 地址 custom: 自定义 merger: 合并 forward: 转发
- * @param {Callback} callback 回调函数
- * @param {any} to 发送的对象
- * @returns {options} 消息参数
- */
- public handleMessageOptions(content: any, type: string, callback?: any, to?: any) {
- const options: any = {
- to: "",
- conversationType: to?.type || this.store.conversation.type,
- payload: content,
- needReadReceipt: this.currentStore.needReadReceipt,
- };
- if (this.currentStore.needTyping) {
- options.cloudCustomData = {
- messageFeature: {
- needTyping: 1,
- version: 1,
- },
- };
- options.cloudCustomData = JSON.stringify(options.cloudCustomData);
- }
- if (type === "file" && callback) {
- options.onProgress = callback;
- }
- switch (options.conversationType) {
- case this.TUICore.TIM.TYPES.CONV_C2C:
- options.to = to?.userProfile?.userID || this.store.conversation?.userProfile?.userID || "";
- break;
- case this.TUICore.TIM.TYPES.CONV_GROUP:
- options.to = to?.groupProfile?.groupID || this.store.conversation?.groupProfile?.groupID || "";
- break;
- default:
- break;
- }
- return options;
- }
- /**
- * 处理异步函数
- * Handling asynchronous functions
- *
- * @param {callback} callback 回调函数
- * @returns {Promise} 返回异步函数
- */
- public handlePromiseCallback(callback: any) {
- return new Promise<void>((resolve, reject) => {
- const config = {
- TUIName: "TUIChat",
- callback: () => {
- callback && callback(resolve, reject);
- },
- };
- this.TUICore.setAwaitFunc(config.TUIName, config.callback);
- });
- }
- /**
- * 重试异步函数
- * Retry asynchronous functions
- * 默认执行一次,之后按时间间隔列表重复执行直到成功,重复次数完毕后仍失败则失败
- * Execute once by default, and then repeat it according to the time interval list until it succeeds.
- * If it still fails after the number of repetitions is complete, it will reject.
- *
- * @param {callback} callback 回调函数/callback function
- * @param {Array<number>} intervalList 间隔时间列表/interval list
- * @param {callback} retryBreakFn 强制重复结束条件函数/break retry function
- * @returns {Promise} 返回异步函数/return
- */
- public handlePromiseCallbackRetry(
- callback: any,
- intervalList: Array<number> = [],
- retryBreakFn: any = function () {
- return false;
- }
- ): Promise<any> {
- return new Promise<void>((resolve, reject) => {
- let times = 0;
- function tryFn() {
- times++;
- callback()
- .then(resolve)
- .catch((error: any) => {
- if (times > intervalList.length || (retryBreakFn && retryBreakFn(error))) {
- reject(error);
- return;
- }
- setTimeout(tryFn, intervalList[times - 1]);
- });
- }
- tryFn();
- });
- }
- /**
- * 文件上传进度函数处理
- * File upload progress function processing
- *
- * @param {number} progress 文件上传进度 1表示完成
- * @param {message} message 文件消息
- */
- public handleUploadProgress(progress: number, message: any) {
- this.currentStore.messageList.map((item: any) => {
- if (item.ID === message.ID) {
- item.progress = progress;
- }
- return item;
- });
- }
- /**
- * 删除会话
- *
- * @param {string} conversationID 会话ID
- * @returns {Promise}
- */
- public async deleteConversation(conversationID: string) {
- return this.handlePromiseCallback(async (resolve: any, reject: any) => {
- try {
- const imResponse: any = await this.TUICore.tim.deleteConversation(conversationID);
- resolve(imResponse);
- } catch (error) {
- reject(error);
- }
- });
- }
- /**
- * /////////////////////////////////////////////////////////////////////////////////
- * //
- * // TIM 方法
- * // TIM methods
- * //
- * /////////////////////////////////////////////////////////////////////////////////
- */
- /**
- * 发送表情消息
- * Send face messages
- *
- * @param {Object} data 消息内容/message content
- * @param {Number} data.index 表情索引/face index
- * @param {String} data.data 额外数据/extra data
- * @returns {Promise}
- */
- public sendFaceMessage(data: any): Promise<any> {
- return this.handlePromiseCallback(async (resolve: any, reject: any) => {
- try {
- const options = this.handleMessageOptions(data, "face");
- const message = this.TUICore.tim.createFaceMessage(options);
- this.currentStore.messageList.push(message);
- const imResponse = await this.TUICore.tim.sendMessage(message);
- this.currentStore.messageList = this.currentStore.messageList.map((item: any) => {
- if (item.ID === imResponse.data.message.ID) {
- return imResponse.data.message;
- }
- return item;
- });
- resolve(imResponse);
- } catch (error) {
- reject(error);
- const middleData = this.currentStore.messageList;
- this.currentStore.messageList = [];
- this.currentStore.messageList = middleData;
- }
- });
- }
- /**
- * 发送图片消息
- * Send image message
- *
- * @param {Image} image 图片文件/image
- * @returns {Promise}
- */
- public sendImageMessage(image: any): Promise<any> {
- return this.handlePromiseCallback(async (resolve: any, reject: any) => {
- try {
- const options = this.handleMessageOptions({ file: image }, "file", (progress: number) => {
- this.handleUploadProgress(progress, message);
- });
- const message = this.TUICore.tim.createImageMessage(options);
- message.progress = 0.01;
- this.currentStore.messageList.push(message);
- const imResponse = await this.TUICore.tim.sendMessage(message);
- this.currentStore.messageList = this.currentStore.messageList.map((item: any) => {
- if (item.ID === imResponse.data.message.ID) {
- return imResponse.data.message;
- }
- return item;
- });
- resolve(imResponse);
- } catch (error) {
- reject(error);
- const middleData = this.currentStore.messageList;
- this.currentStore.messageList = [];
- this.currentStore.messageList = middleData;
- }
- });
- }
- /**
- * 发送视频消息
- * Send video message
- *
- * @param {Video} video 视频文件/video
- * @returns {Promise}
- */
- public sendVideoMessage(video: any): Promise<any> {
- return this.handlePromiseCallback(async (resolve: any, reject: any) => {
- try {
- const options = this.handleMessageOptions({ file: video }, "file", (progress: number) => {
- this.handleUploadProgress(progress, message);
- });
- const message = this.TUICore.tim.createVideoMessage(options);
- message.progress = 0.01;
- this.currentStore.messageList.push(message);
- const imResponse = await this.TUICore.tim.sendMessage(message);
- this.currentStore.messageList = this.currentStore.messageList.map((item: any) => {
- if (item.ID === imResponse.data.message.ID) {
- return imResponse.data.message;
- }
- return item;
- });
- resolve(imResponse);
- } catch (error) {
- reject(error);
- const middleData = this.currentStore.messageList;
- this.currentStore.messageList = [];
- this.currentStore.messageList = middleData;
- }
- });
- }
- /**
- * 发送文件消息
- * Send file message
- *
- * @param {File} file 文件/file
- * @returns {Promise}
- */
- public sendFileMessage(file: any): Promise<any> {
- return this.handlePromiseCallback(async (resolve: any, reject: any) => {
- try {
- const options = this.handleMessageOptions({ file }, "file", (progress: number) => {
- this.handleUploadProgress(progress, message);
- });
- const message = this.TUICore.tim.createFileMessage(options);
- message.progress = 0.01;
- this.currentStore.messageList.push(message);
- const imResponse = await this.TUICore.tim.sendMessage(message);
- this.currentStore.messageList = this.currentStore.messageList.map((item: any) => {
- if (item.ID === imResponse.data.message.ID) {
- return imResponse.data.message;
- }
- return item;
- });
- resolve(imResponse);
- } catch (error) {
- reject(error);
- const middleData = this.currentStore.messageList;
- this.currentStore.messageList = [];
- this.currentStore.messageList = middleData;
- }
- });
- }
- /**
- * 发送自定义消息
- * Send Custom message
- *
- * @param {Object} data 消息内容/message content
- * @param {String} data.data 自定义消息的数据字段/custom message data fields
- * @param {String} data.description 自定义消息的说明字段/custom message description fields
- * @param {String} data.extension 自定义消息的扩展字段/custom message extension fields
- * @returns {Promise}
- */
- public sendCustomMessage(data: any): Promise<any> {
- return this.handlePromiseCallback(async (resolve: any, reject: any) => {
- try {
- data.data = JSON.stringify(data.data);
- const options = this.handleMessageOptions(data, "custom");
- const message = this.TUICore.tim.createCustomMessage(options);
- this.currentStore.messageList.push(message);
- const imResponse = await this.TUICore.tim.sendMessage(message);
- this.currentStore.messageList = this.currentStore.messageList.map((item: any) => {
- if (item.ID === imResponse.data.message.ID) {
- return imResponse.data.message;
- }
- return item;
- });
- resolve(imResponse);
- } catch (error) {
- reject(error);
- const middleData = this.currentStore.messageList;
- this.currentStore.messageList = [];
- this.currentStore.messageList = middleData;
- }
- });
- }
- /**
- * 发送地理位置消息
- * Send location message
- *
- * @param {Object} data 消息内容/message content
- * @param {String} data.description 地理位置描述信息/geographic descriptive information
- * @param {Number} data.longitude 经度/longitude
- * @param {Number} data.latitude 纬度/latitude
- * @returns {Promise}
- */
- public sendLocationMessage(data: any): Promise<any> {
- return this.handlePromiseCallback(async (resolve: any, reject: any) => {
- try {
- const options = this.handleMessageOptions(data, "location");
- const message = this.TUICore.tim.createLocationMessage(options);
- this.currentStore.messageList.push(message);
- const imResponse = await this.TUICore.tim.sendMessage(message);
- resolve(imResponse);
- } catch (error) {
- reject(error);
- const middleData = this.currentStore.messageList;
- this.currentStore.messageList = [];
- this.currentStore.messageList = middleData;
- }
- });
- }
- /**
- * 转发消息
- * forward message
- *
- * @param {message} message 消息实例/message
- * @param {any} to 转发的对象/forward to
- * @returns {Promise}
- */
- public forwardMessage(message: any, to: any): Promise<any> {
- return this.handlePromiseCallback(async (resolve: any, reject: any) => {
- try {
- const options = this.handleMessageOptions(message, "forward", {}, to);
- const imMessage = this.TUICore.tim.createForwardMessage(options);
- const imResponse = await this.TUICore.tim.sendMessage(imMessage);
- if (this.store.conversation.conversationID === imResponse.data.message.conversationID) {
- this.currentStore.messageList.push(imResponse.data.message);
- }
- resolve(imResponse);
- } catch (error) {
- reject(error);
- const middleData = this.currentStore.messageList;
- this.currentStore.messageList = [];
- this.currentStore.messageList = middleData;
- }
- });
- }
- /**
- * 发送消息已读回执
- * Send message read receipt
- *
- * @param {Array} messageList 同一个 C2C 或 GROUP 会话的消息列表,最大长度为30/A list of messages for the same C2C or GROUP conversation, with a maximum length of 30
- * @returns {Promise}
- */
- public async sendMessageReadReceipt(messageList: Array<any>) {
- return this.handlePromiseCallback(async (resolve: any, reject: any) => {
- try {
- const imResponse: any = await this.TUICore.tim.sendMessageReadReceipt(messageList);
- resolve(imResponse);
- } catch (error) {
- reject(error);
- }
- });
- }
- /**
- * 拉取已读回执列表
- * Pull read receipt list
- *
- * @param {Array} messageList 同一群会话的消息列表/The message list of the same group of the conversation
- * @returns {Promise}
- */
- public async getMessageReadReceiptList(messageList: Array<any>) {
- return this.handlePromiseCallback(async (resolve: any, reject: any) => {
- try {
- const imResponse: any = await this.TUICore.tim.getMessageReadReceiptList(messageList);
- resolve(imResponse);
- } catch (error) {
- reject(error);
- }
- });
- }
- /**
- * /////////////////////////////////////////////////////////////////////////////////
- * //
- * // 对外方法
- * //
- * /////////////////////////////////////////////////////////////////////////////////
- */
- /**
- * 获取 messageList
- * get messagelist
- *
- * @param {any} options 获取 messageList 参数/messageList options
- * @param {Boolean} history 是否获取历史消息/Whether to get historical information
- * @returns {Promise}
- */
- public async getMessageList(options: any, history?: boolean) {
- return this.handlePromiseCallback(async (resolve: any, reject: any) => {
- try {
- const imResponse = await this.TUICore.tim.getMessageList(options);
- if (imResponse.data.messageList.length) {
- await this.getMessageReadReceiptList(imResponse.data.messageList);
- }
- if (!history) {
- this.currentStore.messageList = imResponse.data.messageList;
- } else {
- this.currentStore.messageList = [...imResponse.data.messageList, ...this.currentStore.messageList];
- }
- this.currentStore.nextReqMessageID = imResponse.data.nextReqMessageID;
- this.currentStore.isCompleted = imResponse.data.isCompleted;
- resolve(imResponse);
- } catch (error) {
- reject(error);
- }
- });
- }
- /**
- * 获取历史消息
- * get history messagelist
- *
- * @returns {Promise}
- */
- public async getHistoryMessageList() {
- const options = {
- conversationID: this.currentStore.conversation.conversationID,
- nextReqMessageID: this.currentStore.nextReqMessageID,
- count: 15,
- };
- if (!this.currentStore.isCompleted) {
- this.getMessageList(options, true);
- }
- }
- /**
- * 发送文本消息
- * send text message
- *
- * @param {any} text 发送的消息/text message
- * @param {object} data 被引用消息的内容/The content of the quoted message
- * @returns {Promise}
- */
- public sendTextMessage(text: any, data: any): Promise<any> {
- return this.handlePromiseCallback(async (resolve: any, reject: any) => {
- try {
- const options = this.handleMessageOptions({ text }, "text");
- let cloudCustomDataObj = {};
- if (options.cloudCustomData) {
- try {
- cloudCustomDataObj = JSONToObject(options.cloudCustomData);
- } catch {
- cloudCustomDataObj = {};
- }
- }
- const cloudCustomData = JSON.stringify(data);
- const secondOptions = Object.assign(options, {
- cloudCustomData,
- ...cloudCustomDataObj,
- });
- const message = this.TUICore.tim.createTextMessage(secondOptions);
- this.currentStore.messageList.push(message);
- const imResponse = await this.TUICore.tim.sendMessage(message);
- this.currentStore.messageList = this.currentStore.messageList.map((item: any) => {
- if (item.ID === imResponse.data.message.ID) {
- return imResponse.data.message;
- }
- return item;
- });
- resolve(imResponse);
- } catch (error) {
- reject(error);
- const middleData = this.currentStore.messageList;
- this.currentStore.messageList = [];
- this.currentStore.messageList = middleData;
- }
- });
- }
- /**
- * 发送【对方正在输入中】在线自定义消息
- * send typing online custom message
- *
- * @param {Object} data 消息内容/message content
- * @param {String} data.data 自定义消息的数据字段/custom message data field
- * @param {String} data.description 自定义消息的说明字段/custom message description field
- * @param {String} data.extension 自定义消息的扩展字段/custom message extension field
- * @returns {Promise}
- */
- public sendTypingMessage(data: any): Promise<any> {
- return this.handlePromiseCallback(async (resolve: any, reject: any) => {
- try {
- data.data = JSON.stringify(data.data);
- const options = this.handleMessageOptions(data, "custom");
- const message = this.TUICore.tim.createCustomMessage(options);
- const imResponse = await this.TUICore.tim.sendMessage(message, {
- onlineUserOnly: true,
- });
- resolve(imResponse);
- } catch (error) {
- reject(error);
- const middleData = this.currentStore.messageList;
- this.currentStore.messageList = [];
- this.currentStore.messageList = middleData;
- }
- });
- }
- /**
- * 发送@ 提醒功能的文本消息
- * Send @ Reminder text message
- *
- * @param {any} data 消息内容/message content
- * @param {String} data.text 文本消息/text message
- * @param {Array} data.atUserList 需要 @ 的用户列表,如果需要 @ALL,请传入 TIM.TYPES.MSG_AT_ALL / List of users who need @, if you need @ALL, please pass in TIM.TYPES.MSG_AT_ALL
- * @returns {message}
- *
- * - 注:此接口仅用于群聊/This interface is only used for group chat
- */
- public sendTextAtMessage(data: any) {
- return this.handlePromiseCallback(async (resolve: any, reject: any) => {
- try {
- const options = this.handleMessageOptions(data, "text");
- const message = this.TUICore.tim.createTextAtMessage(options);
- this.currentStore.messageList.push(message);
- const imResponse = await this.TUICore.tim.sendMessage(message);
- this.currentStore.messageList = this.currentStore.messageList.map((item: any) => {
- if (item.ID === imResponse.data.message.ID) {
- return imResponse.data.message;
- }
- return item;
- });
- resolve(imResponse);
- } catch (error) {
- reject(error);
- const middleData = this.currentStore.messageList;
- this.currentStore.messageList = [];
- this.currentStore.messageList = middleData;
- }
- });
- }
- /**
- * 发送合并消息
- * send merger message
- *
- * @param {Object} data 消息内容/message content
- * @param {Array.<Message>} data.messageList 合并的消息列表/merger message list
- * @param {String} data.title 合并的标题/merger title
- * @param {String} data.abstractList 摘要列表,不同的消息类型可以设置不同的摘要信息/Summary list, different message types can set different summary information
- * @param {String} data.compatibleText 兼容文本/ompatible text
- * @returns {Promise}
- */
- public sendMergerMessage(data: any): Promise<any> {
- return this.handlePromiseCallback(async (resolve: any, reject: any) => {
- try {
- const options = this.handleMessageOptions(data, "merger");
- const message = this.TUICore.tim.createMergerMessage(options);
- this.currentStore.messageList.push(message);
- const imResponse = await this.TUICore.tim.sendMessage(message);
- this.currentStore.messageList = this.currentStore.messageList.map((item: any) => {
- if (item.ID === imResponse.data.message.ID) {
- return imResponse.data.message;
- }
- return item;
- });
- resolve(imResponse);
- } catch (error) {
- reject(error);
- const middleData = this.currentStore.messageList;
- this.currentStore.messageList = [];
- this.currentStore.messageList = middleData;
- }
- });
- }
- /**
- * 消息撤回
- * revoke message
- *
- * @param {message} message 消息实例/message
- * @returns {Promise}
- */
- public revokeMessage(message: any): Promise<any> {
- return this.handlePromiseCallback(async (resolve: any, reject: any) => {
- try {
- const imResponse = await this.TUICore.tim.revokeMessage(message);
- const cloudCustomData = JSONToObject(message?.cloudCustomData);
- if (cloudCustomData?.messageReply?.messageRootID) {
- await this.revokeReplyMessage(message);
- }
- resolve(imResponse);
- } catch (error) {
- reject(error);
- const middleData = this.currentStore.messageList;
- this.currentStore.messageList = [];
- this.currentStore.messageList = middleData;
- }
- });
- }
- /**
- * 重发消息
- * resend message
- *
- * @param {message} message 消息实例/message
- * @returns {Promise}
- */
- public resendMessage(message: any): Promise<any> {
- return this.handlePromiseCallback(async (resolve: any, reject: any) => {
- try {
- const imResponse = await this.TUICore.tim.resendMessage(message);
- this.currentStore.messageList = this.currentStore.messageList.filter((item: any) => item.ID !== message.ID);
- this.currentStore.messageList.push(imResponse.data.message);
- resolve(imResponse);
- } catch (error) {
- reject(error);
- }
- });
- }
- /**
- * 删除消息
- * delete message
- *
- * @param {Array.<message>} messages 消息实例/message
- * @returns {Promise}
- */
- public deleteMessage(messages: any): Promise<any> {
- return this.handlePromiseCallback(async (resolve: any, reject: any) => {
- try {
- const imResponse = await this.TUICore.tim.deleteMessage(messages);
- resolve(imResponse);
- const middleData = this.currentStore.messageList;
- this.currentStore.messageList = [];
- this.currentStore.messageList = middleData;
- } catch (error) {
- reject(error);
- }
- });
- }
- /**
- * 变更消息
- * modify message
- *
- * @param {Array.<message>} message 消息实例/message
- * @returns {Promise}
- */
- public modifyMessage(message: any): Promise<any> {
- return this.handlePromiseCallback(async (resolve: any, reject: any) => {
- try {
- const imResponse = await this.TUICore.tim.modifyMessage(message);
- resolve(imResponse);
- } catch (error) {
- // 修改消息失败
- // Modify message error
- const code = (error as any)?.code;
- const data = (error as any)?.data;
- if (code === 2480) {
- console.warn("MODIFY_MESSAGE_ERROR", "修改消息发生冲突,data.message 是最新的消息", "data.message:", data?.message);
- } else if (code === 2481) {
- console.warn("MODIFY_MESSAGE_ERROR", "不支持修改直播群消息");
- } else if (code === 20026) {
- console.warn("MODIFY_MESSAGE_ERROR", "消息不存在");
- }
- reject(error);
- }
- });
- }
- /**
- * 回复消息
- * reply message
- * @param {Array.<message>} message 消息实例/message
- * @returns {Promise}
- */
- public replyMessage(message: any, messageRoot?: any): Promise<any> {
- const replyFunction = () => {
- return this.handlePromiseCallback(async (resolve: any, reject: any) => {
- try {
- const repliesObject = {
- messageAbstract: message?.payload?.text,
- messageSender: message?.from,
- messageID: message?.ID,
- messageType: message?.type,
- messageTime: message?.time,
- messageSequence: message?.sequence,
- version: 1,
- };
- if (!messageRoot) {
- const cloudCustomData = JSONToObject(message?.cloudCustomData);
- const messageRootID = cloudCustomData?.messageReply?.messageRootID;
- messageRoot = (await this?.currentStore?.messageList?.find((item: any) => item?.ID === messageRootID)) || this.findMessage(messageRootID);
- }
- const rootCloudCustomData = messageRoot?.cloudCustomData ? JSONToObject(messageRoot?.cloudCustomData) : { messageReplies: {} };
- if (rootCloudCustomData?.messageReplies?.replies) {
- rootCloudCustomData.messageReplies.replies = [
- // eslint-disable-next-line no-unsafe-optional-chaining
- ...rootCloudCustomData?.messageReplies?.replies,
- repliesObject,
- ];
- } else {
- rootCloudCustomData.messageReplies = {
- replies: [repliesObject],
- version: 1,
- };
- }
- messageRoot.cloudCustomData = JSON.stringify(rootCloudCustomData);
- const imResponse = this.modifyMessage(messageRoot);
- resolve(imResponse);
- } catch (error) {
- reject(error);
- }
- });
- };
- const retryBreakFunction = function (error: any) {
- if (error && error?.code === 2480) return false;
- return true;
- };
- return this.handlePromiseCallbackRetry(replyFunction, [500, 1000, 3000], retryBreakFunction);
- }
- /**
- * 撤回回复消息
- * revoke reply message
- * @param {Array.<message>} message 消息实例/message
- * @returns {Promise}
- */
- public revokeReplyMessage(message: any, messageRoot?: any): Promise<any> {
- const revokeReplyFunction = () => {
- return this.handlePromiseCallback(async (resolve: any, reject: any) => {
- try {
- if (!messageRoot) {
- const cloudCustomData = JSONToObject(message?.cloudCustomData);
- const messageRootID = cloudCustomData?.messageReply?.messageRootID;
- messageRoot = (await this?.currentStore?.messageList?.find((item: any) => item?.ID === messageRootID)) || this.findMessage(messageRootID);
- }
- const rootCloudCustomData = messageRoot?.cloudCustomData ? JSONToObject(messageRoot?.cloudCustomData) : { messageReplies: {} };
- if (rootCloudCustomData?.messageReplies?.replies) {
- const index = rootCloudCustomData.messageReplies.replies.findIndex((item: any) => item?.messageID === message?.ID);
- rootCloudCustomData?.messageReplies?.replies?.splice(index, 1);
- }
- messageRoot.cloudCustomData = JSON.stringify(rootCloudCustomData);
- const imResponse = this.modifyMessage(messageRoot);
- resolve(imResponse);
- } catch (error) {
- reject(error);
- }
- });
- };
- const retryBreakFunction = function (error: any) {
- if (error && error?.code === 2480) return false;
- return true;
- };
- return this.handlePromiseCallbackRetry(revokeReplyFunction, [500, 1000, 3000], retryBreakFunction);
- }
- /**
- * 表情回应
- * emoji react
- * @param {Array.<message>} message 消息实例/message
- * @returns {Promise}
- */
- public emojiReact(message: any, emojiID: any): Promise<any> {
- const emojiReactFunction = () => {
- return this.handlePromiseCallback(async (resolve: any, reject: any) => {
- try {
- if (!message || !message?.ID || !emojiID) reject();
- const userID = this.TUICore?.TUIServer?.TUIProfile?.store?.profile?.userID;
- message = (await this?.currentStore?.messageList?.find((item: any) => item?.ID === message?.ID)) || this.findMessage(message?.ID);
- const cloudCustomData = message?.cloudCustomData ? JSONToObject(message?.cloudCustomData) : { messageReact: {} };
- if (cloudCustomData?.messageReact?.reacts) {
- if (cloudCustomData?.messageReact?.reacts[emojiID]) {
- const index = cloudCustomData?.messageReact?.reacts[emojiID]?.indexOf(userID);
- if (index === -1) {
- cloudCustomData?.messageReact?.reacts[emojiID]?.push(userID);
- } else {
- cloudCustomData?.messageReact?.reacts[emojiID]?.splice(index, 1);
- if (cloudCustomData?.messageReact?.reacts[emojiID]?.length === 0) {
- delete cloudCustomData?.messageReact?.reacts[emojiID];
- }
- }
- } else {
- cloudCustomData.messageReact.reacts[emojiID] = [userID];
- }
- } else {
- cloudCustomData.messageReact = {
- reacts: {},
- version: 1,
- };
- cloudCustomData.messageReact.reacts[emojiID] = [userID];
- }
- message.cloudCustomData = JSON.stringify(cloudCustomData);
- const imResponse = this.modifyMessage(message);
- resolve(imResponse);
- } catch (error) {
- reject(error);
- }
- });
- };
- const retryBreakFunction = function (error: any) {
- if (error && error?.code === 2480) return false;
- return true;
- };
- return this.handlePromiseCallbackRetry(emojiReactFunction, [500, 1000, 3000], retryBreakFunction);
- }
- /**
- * 查询消息
- * find message
- * @param {String} messageID 消息实例ID/messageID
- * @returns {Promise}
- */
- public findMessage(messageID: string): Promise<any> {
- return this.handlePromiseCallback(async (resolve: any, reject: any) => {
- try {
- const imResponse = await this.TUICore.tim.findMessage(messageID);
- resolve(imResponse);
- } catch (error) {
- reject(error);
- }
- });
- }
- /**
- * 获取群组属性
- * get group profile
- *
- * @param {any} options 参数
- * @param {String} options.groupID 群组ID
- * @param {Array.<String>} options.groupProfileFilter 群资料过滤器
- * @returns {Promise}
- */
- public getGroupProfile(options: any): Promise<any> {
- return this.handlePromiseCallback(async (resolve: any, reject: any) => {
- try {
- const imResponse = await this.TUICore.tim.getGroupProfile(options);
- this.currentStore.conversation.groupProfile = imResponse.data.group;
- resolve(imResponse);
- } catch (error) {
- reject(error);
- }
- });
- }
- /**
- * 获取群成员资料
- * get group member profile
- *
- * @param {any} options 参数
- * @param {String} options.groupID 群组ID
- * @param {Array.<String>} options.userIDList 要查询的群成员用户 ID 列表
- * @param { Array.<String>} options.memberCustomFieldFilter 群成员自定义字段筛选
- * @returns {Promise}
- */
- public getGroupMemberProfile(options: any): Promise<any> {
- return this.handlePromiseCallback(async (resolve: any, reject: any) => {
- try {
- const imResponse = await this.TUICore.tim.getGroupMemberProfile(options);
- resolve(imResponse);
- } catch (error) {
- reject(error);
- }
- });
- }
- /**
- * 处理申请加群
- * handling group application
- * - 管理员
- * administrator
- *
- * @param {any} options 参数
- * @param {String} options.handleAction 处理结果 Agree(同意) / Reject(拒绝)
- * @param {String} options.handleMessage 附言
- * @param {Message} options.message 对应【群系统通知】的消息实例
- * @returns {Promise}
- */
- public handleGroupApplication(options: any): Promise<any> {
- return this.handlePromiseCallback(async (resolve: any, reject: any) => {
- try {
- const imResponse = await this.TUICore.tim.handleGroupApplication(options);
- resolve(imResponse);
- } catch (error) {
- reject(error);
- }
- });
- }
- /**
- * 获取其他用户资料
- * get user profile
- *
- * @param {Array<string>} userIDList 用户的账号列表/userID list
- * @returns {Promise}
- */
- public async getUserProfile(userIDList: Array<string>) {
- return this.handlePromiseCallback(async (resolve: any, reject: any) => {
- try {
- const imResponse = await this.TUICore.tim.getUserProfile({
- userIDList,
- });
- resolve(imResponse);
- } catch (error) {
- reject(error);
- }
- });
- }
- /**
- * 获取 SDK 缓存的好友列表
- * Get the friend list cached by the SDK
- *
- * @param {Array<string>} userIDList 用户的账号列表
- * @returns {Promise}
- */
- public async getFriendList(): Promise<void> {
- return this.handlePromiseCallback(async (resolve: any, reject: any) => {
- try {
- const imResponse = await this.TUICore.tim.getFriendList();
- resolve(imResponse);
- } catch (error) {
- reject(error);
- }
- });
- }
- /**
- * 校验好友关系
- * check friend
- *
- * @param {string} userID 用户账号
- * @returns {Promise}
- */
- public async checkFriend(userID: string, type: string): Promise<void> {
- return this.handlePromiseCallback(async (resolve: any, reject: any) => {
- try {
- const imResponse = await this.TUICore.tim.checkFriend({
- userIDList: [userID],
- type,
- });
- const isFriendShip = imResponse?.data?.successUserIDList[0]?.relation;
- resolve(isFriendShip);
- } catch (error) {
- reject(error);
- }
- });
- }
- /**
- * 获取群消息已读成员列表
- * Get the list of memebers who have read the group message.
- *
- * @param {message} message 消息实例/message
- * @param {string} cursor 分页拉取的游标,第一次拉取传''/Paging pull the cursor,first pull pass ''
- * @param {number} count 分页拉取的个数/The number of page pulls
- * @returns {Promise}
- */
- public async getGroupReadMemberList(message: any, cursor = "", count = 15): Promise<any> {
- return this.handlePromiseCallback(async (resolve: any, reject: any) => {
- try {
- const imResponse = await this.TUICore.tim.getGroupMessageReadMemberList({
- message,
- filter: 0,
- cursor,
- count,
- });
- resolve(imResponse);
- } catch (error) {
- reject(error);
- }
- });
- }
- /**
- * 获取群消息未读成员列表
- * Get the list of memebers who have not read the group message.
- *
- * @param {message} message 消息实例/message
- * @param {string} cursor 分页拉取的游标,第一次拉取传''/Paging pull the cursor,first pull pass ''
- * @param {number} count 分页拉取的个数/The number of page pulls
- * @returns {Promise}
- */
- public async getGroupUnreadMemberList(message: any, cursor = "", count = 15): Promise<any> {
- return this.handlePromiseCallback(async (resolve: any, reject: any) => {
- try {
- const imResponse = await this.TUICore.tim.getGroupMessageReadMemberList({
- message,
- filter: 1,
- cursor,
- count,
- });
- resolve(imResponse);
- } catch (error) {
- reject(error);
- }
- });
- }
- /**
- * 自己发送消息上屏显示
- *
- * @param {message} message 消息实例/message
- */
- public async handleMessageSentByMeToView(message: any) {
- if (message?.conversationID === this?.store?.conversation?.conversationID) {
- this.currentStore.messageList.push(message);
- }
- return;
- }
- /**
- * /////////////////////////////////////////////////////////////////////////////////
- * //
- * // UI 数据绑定server数据同步
- * // UI data binding server data synchronization
- * //
- * /////////////////////////////////////////////////////////////////////////////////
- */
- /**
- * 赋值
- * bind
- *
- * @param {Object} params 使用的数据/params
- * @returns {Object} 数据/data
- */
- public bind(params: any) {
- return (this.currentStore = params);
- }
- }
|