CommentForm.js 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. import React from 'react';
  2. import PropTypes from 'prop-types';
  3. import ReactUtils from '../ReactUtils';
  4. import CommentEditor from '../PageComment/CommentEditor';
  5. import CommentPreview from '../PageComment/CommentPreview';
  6. import Button from 'react-bootstrap/es/Button';
  7. import Tab from 'react-bootstrap/es/Tab';
  8. import Tabs from 'react-bootstrap/es/Tabs';
  9. import UserPicture from '../User/UserPicture';
  10. /**
  11. *
  12. * @author Yuki Takei <yuki@weseek.co.jp>
  13. *
  14. * @export
  15. * @class Comment
  16. * @extends {React.Component}
  17. */
  18. export default class CommentForm extends React.Component {
  19. constructor(props) {
  20. super(props);
  21. this.state = {
  22. comment: '',
  23. isMarkdown: true,
  24. html: '',
  25. key: 1,
  26. };
  27. this.updateState = this.updateState.bind(this);
  28. this.postComment = this.postComment.bind(this);
  29. this.renderHtml = this.renderHtml.bind(this);
  30. this.handleSelect = this.handleSelect.bind(this);
  31. }
  32. updateState(event) {
  33. const target = event.target;
  34. const value = target.type === 'checkbox' ? target.checked : target.value;
  35. const name = target.name;
  36. this.setState({
  37. [name]: value
  38. });
  39. }
  40. handleSelect(key) {
  41. this.setState({ key });
  42. this.renderHtml(this.state.comment);
  43. }
  44. /**
  45. * Load data of comments and rerender <PageComments />
  46. */
  47. postComment(event) {
  48. event.preventDefault();
  49. this.props.crowi.apiPost('/comments.add', {
  50. commentForm: {
  51. comment: this.state.comment,
  52. _csrf: this.props.crowi.csrfToken,
  53. page_id: this.props.pageId,
  54. revision_id: this.props.revisionId,
  55. is_markdown: this.state.isMarkdown,
  56. }
  57. })
  58. .then((res) => {
  59. if (this.props.onPostComplete != null) {
  60. this.props.onPostComplete(res.comment);
  61. }
  62. this.setState({
  63. comment: '',
  64. isMarkdown: true,
  65. html: '',
  66. key: 1,
  67. });
  68. });
  69. }
  70. getCommentHtml() {
  71. return (
  72. <CommentPreview
  73. html={this.state.html}
  74. inputRef={el => this.previewElement = el}/>
  75. );
  76. }
  77. renderHtml(markdown) {
  78. var context = {
  79. markdown,
  80. dom: this.previewElement,
  81. };
  82. const crowiRenderer = this.props.crowiRenderer;
  83. const interceptorManager = this.props.crowi.interceptorManager;
  84. interceptorManager.process('preRenderCommnetPreview', context)
  85. .then(() => interceptorManager.process('prePreProcess', context))
  86. .then(() => {
  87. context.markdown = crowiRenderer.preProcess(context.markdown);
  88. })
  89. .then(() => interceptorManager.process('postPreProcess', context))
  90. .then(() => {
  91. var parsedHTML = crowiRenderer.process(context.markdown);
  92. context['parsedHTML'] = parsedHTML;
  93. })
  94. .then(() => interceptorManager.process('prePostProcess', context))
  95. .then(() => {
  96. context.parsedHTML = crowiRenderer.postProcess(context.parsedHTML, context.dom);
  97. })
  98. .then(() => interceptorManager.process('postPostProcess', context))
  99. .then(() => interceptorManager.process('preRenderCommentPreviewHtml', context))
  100. .then(() => {
  101. this.setState({ html: context.parsedHTML });
  102. })
  103. // process interceptors for post rendering
  104. .then(() => interceptorManager.process('postRenderCommentPreviewHtml', context));
  105. }
  106. generateInnerHtml(html) {
  107. return {__html: html};
  108. }
  109. render() {
  110. const crowi = this.props.crowi;
  111. const username = crowi.me;
  112. const user = crowi.findUser(username);
  113. const creatorsPage = `/user/${username}`;
  114. const comment = this.state.comment;
  115. const commentPreview = this.state.isMarkdown ? this.getCommentHtml(): ReactUtils.nl2br(comment);
  116. return (
  117. <div>
  118. <form className="form page-comment-form" id="page-comment-form" onSubmit={this.postComment}>
  119. { username &&
  120. <div className="comment-form">
  121. <div className="comment-form-user">
  122. <a href={creatorsPage}>
  123. <UserPicture user={user} />
  124. </a>
  125. </div>
  126. <div className="comment-form-main">
  127. <div className="comment-write">
  128. <Tabs activeKey={this.state.key} id="comment-form-tabs" onSelect={this.handleSelect} animation={false}>
  129. <Tab eventKey={1} title="Write">
  130. {/* <textarea className="comment-form-comment form-control" id="comment-form-comment" name="comment" required placeholder="Write comments here..." value={this.state.comment} onChange={this.updateState} >
  131. </textarea> */}
  132. <CommentEditor
  133. // ref="editor"
  134. // value={this.state.markdown}
  135. // editorOptions={this.state.editorOptions}
  136. // isMobile={this.props.crowi.isMobile}
  137. // isUploadable={this.state.isUploadable}
  138. // isUploadableFile={this.state.isUploadableFile}
  139. // emojiStrategy={emojiStrategy}
  140. // onScroll={this.onEditorScroll}
  141. // onScrollCursorIntoView={this.onEditorScrollCursorIntoView}
  142. // onChange={this.onMarkdownChanged}
  143. // onSave={this.onSave}
  144. // onUpload={this.onUpload}
  145. />
  146. </Tab>
  147. { this.state.isMarkdown == true &&
  148. <Tab eventKey={2} title="Preview">
  149. <div className="comment-form-preview">
  150. {commentPreview}
  151. </div>
  152. </Tab>
  153. }
  154. </Tabs>
  155. </div>
  156. <div className="comment-submit">
  157. <div className="pull-left">
  158. { this.state.key == 1 &&
  159. <label>
  160. <input type="checkbox" id="comment-form-is-markdown" name="isMarkdown" checked={this.state.isMarkdown} value="1" onChange={this.updateState} /> Markdown
  161. </label>
  162. }
  163. </div>
  164. <div className="pull-right">
  165. <Button type="submit" value="Submit" bsStyle="primary" className="fcbtn btn btn-sm btn-primary btn-outline btn-rounded btn-1b">
  166. Comment
  167. </Button>
  168. </div>
  169. <div className="clearfix">
  170. </div>
  171. </div>
  172. </div>
  173. </div>
  174. }
  175. </form>
  176. </div>
  177. );
  178. }
  179. }
  180. CommentForm.propTypes = {
  181. crowi: PropTypes.object.isRequired,
  182. onPostComplete: PropTypes.func,
  183. pageId: PropTypes.string,
  184. revisionId: PropTypes.string,
  185. crowiRenderer: PropTypes.object.isRequired,
  186. };