react_comments-8.x-1.0-beta2/js/src/src/components/CommentBox.js

js/src/src/components/CommentBox.js
import React, { Component } from 'react';
import { Editor, EditorState, ContentState } from 'draft-js';
import './CommentBox.css';
import Throbber from 'react-throbber';
import 'react-throbber/src/style.css';
import Constants from '../utils/constants';
import validateEmail from '../utils/validateEmail';
import UserPicture from "./UserPicture";
import CommentNotify from './CommentNotify';

class CommentBox extends Component {
  state = {
    isOpen: false,
    isFocused: false,
    isLoading: false,
    message: false,
    notify: this.props.notify,
    messageOnly: false,
    anonName: false,
    anonEmail: false,
    editorState: (this.props.type === 'edit') ?
      EditorState.createWithContent(ContentState.createFromText(this.props.text)) :
      EditorState.createEmpty()
  };

  getLoginLink = () => {
    return `/user/login?destination=${encodeURIComponent(window.location.pathname)}%23comments-app-container`;
  };

  toggleFocus = () => {
    this.setState({
      isFocused: !this.state.isFocused,
      isOpen: true
    });
  };

  getCommentText = () => this.state.editorState.getCurrentContent().getPlainText().trim();

  getDefaultNotify = () => this.props.type === 'edit' ? this.state.notify : -1;

  postComment = (commentText) => {
    if (this.state.isLoading) return;

    if (!this.userCanPost()) return;

    this.setState({ isLoading: true, message: false });
    this.props.postComment(commentText, this.state.anonName, this.state.anonEmail, this.state.notify).then((response) => {

      if (response.code === 'success') {
        this.setState({
          isLoading: false,
          editorState: EditorState.createEmpty(),
        });
      }
      else if (response.code === 'queued_for_moderation') {
        this.setState({
          message: {
            message: response.message,
            type: 'success'
          },
          isLoading: false,
          editorState: EditorState.createEmpty(),
        });
      }
    }).catch((error) => {
      const message = {
        message: error.message,
        type: 'error'
      };
      this.setState({ isLoading: false, message: message });
    });
  };

  postReply = (commentText) => {
    if (this.state.isLoading) return;

    if (!this.userCanPost()) return;

    this.setState({ isLoading: true, message: false });
    this.props.postReply(commentText, this.state.anonName, this.state.anonEmail, this.state.notify).then((response) => {
      if (response.code === 'success') {
        this.setState({ isOpen: false, message: false });
        this.props.closeReplyBox();
      }
      else if (response.code === 'queued_for_moderation') {
        const message = {
          message: response.message,
          type: 'success'
        };
        this.setState({ message: message, messageOnly: true, isLoading: false });
      }
    }).catch((error) => {
      const message = {
        message: error.message,
        type: 'error'
      };
      this.setState({ isLoading: false, message: message });
    });
  };

  saveEdit = (commentText) => {
    if (this.state.isLoading) return;

    if (!this.userCanPost()) return;

    this.setState({ isLoading: true, message: false });
    this.props.saveEdit(commentText, this.state.notify).then(() => {
      this.props.cancelEdit();
    }).catch((error) => {
      const message = {
        message: error.message,
        type: 'error'
      };
      this.setState({ isLoading: false, message: message });
    });
  };

  userCanPost = () => {
    const {user, settings} = this.props;
    const {notify} = this.state;
    const isAnon = user && user.isAnon;
    const anonSetting = settings.anonymous;

    if (isAnon && !this.state.anonName) {
      this.setState({ message: { message: window.Drupal.t('Please provide your name or alias to post as a guest'), type: 'error'}});
      return false;
    }
    else if (isAnon && !this.state.anonEmail && (anonSetting === Constants.anonMustContact)) {
      this.setState({ message: { message: window.Drupal.t('Please provide your email to post as a guest'), type: 'error'}});
      return false;
    }
    else if (isAnon && !this.state.anonEmail && notify > 0) {
      this.setState({ message: { message: window.Drupal.t('Please provide your email to receive notifications'), type: 'error'}});
      return false;
    }
    else if (isAnon && this.state.anonEmail && !validateEmail(this.state.anonEmail)) {
      this.setState({ message: { message: window.Drupal.t('Please provide a valid email address'), type: 'error'}});
      return false;
    }
    else {
      return true;
    }
  };

  handleAnonFormChange = (e) => {
    if (e.target.value && e.target.id === 'rc_name') {
      this.setState({anonName: e.target.value});
    }
    else if (e.target.value && e.target.id === 'rc_email') {
      this.setState({anonEmail: e.target.value});
    }
    else if (e.target.id === 'rc_name') {
      this.setState({anonName: false});
    }
    else {
      this.setState({anonEmail: false});
    }
  };

  componentDidMount() {
    if (this.props.user && this.props.type === 'reply') {
      const x = window.scrollX;
      const y = window.scrollY;
      this.commentBox.focus();
      window.scrollTo(x, y);
    }
  }

  render() {
    const { user, settings, type, cancelEdit } = this.props;
    const { isOpen, isFocused, isLoading, message, messageOnly, editorState, notify } = this.state;

    if (!window.commentsAppStatus) return null;

    let containerClasses = ['rc_comment-box-container'];
    if (isOpen || type === 'reply' || type === 'edit' ) containerClasses.push('rc_is-open');
    if (isLoading) containerClasses.push('rc_is-loading');
    if (messageOnly) containerClasses.push('rc_message-only');
    if (type === 'reply') containerClasses.push('rc_is-reply');
    if (type === 'edit') containerClasses.push('rc_is-edit');
    containerClasses = containerClasses.join(' ');

    const showLoginButton = !user || user.isAnon;
    const userCanPostComments = user && user.hasPermission('post comments');

    const commentNotify = window.commentsAppNotify && (
      <CommentNotify
        current={notify}
        initial={this.props.notify}
        loading={this.state.loading}
        changeHandler={notify => this.setState({ notify })}  />
    );

    return (
      <div className={containerClasses}>
        { type !== 'edit' && <UserPicture thumbnail={user && user.thumbnail} /> }
        <div className="rc_input-outer-wrapper">
          { message && <div className={`rc_message rc_message-type--${message.type}`}>{message.message}</div> }
          <div className="rc_throbber-wrapper">
            { isLoading && <Throbber size="25px"/> }
            <div className="rc_notify-wrapper">
              { commentNotify }
            </div>
            <div className="rc_input-wrapper">
              <Editor
                  placeholder={ !isFocused && (type !== 'edit') ? window.Drupal.t('Join the discussion...') : '' }
                  editorState={ editorState }
                  onChange={(editorState) => this.setState({ editorState })}
                  ref={(commentBox) => this.commentBox = commentBox}
                  onFocus={this.toggleFocus}
                  onBlur={this.toggleFocus}
              />
              <div className="rc_input-actions">
                { type === 'edit' &&
                <span>
                <button onClick={() => cancelEdit()} className="rc_cancel-comment">{window.Drupal.t('Cancel')}</button>
                <button onClick={() => this.saveEdit(this.getCommentText())} className="rc_add-comment">{window.Drupal.t('Save Edit')}</button>
              </span>
                }
                { (type === 'reply' && user && userCanPostComments) && <button onClick={() => this.postReply(this.getCommentText()) } className="rc_add-comment">{user.name ? window.Drupal.t('Post as !name', {'!name':user.name}) : window.Drupal.t('Post')}</button> }
                { (type === 'comment' && user && userCanPostComments) && <button onClick={() => this.postComment(this.getCommentText())} className="rc_add-comment">{user.name ? window.Drupal.t('Post as !name', {'!name':user.name}) : window.Drupal.t('Post')}</button> }
              </div>
            </div>
          </div>

          { showLoginButton && <div className="rc_anon-wrapper">
            <div>
              <label htmlFor="rc_login-button">{window.Drupal.t('log in to comment')}</label>
              <a id="rc_login-button" className="rc_login-button" href={this.getLoginLink()}>{window.Drupal.t('Log in')}</a>
            </div>
            { userCanPostComments && <div className="rc_anon-form">
              <div>
                <label htmlFor="rc_name">{window.Drupal.t('or post as a guest')}</label>
                <div className="rc_anon-form-input-wrapper">
                  <input onChange={this.handleAnonFormChange} id="rc_name" type="text" placeholder={window.Drupal.t('Name')}/>
                  { (settings.anonymous !== Constants.anonMayNotContact) &&
                    <input onChange={this.handleAnonFormChange} id="rc_email" type="text" placeholder={window.Drupal.t('Email')}/>
                  }
                </div>
              </div>
            </div> }
          </div> }
        </div>

      </div>
    );
  }
}

export default CommentBox;

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc