|
@@ -1,180 +1,305 @@
|
|
|
-import TIM from './tim-wx';
|
|
|
-import LibGenerateTestUserSig from "./lib-generate-test-usersig-es.min";
|
|
|
+import './runtime'
|
|
|
+import TIM from './tim-wx';
|
|
|
+import LibGenerateTestUserSig from "./lib-generate-test-usersig-es.min";
|
|
|
+
|
|
|
+const EXPIRETIME = 604800;
|
|
|
+const LOGTAG = '--JHIM--:';
|
|
|
|
|
|
-const EXPIRETIME = 604800;
|
|
|
-const LOGTAG = '--JHIM--:';
|
|
|
+class JhImGroup {
|
|
|
+ constructor(jhim, groupId, groupType, name ,avatar) {
|
|
|
+ this.jhim = jhim;
|
|
|
+ this.groupId = groupId;
|
|
|
+ this.groupType = groupType;
|
|
|
+ this.name = name;
|
|
|
+ this.avatar = avatar;
|
|
|
+ this.groupReady = false;
|
|
|
+ return this;
|
|
|
+ }
|
|
|
+ get ready() {
|
|
|
+ return this.jhim.ready && this.groupReady;
|
|
|
+ }
|
|
|
+ join(isOwner) {
|
|
|
+ console.log(LOGTAG + 'join', this.groupId, isOwner);
|
|
|
+
|
|
|
+ let join = () => {
|
|
|
+ console.log(LOGTAG + 'dojoin', this.groupId);
|
|
|
+ return this.jhim.tim.joinGroup({
|
|
|
+ groupID: this.groupId,
|
|
|
+ type: TIM.TYPES.GRP_AVCHATROOM
|
|
|
+ }).then(res => {
|
|
|
+ console.log(LOGTAG + 'joinGrouped', res.data.status);
|
|
|
+ switch (res.data.status) {
|
|
|
+ case TIM.TYPES.JOIN_STATUS_WAIT_APPROVAL: // 等待管理员同意
|
|
|
+ break;
|
|
|
+ case TIM.TYPES.JOIN_STATUS_SUCCESS: // 加群成功
|
|
|
+ case TIM.TYPES.JOIN_STATUS_ALREADY_IN_GROUP: // 已经在群中
|
|
|
+ this.groupReady = true;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
|
|
|
-export default class JhIm {
|
|
|
- constructor(userId, sdkAppID, secretKey) {
|
|
|
- this.userId = userId;
|
|
|
- this.sdkAppID = sdkAppID;
|
|
|
- this.secretKey = secretKey;
|
|
|
- this.tim = TIM.create({ SDKAppID: this.sdkAppID });
|
|
|
- const generator = new LibGenerateTestUserSig(this.sdkAppID, this.secretKey, EXPIRETIME);
|
|
|
- this.userSig = generator.genTestUserSig(this.userId);
|
|
|
- this.roomId = null;
|
|
|
- this.logined = false;
|
|
|
- this.groupReady = false;
|
|
|
-
|
|
|
- // 0 普通级别,日志量较多,接入时建议使用
|
|
|
- // 1 release级别,SDK 输出关键信息,生产环境时建议使用
|
|
|
- // 2 告警级别,SDK 只输出告警和错误级别的日志
|
|
|
- // 3 错误级别,SDK 只输出错误级别的日志
|
|
|
- // 4 无日志级别,SDK 将不打印任何日志
|
|
|
- this.tim.setLogLevel(1);
|
|
|
-
|
|
|
- this.tim.on(TIM.EVENT.MESSAGE_RECEIVED, event=>{
|
|
|
- console.log(LOGTAG+'recv',event);
|
|
|
- let msgs = [];
|
|
|
- event.data.forEach(v=>{
|
|
|
- if(v.type == "TIMTextElem") {
|
|
|
- msgs.push({
|
|
|
- name: v.nick,
|
|
|
- avatar: v.avatar,
|
|
|
- text: v.payload.text
|
|
|
- })
|
|
|
- }else if(v.type == "TIMGroupTipElem") {
|
|
|
- this.onIMGroupTipElem&&this.onIMGroupTipElem(v.payload);
|
|
|
- }
|
|
|
- })
|
|
|
-
|
|
|
- this.onIMMessageReceived&&this.onIMMessageReceived(msgs);
|
|
|
- }, this);
|
|
|
+ return this.jhim.tim.searchGroupByID(this.groupId).then(() => {
|
|
|
+ return join();
|
|
|
+ }, () => {
|
|
|
+ console.log(LOGTAG + 'createGroup');
|
|
|
+ return this.jhim.tim.createGroup({
|
|
|
+ groupID: this.groupId,
|
|
|
+ name: this.groupId,
|
|
|
+ type: this.groupType,
|
|
|
+ }).then(() => {
|
|
|
+ return join();
|
|
|
+ });
|
|
|
+ });
|
|
|
+ }
|
|
|
+ exit(dismiss) {
|
|
|
+ console.log(LOGTAG + 'exit', this.groupId, dismiss);
|
|
|
+ return this.jhim.tim.quitGroup(this.groupId).then(() => {
|
|
|
+ this.groupReady = false;
|
|
|
+ }).then(()=>{
|
|
|
+ if(dismiss) {
|
|
|
+ return this.jhim.tim.dismissGroup(this.groupId);;
|
|
|
+ }else {
|
|
|
+ return Promise.resolve();
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ getProfile() {
|
|
|
+ return this.jhim.tim.getGroupProfile({
|
|
|
+ groupID: this.groupId
|
|
|
+ }).then(res => res.data.group);
|
|
|
+ // memberCount
|
|
|
+ }
|
|
|
+ on(cb, type) {
|
|
|
+ if(!cb) return this;
|
|
|
+ cb.jhimgroupcb = event => {
|
|
|
+ let msgs = [];
|
|
|
+ event.data.forEach(v => {
|
|
|
+ if(v.conversationType==TIM.TYPES.CONV_GROUP && v.to==this.groupId && (!type || type==v.type)){
|
|
|
+ msgs.push(v)
|
|
|
+ }
|
|
|
+ });
|
|
|
+ if(msgs.length) cb(msgs);
|
|
|
+ }
|
|
|
+ return this;
|
|
|
+ }
|
|
|
+ off(cb) {
|
|
|
+ if(!cb) return this;
|
|
|
+ this.jhim.tim.off(TIM.EVENT.MESSAGE_RECEIVED, cb.jhimgroupcb);
|
|
|
+ return this;
|
|
|
+ }
|
|
|
+ onReady(cb) {
|
|
|
+ if(!cb) return this;
|
|
|
+ cb.jhimcbready = event => {
|
|
|
+ cb(this.ready)
|
|
|
+ }
|
|
|
+ cb.jhimcbnotready = event => {
|
|
|
+ cb(this.ready)
|
|
|
+ }
|
|
|
+ this.jhim.tim.on(TIM.EVENT.SDK_READY, cb.jhimcbready);
|
|
|
+ this.jhim.tim.on(TIM.EVENT.SDK_NOT_READY, cb.jhimcbnotready);
|
|
|
+ return this;
|
|
|
+ }
|
|
|
+ offReady(cb) {
|
|
|
+ if(!cb) return this;
|
|
|
+ this.tim.off(TIM.EVENT.SDK_READY, cb.jhimcbready);
|
|
|
+ this.tim.off(TIM.EVENT.SDK_NOT_READY, cb.jhimcbnotready);
|
|
|
+ return this;
|
|
|
+ }
|
|
|
+ sendText(text) {
|
|
|
+ const message = this.jhim.tim.createTextMessage({
|
|
|
+ to: this.groupId,
|
|
|
+ conversationType: TIM.TYPES.CONV_GROUP,
|
|
|
+ payload: {
|
|
|
+ text
|
|
|
+ },
|
|
|
+ })
|
|
|
+ return this.jhim.tim.sendMessage(message).then(() => message);
|
|
|
+ }
|
|
|
+ sendCustomMessage(payload) {
|
|
|
+ const message = this.tim.createCustomMessage({
|
|
|
+ to: this.groupId,
|
|
|
+ conversationType: TIM.TYPES.CONV_GROUP,
|
|
|
+ payload,
|
|
|
+ })
|
|
|
+ return this.tim.sendMessage(message).then(() => message);
|
|
|
+ }
|
|
|
+}
|
|
|
|
|
|
- this.tim.on(TIM.EVENT.SDK_READY, event=>this.onIMSDKReady&&this.onIMSDKReady(event), this);
|
|
|
- this.tim.on(TIM.EVENT.SDK_NOT_READY, event=>{
|
|
|
- this.logined = false;
|
|
|
- this.onIMSDKNotReady&&this.onIMSDKNotReady();
|
|
|
- }, this);
|
|
|
+let instance = null;
|
|
|
+export default class JhIm {
|
|
|
+ static getInstance(userId, sdkAppID, secretKey, userSig) {
|
|
|
+ if (JhIm.instance) return JhIm.instance;
|
|
|
+ return JhIm.instance = new JhIm(userId, sdkAppID, secretKey, userSig);
|
|
|
+ }
|
|
|
+
|
|
|
+ constructor(userId, sdkAppID, secretKey, userSig) {
|
|
|
+ this.userId = userId;
|
|
|
+ this.sdkAppID = sdkAppID;
|
|
|
+ this.secretKey = secretKey;
|
|
|
+ this.tim = TIM.create({
|
|
|
+ SDKAppID: this.sdkAppID
|
|
|
+ });
|
|
|
+ const generator = new LibGenerateTestUserSig(this.sdkAppID, this.secretKey, EXPIRETIME);
|
|
|
+ this.userSig = userSig || generator.genTestUserSig(this.userId);
|
|
|
+ this.ready = false;
|
|
|
+ this.roomId = null;
|
|
|
+ this.groupReady = false;
|
|
|
+
|
|
|
+ // 0 普通级别,日志量较多,接入时建议使用
|
|
|
+ // 1 release级别,SDK 输出关键信息,生产环境时建议使用
|
|
|
+ // 2 告警级别,SDK 只输出告警和错误级别的日志
|
|
|
+ // 3 错误级别,SDK 只输出错误级别的日志
|
|
|
+ // 4 无日志级别,SDK 将不打印任何日志
|
|
|
+ this.tim.setLogLevel(3);
|
|
|
+
|
|
|
+ this.TYPES = TIM.TYPES;
|
|
|
+ this.EVENT = TIM.EVENT;
|
|
|
+
|
|
|
+ this.tim.on(TIM.EVENT.MESSAGE_RECEIVED, event => {
|
|
|
+ console.log(LOGTAG + 'recv', event);
|
|
|
+ let msgs = [];
|
|
|
+ event.data.forEach(v => {
|
|
|
+ // https://imsdk-1252463788.file.myqcloud.com/IM_DOC/Web/Message.html
|
|
|
+ if (v.type == TIM.TYPES.MSG_TEXT) {
|
|
|
+ msgs.push(v);
|
|
|
+ msgs.push({
|
|
|
+ type: v.type,
|
|
|
+ name: v.nick,
|
|
|
+ avatar: v.avatar,
|
|
|
+ text: v.payload.text,
|
|
|
+ conversationType: v.conversationType,
|
|
|
+ time: v.time,
|
|
|
+ })
|
|
|
+ } else if (v.type == "TIMGroupTipElem") {
|
|
|
+ this.onIMGroupTipElem && this.onIMGroupTipElem(v.payload);
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ this.onIMMessageReceived && this.onIMMessageReceived(msgs);
|
|
|
+ }, this);
|
|
|
+
|
|
|
+ this.tim.on(TIM.EVENT.SDK_READY, event => {
|
|
|
+ this.ready = true;
|
|
|
+ }, this);
|
|
|
+ this.tim.on(TIM.EVENT.SDK_NOT_READY, event => {
|
|
|
+ this.ready = false;
|
|
|
+ }, this);
|
|
|
+
|
|
|
+ return this;
|
|
|
+ }
|
|
|
+ destory() {
|
|
|
+ this.tim = null;
|
|
|
+ }
|
|
|
+ on(name, cb) {
|
|
|
+ // 事件
|
|
|
+ // https://imsdk-1252463788.file.myqcloud.com/IM_DOC/Web/module-EVENT.html
|
|
|
+ // 1. 收到消息 TIM.EVENT.MESSAGE_RECEIVED
|
|
|
+ // https://imsdk-1252463788.file.myqcloud.com/IM_DOC/Web/Message.html
|
|
|
+ // -- type,
|
|
|
+ // -- nick,
|
|
|
+ // -- avatar,
|
|
|
+ // -- payload
|
|
|
+ // -- conversationType
|
|
|
+ // -- time,
|
|
|
+ // 2. 接入 TIM.EVENT.SDK_READY
|
|
|
+ // 3. 掉线 TIM.EVENT.SDK_NOT_READY
|
|
|
+ // 4. 收到被踢下线通知 TIM.EVENT.KICKED_OUT
|
|
|
+ // TIM.EVENT.KICKED_OUT
|
|
|
+ // 5. 收到 SDK 发生错误通知 TIM.EVENT.ERROR
|
|
|
+ // - event.name - TIM.EVENT.ERROR
|
|
|
+ // - event.data.code - 错误码
|
|
|
+ // - event.data.message - 错误信息
|
|
|
+ this.tim.on(name, cb);
|
|
|
+ return this;
|
|
|
+ }
|
|
|
+ off(name, cb) {
|
|
|
+ this.tim.off(name, cb);
|
|
|
+ return this;
|
|
|
+ }
|
|
|
+ login(name, avatar) {
|
|
|
+ if (this.ready) return Promise.resolve();
|
|
|
|
|
|
- // 收到被踢下线通知
|
|
|
- // event.name - TIM.EVENT.KICKED_OUT
|
|
|
- // event.data.type - 被踢下线的原因,例如 :
|
|
|
- // - TIM.TYPES.KICKED_OUT_MULT_ACCOUNT 多实例登录被踢
|
|
|
- // - TIM.TYPES.KICKED_OUT_MULT_DEVICE 多终端登录被踢
|
|
|
- // - TIM.TYPES.KICKED_OUT_USERSIG_EXPIRED 签名过期被踢。使用前需要将SDK版本升级至v2.4.0或以上。
|
|
|
- this.tim.on(TIM.EVENT.KICKED_OUT, event=>this.onIMKickedOut&&this.onIMKickedOut(event), this);
|
|
|
-
|
|
|
- // 收到 SDK 发生错误通知,可以获取错误码和错误信息
|
|
|
- // event.name - TIM.EVENT.ERROR
|
|
|
- // event.data.code - 错误码
|
|
|
- // event.data.message - 错误信息
|
|
|
- this.tim.on(TIM.EVENT.ERROR, event=>this.onIMError&&this.onIMError(event), this);
|
|
|
- return this;
|
|
|
- }
|
|
|
- on(name, cb) {
|
|
|
- this[name] = cb;
|
|
|
- return this;
|
|
|
- }
|
|
|
- off(name) {
|
|
|
- this[name] = null;
|
|
|
- return this;
|
|
|
- }
|
|
|
- login(name, avatar) {
|
|
|
- if(this.logined) return Promise.resolve();
|
|
|
-
|
|
|
- this.name = name;
|
|
|
- this.avatar = avatar;
|
|
|
- return new Promise(resolve=>{
|
|
|
- let cb = event=>{
|
|
|
- this.logined = true;
|
|
|
- this.tim.updateMyProfile({
|
|
|
- nick: name,
|
|
|
- avatar: avatar,
|
|
|
- allowType: TIM.TYPES.ALLOW_TYPE_ALLOW_ANY
|
|
|
- });
|
|
|
- console.log(LOGTAG+'ready');
|
|
|
- this.onIMReady&&this.onIMReady(event);
|
|
|
- resolve();
|
|
|
- this.tim.off(TIM.EVENT.SDK_READY, cb, this);
|
|
|
- }
|
|
|
- this.tim.on(TIM.EVENT.SDK_READY, cb, this);
|
|
|
- console.log(LOGTAG+'login');
|
|
|
- this.tim.login({
|
|
|
- userID: this.userId,
|
|
|
- userSig: this.userSig,
|
|
|
- })
|
|
|
- });
|
|
|
- }
|
|
|
- logout() {
|
|
|
- if(!this.logined) return Promise.resolve();
|
|
|
-
|
|
|
- return this.tim.logout().then(()=>{
|
|
|
- this.logined = false;
|
|
|
- });
|
|
|
- }
|
|
|
- createGroup(roomId) {
|
|
|
- console.log(LOGTAG+'search for createGroup', roomId);
|
|
|
- this.roomId = String(roomId);
|
|
|
- return this.tim.searchGroupByID(this.roomId).then(()=>{
|
|
|
- return this.joinGroup(roomId);
|
|
|
- },()=>{
|
|
|
- console.log(LOGTAG+'createGroup');
|
|
|
- return this.tim.createGroup({
|
|
|
- groupID: this.roomId,
|
|
|
- name: this.roomId,
|
|
|
- type: TIM.TYPES.GRP_AVCHATROOM,
|
|
|
- }).then(() => {
|
|
|
- return this.joinGroup(roomId);
|
|
|
- });
|
|
|
- });
|
|
|
- }
|
|
|
- dismissGroup() {
|
|
|
- console.log(LOGTAG+'dismissGroup');
|
|
|
- return this.tim.dismissGroup(this.roomId).then(() => {
|
|
|
- this.groupReady = false;
|
|
|
- this.roomId = null;
|
|
|
- });
|
|
|
- }
|
|
|
- joinGroup(roomId) {
|
|
|
- console.log(LOGTAG+'joinGroup',roomId);
|
|
|
- this.roomId = String(roomId);
|
|
|
- return this.tim.joinGroup({
|
|
|
- groupID: this.roomId,
|
|
|
- type: TIM.TYPES.GRP_AVCHATROOM
|
|
|
- }).then((imResponse) => {
|
|
|
- console.log(LOGTAG+'joinGrouped',imResponse.data.status);
|
|
|
- switch (imResponse.data.status) {
|
|
|
- case TIM.TYPES.JOIN_STATUS_WAIT_APPROVAL: // 等待管理员同意
|
|
|
- break;
|
|
|
- case TIM.TYPES.JOIN_STATUS_SUCCESS: // 加群成功
|
|
|
- case TIM.TYPES.JOIN_STATUS_ALREADY_IN_GROUP: // 已经在群中
|
|
|
- this.groupReady = true;
|
|
|
- break;
|
|
|
+ console.log(LOGTAG + 'login');
|
|
|
+ this.name = name;
|
|
|
+ this.avatar = avatar;
|
|
|
+
|
|
|
+ return new Promise(resolve => {
|
|
|
+ let cb = event => {
|
|
|
+ console.log(LOGTAG + 'ready');
|
|
|
+ this.ready = true;
|
|
|
+ this.tim.updateMyProfile({
|
|
|
+ nick: name,
|
|
|
+ avatar: avatar,
|
|
|
+ allowType: TIM.TYPES.ALLOW_TYPE_ALLOW_ANY
|
|
|
+ });
|
|
|
+ resolve();
|
|
|
+ this.tim.off(TIM.EVENT.SDK_READY, cb, this);
|
|
|
}
|
|
|
+ this.tim.on(TIM.EVENT.SDK_READY, cb, this);
|
|
|
+ this.tim.login({
|
|
|
+ userID: this.userId,
|
|
|
+ userSig: this.userSig,
|
|
|
+ })
|
|
|
+ });
|
|
|
+ }
|
|
|
+ logout() {
|
|
|
+ return this.tim.logout().then(() => {
|
|
|
+ this.ready = false;
|
|
|
});
|
|
|
- }
|
|
|
- exitGroup() {
|
|
|
- console.log(LOGTAG+'exitGroup');
|
|
|
- return this.tim.quitGroup(this.roomId).then(()=>{
|
|
|
- this.groupReady = false;
|
|
|
- this.roomId = null;
|
|
|
- });
|
|
|
- }
|
|
|
- sendGroupText(text) {
|
|
|
- const message = this.tim.createTextMessage({
|
|
|
- to: this.roomId,
|
|
|
- conversationType: TIM.TYPES.CONV_GROUP,
|
|
|
- payload: {text},
|
|
|
- })
|
|
|
- return this.tim.sendMessage(message).then(()=>({
|
|
|
- name: this.name,
|
|
|
- avatar: this.avatar,
|
|
|
- text: text,
|
|
|
- }));
|
|
|
- }
|
|
|
- sendGroupMessage(payload) {
|
|
|
- const message = this.tim.createCustomMessage({
|
|
|
- to: this.roomId,
|
|
|
- conversationType: TIM.TYPES.CONV_GROUP,
|
|
|
- payload,
|
|
|
- })
|
|
|
- return this.tim.sendMessage(message);
|
|
|
- }
|
|
|
- getGroupProfile() {
|
|
|
- return this.tim.getGroupProfile({ groupID: this.roomId }).then(res => imResponse.data.group);
|
|
|
- }
|
|
|
- getGroupNum() {
|
|
|
- return this.getGroupProfile(res=>res.memberCount);
|
|
|
- }
|
|
|
-}
|
|
|
+ }
|
|
|
+ onReady(cb) {
|
|
|
+ if(!cb) return this;
|
|
|
+ cb.jhimcbready = event => {
|
|
|
+ this.ready = true;
|
|
|
+ }
|
|
|
+ cb.jhimcbnotready = event => {
|
|
|
+ this.ready = false;
|
|
|
+ }
|
|
|
+ this.tim.on(TIM.EVENT.SDK_READY, cb.jhimcbready);
|
|
|
+ this.tim.on(TIM.EVENT.SDK_NOT_READY, cb.jhimcbnotready);
|
|
|
+ }
|
|
|
+ offReady(cb) {
|
|
|
+ if(!cb) return this;
|
|
|
+ this.tim.off(TIM.EVENT.SDK_READY, cb.jhimcbready);
|
|
|
+ this.tim.off(TIM.EVENT.SDK_NOT_READY, cb.jhimcbnotready);
|
|
|
+ }
|
|
|
+ createGroup(groupId, type=TIM.TYPES.GRP_AVCHATROOM) {
|
|
|
+ return new JhImGroup(this, groupId, type, this.name ,this.avatar);
|
|
|
+ }
|
|
|
+ onMessageRecv(cb, from, type, conversationType=TIM.TIM.TYPES.CONV_C2C) {
|
|
|
+ if(!cb) return;
|
|
|
+ cb.jhimcb = event => {
|
|
|
+ let msgs = event.data.filter( v=> {
|
|
|
+ if(from && v.from != from) return false;
|
|
|
+ if(conversationType && v.conversationType != conversationType) return false;
|
|
|
+ if(type && v.type != type) return false;
|
|
|
+ return true;
|
|
|
+ });
|
|
|
+ msgs.length && cb(msgs);
|
|
|
+ }
|
|
|
+ this.tim.on(TIM.EVENT.MESSAGE_RECEIVED, cb.jhimcb);
|
|
|
+ }
|
|
|
+ offMessageRecv(cb) {
|
|
|
+ if(!cb) return;
|
|
|
+ this.time.off(TIM.EVENT.MESSAGE_RECEIVED,cb.jhimcb);
|
|
|
+ }
|
|
|
+ sendText(text, to) {
|
|
|
+ const message = this.tim.createTextMessage({
|
|
|
+ to,
|
|
|
+ conversationType: TIM.TIM.TYPES.CONV_C2C,
|
|
|
+ payload: {
|
|
|
+ text
|
|
|
+ },
|
|
|
+ })
|
|
|
+ return this.tim.sendMessage(message).then(() => message);
|
|
|
+ }
|
|
|
+ sendCustomMessage(payload, to) {
|
|
|
+ const message = this.tim.createCustomMessage({
|
|
|
+ to: to,
|
|
|
+ conversationType: TIM.TYPES.CONV_C2C,
|
|
|
+ payload,
|
|
|
+ })
|
|
|
+ return this.tim.sendMessage(message).then(() => message);
|
|
|
+ }
|
|
|
+}
|