123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461 |
- import {action, observable} from 'mobx-miniprogram'
- import TIM from "tim-wx-sdk";
- import Tim from "../model/tim";
- import {toast} from "../utils/utils";
- import EduTRTC from "../model/edu-trct";
- import Api from "../model/api";
- export const timStore = observable({
- sdkReady: false,
- conversationList: [],
- messageList: [],
- maxMessageListLength: 1000,
- _targetUserId: null,//单聊对象id
- intoView: null,//结合scrollview 设置每个消息的id为xxx+index,然后设置intoView为消息长度-1,滑动到这个位置为最下方
- isCompleted: false,//单聊消息是否下拉完了
- canScroll: true,//群聊消息是否可以滑动 后期可以在触摸聊天内容的时候设置成false,在主动滑到最底部设置成true来提高用户体验
- user: {
- nickname: '',
- avatar: '',
- gender: TIM.TYPES.GENDER_MALE,
- },
- userId: '',
- userSig: '',
- groupId: '',
- groupReady: false,
- isCanShare: 0,
- isAudVideo: 0,
- isAudText: 0,
- isStuVideo: 0,
- handReply: false,
- //live
- pusher: {},
- playerList: [],
- initLive: action(function (page) {
- try {
- EduTRTC.getInstance().initPage(page);
- this.bindTRTCRoomEvent()
- this.pusher = EduTRTC.getInstance().createPusher();
- const config = {
- userID: this.userId,
- sdkAppID: Tim.SDKAppID,
- userSig: this.userSig,
- strRoomID: this.groupId,
- scene: 'live'
- }
- this.pusher = EduTRTC.getInstance().getSDK().enterRoom(config);
- } catch (e) {
- console.log("异常", e)
- }
- }),
- exitRoom: action(function () {
- const result = EduTRTC.getInstance().exitRoom()
- this.pusher = result.pusher;
- this.playerList = result.playerList;
- }),
- setScroll: action(function (canScroll) {
- this.canScroll = canScroll;
- }),
- setUser: action(async function (user, groupId, userSig) {
- if (this.userId != user.userID && this.groupId != groupId && this.sdkReady) {
- await this.logout()
- }
- this.user = user;
- this.userSig = userSig;
- this.userId = user.userID;
- this.groupId = groupId;
- }),
- login: action(async function () {
- if (this.sdkReady) {
- if (!this.groupReady) {
- await this.joinGroup();
- }
- return;
- }
- this._runListener()
- await Tim.getInstance().login(this.userId, this.userSig)
- }),
- logout: action(async function () {
- await this.quitGroup();
- await Tim.getInstance().logout()
- }),
- isReady: action(function () {
- return this.sdkReady
- }),
- quitGroup: action(async function () {
- this.groupReady = false;
- this.isCanShare = 0
- this.isAudVideo = 0
- this.isAudText = 0
- this.isStuVideo = 0
- await Tim.getInstance().quitGroup(this.groupId)
- }),
- getConversationList: action(async function () {
- this.conversationList = await Tim.getInstance().getConversationList()
- }),
- getMessageList: action(async function () {
- if (!this._targetUserId) {
- throw Error("未指定目标用户 id")
- }
- this.messageList = await Tim.getInstance()
- .reset()
- .getMessageList(this._targetUserId)
- this.intoView = this.messageList.length - 1
- await Tim.getInstance().setMessageRead(this._targetUserId)
- }),
- setTargetUserId: action(function (targetUserId) {
- this._targetUserId = targetUserId
- }),
- pushMessage: action(function (message) {
- if (this.messageList.length === this.maxMessageListLength) {
- this.messageList.shift()
- }
- message = {
- name: message.nick || message.from,
- message: message.payload.text
- }
- this.messageList = this.messageList.concat([message])
- this.intoView = this.messageList.length - 1
- if (this.canScroll) {
- wx.pageScrollTo({scrollTop: 99999})
- }
- }),
- scrollMessageList: action(async function () {
- const messageList = await Tim.getInstance()
- .getMessageList(this._targetUserId);
- this.intoView = this.messageList.length === Tim.getInstance().messageList.length ?
- messageList.length : messageList.length - 1
- /**
- * tips
- * 1. MobX 中属性的值是 Array 的时候,他是一个被包装过的 Array,并非原生 Array,它是一个响应式对象
- * 2. 经过包装的 Array 同样具备大多数原生 Array 所具备的方法。
- * 3. 想把响应式的对象数组变成普通数组,可以调用slice()函数遍历所有对象元素生成一个新的普通数组
- */
- this.messageList = messageList.concat(this.messageList.slice())
- }),
- resetMessage: action(function () {
- this.messageList = []
- this._targetUserId = null
- this.intoView = 0
- this.isCompleted = false
- }),
- _runListener() {
- const sdk = Tim.getInstance().getSDK();
- sdk.on(TIM.EVENT.SDK_READY, this.onSDKReady, this)
- sdk.on(TIM.EVENT.SDK_NOT_READY, this.onSdkNotReady, this);
- sdk.on(TIM.EVENT.KICKED_OUT, this.onSdkNotReady, this);
- sdk.on(TIM.EVENT.CONVERSATION_LIST_UPDATED, this.onConversationListUpdated, this);
- sdk.on(TIM.EVENT.MESSAGE_RECEIVED, this._handleMessageReceived, this);
- sdk.on(TIM.EVENT.ERROR, this._handleError, this);
- },
- async joinGroup() {
- //加入群
- this.resetMessage();
- const groupCustomField = await Tim.getInstance().joinGroup(this.groupId);
- if (groupCustomField) {
- groupCustomField.forEach(item => {
- this[item.key] = item.value;
- })
- }
- if (this.isCanShare == 1) {
- wx.showShareMenu();
- } else {
- wx.hideShareMenu();
- }
- this.groupReady = true;
- this.pushMessage({
- nick: '系统通知',
- payload: {
- text: `欢迎${this.user.nickname}加入`
- }
- })
- },
- async onConversationListUpdated(event) {
- if (!event.data.length) {
- return
- }
- this.conversationList = event.data
- const unreadCount = event.data.reduce(
- (sum, item) => sum + item.unreadCount, 0)
- },
- async onSDKReady() {
- this.sdkReady = true
- //SDK准备好了 更新用户信息
- await Tim.getInstance().updateMyProfile(this.user)
- await this.joinGroup();
- },
- onSdkNotReady() {
- this.sdkReady = false
- this.groupReady = false
- this.isCanShare = 0
- this.isAudVideo = 0
- this.isAudText = 0
- this.isStuVideo = 0
- const sdk = Tim.getInstance().getSDK()
- sdk.off(TIM.EVENT.SDK_READY, this.onSDKReady);
- sdk.off(TIM.EVENT.SDK_NOT_READY, this.onSdkNotReady);
- sdk.off(TIM.EVENT.KICKED_OUT, this.onSdkNotReady);
- sdk.off(TIM.EVENT.CONVERSATION_LIST_UPDATED, this.onConversationListUpdated);
- sdk.off(TIM.EVENT.MESSAGE_RECEIVED, this._handleMessageReceived);
- sdk.off(TIM.EVENT.ERROR, this._handleError);
- },
- async _handleMessageReceived(event) {
- console.log("收到消息", event)
- const filterMsgs = event.data
- .filter(item => (item.to === this.groupId || item.to === this.userId));
- for (const message of filterMsgs) {
- if (message.type == TIM.TYPES.MSG_GRP_SYS_NOTICE) {
- let text = this.parseGroupSystemNotice(message.payload);
- message.nick = "系统通知"
- message.payload.text = text
- console.log(text);
- }
- if (message.type == TIM.TYPES.MSG_GRP_TIP) {
- let text = this.parseGroupTipContent(message.payload);
- message.nick = "系统提示"
- message.payload.text = text
- console.log(text);
- }
- if (message.type === TIM.TYPES.MSG_GRP_TIP) {
- let groupCustomField = message.payload?.newGroupProfile?.groupCustomField;
- if (groupCustomField) {
- groupCustomField.forEach(item => {
- console.log('收到群资料变更', item.key, item.value);
- this[item.key] = item.value;
- })
- }
- if (this.isCanShare == 1) {
- wx.showShareMenu();
- } else {
- wx.hideShareMenu();
- }
- }
- if (message.type === TIM.TYPES.MSG_CUSTOM) {
- await this.parseGroupCustom(message.payload);
- }
- if (message.type === TIM.TYPES.MSG_TEXT) {
- this.pushMessage(message)
- }
- }
- // if (!this._targetUserId) {
- // return
- // }
- //
- // const currentConversationMessage = event.data
- // .filter(item => item.from === this._targetUserId)
- // if (currentConversationMessage.length) {
- // this.messageList = this.messageList.concat(currentConversationMessage)
- // this.intoView = this.messageList.length - 1
- // await Tim.getInstance().setMessageRead(this._targetUserId)
- // }
- },
- _handleError(event) {
- console.log("IM错误", event)
- // event.name - TIM.EVENT.ERROR
- // event.data.code - 错误码
- // event.data.message - 错误信息
- },
- parseGroupSystemNotice(payload) {
- const groupName =
- payload.groupProfile.groupName || payload.groupProfile.groupID
- switch (payload.operationType) {
- case 1:
- return `${payload.operatorID} 申请加入群组:${groupName}`
- case 2:
- return `成功加入群组:${groupName}`
- case 3:
- return `申请加入群组:${groupName}被拒绝`
- case 4:
- return `被管理员${payload.operatorID}踢出群组:${groupName}`
- case 5:
- toast('直播结束');
- wx.navigateBack();
- return `群:${groupName} 已被${payload.operatorID}解散`
- case 6:
- return `${payload.operatorID}创建群:${groupName}`
- case 7:
- return `${payload.operatorID}邀请你加群:${groupName}`
- case 8:
- return `你退出群组:${groupName}`
- case 9:
- return `你被${payload.operatorID}设置为群:${groupName}的管理员`
- case 10:
- return `你被${payload.operatorID}撤销群:${groupName}的管理员身份`
- case 255:
- return '自定义群系统通知'
- }
- },
- parseGroupTipContent(payload) {
- switch (payload.operationType) {
- case TIM.TYPES.GRP_TIP_MBR_PROFILE_UPDATED: // 群成员资料变更,例如:群成员被禁言
- const memberList = message.payload.memberList;
- for (let member of memberList) {
- console.log(`${member.userID} 被禁言${member.muteTime}秒`);
- }
- break;
- case TIM.TYPES.GRP_TIP_MBR_JOIN:
- return `群成员:${payload.userIDList.join(',')},加入群组`
- case TIM.TYPES.GRP_TIP_MBR_QUIT:
- return `群成员:${payload.userIDList.join(',')},退出群组`
- case TIM.TYPES.GRP_TIP_MBR_KICKED_OUT:
- return `群成员:${payload.userIDList.join(',')},被${payload.operatorID}踢出群组`
- case TIM.TYPES.GRP_TIP_MBR_SET_ADMIN:
- return `群成员:${payload.userIDList.join(',')},成为管理员`
- case TIM.TYPES.GRP_TIP_MBR_CANCELED_ADMIN:
- return `群成员:${payload.userIDList.join(',')},被撤销管理员`
- default:
- return '[群提示消息]'
- }
- },
- async parseGroupCustom(payload) {
- let data = JSON.parse(payload.data);
- let to = data.to;
- let version = data.version;
- let action = data.action;
- if (to == this.userId) {
- if (version == Tim.VERSION) {
- switch (action) {
- case Tim.IM_ACTION_HAND:
- const res = await wx.showModal({
- title: "老师邀请你上麦",
- confirmText: '同意',
- cancelText: '拒绝'
- })
- if (res.confirm) {
- await Tim.getInstance().sendCMD(Tim.getInstance().createHandOKMsg(data.time, this.groupId));
- this.setPusherAttributesHandler({enableCamera: true, enableMic: true})
- this.uploadLink();
- } else {
- await Tim.getInstance().sendCMD(Tim.getInstance().createHandCancelMsg(data.time, this.groupId));
- this.setPusherAttributesHandler({enableCamera: false, enableMic: false})
- }
- break
- case Tim.IM_ACTION_HAND_OK:
- toast("老师同意连麦")
- this.setPusherAttributesHandler({enableCamera: true, enableMic: true})
- this.uploadLink();
- break
- case Tim.IM_ACTION_HAND_CANCEL:
- toast("老师拒绝连麦")
- this.setPusherAttributesHandler({enableCamera: false, enableMic: false})
- break
- case Tim.IM_ACTION_QUIT_LINK:
- this.setPusherAttributesHandler({enableCamera: false, enableMic: false})
- toast("您已被老师下麦");
- break
- }
- }
- }
- },
- uploadLink(){
- try {
- Api.uploadLinkOk({
- scheduleIdStr: this.groupId,
- eStuIdStr: this.userId.split("_")[1],
- });
- }catch (e){
- console.log(e)
- }
- },
- bindTRTCRoomEvent() {
- let sdk = EduTRTC.getInstance().getSDK();
- const TRTC_EVENT = sdk.EVENT
- // 初始化事件订阅
- sdk.on(TRTC_EVENT.LOCAL_JOIN, (event) => {
- console.log('本地加入房间', event)
- })
- sdk.on(TRTC_EVENT.LOCAL_LEAVE, (event) => {
- console.log('本地离开房间', event)
- })
- sdk.on(TRTC_EVENT.KICKED_OUT, (event) => {
- console.log('服务端踢人或房间被解散退房', event)
- })
- sdk.on(TRTC_EVENT.ERROR, (event) => {
- console.log('TRTC错误', event)
- })
- sdk.on(TRTC_EVENT.REMOTE_USER_JOIN, (event) => {
- console.log('远端用户加入', event)
- })
- sdk.on(TRTC_EVENT.REMOTE_USER_LEAVE, (event) => {
- console.log('远端用户离开', event)
- const {userID, playerList} = event.data
- this.playerList = event.data.playerList
- })
- sdk.on(TRTC_EVENT.REMOTE_VIDEO_ADD, (event) => {
- console.log('远端用户推送视频', event)
- const {player} = event.data
- // 开始播放远端的视频流,默认是不播放的
- this.setPlayerAttributesHandler(player, {muteVideo: false})
- })
- sdk.on(TRTC_EVENT.REMOTE_VIDEO_REMOVE, (event) => {
- console.log('远端用户取消推送视频', event)
- const {player} = event.data
- this.setPlayerAttributesHandler(player, {muteVideo: true})
- })
- sdk.on(TRTC_EVENT.REMOTE_AUDIO_ADD, (event) => {
- console.log('远端用户推送音频', event)
- const {player} = event.data
- this.setPlayerAttributesHandler(player, {muteAudio: false})
- })
- sdk.on(TRTC_EVENT.REMOTE_AUDIO_REMOVE, (event) => {
- console.log('远端用户取消推送音频', event)
- const {player} = event.data
- this.setPlayerAttributesHandler(player, {muteAudio: true})
- })
- sdk.on(TRTC_EVENT.REMOTE_AUDIO_VOLUME_UPDATE, (event) => {
- console.log('远端用户音频大小更新', event)
- this.playerList = event.data.playerList
- })
- sdk.on(TRTC_EVENT.LOCAL_AUDIO_VOLUME_UPDATE, (event) => {
- console.log('本地用户音频大小更新', event)
- this.pusher = event.data.pusher
- })
- },
- // 设置 pusher 属性
- setPusherAttributesHandler(options) {
- let sdk = EduTRTC.getInstance().getSDK();
- this.pusher = sdk.setPusherAttributes(options);
- this.handReply = !this.handReply;
- },
- // 设置某个 player 属性
- setPlayerAttributesHandler(player, options) {
- let sdk = EduTRTC.getInstance().getSDK();
- this.playerList = sdk.setPlayerAttributes(player.streamID, options);
- },
- })
|