UNPKG

agora-edu-core

Version:

Core APIs for building an online classroom

516 lines (500 loc) 22 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.UserStore = void 0; require("core-js/modules/esnext.map.delete-all.js"); require("core-js/modules/esnext.map.every.js"); require("core-js/modules/esnext.map.filter.js"); require("core-js/modules/esnext.map.find.js"); require("core-js/modules/esnext.map.find-key.js"); require("core-js/modules/esnext.map.includes.js"); require("core-js/modules/esnext.map.key-of.js"); require("core-js/modules/esnext.map.map-keys.js"); require("core-js/modules/esnext.map.map-values.js"); require("core-js/modules/esnext.map.merge.js"); require("core-js/modules/esnext.map.reduce.js"); require("core-js/modules/esnext.map.some.js"); require("core-js/modules/esnext.map.update.js"); var _agoraRteSdk = require("agora-rte-sdk"); var _mobx = require("mobx"); var _ = require("../../../.."); var _type = require("../../../../type"); var _utils = require("../../../../utils"); var _batch = require("../../../../utils/batch"); var _error = require("../../../../utils/error"); var _base = require("../base"); var _struct = require("./struct"); var _dec, _class, _descriptor, _dec2, _dec3, _dec4, _dec5, _dec6, _dec7, _dec8, _dec9, _dec0, _class2, _descriptor2, _SceneEventHandler; function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; } function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; } function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } function _initializerDefineProperty(e, i, r, l) { r && Object.defineProperty(e, i, { enumerable: r.enumerable, configurable: r.configurable, writable: r.writable, value: r.initializer ? r.initializer.call(l) : void 0 }); } function _applyDecoratedDescriptor(i, e, r, n, l) { var a = {}; return Object.keys(n).forEach(function (i) { a[i] = n[i]; }), a.enumerable = !!a.enumerable, a.configurable = !!a.configurable, ("value" in a || a.initializer) && (a.writable = !0), a = r.slice().reverse().reduce(function (r, n) { return n(i, e, r) || r; }, a), l && void 0 !== a.initializer && (a.value = a.initializer ? a.initializer.call(l) : void 0, a.initializer = void 0), void 0 === a.initializer ? (Object.defineProperty(i, e, a), null) : a; } function _initializerWarningHelper(r, e) { throw Error("Decorating class property failed. Please ensure that transform-class-properties is enabled and runs after the decorators transform."); } /** * `UserStore` 类用于管理用户。 */ /** @en * The `UserStore` class is used for managing users. */ let UserStore = exports.UserStore = (_dec = _mobx.action.bound, _class = class UserStore extends _base.EduStoreBase { constructor(...args) { super(...args); this._disposers = []; _initializerDefineProperty(this, "_dataStore", _descriptor, this); } /** * @internal * * 主房间数据信息 **/ /** @en * @internal * * Main room datastore */ get mainRoomDataStore() { const scene = this.classroomStore.connectionStore.mainRoomScene; const handler = SceneEventHandler.getEventHandler(scene); return handler.dataStore; } /** * @internal * * 分组房间数据信息 **/ /** @en * @internal * * Sub room datastore */ get subRoomDataStore() { const scene = this.classroomStore.connectionStore.subRoomScene; const handler = SceneEventHandler.getEventHandler(scene); return handler.dataStore; } /** * 本地用户 **/ /** @en * Local user */ get localUser() { const { userUuid } = _.EduClassroomConfig.shared.sessionInfo; return this._dataStore.users.get(userUuid); } /** * 房间内所有用户 **/ /** @en * All users in the room */ get users() { return this._dataStore.users; } /** * 房间内用户数 */ /** @en * Number of users in the room */ get userCount() { return this._dataStore.userCount; } /** * 老师列表 **/ /** @en * Teacher list */ get teacherList() { return this._dataStore.teacherList; } /** * 学生列表 **/ /** @en * Student list */ get studentList() { return this._dataStore.studentList; } /** * 助教列表 **/ /** @en * Assistant list */ get assistantList() { return this._dataStore.assistantList; } /** * 奖励信息字典 * key: 用户UUID * value: 用户获得的奖励数 **/ /** @en * Rewards info map * key: User UUID * value: The number of rewards the user gets */ get rewards() { return this._dataStore.rewards; } /** * 获取用户列表 * @param params 查询条件 * @returns 用户列表 * **/ /** @en * Gets the user list * @param params Search conditions * @returns User list */ async fetchUserList(params) { try { const data = await this.classroomStore.api.fetchUserList(this.classroomStore.connectionStore.sceneId, _objectSpread({}, params)); return { total: data.total, count: data.count, nextId: data.nextId, list: data.list }; } catch (error) { return _error.EduErrorCenter.shared.handleThrowableError(_error.AGEduErrorCode.EDU_ERR_FETCH_USER_LIST, error); } } /** * 将用户踢出房间 * @param userUuid 用户 ID * @param isBan 是否永久封禁该用户 * **/ /** @en * Kicks a user out of the room * @param userUuid The user ID * @param isBan Whether to ban the user */ async kickOutOnceOrBan(userUuid, isBan) { try { await this.classroomStore.api.kickOutOnceOrBan(userUuid, isBan, this.classroomStore.connectionStore.sceneId); } catch (error) { return _error.EduErrorCenter.shared.handleThrowableError(_error.AGEduErrorCode.EDU_ERR_KICK_OUT_FAIL, error); } } _setEventHandler(scene) { if (this.classroomStore.connectionStore.mainRoomScene === scene) { let handler = SceneEventHandler.getEventHandler(scene); if (!handler) { handler = SceneEventHandler.createEventHandler(scene); } this._dataStore = handler.dataStore; } else { const handler = SceneEventHandler.createEventHandler(scene); this._dataStore = handler.dataStore; } } /** * 更新用户自定属性 * @param users 要更新的用户属性信息 * @param fromScene 要更新的用户所在的房间对象,不传默认为当前房间 */ /** @en * Updates users properties * @param users Information about the user properties to be updated * @param fromScene The room object in which the user resides. If not passed, defaults to the current room */ async updateUserProperties(users, fromScene) { const scene = fromScene || this.classroomStore.connectionStore.scene; try { if (scene) { await this.api.updateBatchUserProperties({ roomUuid: scene.sceneId, data: users }); } } catch (err) { _error.EduErrorCenter.shared.handleThrowableError(_error.AGEduErrorCode.EDU_ERR_ROOM_FLEXPROPERTEIS_FAIL, err); } } /** * @internal */ /** @en * @internal */ onInstall() { this._disposers.push((0, _mobx.computed)(() => this.classroomStore.connectionStore.scene).observe(({ newValue, oldValue }) => { if (newValue) { this._setEventHandler(newValue); } })); } /** * @internal */ /** @en * @internal */ onDestroy() { SceneEventHandler.cleanup(); this._disposers.forEach(d => d()); this._disposers = []; } }, _descriptor = _applyDecoratedDescriptor(_class.prototype, "_dataStore", [_mobx.observable], { configurable: true, enumerable: true, writable: true, initializer: function () { return { users: new Map(), teacherList: new Map(), studentList: new Map(), assistantList: new Map(), rewards: new Map(), userCount: 0 }; } }), _applyDecoratedDescriptor(_class.prototype, "mainRoomDataStore", [_mobx.computed], Object.getOwnPropertyDescriptor(_class.prototype, "mainRoomDataStore"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "subRoomDataStore", [_mobx.computed], Object.getOwnPropertyDescriptor(_class.prototype, "subRoomDataStore"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "localUser", [_mobx.computed], Object.getOwnPropertyDescriptor(_class.prototype, "localUser"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "users", [_mobx.computed], Object.getOwnPropertyDescriptor(_class.prototype, "users"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "userCount", [_mobx.computed], Object.getOwnPropertyDescriptor(_class.prototype, "userCount"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "teacherList", [_mobx.computed], Object.getOwnPropertyDescriptor(_class.prototype, "teacherList"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "studentList", [_mobx.computed], Object.getOwnPropertyDescriptor(_class.prototype, "studentList"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "assistantList", [_mobx.computed], Object.getOwnPropertyDescriptor(_class.prototype, "assistantList"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "rewards", [_mobx.computed], Object.getOwnPropertyDescriptor(_class.prototype, "rewards"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "kickOutOnceOrBan", [_dec], Object.getOwnPropertyDescriptor(_class.prototype, "kickOutOnceOrBan"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "_setEventHandler", [_mobx.action], Object.getOwnPropertyDescriptor(_class.prototype, "_setEventHandler"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "updateUserProperties", [_agoraRteSdk.bound], Object.getOwnPropertyDescriptor(_class.prototype, "updateUserProperties"), _class.prototype), _class); let SceneEventHandler = (_dec2 = _mobx.action.bound, _dec3 = _mobx.action.bound, _dec4 = _mobx.action.bound, _dec5 = _mobx.action.bound, _dec6 = _mobx.action.bound, _dec7 = _mobx.action.bound, _dec8 = _mobx.action.bound, _dec9 = _mobx.action.bound, _dec0 = _mobx.action.bound, _class2 = (_SceneEventHandler = class SceneEventHandler { static createEventHandler(scene) { if (SceneEventHandler._handlers[scene.sceneId]) { SceneEventHandler._handlers[scene.sceneId].removeEventHandlers(); } const handler = new SceneEventHandler(scene); handler.addEventHandlers(); SceneEventHandler._handlers[scene.sceneId] = handler; return SceneEventHandler._handlers[scene.sceneId]; } static getEventHandler(scene) { return SceneEventHandler._handlers[scene.sceneId]; } static cleanup() { Object.keys(SceneEventHandler._handlers).forEach(k => { SceneEventHandler._handlers[k].removeEventHandlers(); }); SceneEventHandler._handlers = {}; } constructor(_scene) { this._scene = _scene; _initializerDefineProperty(this, "dataStore", _descriptor2, this); } addEventHandlers() { this._scene.on(_agoraRteSdk.AgoraRteEventType.UserAdded, this._addUsers); this._scene.on(_agoraRteSdk.AgoraRteEventType.UserRemoved, this._removeUsers); this._scene.on(_agoraRteSdk.AgoraRteEventType.UserUpdated, this._updateUsers); this._scene.on(_agoraRteSdk.AgoraRteEventType.UserPropertyUpdated, this._handleUserPropertiesChange); this._scene.on(_agoraRteSdk.AgoraRteEventType.RoomPropertyUpdated, this._handleRoomPropertiesChange); this._scene.on(_agoraRteSdk.AgoraRteEventType.UserPropertyListUpdated, this._updateBatchUserProperties); this._scene.on(_agoraRteSdk.AgoraRteEventType.UserCountUpdated, this._handleUserCountUpdated); } removeEventHandlers() { this._scene.off(_agoraRteSdk.AgoraRteEventType.UserAdded, this._addUsers); this._scene.off(_agoraRteSdk.AgoraRteEventType.UserRemoved, this._removeUsers); this._scene.off(_agoraRteSdk.AgoraRteEventType.UserUpdated, this._updateUsers); this._scene.off(_agoraRteSdk.AgoraRteEventType.UserPropertyUpdated, this._handleUserPropertiesChange); this._scene.off(_agoraRteSdk.AgoraRteEventType.RoomPropertyUpdated, this._handleRoomPropertiesChange); this._scene.off(_agoraRteSdk.AgoraRteEventType.UserPropertyListUpdated, this._updateBatchUserProperties); this._scene.off(_agoraRteSdk.AgoraRteEventType.UserCountUpdated, this._handleUserCountUpdated); } /** * 监听在线用户数变更信息 * @param count */ _handleUserCountUpdated(count) { this.dataStore.userCount = count; } /** * 监听房间属性更新学员奖励信息 * @param changedRoomProperties * @param roomProperties */ _handleRoomPropertiesChange(changedRoomProperties, roomProperties) { if (changedRoomProperties.includes('students')) { this.dataStore.rewards = new Map(Object.entries(roomProperties['students']).map(([userUuid, { reward }]) => { return [userUuid, reward]; })); } } _addUsers(users) { users.forEach(user => { const userItem = new _struct.EduUser(user).toPlainObject(); // userItem.userProperties = observable(new Map(userItem.userProperties)); userItem.userProperties = new Map(userItem.userProperties); if (userItem.userRole === _type.EduRoleTypeEnum.teacher) { this.dataStore.teacherList.set(user.userUuid, userItem); } if (userItem.userRole === _type.EduRoleTypeEnum.student) { this.dataStore.studentList.set(user.userUuid, userItem); } if (userItem.userRole === _type.EduRoleTypeEnum.assistant) { this.dataStore.assistantList.set(user.userUuid, userItem); } this.dataStore.users.set(user.userUuid, userItem); this._handleUserPropertiesChange(user.userUuid, user.userProperties.toObject()); }); } _removeUsers(users, type) { const { sessionInfo } = _.EduClassroomConfig.shared; users.forEach(user => { // 2 means user has been kicked out if (type === 2) { _.EduEventCenter.shared.emitClasroomEvents(_type.AgoraEduClassroomEvent.KickOut, user); } const userRole = (0, _utils.RteRole2EduRole)(sessionInfo.roomType, user.userRole); if (user.userUuid !== sessionInfo.userUuid) { if (userRole === _type.EduRoleTypeEnum.teacher) { this.dataStore.teacherList.delete(user.userUuid); } if (userRole === _type.EduRoleTypeEnum.student) { this.dataStore.studentList.delete(user.userUuid); } if (userRole === _type.EduRoleTypeEnum.assistant) { this.dataStore.assistantList.delete(user.userUuid); } this.dataStore.users.delete(user.userUuid); } }); } _updateUsers(users) { users.forEach(user => { const userItem = new _struct.EduUser(user).toPlainObject(); if (userItem.userRole === _type.EduRoleTypeEnum.teacher) { this.dataStore.teacherList.set(user.userUuid, userItem); } if (userItem.userRole === _type.EduRoleTypeEnum.student) { this.dataStore.studentList.set(user.userUuid, userItem); } if (userItem.userRole === _type.EduRoleTypeEnum.assistant) { this.dataStore.assistantList.set(user.userUuid, userItem); } this.dataStore.users.set(user.userUuid, userItem); }); } _handleUserPropertiesChange(userUuid, userProperties, operator, cause) { const { reward } = userProperties; if (reward) { const newRewards = new Map(this.dataStore.rewards); newRewards.set(userUuid, reward.count || 0); this._updateRewards(newRewards, false, operator, cause); } this._updateUserProperties(userUuid, userProperties); } _updateUserProperties(userUuid, userProperties) { const map = new Map(); for (const key in userProperties) { map.set(key, userProperties[key]); } // update user list const user = this.dataStore.users.get(userUuid); if (user) { const newUser = _objectSpread(_objectSpread({}, user), {}, { userProperties: map }); this.dataStore.users.set(userUuid, newUser); } // update teacher list const teacher = this.dataStore.teacherList.get(userUuid); if (teacher) { const newUser = _objectSpread(_objectSpread({}, teacher), {}, { userProperties: map }); this.dataStore.teacherList.set(userUuid, newUser); } // update student list const student = this.dataStore.studentList.get(userUuid); if (student) { const newUser = _objectSpread(_objectSpread({}, student), {}, { userProperties: map }); this.dataStore.studentList.set(userUuid, newUser); } // update assistant list const assistant = this.dataStore.assistantList.get(userUuid); if (assistant) { const newUser = _objectSpread(_objectSpread({}, assistant), {}, { userProperties: map }); this.dataStore.assistantList.set(userUuid, newUser); } } async _updateRewards(newRewards, isBatch = false, operator, cause) { const oldRewards = this.dataStore.rewards; this.dataStore.rewards = newRewards; const users = this._getRewardedUsers(oldRewards, newRewards); (cause === null || cause === void 0 ? void 0 : cause.cmd) === _type.AgoraCommandEnum.UserRewardChanged && _.EduEventCenter.shared.emitClasroomEvents(isBatch ? _type.AgoraEduClassroomEvent.BatchRewardReceived : _type.AgoraEduClassroomEvent.RewardReceived, users); } _updateBatchUserProperties(users, batch, operator, cause) { _batch.BatchRecord.getBatchRecord(batch.id).setCurrent(batch.index).setTotal(batch.total).setCallback(batchArray => { const allUsers = batchArray.flat(); const newRewards = new Map(this.dataStore.rewards); for (const user of allUsers) { const { userUuid, userProperties } = user; const { reward } = userProperties; if (reward) { newRewards.set(userUuid, reward.count || 0); } this._updateUserProperties(userUuid, userProperties); } this._updateRewards(newRewards, true, operator, cause); }).addChunk(users).execute(); } _getRewardedUsers(oldRewards, newRewards) { const changedUserUuids = []; for (const [userUuid] of newRewards) { let previousReward = 0; if (oldRewards) { previousReward = oldRewards.get(userUuid) || 0; } const reward = newRewards.get(userUuid) || 0; if (reward > previousReward) { changedUserUuids.push(userUuid); } } if (changedUserUuids.length > 0) { const users = changedUserUuids.map(userUuid => { var _this$dataStore$stude; return { userUuid, userName: (_this$dataStore$stude = this.dataStore.studentList.get(userUuid)) === null || _this$dataStore$stude === void 0 ? void 0 : _this$dataStore$stude.userName }; }); return users; } return []; } }, _SceneEventHandler._handlers = {}, _SceneEventHandler), _descriptor2 = _applyDecoratedDescriptor(_class2.prototype, "dataStore", [_mobx.observable], { configurable: true, enumerable: true, writable: true, initializer: function () { return { users: new Map(), teacherList: new Map(), studentList: new Map(), assistantList: new Map(), rewards: new Map(), userCount: 0 }; } }), _applyDecoratedDescriptor(_class2.prototype, "_handleUserCountUpdated", [_dec2], Object.getOwnPropertyDescriptor(_class2.prototype, "_handleUserCountUpdated"), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, "_handleRoomPropertiesChange", [_dec3], Object.getOwnPropertyDescriptor(_class2.prototype, "_handleRoomPropertiesChange"), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, "_addUsers", [_dec4], Object.getOwnPropertyDescriptor(_class2.prototype, "_addUsers"), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, "_removeUsers", [_dec5], Object.getOwnPropertyDescriptor(_class2.prototype, "_removeUsers"), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, "_updateUsers", [_dec6], Object.getOwnPropertyDescriptor(_class2.prototype, "_updateUsers"), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, "_handleUserPropertiesChange", [_dec7], Object.getOwnPropertyDescriptor(_class2.prototype, "_handleUserPropertiesChange"), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, "_updateUserProperties", [_dec8], Object.getOwnPropertyDescriptor(_class2.prototype, "_updateUserProperties"), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, "_updateRewards", [_dec9], Object.getOwnPropertyDescriptor(_class2.prototype, "_updateRewards"), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, "_updateBatchUserProperties", [_dec0], Object.getOwnPropertyDescriptor(_class2.prototype, "_updateBatchUserProperties"), _class2.prototype), _class2);