agora-edu-core
Version:
Core APIs for building an online classroom
420 lines (408 loc) • 16 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.CloudDriveStore = 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 _mobx = require("mobx");
var _index = require("../../../../configs/index");
var _error = require("../../../../utils/error");
var _type = require("./type");
var _base = require("../base");
var _utils = require("./utils");
var _axios = _interopRequireDefault(require("axios"));
var _struct = require("./struct");
var _agoraRteSdk = require("agora-rte-sdk");
var _dec, _dec2, _dec3, _dec4, _dec5, _class, _descriptor, _descriptor2;
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
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."); }
/**
* `CloudDriveStore` 类提供云盘相关能力。
*/
/** @en
* The `CloudDriveStore` class provides abilities related the cloud drive.
*/
let CloudDriveStore = exports.CloudDriveStore = (_dec = _mobx.action.bound, _dec2 = _mobx.action.bound, _dec3 = _mobx.action.bound, _dec4 = _mobx.action.bound, _dec5 = _mobx.action.bound, _class = class CloudDriveStore extends _base.EduStoreBase {
constructor() {
super(...arguments);
/**
* 云盘个人资源文件列表
*/
/** @en
* Personal resources
*/
_initializerDefineProperty(this, "personalResources", _descriptor, this);
/**
* 云盘资源上传进度
*/
/** @en
* Progresses of resources
*/
_initializerDefineProperty(this, "uploadProgress", _descriptor2, this);
this._checkpoints = new Map();
}
/**
* 取消上传资源
*
* @param resourceUuid 资源 ID
**/
/** @en
* Cancels uploading the file
*
* @param resourceUuid The resource ID
*/
async cancelUpload(resourceUuid) {
const checkpoint = this._checkpoints.get(resourceUuid);
if (checkpoint) {
switch (checkpoint.type) {
case _type.UploadType.COMMON_XHR:
const {
checkPoint: cancelTokenSource
} = checkpoint;
if (cancelTokenSource) {
cancelTokenSource.cancel('Cancled');
this.uploadProgress.delete(resourceUuid);
}
break;
}
} else {
_error.EduErrorCenter.shared.handleThrowableError(_error.AGEduErrorCode.EDU_ERR_UPLOAD_FAILED_NO_CHECKPOINT, new Error(`get upload checkpoint failed when cancel upload`));
}
}
/**
* 重新上传资源
*
* @param resourceUuid 资源 ID
**/
/** @en
* Retries uploading the file
* @param resourceUuid The resource ID
*/
retryUpload(resourceUuid) {
const checkpoint = this._checkpoints.get(resourceUuid);
if (checkpoint) {
const {
file,
ext,
contentType,
conversion
} = checkpoint;
this.uploadPersonalResource(file, resourceUuid, ext, contentType, conversion);
} else {
_error.EduErrorCenter.shared.handleThrowableError(_error.AGEduErrorCode.EDU_ERR_UPLOAD_FAILED_NO_CHECKPOINT, new Error(`get upload checkpoint failed when retry upload`));
}
}
/**
* 获取个人云盘资源
* @param options 分页参数
* @returns 云盘资源分页信息
**/
/** @en
* Gets all personal resources
* @param options The paging option
* @returns Cloud disk resource page information
*/
async fetchPersonalResources(options) {
let data = {
list: [],
total: 0
};
try {
const {
userUuid
} = _index.EduClassroomConfig.shared.sessionInfo;
data = await this.classroomStore.api.fetchPersonalResources(userUuid, {
pageSize: options.pageSize,
pageNo: options.pageNo,
resourceName: options.resourceName
});
} catch (e) {
return _error.EduErrorCenter.shared.handleThrowableError(_error.AGEduErrorCode.EDU_ERR_CLOUD_FETCH_PERSONAL_RESOURCE_FAIL, e);
}
return data;
}
_initProgress(progress) {
this.uploadProgress.set(progress.resourceUuid, progress);
}
/**
* @internal
*/
/** @en
* @internal
*/
async _updateProgress(resourceUuid, progressValue, status) {
const progress = this.uploadProgress.get(resourceUuid);
if (progress) {
if (progressValue) {
progress.progress = progressValue;
if (progressValue === 1) {
progress.status = _type.CloudDriveResourceUploadStatus.Success;
}
}
if (status) progress.status = status;
}
}
async _putFile(file, progressUuid, ossConfig) {
const {
preSignedUrl,
fileUrl
} = ossConfig;
const cancelTokenSource = _axios.default.CancelToken.source();
try {
await _axios.default.put(preSignedUrl, file, {
cancelToken: cancelTokenSource.token,
headers: {
'Content-Type': ossConfig.contentType
},
onUploadProgress: progressEvent => {
const checkpoint = this._checkpoints.get(progressUuid);
if (!checkpoint.checkPoint) this._checkpoints.set(progressUuid, _objectSpread(_objectSpread({}, checkpoint), {}, {
checkPoint: cancelTokenSource
}));
const percentCompleted = progressEvent.loaded / progressEvent.total;
(0, _mobx.runInAction)(() => {
this._updateProgress(progressUuid, percentCompleted);
});
}
});
this._checkpoints.delete(progressUuid);
} catch (e) {
if (e.message === 'Cancled') {
this._updateProgress(progressUuid, undefined, _type.CloudDriveResourceUploadStatus.Canceled);
return '';
} else {
this._updateProgress(progressUuid, undefined, _type.CloudDriveResourceUploadStatus.Failed);
_error.EduErrorCenter.shared.handleThrowableError(_error.AGEduErrorCode.EDU_ERR_UPLOAD_AWS_FAIL, new Error(`upload to oss error`));
}
}
return fileUrl;
}
/**
* 将已上传的资源文件映射为云盘内的一个文件
* @param resourceUuid 资源 UUID
* @param resourceInfo 资源信息
*/
/** @en
* Create a record that maps to the uploaded resource file
* @param resourceUuid Resource UUID
* @param resourceInfo Resource Info
*/
async addPersonalResource(resourceUuid, resourceInfo) {
const {
sessionInfo
} = _index.EduClassroomConfig.shared;
const {
userUuid
} = sessionInfo;
return await this.classroomStore.api.addCloudDriveFile(resourceUuid, userUuid, resourceInfo);
}
/**
* 更新云盘文件信息
* @param resourceUuid
* @param resourceInfo
* @returns
*/
/** @en
* Updates the cloud drive file info
* @param resourceUuid
* @param resourceInfo
* @returns
*/
async updatePersonalResource(resourceUuid, resourceInfo) {
const {
sessionInfo
} = _index.EduClassroomConfig.shared;
const {
userUuid
} = sessionInfo;
return await this.classroomStore.api.updateCloudDriveFile(resourceUuid, userUuid, resourceInfo);
}
/**
* 上传资源到云盘,上传后需要调用 addPersonalResource 方法创建一条资源对应的课件记录即可在云盘中使用。
* @param file 资源文件对象
* @param progressUuid 上传 UUID
* @param ext 资源扩展名
* @param contentType static: 静态, dynamic:动态
* @param conversion 转换选项
* @returns 上传成功后的文件信息
**/
/** @en
* Uploads a file to personal resources, addPersonalResource is required to call after uploading, which creates a record that will show in cloud drive.
* @param file The file
* @param progressUuid Progress UUID
* @param ext Extension name of the resource
* @param contentType static or dynamic
* @param conversion conversion options
* @returns Information about the uploaded file
*/
async uploadPersonalResource(file, progressUuid, ext, contentType, conversion) {
try {
const {
sessionInfo: {
userUuid
}
} = _index.EduClassroomConfig.shared;
const {
name: resourceName,
size
} = file;
// step 1. fetch sts token for futher operations
const uploadData = {
resourceUuid: progressUuid,
userUuid,
resourceName,
contentType,
ext,
size,
updateTime: 0
}; // presignedUrls body
const progress = new _struct.CloudDriveUploadingProgress(uploadData);
this._initProgress(progress);
if (!this._checkpoints.get(progressUuid)) {
this._checkpoints.set(progressUuid, {
type: _type.UploadType.COMMON_XHR,
file,
contentType,
ext,
conversion
});
}
// step 1. fetch sts token for futher operations
const data = await this.classroomStore.api.fetchFileUploadSts({
userUuid,
resourceName,
contentType,
ext,
size,
conversion
});
// step 2. begin upload by vendor
// aws
const {
accessKeyId,
accessKeySecret,
bucketName,
ossEndpoint,
securityToken,
ossKey,
resourceUuid,
//only available for aws for now
preSignedUrl,
url: fileUrl
} = data[0];
const url = await this._putFile(file, progressUuid, {
accessKeyId,
accessKeySecret,
bucketName,
ossEndpoint,
securityToken,
ossKey,
preSignedUrl,
fileUrl,
contentType
});
// step 3. done uploading, binding
if (url) {
await this.classroomStore.api.addCloudDriveFile(resourceUuid, userUuid, {
resourceName,
ext,
size: file.size,
url,
conversion
});
}
return url ? {
ext,
resourceName,
resourceUuid,
url
} : {};
} catch (e) {
_error.EduErrorCenter.shared.handleThrowableError(_error.AGEduErrorCode.EDU_ERR_UPLOAD_FAIL, e);
}
}
/**
* 移除个人资源
* @param resourceUuids 资源 ID
**/
/** @en
* Removes files from personal resources
* @param resourceUuids The resource IDs
*/
async removePersonalResources(resourceUuids) {
try {
const {
sessionInfo
} = _index.EduClassroomConfig.shared;
const {
userUuid
} = sessionInfo;
await this.classroomStore.api.removeMaterials(resourceUuids, userUuid);
for (const uuid of resourceUuids) {
this.personalResources.delete(uuid);
}
} catch (e) {
return _error.EduErrorCenter.shared.handleThrowableError(_error.AGEduErrorCode.EDU_ERR_CLOUD_REMOVE_PERSONAL_RESOURCE_FAIL, e);
}
}
/**
* 计算资源文件 UUID
* @param resource
* @returns 资源文件 UUID
*/
/** @en
* Figure out a UUID for the resource file
* @param resource
* @returns Resource file UUID
*/
calcResourceUuid(resource) {
return _utils.CloudDriveUtils.calcResourceUuid(resource);
}
/**
* @internal
*/
/** @en
* @internal
*/
onInstall() {}
/**
* @internal
*/
/** @en
* @internal
*/
onDestroy() {}
}, _descriptor = _applyDecoratedDescriptor(_class.prototype, "personalResources", [_mobx.observable], {
configurable: true,
enumerable: true,
writable: true,
initializer: function () {
return new Map();
}
}), _descriptor2 = _applyDecoratedDescriptor(_class.prototype, "uploadProgress", [_mobx.observable], {
configurable: true,
enumerable: true,
writable: true,
initializer: function () {
return new Map();
}
}), _applyDecoratedDescriptor(_class.prototype, "cancelUpload", [_dec], Object.getOwnPropertyDescriptor(_class.prototype, "cancelUpload"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "retryUpload", [_dec2], Object.getOwnPropertyDescriptor(_class.prototype, "retryUpload"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "fetchPersonalResources", [_dec3], Object.getOwnPropertyDescriptor(_class.prototype, "fetchPersonalResources"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "_initProgress", [_dec4], Object.getOwnPropertyDescriptor(_class.prototype, "_initProgress"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "_updateProgress", [_dec5], Object.getOwnPropertyDescriptor(_class.prototype, "_updateProgress"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "addPersonalResource", [_agoraRteSdk.bound], Object.getOwnPropertyDescriptor(_class.prototype, "addPersonalResource"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "updatePersonalResource", [_agoraRteSdk.bound], Object.getOwnPropertyDescriptor(_class.prototype, "updatePersonalResource"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "uploadPersonalResource", [_agoraRteSdk.bound], Object.getOwnPropertyDescriptor(_class.prototype, "uploadPersonalResource"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "removePersonalResources", [_agoraRteSdk.bound], Object.getOwnPropertyDescriptor(_class.prototype, "removePersonalResources"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "calcResourceUuid", [_agoraRteSdk.bound], Object.getOwnPropertyDescriptor(_class.prototype, "calcResourceUuid"), _class.prototype), _class);