<commit_before>import React from 'react';
import classNames from 'classnames';
import MarkdownEditor from '../../lib/MarkdownEditor';
import AssetUploader from '../../lib/AssetUploader';
import autoresizeTextarea from '../../lib/autoresizeTextarea';

class FormMarkdownEdtiorField extends React.Component {
  static propTypes = {
    id: React.PropTypes.string,
    name: React.PropTypes.string,
    value: React.PropTypes.string,
    placeholder: React.PropTypes.string,
    rows: React.PropTypes.number
  };

  state = {
    draggingFile: false
  };

  componentDidMount() {
    this.markdownEditor = new MarkdownEditor(this.textarea);
    this.assetUploader = new AssetUploader({ onAssetUploaded: this._handleAssetUploaded });

    autoresizeTextarea(this.textarea);
  }

  componentWillUnmount() {
    delete this.markdownEditor;
    delete this.assetUploader;
  }

  render() {
    let containerClasses = classNames({ "has-success": this.state.draggingFile });

    return (
      <div className={containerClasses}>
        <div className="mb2">
          <button className="btn btn-outline border-gray rounded mr1" onClick={this._handleBoldButtonClick}><i className="fa fa-bold"></i></button>
          <button className="btn btn-outline border-gray rounded mr3" onClick={this._handleItalicButtonClick}><i className="fa fa-italic"></i></button>
          <button className="btn btn-outline border-gray rounded mr1" onClick={this._handleQuoteButtonClick}><i className="fa fa-quote-right"></i></button>
          <button className="btn btn-outline border-gray rounded mr1" onClick={this._handleCodeButtonClick}><i className="fa fa-code"></i></button>
          <button className="btn btn-outline border-gray rounded mr3" onClick={this._handleLinkButtonClick}><i className="fa fa-link"></i></button>
          <button className="btn btn-outline border-gray rounded mr1" onClick={this._handleBulletedListButtonClick}><i className="fa fa-list"></i></button>
          <button className="btn btn-outline border-gray rounded mr1" onClick={this._handleNumberedListButtonClick}><i className="fa fa-list-ol"></i></button>
        </div>
        <textarea
          id={this.props.id}
          name={this.props.name}
          placeholder={this.props.placeholder}
          defaultValue={this.props.value}
          rows={this.props.rows}
          onChange={this._handleOnChange}
          onPaste={this._handleOnPaste}
          onDragEnter={this._handleOnDragEnter}
          onDragOver={this._handleOnDragOver}
          onDragLeave={this._handleOnDragLeave}
          onDrop={this._handleOnDrop}
          ref={c => this.textarea = c}
          style={{overflowY: "hidden", resize: "vertical"}}
          className={"form-control"} />
      </div>
    );
  }

  _uploadFilesFromEvent(e) {
    var files = this.assetUploader.uploadFromEvent(e);

    // Were there any files uploaded in this event?
    if(files.length > 0) {
      // Since we've caught these files, we don't want the browser redirecting
      // to the file's location on the filesystem
      e.preventDefault();

      // Insert each of the files into the textarea
      files.forEach((f) => { this.markdownEditor.insert("![Uploading " + f.name + "...]()"); });

      // Since we've modified the textarea's value, we need to resize and focus
      // again.
      autoresizeTextarea(this.textarea);
      this.textarea.focus();
    }
  }

  _handleAssetUploaded(e) {
    console.log("uploaded...", e);
  }
<commit_msg>Show asset upload errors in the markdown editor<commit_after>import React from 'react';
import classNames from 'classnames';
import MarkdownEditor from '../../lib/MarkdownEditor';
import AssetUploader from '../../lib/AssetUploader';
import autoresizeTextarea from '../../lib/autoresizeTextarea';

class FormMarkdownEdtiorField extends React.Component {
  static propTypes = {
    id: React.PropTypes.string,
    name: React.PropTypes.string,
    value: React.PropTypes.string,
    placeholder: React.PropTypes.string,
    rows: React.PropTypes.number
  };

  state = {
    draggingFile: false
  };

  componentDidMount() {
    this.markdownEditor = new MarkdownEditor(this.textarea);
    this.assetUploader = new AssetUploader({ onAssetUploaded: this._handleAssetUploaded });

    autoresizeTextarea(this.textarea);
  }

  componentWillUnmount() {
    delete this.markdownEditor;
    delete this.assetUploader;
  }

  render() {
    let containerClasses = classNames({ "has-success": this.state.draggingFile });

    if(this.state.error) {
      var errorNode = (
        <div className="mt2 mb2 border border-red p2 red rounded clearfix">
          <div className="col" style={{position: "relative", top: "1px"}}>
            <i className="fa fa-warning mr2" />{this.state.error}
          </div>
          <div className="col-right">
            <button className="btn m0 p0" onClick={this._handleErrorDismissClick}><i className="fa fa-close"/></button>
          </div>
        </div>
      );
    };

    return (
      <div className={containerClasses}>
        <div className="mb2">
          <button className="btn btn-outline border-gray rounded mr1" onClick={this._handleBoldButtonClick}><i className="fa fa-bold"></i></button>
          <button className="btn btn-outline border-gray rounded mr3" onClick={this._handleItalicButtonClick}><i className="fa fa-italic"></i></button>
          <button className="btn btn-outline border-gray rounded mr1" onClick={this._handleQuoteButtonClick}><i className="fa fa-quote-right"></i></button>
          <button className="btn btn-outline border-gray rounded mr1" onClick={this._handleCodeButtonClick}><i className="fa fa-code"></i></button>
          <button className="btn btn-outline border-gray rounded mr3" onClick={this._handleLinkButtonClick}><i className="fa fa-link"></i></button>
          <button className="btn btn-outline border-gray rounded mr1" onClick={this._handleBulletedListButtonClick}><i className="fa fa-list"></i></button>
          <button className="btn btn-outline border-gray rounded mr1" onClick={this._handleNumberedListButtonClick}><i className="fa fa-list-ol"></i></button>
        </div>
        {errorNode}
        <textarea
          id={this.props.id}
          name={this.props.name}
          placeholder={this.props.placeholder}
          defaultValue={this.props.value}
          rows={this.props.rows}
          onChange={this._handleOnChange}
          onPaste={this._handleOnPaste}
          onDragEnter={this._handleOnDragEnter}
          onDragOver={this._handleOnDragOver}
          onDragLeave={this._handleOnDragLeave}
          onDrop={this._handleOnDrop}
          ref={c => this.textarea = c}
          style={{overflowY: "hidden", resize: "vertical"}}
          className={"form-control"} />
      </div>
    );
  }

  _uploadFilesFromEvent(e) {
    var files = this.assetUploader.uploadFromEvent(e);

    // Were there any files uploaded in this event?
    if(files.length > 0) {
      // Since we've caught these files, we don't want the browser redirecting
      // to the file's location on the filesystem
      e.preventDefault();

      // Insert each of the files into the textarea
      files.forEach((f) => { this.markdownEditor.insert("![Uploading " + f.name + "...]()"); });

      // Since we've modified the textarea's value, we need to resize and focus
      // again.
      autoresizeTextarea(this.textarea);
      this.textarea.focus();
    }
  }

  _handleAssetUploaded = (e) => {
    console.log("uploaded...", e);
  };

  _handleAssetUploadError = (exception) => {
    this.setState({ error: exception.message });
  };

  _handleErrorDismissClick = (e) => {
    e.preventDefault();

    this.setState({ error: null });
  };

{'fraction_non_alphanumeric': 0.13683393688566994, 'fraction_numerical': 0.0032333160889808587, 'mean_word_length': 3.193600867678959, 'pattern_counts': {'":': 2, '<': 79, '<?xml version=': 0, '>': 88, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5823763', 'n_tokens_mistral': 2273, 'n_tokens_neox': 2216, 'n_words': 479}