<commit_before>/*
 *
 * DocUploader
 *
 */
import React from 'react'
import { inject, observer } from 'mobx-react'
import PropTypes from 'prop-types'

import { ASSETS_ENDPOINT } from '../../config'

import { Wrapper, InputFile } from './styles'

import { makeDebugger, storePlug, uid } from '../../utils'
import { init, onUploadError, getOSSDir, getOSSFileName } from './logic'

/* eslint-disable no-unused-vars */
const debug = makeDebugger('C:DocUploader')
/* eslint-enable no-unused-vars */

class DocUploaderContainer extends React.Component {
  /*
  constructor(props) {
    super(props)

    const { docUploader } = props
    init(docUploader)
    this.initOssClient()

    this.state = {
      ossClient: null,
      uniqueId: uid.gen(),
    }
  }
  */

  state = {
    ossClient: null,
    // use unique id to init the file input, otherwise it will be the some instance
    uniqueId: uid.gen(),
  }

  componentDidMount() {
    const { docUploader } = this.props
    init(docUploader)
    this.initOssClient()
  }

  componentWillUnmount() {
    /* eslint-disable */
    delete this.state.ossClient
    /* eslint-enable */
  }

  initOssClient() {
    /* eslint-disable */
    /* OSS sdk is import in _document from ali cdn */
    try {
      /* this.state.ossClient = new OSS.Wrapper({ */
      const ossClient = new OSS.Wrapper({
        region: process.env.ALI_OSS_RESION,
        accessKeyId: process.env.ALI_ACCESS_KEY,
        accessKeySecret: process.env.ALI_ACCESS_SECRET,
        bucket: process.env.ALI_OSS_BUCKET,
        /* internal: true, */
        /* secure: true, */
      })

      this.setState({ ossClient })
    } catch (e) {
      console.error(e)
      this.props.onUploadError(e)
    }
    /* eslint-enable */
  }

  onUploadDone(url) {
    /* eslint-disable */
    this.props.onUploadDone(url)
    delete this.state.ossClient
    /* eslint-enable */
    this.initOssClient()
  }

  /* eslint-disable */
  handleCHange(e) {
    console.log('handleCHange e: ', e)
    const files = e.target.files
    /* console.log('handleCHange files: ', files) */
    const theFile = files[0]
    if (!theFile) return false

    const FileSize = theFile.size / 1024 / 1024
    if (FileSize > 2) {
      return alert('资源有限，请不要上传大于 2MB 的文件')
    }

    this.props.onUploadStart()
    const filename = theFile.name
    const fullpath = `${getOSSDir()}/${getOSSFileName(filename)}`

    this.state.ossClient
      .multipartUpload(fullpath, theFile)
      .then(result => {
        const url = `${ASSETS_ENDPOINT}/${result.name}`
        this.onUploadDone(url)
      })
      .catch(err => this.props.onUploadError(err))
  }
  /* eslint-enable */

  render() {
    const { children } = this.props
    const { uniqueId } = this.state

    return (
      <Wrapper>
        <InputFile
          type="file"
          name={`file-${uniqueId}`}
          id={`file-${uniqueId}`}
          accept="image/*"
          onChange={this.handleCHange.bind(this)}
        />
        {/* eslint-disable */}
        <label htmlFor={`file-${uniqueId}`}>{children}</label>
        {/* eslint-enable */}
      </Wrapper>
    )
  }
}

DocUploaderContainer.propTypes = {
  children: PropTypes.oneOfType([PropTypes.string, PropTypes.node]).isRequired,
  onUploadStart: PropTypes.func,
  onUploadError: PropTypes.func,
  onUploadDone: PropTypes.func,
  docUploader: PropTypes.any.isRequired,
}

DocUploaderContainer.defaultProps = {
  onUploadStart: debug,
  onUploadDone: debug,
  onUploadError,
}

export default inject(storePlug('docUploader'))(observer(DocUploaderContainer))<commit_msg>feat(uploader): support upload on paste, closes #303<commit_after>/*
 *
 * DocUploader
 *
 */
import React from 'react'
import { inject, observer } from 'mobx-react'
import PropTypes from 'prop-types'
import R from 'ramda'

import { ASSETS_ENDPOINT } from '../../config'

import { Wrapper, InputFile } from './styles'

import { makeDebugger, storePlug, uid, Global } from '../../utils'
import { init, onUploadError, getOSSDir, getOSSFileName } from './logic'

/* eslint-disable no-unused-vars */
const debug = makeDebugger('C:DocUploader')
/* eslint-enable no-unused-vars */

class DocUploaderContainer extends React.Component {
  /*
  constructor(props) {
    super(props)

    const { docUploader } = props
    init(docUploader)
    this.initOssClient()

    this.state = {
      ossClient: null,
      uniqueId: uid.gen(),
    }
  }
  */

  state = {
    ossClient: null,
    // use unique id to init the file input, otherwise it will be the some instance
    uniqueId: uid.gen(),
  }

  componentDidMount() {
    const { docUploader, pasteImage } = this.props
    init(docUploader)

    this.initOssClient()
    if (pasteImage) this.initPasteWatcher()
  }

  componentWillUnmount() {
    debug('componentWillUnmount')
    /* eslint-disable */
    delete this.state.ossClient
    /* eslint-enable */
    const { pasteImage } = this.props
    if (pasteImage) {
      Global.removeEventListener('paste', this.handlePaste.bind(this), true)
    }
  }

  initPasteWatcher() {
    debug('initPasteWatcher')
    Global.addEventListener('paste', this.handlePaste.bind(this), true)
  }

  initOssClient() {
    /* eslint-disable */
    /* OSS sdk is import in _document from ali cdn */
    try {
      /* this.state.ossClient = new OSS.Wrapper({ */
      const ossClient = new OSS.Wrapper({
        region: process.env.ALI_OSS_RESION,
        accessKeyId: process.env.ALI_ACCESS_KEY,
        accessKeySecret: process.env.ALI_ACCESS_SECRET,
        bucket: process.env.ALI_OSS_BUCKET,
        /* internal: true, */
        /* secure: true, */
      })

      this.setState({ ossClient })
    } catch (e) {
      console.error(e)
      this.props.onUploadError(e)
    }
    /* eslint-enable */
  }

  handlePaste({ clipboardData: { files } }) {
    const file = files[0]
    this.doUploadFile(file)
  }

  onUploadDone(url) {
    /* eslint-disable */
    this.props.onUploadDone(url)
    delete this.state.ossClient
    /* eslint-enable */
    this.initOssClient()
  }

  handleInputChange({ target: { files } }) {
    console.log('handleInputChange e: ', files)
    // const {files} = e.target.files
    const file = files[0]

    this.doUploadFile(file)
  }

  doUploadFile(file) {
    if (!file || !R.startsWith('image/', file.type)) return false
    console.log('is Image!')

    const fileSize = file.size / 1024 / 1024
    if (fileSize > 2) {
      return alert('资源有限，请不要上传大于 2MB 的文件')
    }
    const { onUploadStart, onUploadError } = this.props
    const { ossClient } = this.state

    onUploadStart()
    const filename = file.name
    const fullpath = `${getOSSDir()}/${getOSSFileName(filename)}`

    ossClient
      .multipartUpload(fullpath, file)
      .then(result => {
        const url = `${ASSETS_ENDPOINT}/${result.name}`
        this.onUploadDone(url)
      })
      .catch(err => onUploadError(err))
  }

  render() {
    const { children } = this.props
    const { uniqueId } = this.state

    return (
      <Wrapper>
        <InputFile
          type="file"
          name={`file-${uniqueId}`}
          id={`file-${uniqueId}`}
          accept="image/*"
          onChange={this.handleInputChange.bind(this)}
        />
        {/* eslint-disable */}
        <label htmlFor={`file-${uniqueId}`}>{children}</label>
        {/* eslint-enable */}
      </Wrapper>
    )
  }
}

DocUploaderContainer.propTypes = {
  children: PropTypes.oneOfType([PropTypes.string, PropTypes.node]).isRequired,
  onUploadStart: PropTypes.func,
  onUploadError: PropTypes.func,
  onUploadDone: PropTypes.func,
  docUploader: PropTypes.any.isRequired,
  pasteImage: PropTypes.bool,
}

DocUploaderContainer.defaultProps = {
  onUploadStart: debug,
  onUploadDone: debug,
  onUploadError,
  pasteImage: true,
}

export default inject(storePlug('docUploader'))(observer(DocUploaderContainer))
{'fraction_non_alphanumeric': 0.13846153846153847, 'fraction_numerical': 0.003305785123966942, 'mean_word_length': 2.7191489361702126, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 19, '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': '7034949', 'n_tokens_mistral': 2620, 'n_tokens_neox': 2579, 'n_words': 499}