<commit_before>import React from 'react';
import BaseComponent from 'lib/BaseComponent';
import EditorImagePreview from './EditorImagePreview';
import _ from 'lodash';
import update from 'react-addons-update';
import { Link } from 'react-router';

// material-ui
import Divider from 'material-ui/Divider';
import Paper from 'material-ui/Paper';
import { Tabs, Tab } from 'material-ui/Tabs';
import FileUpload from 'material-ui/svg-icons/file/file-upload';
import Folder from 'material-ui/svg-icons/file/folder';
import RaisedButton from 'material-ui/RaisedButton';

/* eslint-disable no-nested-ternary */
const UPLOAD_URL = process.env.NODE_ENV
  ? (process.env.NODE_ENV === 'production'
    ? 'https://admin.thegazelle.org/upload'
    : 'https://adminbeta.thegazelle.org/upload')
  : 'http://localhost:4000/upload';
/* eslint-enable no-nested-ternary */

export default class EditorImageUploader extends BaseComponent {
  constructor() {
    super();
    this.safeSetState({
      files: [],
      changed: false,
      uploading: false,
    });
    this.handleInputChange = this.handleInputChange.bind(this);
    this.handleUpload = this.handleUpload.bind(this);
    this.deleteImagePreview = this.deleteImagePreview.bind(this);
    this.addImagePreviewUrl = this.addImagePreviewUrl.bind(this);
    this.changeImageName = this.changeImageName.bind(this);
    this.handlePreviewChange = this.handlePreviewChange.bind(this);
    this.handleUploadTerminated = this.handleUploadTerminated.bind(this);
    this.postUploadReset = this.postUploadReset.bind(this);
  }

  handleUpload(e) {
    e.preventDefault();
    const mergeObject = {};
    this.state.files.forEach((fileObject, index) => {
      // Upload it
      this.uploadFile(fileObject);
      // Configure mergeObject to set it as loading
      mergeObject[index] = {
        metaData: { $merge: { uploadStatus: 1 } },
      };
    });
    const newFiles = update(this.state.files, mergeObject);
    this.safeSetState({
      uploading: true,
      files: newFiles,
    });
  }

  uploadFile(fileObject) {
    const file = fileObject.file;
    const xhr = new XMLHttpRequest();
    const formData = new FormData();
    xhr.onload = () => {
      const response = xhr.response;
      if (response.split(' ')[0] === 'success') {
        const amazonURL = response.split(' ')[1];
        this.handleUploadTerminated(fileObject.metaData.name, 2, amazonURL);
      } else {
        let errorMessage;
        if (response === 'Error uploading') {
          errorMessage = 'The server had an error while trying to upload the image to s3';
        } else if (response.split(',')[0] === 'object already exists') {
          errorMessage = `An object already exists with the key: ${response.split(',')[1]}`;
        } else {
          errorMessage = `An unexpected error occured: ${response}`;
        }
        this.handleUploadTerminated(fileObject.metaData.name, 3, undefined, errorMessage);
      }
    };
    xhr.onerror = (err) => {
      // Set upload status to failed
      console.error(err); // eslint-disable-line no-console
      const errorMessage = 'An unknown error occured contacting the server, ' +
                           'error logged in developer console';
      this.handleUploadTerminated(fileObject.metaData.name, 3, undefined, errorMessage);
    };
    xhr.open('POST', UPLOAD_URL, true);
    xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
    // Put file in request and assign user-defined name
    formData.set('image', file, fileObject.metaData.name);
    // Send data
    xhr.send(formData);
  }

  handleUploadTerminated(fileName, uploadStatus, amazonURL, errorMessage) {
    const newChanged = this.state.files.some((storedFileObject) => {
      if (storedFileObject.metaData.name === fileName) {
        return false;
      }
      const upStat = storedFileObject.metaData.uploadStatus;

      return !(upStat === 2 || upStat === 3);
    });
    const index = this.state.files.findIndex(
      storedFileObject => storedFileObject.metaData.name === fileName
    );
    if (index !== -1) {
      const newFiles = update(this.state.files,
        {
          [index]: {
            metaData: {
              $merge: {
                uploadStatus,
                amazonURL,
                errorMessage,
              },
            },
          },
        });
      this.safeSetState({
        files: newFiles,
        changed: newChanged,
      });
    } else {
      console.error("Unexpected error, couldn't find file"); // eslint-disable-line no-console
    }
    if (!newChanged) {
      this.safeSetState({
        changed: false,
      });
    }
  }

  handleInputChange(e) {
    e.preventDefault();
    const files = e.target.files;
    const fileArray = _.map(files, file => ({ file, metaData: { name: file.name } }));
    let newFiles = this.state.files.concat(fileArray);
    newFiles = _.uniqBy(newFiles, fileObject => fileObject.metaData.name);
    this.safeSetState({
      files: newFiles,
    });

    fileArray.forEach((file) => {
      this.addImagePreviewUrl(file);
    });

    e.target.parentNode.reset();
  }

  handlePreviewChange() {
    if (this.state.uploading) {
      // Ignore this function if currently uploading
      return;
    }
    if (this.state.files && this.state.files.length && !this.state.changed) {
      this.safeSetState({
        changed: true,
      });
    } else if ((!this.state.files || this.state.files.length === 0) && this.state.changed) {
      this.safeSetState({
        changed: false,
      });
    }
  }

  deleteImagePreview(name) {
    const index = this.state.files.findIndex(fileObject => fileObject.metaData.name === name);
    if (index !== -1) {
      const newFiles = update(this.state.files, { $splice: [[index, 1]] });
      this.safeSetState({
        files: newFiles,<commit_msg>Small bug fix in handleInputChange of EditorImageController<commit_after>import React from 'react';
import BaseComponent from 'lib/BaseComponent';
import EditorImagePreview from './EditorImagePreview';
import _ from 'lodash';
import update from 'react-addons-update';
import { Link } from 'react-router';

// material-ui
import Divider from 'material-ui/Divider';
import Paper from 'material-ui/Paper';
import { Tabs, Tab } from 'material-ui/Tabs';
import FileUpload from 'material-ui/svg-icons/file/file-upload';
import Folder from 'material-ui/svg-icons/file/folder';
import RaisedButton from 'material-ui/RaisedButton';

/* eslint-disable no-nested-ternary */
const UPLOAD_URL = process.env.NODE_ENV
  ? (process.env.NODE_ENV === 'production'
    ? 'https://admin.thegazelle.org/upload'
    : 'https://adminbeta.thegazelle.org/upload')
  : 'http://localhost:4000/upload';
/* eslint-enable no-nested-ternary */

export default class EditorImageUploader extends BaseComponent {
  constructor() {
    super();
    this.safeSetState({
      files: [],
      changed: false,
      uploading: false,
    });
    this.handleInputChange = this.handleInputChange.bind(this);
    this.handleUpload = this.handleUpload.bind(this);
    this.deleteImagePreview = this.deleteImagePreview.bind(this);
    this.addImagePreviewUrl = this.addImagePreviewUrl.bind(this);
    this.changeImageName = this.changeImageName.bind(this);
    this.handlePreviewChange = this.handlePreviewChange.bind(this);
    this.handleUploadTerminated = this.handleUploadTerminated.bind(this);
    this.postUploadReset = this.postUploadReset.bind(this);
  }

  handleUpload(e) {
    e.preventDefault();
    const mergeObject = {};
    this.state.files.forEach((fileObject, index) => {
      // Upload it
      this.uploadFile(fileObject);
      // Configure mergeObject to set it as loading
      mergeObject[index] = {
        metaData: { $merge: { uploadStatus: 1 } },
      };
    });
    const newFiles = update(this.state.files, mergeObject);
    this.safeSetState({
      uploading: true,
      files: newFiles,
    });
  }

  uploadFile(fileObject) {
    const file = fileObject.file;
    const xhr = new XMLHttpRequest();
    const formData = new FormData();
    xhr.onload = () => {
      const response = xhr.response;
      if (response.split(' ')[0] === 'success') {
        const amazonURL = response.split(' ')[1];
        this.handleUploadTerminated(fileObject.metaData.name, 2, amazonURL);
      } else {
        let errorMessage;
        if (response === 'Error uploading') {
          errorMessage = 'The server had an error while trying to upload the image to s3';
        } else if (response.split(',')[0] === 'object already exists') {
          errorMessage = `An object already exists with the key: ${response.split(',')[1]}`;
        } else {
          errorMessage = `An unexpected error occured: ${response}`;
        }
        this.handleUploadTerminated(fileObject.metaData.name, 3, undefined, errorMessage);
      }
    };
    xhr.onerror = (err) => {
      // Set upload status to failed
      console.error(err); // eslint-disable-line no-console
      const errorMessage = 'An unknown error occured contacting the server, ' +
                           'error logged in developer console';
      this.handleUploadTerminated(fileObject.metaData.name, 3, undefined, errorMessage);
    };
    xhr.open('POST', UPLOAD_URL, true);
    xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
    // Put file in request and assign user-defined name
    formData.set('image', file, fileObject.metaData.name);
    // Send data
    xhr.send(formData);
  }

  handleUploadTerminated(fileName, uploadStatus, amazonURL, errorMessage) {
    const newChanged = this.state.files.some((storedFileObject) => {
      if (storedFileObject.metaData.name === fileName) {
        return false;
      }
      const upStat = storedFileObject.metaData.uploadStatus;

      return !(upStat === 2 || upStat === 3);
    });
    const index = this.state.files.findIndex(
      storedFileObject => storedFileObject.metaData.name === fileName
    );
    if (index !== -1) {
      const newFiles = update(this.state.files,
        {
          [index]: {
            metaData: {
              $merge: {
                uploadStatus,
                amazonURL,
                errorMessage,
              },
            },
          },
        });
      this.safeSetState({
        files: newFiles,
        changed: newChanged,
      });
    } else {
      console.error("Unexpected error, couldn't find file"); // eslint-disable-line no-console
    }
    if (!newChanged) {
      this.safeSetState({
        changed: false,
      });
    }
  }

  handleInputChange(e) {
    e.preventDefault();
    const files = e.target.files;
    const fileArray = _.map(files, file => ({ file, metaData: { name: file.name } }));
    let newFiles = this.state.files.concat(fileArray);
    newFiles = _.uniqBy(newFiles, fileObject => fileObject.metaData.name);
    this.safeSetState({
      files: newFiles,
    });

    fileArray.forEach((file) => {
      this.addImagePreviewUrl(file);
    });

    // Reset to "No Files Chosen" in the input element instead of saying "10 files" or so
    e.target.parentNode.parentNode.parentNode.parentNode.parentNode.reset();
  }

  handlePreviewChange() {
    if (this.state.uploading) {
      // Ignore this function if currently uploading
      return;
    }
    if (this.state.files && this.state.files.length && !this.state.changed) {
      this.safeSetState({
        changed: true,
      });
    } else if ((!this.state.files || this.state.files.length === 0) && this.state.changed) {
      this.safeSetState({
        changed: false,
      });
    }
  }

  deleteImagePreview(name) {
    const index = this.state.files.findIndex(fileObject => fileObject.metaData.name === name);
    if (index !== -1) {
      const newFiles = update(this.state.files, { $splice: [[index, 1]] });
      this.safeSetState({
        files: newFiles,
{'fraction_non_alphanumeric': 0.1341422312099764, 'fraction_numerical': 0.003370407819346141, 'mean_word_length': 2.758391386953768, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 21, 'https://': 4, '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': '2882871', 'n_tokens_mistral': 3538, 'n_tokens_neox': 3504, 'n_words': 757}