agora-edu-core
Version:
Core APIs for building an online classroom
516 lines (500 loc) • 22 kB
JavaScript
"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);