"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var _button = require("antd/es/button"); var _button2 = _interopRequireDefault(_button); var _popover = require("antd/es/popover"); var _popover2 = _interopRequireDefault(_popover); var _icon = require("antd/es/icon"); var _icon2 = _interopRequireDefault(_icon); var _message2 = require("antd/es/message"); var _message3 = _interopRequireDefault(_message2); var _input = require("antd/es/input"); var _input2 = _interopRequireDefault(_input); var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); require("antd/es/button/style"); require("antd/es/popover/style"); require("antd/es/icon/style"); require("antd/es/message/style"); require("antd/es/input/style"); var _dayjs = require("dayjs"); var _dayjs2 = _interopRequireDefault(_dayjs); var _shortid = require("shortid"); var _shortid2 = _interopRequireDefault(_shortid); var _propTypes = require("prop-types"); var _propTypes2 = _interopRequireDefault(_propTypes); var _classnames = require("classnames"); var _classnames2 = _interopRequireDefault(_classnames); var _react = require("react"); var _react2 = _interopRequireDefault(_react); var _reactIntlUniversal = require("react-intl-universal"); var _reactIntlUniversal2 = _interopRequireDefault(_reactIntlUniversal); var _Emoji = require("./Emoji"); var _Emoji2 = _interopRequireDefault(_Emoji); var _Upload = require("./Upload"); var _Upload2 = _interopRequireDefault(_Upload); var _Comment = require("../../Comment"); var _Comment2 = _interopRequireDefault(_Comment); var _utils = require("./../../utils"); var _constant = require("../../constant"); var _helper = require("../../helper"); require("./index.css"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } var TextArea = _input2.default.TextArea; var client = function client(oss) { return new window.OSS.Wrapper({ accessKeyId: oss.access_key_id, accessKeySecret: oss.access_key_secret, stsToken: oss.security_token, endpoint: _constant.OSS_ENDPOINT, //常量,你可以自己定义 bucket: _constant.OSS_BUCKET }); }; var uploadPath = function uploadPath(path, file) { return path + "/" + (0, _dayjs2.default)().format("YYYYMMDD") + "/" + _shortid2.default.generate() + "." + file.type.split("/")[1]; }; var UploadToOss = function UploadToOss(oss, path, file) { var url = uploadPath(path, file); return new Promise(function (resolve, reject) { client(oss).multipartUpload(url, file).then(function (data) { resolve(data); }).catch(function (error) { reject(error); }); }); }; var Editor = function (_React$Component) { _inherits(Editor, _React$Component); function Editor(props) { _classCallCheck(this, Editor); var _this = _possibleConstructorReturn(this, (Editor.__proto__ || Object.getPrototypeOf(Editor)).call(this, props)); _this.state = { showUpload: false, value: props.value || "", // 编辑器里面的值 fileList: props.fileList || [], // 图片列表 fileMap: {}, // 已经上传的图片路径和 uid 的映射 { uid: path } uploadVisible: false }; _this.handleChange = _this.handleChange.bind(_this); _this.handleClickEmoji = _this.handleClickEmoji.bind(_this); _this.handleChangeFileList = _this.handleChangeFileList.bind(_this); _this.handleShowUpload = _this.handleShowUpload.bind(_this); _this.handleUpload = _this.handleUpload.bind(_this); _this.handleSubmit = _this.handleSubmit.bind(_this); _this.handlePaste = _this.handlePaste.bind(_this); _this.resetState = _this.resetState.bind(_this); _this.handleEmojiScroll = _this.handleEmojiScroll.bind(_this); _this.handlePressEnter = _this.handlePressEnter.bind(_this); _this.invokeFileListChange = _this.invokeFileListChange.bind(_this); return _this; } _createClass(Editor, [{ key: "componentDidMount", value: function componentDidMount() { var _props = this.props, app = _props.app, onRef = _props.onRef; if (app.currentUser && (app.currentUser.user_id > 0 || app.currentUser.id > 0)) { app.sOssSts(); } if ((0, _helper.isFunction)(onRef)) { onRef(this); } } }, { key: "handleEmojiScroll", value: function handleEmojiScroll(e) { if (!this.emoji) { return; } e.preventDefault(); if (e.deltaY > 0) { this.emoji.next(); } else if (e.deltaY < 0) { this.emoji.prev(); } } /** * 编辑器的值改变事件 * 将最新的值存储到 state 中 * @param {string} value 输入的值 */ }, { key: "handleChange", value: function handleChange(value) { this.setState({ value: value }); if (this.props.onChange) { this.props.onChange(value); } } /** * 点击 emoji 的事件 * 点击后,需要将改 emoji 插入到编辑器中 * 插入的值为 [emoji chinese name] * 参数 emoji 即为 emoji chinese name * @param {string}} emoji emoji 的中文,如 微笑 */ }, { key: "handleClickEmoji", value: function handleClickEmoji(emoji) { var value = this.props.value || this.state.value; value += "[" + emoji + "]"; this.handleChange(value); } /** * 监听文件列表改变事件 * @param {Array} fileList 文件列表 */ }, { key: "handleChangeFileList", value: function handleChangeFileList(fileList) { var list = fileList; if (fileList.length > this.props.maxUpload) { list = fileList.slice(0, this.props.maxUpload); } this.invokeFileListChange(list); } /** * 控制上传 Popover 的显示和隐藏 * @param {boolean} showUpload 是否显示上传的 Popover */ }, { key: "handleShowUpload", value: function handleShowUpload(showUpload) { if (typeof showUpload === "boolean") { this.setState({ showUpload: showUpload }); } else { this.setState({ showUpload: !this.state.showUpload }); } } /** * 上传文件 * @param {object} param 文件对象 */ }, { key: "handleUpload", value: function handleUpload(_ref) { var uid = _ref.uid, path = _ref.path; var fileMap = this.state.fileMap; var fileList = this.state.fileList; fileMap[uid] = path; fileList = fileList.map(function (item) { if (item.uid === uid) { item.thumbUrl = _constant.OSS_LINK + path; } return item; }); this.setState({ fileMap: fileMap }); this.invokeFileListChange(fileList); } /** * **统一处理fileList的修改** * 1. upload * 2. paste * PS: 移动端需要做额外操作 * -- evo 20200223 */ }, { key: "invokeFileListChange", value: function invokeFileListChange(fileList) { var _props2 = this.props, limitOne = _props2.limitOne, handleChangeFileList = _props2.handleChangeFileList; handleChangeFileList(fileList); this.setState({ fileList: fileList }); if (limitOne && _utils.isMobile) { var file = fileList[0]; if (file && file.status === "done" && !file.thumbUrl.includes("data:image")) { this.setState({ uploadVisible: false }); } } } /** * 粘贴回调 */ }, { key: "handlePaste", value: function handlePaste(e) { var _this2 = this; if (this.state.fileList.length >= this.props.maxUpload) { return; } var items = e.clipboardData && e.clipboardData.items; var file = null; if (items && items.length) { for (var i = 0; i < items.length; i++) { if (items[i].type.indexOf("image") !== -1) { file = items[i].getAsFile(); break; } } if (file === null) return; } this.setState({ uploadVisible: true }); var reader = new FileReader(); reader.readAsDataURL(file); reader.onloadend = function () { // DRIVER_LICENSE_PATH oss 的存储路径位置 UploadToOss(_this2.props.app.oss, _constant.DRIVER_LICENSE_PATH, file).then(function (data) { var fileList = _this2.state.fileList.concat({ url: _constant.OSS_LINK + data.name, thumbUrl: _constant.OSS_LINK + data.name, type: file.type, uid: new Date().valueOf() }); _this2.invokeFileListChange(fileList); }).catch(function (e) { var msg = e.message || _constant.ERROR_DEFAULT; if (_this2.props.showError) { _message3.default.error(msg); } if (_this2.props.onError) { _this2.props.onError(msg, { response: e.response }); } }); }; } /** * 提交编辑器内容 * 提交功能,交给父组件来实现 * 需要父组件传入 onSubmit */ }, { key: "handleSubmit", value: function handleSubmit() { var _this3 = this; var maxLength = this.props.maxLength; var _state = this.state, value = _state.value, fileMap = _state.fileMap, fileList = _state.fileList; if (value.length > maxLength) { // message.error(`字数不得超过${maxLength}字`); _message3.default.error(_reactIntlUniversal2.default.get("editor.maxLength", { maxLength: maxLength })); return; } var files = []; if (fileList.length) { fileList.forEach(function (item) { if (item.url) { files.push(item.url); return; } if (!fileMap[item.uid]) { return; } files.push("" + _constant.OSS_LINK + fileMap[item.uid]); }); } if (this.props.beforeSubmit) { Promise.resolve(this.props.beforeSubmit({ text: value, files: files })).then(function (res) { if (!(res === false)) { _this3.props.onSubmit({ text: value, files: files }, function (res, action) { _this3.resetState(); if (action === "comment" && _this3.props.onCommentSuccess) { _this3.props.onCommentSuccess(res); } }); } }); } else { this.props.onSubmit({ text: value, files: files }, function (res, action) { _this3.resetState(); if (action === "comment" && _this3.props.onCommentSuccess) { _this3.props.onCommentSuccess(res); } }); } } }, { key: "resetState", value: function resetState() { this.handleChange(""); this.handleChangeFileList([]); this.setState({ showUpload: false, value: "", fileList: [], fileMap: {} }); } }, { key: "checkDisabledSubmit", value: function checkDisabledSubmit() { var _props3 = this.props, btnDisabled = _props3.btnDisabled, value = _props3.value, fileList = _props3.fileList; if (btnDisabled) { return true; } if (value && value !== "") { return false; } if (this.state.value && this.state.value !== "") { return false; } if (fileList && fileList.length > 0) { return false; } if (this.state.fileList.length > 0) { return false; } return true; } /** * **处理Enter事件** * 1. `allowEnterSubmit`为true时enter触发submit事件 * 2. `e.preventDefault`为了防止enter事件后仍触发换行 * 3. enter事件开启后,仍可以用`shift + enter`触发换行 * -- evo 20200222 */ }, { key: "handlePressEnter", value: function handlePressEnter(e) { if (this.props.allowEnterSubmit) { if (!e.shiftKey) { e.preventDefault(); this.handleSubmit(); } } } }, { key: "render", value: function render() { var _this4 = this; var _props4 = this.props, value = _props4.value, rows = _props4.rows, showEmoji = _props4.showEmoji, showUpload = _props4.showUpload, multiple = _props4.multiple, emojiPopoverPlacement = _props4.emojiPopoverPlacement, uploadPopoverPlacement = _props4.uploadPopoverPlacement, uploadOverlayClassName = _props4.uploadOverlayClassName, fileList = _props4.fileList, maxUpload = _props4.maxUpload, btnLoading = _props4.btnLoading, button = _props4.button, emojiToolIcon = _props4.emojiToolIcon, imageToolIcon = _props4.imageToolIcon, maxLength = _props4.maxLength, autoFocus = _props4.autoFocus, app = _props4.app; var placeholder = this.props.placeholder || _reactIntlUniversal2.default.get("editor.placeholder"); var btnSubmitText = this.props.btnSubmitText || _reactIntlUniversal2.default.get("editor.SubmitBtn"); var handleSubmit = this.handleSubmit; var disabledSubmit = this.checkDisabledSubmit(); var inputValue = value || this.state.value; var uploadFileList = fileList || this.state.fileList; var isLogin = app.currentUser && (app.currentUser.user_id > 0 || app.currentUser.id > 0); return _react2.default.createElement( "div", { className: "comment-editor-container", onPaste: this.handlePaste }, isLogin ? _react2.default.createElement( _react.Fragment, null, _react2.default.createElement("div", { className: (0, _classnames2.default)({ "comment-editor-toolbar": true, "comment-editor-toolbar-error": inputValue.length > maxLength }) }), _react2.default.createElement( "div", { className: "comment-editor" }, _react2.default.createElement(TextArea, { value: inputValue, onChange: function onChange(e) { _this4.handleChange(e.target.value); }, rows: rows, placeholder: placeholder, autoFocus: autoFocus, onPressEnter: this.handlePressEnter }), _react2.default.createElement( "div", { className: "comment-toolbar" }, _react2.default.createElement( "div", { className: "comment-toolbar-left" }, showEmoji && _react2.default.createElement( _popover2.default, { trigger: "click", placement: emojiPopoverPlacement, autoAdjustOverflow: false, overlayStyle: { zIndex: 9999 }, content: _react2.default.createElement( "div", { style: { width: 240, height: 205 }, onWheel: this.handleEmojiScroll }, _react2.default.createElement(_Emoji2.default, { onClick: this.handleClickEmoji, ref: function ref(node) { _this4.emoji = node; }, emojiList: this.props.app.emojiList }) ), overlayClassName: "comment-emoji-popover" }, emojiToolIcon || _react2.default.createElement(_icon2.default, { type: "smile-o", className: "comment-toolbar-icon" }) ), showUpload ? _react2.default.createElement( _popover2.default, { trigger: "click" // TODO: 针对非 react.js,直接使用 click 事件来控制展开或关闭 , visible: this.state.uploadVisible, placement: uploadPopoverPlacement, overlayClassName: uploadOverlayClassName, autoAdjustOverflow: false, overlayStyle: { zIndex: 9999 }, onVisibleChange: function onVisibleChange(visible) { _this4.setState({ uploadVisible: visible }); }, content: _react2.default.createElement( "div", { className: "comment-img-popover" }, _react2.default.createElement(_Upload2.default, { onRef: function onRef(node) { return _this4.uploadRef = node; }, multiple: multiple, onChangeFileList: this.handleChangeFileList, onUpload: this.handleUpload, maxUpload: maxUpload, fileList: uploadFileList, showError: this.props.showError, onError: this.props.onError }), _react2.default.createElement("div", { className: "clearfix" }) ), title: _react2.default.createElement( "div", { className: "comment-img-title" }, _react2.default.createElement( "span", null, _reactIntlUniversal2.default.get("editor.uploadTip"), maxUpload >= 2 ? _react2.default.createElement( "span", { className: "comment-img-title-counter" }, _reactIntlUniversal2.default.get("editor.uploadCount", { count: maxUpload - uploadFileList.length }) ) : null ) ) }, imageToolIcon ? _react2.default.cloneElement(imageToolIcon, { onClick: function onClick() { return _this4.handleShowUpload(true); } }) : _react2.default.createElement(_icon2.default, { type: "picture", className: "comment-toolbar-icon", style: { marginLeft: 20 }, onClick: function onClick() { return _this4.handleShowUpload(true); } }) ) : null ), _react2.default.createElement( "div", { className: "comment-toolbar-right" }, button ? _react2.default.cloneElement(button, { onClick: button.props.onClick || handleSubmit }) : _react2.default.createElement( _button2.default, { onClick: function onClick() { return _this4.handleSubmit(); }, type: "primary", loading: btnLoading, disabled: disabledSubmit }, btnSubmitText ) ) ) ) ) : _react2.default.createElement( _react.Fragment, null, _react2.default.createElement( "div", { className: "comment-unlogin-tip" }, _reactIntlUniversal2.default.get("comment.unlogin") ), _react2.default.createElement( "div", { className: "comment-unlogin-button" }, _react2.default.createElement( _button2.default, { type: "primary", onClick: function onClick() { window.location.href = app.LOGINLINK + "?f=" + window.location.href; } }, _reactIntlUniversal2.default.get("account.login") ) ) ) ); } }]); return Editor; }(_react2.default.Component); Editor.propTypes = { rows: _propTypes2.default.number, placeholder: _propTypes2.default.string, showEmoji: _propTypes2.default.bool, emojiPopoverPlacement: _propTypes2.default.string, showUpload: _propTypes2.default.bool, uploadPopoverPlacement: _propTypes2.default.string, uploadOverlayClassName: _propTypes2.default.string, multiple: _propTypes2.default.bool, closeUploadWhenBlur: _propTypes2.default.bool, maxUpload: _propTypes2.default.number, value: _propTypes2.default.string, onChange: _propTypes2.default.func, onSubmit: _propTypes2.default.func, beforeSubmit: _propTypes2.default.func, btnSubmitText: _propTypes2.default.string, btnLoading: _propTypes2.default.bool, btnDisabled: _propTypes2.default.bool, button: _propTypes2.default.node, emojiToolIcon: _propTypes2.default.node, imageToolIcon: _propTypes2.default.node, showError: _propTypes2.default.bool, onError: _propTypes2.default.func, maxLength: _propTypes2.default.number, // Enter事件相关 allowEnterSubmit: _propTypes2.default.bool, // 私信仅允许选中一个,此处可以优化为通用的limit limitOne: _propTypes2.default.bool }; Editor.defaultProps = { rows: 5, // placeholder: "说点什么吧", showEmoji: true, showUpload: true, multiple: true, emojiPopoverPlacement: "bottomLeft", closeUploadWhenBlur: false, uploadPopoverPlacement: "bottomLeft", uploadOverlayClassName: "", maxUpload: 1, // btnSubmitText: "发表", btnLoading: false, btnDisabled: false, showError: true, maxLength: 5000, app: {}, handleChangeFileList: function handleChangeFileList() {}, // Enter事件相关 allowEnterSubmit: false, limitOne: false }; exports.default = (0, _Comment2.default)(Editor); //# sourceMappingURL=index.js.map