| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398 | 
							- import React from "react";
 - import PropTypes from "prop-types";
 - import { Icon, Button, Popover, Input, message } from "antd";
 - import classnames from "classnames";
 - import intl from "react-intl-universal";
 - import { OSS_LINK } from "../../constant";
 - import { isFunction } from "../../helper";
 - import Upload from "./Upload";
 - import Emoji from "./Emoji";
 - import "./index.css";
 - 
 - const { TextArea } = Input;
 - 
 - class Editor extends React.Component {
 -   constructor(props) {
 -     super(props);
 -     this.state = {
 -       showUpload: false,
 -       value: "", // 编辑器里面的值
 - 
 -       fileList: [], // 图片列表
 -       fileMap: {} // 已经上传的图片路径和 uid 的映射 { uid: path }
 -     };
 -     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.resetState = this.resetState.bind(this);
 -     this.handleEmojiScroll = this.handleEmojiScroll.bind(this);
 -   }
 - 
 -   componentDidMount() {
 -     if (isFunction(this.props.onRef)) {
 -       this.props.onRef(this);
 -     }
 -   }
 - 
 -   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 输入的值
 -    */
 -   handleChange(value) {
 -     this.setState({ value });
 -     if (this.props.onChange) {
 -       this.props.onChange(value);
 -     }
 -   }
 - 
 -   /**
 -    * 点击 emoji 的事件
 -    * 点击后,需要将改 emoji 插入到编辑器中
 -    * 插入的值为 [emoji chinese name]
 -    * 参数 emoji 即为 emoji chinese name
 -    * @param {string}} emoji emoji 的中文,如 微笑
 -    */
 -   handleClickEmoji(emoji) {
 -     let { value } = this.state;
 -     value += `[${emoji}]`;
 -     this.handleChange(value);
 -   }
 - 
 -   /**
 -    * 监听文件列表改变事件
 -    * @param {Array} fileList 文件列表
 -    */
 -   handleChangeFileList(fileList) {
 -     let list = fileList;
 -     if (fileList.length > this.props.maxUpload) {
 -       list = fileList.slice(0, this.props.maxUpload);
 -     }
 -     this.setState({ fileList: list });
 -   }
 - 
 -   /**
 -    * 控制上传 Popover 的显示和隐藏
 -    * @param {boolean} showUpload 是否显示上传的 Popover
 -    */
 -   handleShowUpload(showUpload) {
 -     if (typeof showUpload === "boolean") {
 -       this.setState({ showUpload: showUpload });
 -     } else {
 -       this.setState({ showUpload: !this.state.showUpload });
 -     }
 -   }
 - 
 -   /**
 -    * 上传文件
 -    * @param {object} param 文件对象
 -    */
 -   handleUpload({ uid, path }) {
 -     const { fileMap } = this.state;
 -     let { fileList } = this.state;
 -     fileMap[uid] = path;
 -     fileList = fileList.map(item => {
 -       if (item.uid === uid) {
 -         item.thumbUrl = OSS_LINK + path;
 -       }
 -       return item;
 -     });
 -     this.setState({ fileMap, fileList });
 -   }
 - 
 -   /**
 -    * 提交编辑器内容
 -    * 提交功能,交给父组件来实现
 -    * 需要父组件传入 onSubmit
 -    */
 -   handleSubmit() {
 -     const { maxLength } = this.props;
 -     let { value, fileMap, fileList } = this.state;
 -     if (value.length > maxLength) {
 -       // message.error(`字数不得超过${maxLength}字`);
 -       message.error(intl.get("editor.maxLength", { maxLength }));
 -       return;
 -     }
 -     const files = [];
 -     if (fileList.length) {
 -       fileList.forEach(item => {
 -         if (!fileMap[item.uid]) {
 -           return;
 -         }
 -         files.push(`${OSS_LINK}${fileMap[item.uid]}`);
 -       });
 -     }
 -     if (this.props.beforeSubmit) {
 -       Promise.resolve(this.props.beforeSubmit({ text: value, files })).then(
 -         res => {
 -           if (!(res === false)) {
 -             this.props.onSubmit({ text: value, files }, () => {
 -               this.resetState();
 -               if (this.props.onCommentSuccess) {
 -                 this.props.onCommentSuccess();
 -               }
 -             });
 -           }
 -         }
 -       );
 -     } else {
 -       this.props.onSubmit({ text: value, files }, () => {
 -         this.resetState();
 -         if (this.props.onCommentSuccess) {
 -           this.props.onCommentSuccess();
 -         }
 -       });
 -     }
 -   }
 - 
 -   resetState() {
 -     this.setState({
 -       showUpload: false,
 -       value: "",
 -       fileList: [],
 -       fileMap: {}
 -     });
 -   }
 - 
 -   render() {
 -     const {
 -       value,
 -       // placeholder,
 -       rows,
 -       showEmoji,
 -       showUpload,
 -       multiple,
 -       emojiPopoverPlacement,
 -       uploadPopoverPlacement,
 -       uploadOverlayClassName,
 -       closeUploadWhenBlur,
 -       maxUpload,
 -       // btnSubmitText,
 -       btnLoading,
 -       btnDisabled,
 -       button,
 -       emojiToolIcon,
 -       imageToolIcon,
 -       maxLength,
 -       autoFocus
 -     } = this.props;
 -     let placeholder = this.props.placeholder || intl.get("editor.placeholder");
 -     let btnSubmitText =
 -       this.props.btnSubmitText || intl.get("editor.SubmitBtn");
 -     const handleSubmit = this.handleSubmit;
 -     const disabledSubmit =
 -       btnDisabled ||
 -       (!this.props.value && !this.state.value && !this.state.fileList.length);
 -     const inputValue = value || this.state.value;
 -     return (
 -       <div className="comment-editor-container">
 -         <div
 -           className={classnames({
 -             "comment-editor-toolbar": true,
 -             "comment-editor-toolbar-error": inputValue.length > maxLength
 -           })}
 -         >
 -           {/* {intl.get("editor.alreadyEntered", {
 -             count: inputValue.length,
 -             maxLength
 -           })} */}
 -         </div>
 -         <div className="comment-editor">
 -           <TextArea
 -             value={inputValue}
 -             onChange={e => this.handleChange(e.target.value)}
 -             rows={rows}
 -             placeholder={placeholder}
 -             autoFocus={autoFocus}
 -           />
 - 
 -           <div className="comment-toolbar">
 -             <div className="comment-toolbar-left">
 -               {showEmoji && (
 -                 <Popover
 -                   trigger="click"
 -                   placement={emojiPopoverPlacement}
 -                   autoAdjustOverflow={false}
 -                   overlayStyle={{ zIndex: 999 }}
 -                   content={
 -                     <div
 -                       style={{ width: 240, height: 205 }}
 -                       onWheel={this.handleEmojiScroll}
 -                     >
 -                       <Emoji
 -                         onClick={this.handleClickEmoji}
 -                         ref={node => {
 -                           this.emoji = node;
 -                         }}
 -                       />
 -                     </div>
 -                   }
 -                   overlayClassName="comment-emoji-popover"
 -                 >
 -                   {emojiToolIcon || (
 -                     <Icon type="smile-o" className="comment-toolbar-icon" />
 -                   )}
 -                 </Popover>
 -               )}
 - 
 -               {showUpload ? (
 -                 <Popover
 -                   trigger="click"
 -                   // TODO: 针对非 react.js,直接使用 click 事件来控制展开或关闭
 -                   // visible={this.state.showUpload}
 -                   placement={uploadPopoverPlacement}
 -                   overlayClassName={uploadOverlayClassName}
 -                   autoAdjustOverflow={false}
 -                   overlayStyle={{ zIndex: 999 }}
 -                   onVisibleChange={
 -                     closeUploadWhenBlur
 -                       ? visible => {
 -                           this.handleShowUpload(visible);
 -                         }
 -                       : null
 -                   }
 -                   content={
 -                     <div
 -                       style={{
 -                         width: 336, // 一行显示3张
 -                         minHeight: 100,
 -                         margin: "0 auto"
 -                       }}
 -                     >
 -                       <Upload
 -                         multiple={multiple}
 -                         onChangeFileList={this.handleChangeFileList}
 -                         onUpload={this.handleUpload}
 -                         maxUpload={maxUpload}
 -                         fileList={this.state.fileList}
 -                         showError={this.props.showError}
 -                         onError={this.props.onError}
 -                       />
 -                       <div className="clearfix" />
 -                     </div>
 -                   }
 -                   title={
 -                     <div style={{ margin: "5px auto" }}>
 -                       <span>
 -                         {intl.get("editor.uploadTip")}
 -                         {maxUpload >= 2 ? (
 -                           <span style={{ color: "#666", fontWeight: 400 }}>
 -                             {intl.get("editor.uploadCount", {
 -                               count: maxUpload - this.state.fileList.length
 -                             })}
 -                           </span>
 -                         ) : null}
 -                       </span>
 -                       {/* 因为是点击别的区域关闭,所以不用右上角的 Icon */}
 -                       {/* <Icon
 -                         type="close"
 -                         onClick={() => this.handleShowUpload(false)}
 -                         style={{
 -                           float: "right",
 -                           cursor: "pointer",
 -                           marginTop: 4
 -                         }}
 -                       /> */}
 -                     </div>
 -                   }
 -                 >
 -                   {imageToolIcon ? (
 -                     React.cloneElement(imageToolIcon, {
 -                       onClick: () => this.handleShowUpload(true)
 -                     })
 -                   ) : (
 -                     <Icon
 -                       type="picture"
 -                       className="comment-toolbar-icon"
 -                       style={{ marginLeft: 10 }}
 -                       onClick={() => this.handleShowUpload(true)}
 -                     />
 -                   )}
 -                 </Popover>
 -               ) : null}
 -             </div>
 - 
 -             <div className="comment-toolbar-right">
 -               {button ? (
 -                 React.cloneElement(button, {
 -                   onClick: button.props.onClick || handleSubmit
 -                 })
 -               ) : (
 -                 <Button
 -                   onClick={() => this.handleSubmit()}
 -                   type="primary"
 -                   loading={btnLoading}
 -                   disabled={disabledSubmit}
 -                 >
 -                   {btnSubmitText}
 -                 </Button>
 -               )}
 -             </div>
 -           </div>
 -         </div>
 -       </div>
 -     );
 -   }
 - }
 - 
 - Editor.propTypes = {
 -   rows: PropTypes.number,
 -   placeholder: PropTypes.string,
 -   showEmoji: PropTypes.bool,
 -   emojiPopoverPlacement: PropTypes.string,
 -   showUpload: PropTypes.bool,
 -   uploadPopoverPlacement: PropTypes.string,
 -   uploadOverlayClassName: PropTypes.string,
 -   multiple: PropTypes.bool,
 -   closeUploadWhenBlur: PropTypes.bool,
 -   maxUpload: PropTypes.number,
 -   value: PropTypes.string,
 -   onChange: PropTypes.func,
 -   onSubmit: PropTypes.func,
 -   beforeSubmit: PropTypes.func,
 -   btnSubmitText: PropTypes.string,
 -   btnLoading: PropTypes.bool,
 -   btnDisabled: PropTypes.bool,
 -   button: PropTypes.node,
 -   emojiToolIcon: PropTypes.node,
 -   imageToolIcon: PropTypes.node,
 -   showError: PropTypes.bool,
 -   onError: PropTypes.func,
 -   maxLength: PropTypes.number
 - };
 - 
 - 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
 - };
 - 
 - export default Editor;
 
 
  |