import { i18next, Backend, Toast, Alert, Confirm, Prompt, Photo, Video } from './third_party'; import Options from './Options'; import Storage from './utils/Storage'; import PackageManager from './package/PackageManager'; import EventDispatcher from './event/EventDispatcher'; import Editor from './editor/Editor.jsx'; import Ajax from './utils/Ajax'; import LanguageLoader from './utils/LanguageLoader'; /** * 应用程序 * @author mrdoob / http://mrdoob.com/ * @author tengge / https://github.com/tengge1 */ function Application(container, options) { // 容器 this.container = container; this.width = this.container.clientWidth; this.height = this.container.clientHeight; window.app = this; // 配置 this.options = new Options(options); // 存储 this.storage = new Storage(); this.debug = this.storage.get('debug') || false; // 包管理器 this.packageManager = new PackageManager(); this.require = this.packageManager.require.bind(this.packageManager); // 事件 this.event = new EventDispatcher(this); this.call = this.event.call.bind(this.event); this.on = this.event.on.bind(this.event); // 加载语言包 if (!window._t) { const loader = new LanguageLoader(); loader.load().then(() => { this.ui = React.createElement(Editor); // TODO: 由于ammo.js升级,导致很多类库不兼容,所以只能这么写。 Ammo().then(AmmoLib => { window.Ammo = AmmoLib; this.event.start(); ReactDOM.render(this.ui, this.container); }); }); } } // ----------------------- UI函数 --------------------------------- /** * 创建元素 * @param {React.Component} type ReactComponent类型 * @param {Object} props ReactComponent属性 * @param {Object} children 子节点 */ Application.prototype.createElement = function (type, props, children) { return this.editor.createElement(type, props, children); }; /** * 添加元素 * @param {Object} element ReactElement元素 * @param {Function} callback 回调函数 */ Application.prototype.addElement = function (element, callback) { return this.editor.addElement(element, callback); }; /** * 移除元素 * @param {Object} element ReactElement元素 * @param {Function} callback 回调函数 */ Application.prototype.removeElement = function (element, callback) { return this.editor.removeElement(element, callback); }; /** * 弹窗一段时间消失的消息窗口 * @param {String} content 内容 */ Application.prototype.toast = function (content) { let component = this.createElement(Toast, undefined, content); this.addElement(component); setTimeout(() => { this.removeElement(component); }, 3000); }; /** * 提示窗口 * @param {Object} options 选项 * @param {String} options.title 标题 * @param {String} options.content 内容 * @param {String} options.className 样式类 * @param {Object} options.style 样式 * @param {Function} options.onOK 点击确定回调函数 * @param {Function} options.onClose 点击关闭回调函数 */ Application.prototype.alert = function (options = {}) { let { title, content, className, style, onOK, onClose } = options; let component; let close = () => { component && this.removeElement(component); }; if (onOK === undefined && onClose === undefined) { onOK = onClose = close; } else if (onClose === undefined) { onClose = onOK; } component = this.createElement(Alert, { title, okText: _t('OK'), className, style, onOK, onClose, }, content); this.addElement(component); return { component, close, }; }; /** * 询问窗口 * @param {Object} options 选项 * @param {String} options.title 标题 * @param {String} options.content 内容 * @param {String} options.className 样式类 * @param {Object} options.style 样式 * @param {Function} options.onOK 点击确定回调函数 * @param {Function} options.onCancel 点击取消回调函数 */ Application.prototype.confirm = function (options = {}) { let { title, content, className, style, onOK, onCancel } = options; let component; let close = () => { component && this.removeElement(component); }; let handleOK = () => { if (onOK && onOK() !== false) { close(); } }; if (onCancel === undefined) { onCancel = close; } component = this.createElement(Confirm, { title, okText: _t('OK'), cancelText: _t('Cancel'), className, style, onOK: handleOK, onCancel, onClose: onCancel, }, content); this.addElement(component); return { component, close, }; }; /** * 输入窗口 * @param {Object} options 选项 * @param {String} options.title 标题 * @param {String} options.content 内容 * @param {String} options.className 样式类 * @param {Object} options.style 样式 * @param {String} options.value 默认值 * @param {Function} options.onOK 点击确定执行函数 * @param {Function} options.onClose 点击关闭执行函数 */ Application.prototype.prompt = function (options = {}) { let { title, content, className, style, value, onOK, onClose } = options; let component; let close = () => { component && this.removeElement(component); }; let handleOK = value => { if (onOK && onOK(value) !== false) { close(); } }; if (onClose === undefined) { onClose = close; } component = this.createElement(Prompt, { title, content, className, style, value, okText: _t('OK'), onOK: handleOK, onClose, }); this.addElement(component); return { component, close, }; }; /** * 显示加载器 * @param {*} text 加载器文本 */ Application.prototype.mask = function (text) { this.call('showMask', this, true, text); }; /** * 隐藏加载器 */ Application.prototype.unmask = function () { this.call('showMask', this, false); }; /** * 查看图片 * @param {String} url 地址 */ Application.prototype.photo = function (url) { let component = null; let close = () => { if (component) { this.removeElement(component); component = null; } }; component = this.createElement(Photo, { url, onClick: close }); this.addElement(component); }; /** * 查看视频 * @param {String} url 地址 */ Application.prototype.video = function (url) { let component = null; let close = () => { if (component) { this.removeElement(component); component = null; } }; component = this.createElement(Video, { url, onClick: close }); this.addElement(component); }; // -------------------- 工具函数 ----------------------- /** * 上传文件 * @param {Object} url 上传Url * @param {String} callback 回调函数 */ Application.prototype.upload = function () { var input; return function (url, callback) { if (!input) { input = document.createElement('input'); input.type = 'file'; input.style.display = 'none'; input.addEventListener('change', event => { Ajax.post(url, { file: event.target.files[0], }, json => { var obj = JSON.parse(json); if (obj.Code === 200) { callback(obj); } else { app.toast(obj.Msg); } }); }); document.body.appendChild(input); } input.click(); }; }(); // ----------------------- 记录日志 -------------------------------- Application.prototype.log = function (content) { // 普通日志 this.call('log', this, content); }; Application.prototype.warn = function (content) { // 警告日志 this.call('log', this, content, 'warn'); }; Application.prototype.error = function (content) { // 错误日志 this.call('log', this, content, 'error'); }; export default Application;