TarikHuber / rmw-shell

Shell of main components for the React Most Wanted project
26 stars 23 forks source link

Profil Image sometimes turned by 90 degrees (Iphones) #26

Open wortkotze opened 5 years ago

wortkotze commented 5 years ago

We encounter some issues that the profil picture is uploaded with 90 degree turn. We checked the EXIF Information of the uploaded pictures but it doesn't show anything that u need to turn the image ...

any idea?

wortkotze commented 5 years ago

We fixed the issue with the following fix for ImageCropper Component

`import 'firebase/storage' import Button from '@material-ui/core/Button' import CircularProgress from '@material-ui/core/CircularProgress' import Dialog from '@material-ui/core/Dialog' import DialogActions from '@material-ui/core/DialogActions' import DialogContent from '@material-ui/core/DialogContent' import DialogTitle from '@material-ui/core/DialogTitle' import LinearProgress from '@material-ui/core/LinearProgress' import PropTypes from 'prop-types' import React, { Component } from 'react' import firebase from 'firebase/app' import withMobileDialog from '@material-ui/core/withMobileDialog' import { connect } from 'react-redux' import { injectIntl, intlShape } from 'react-intl' import { withFirebase } from 'firekit-provider' import AvatarEditor from 'react-avatar-editor' import classNames from 'classnames' import { withStyles } from '@material-ui/core/styles'

var EXIF = require('exif-js')

const styles = theme => ({ ctaInput: { opacity: 0 }, ctaMainBlack: { background: '#000', border: '1px solid #000', borderRadius: '0px', textTransform: 'none', color: '#FFF', height: '50px', padding: '0 30px', fontFamily: 'AudiType, sans-serif', width: '100%', boxShadow: '0px 0px 0px 0px', marginTop: '10px',

'&:active': {
  background: '#000'
},

'&:hover': {
  background: '#000'
}

},

ctaMainWhite: { background: '#FFF', border: '1px solid #000', borderRadius: '0px', textTransform: 'none', color: '#000', height: '50px', padding: '0 30px', fontFamily: 'AudiType, sans-serif', boxShadow: '0px 0px 0px 0px', width: '100%',

'&:active': {
  background: '#000'
},

'&:hover': {
  background: '#FFF'
}

},

container: { display: 'flex', alignItems: 'stretch', justifyContent: 'center', flexDirection: 'row', background: '#fff' }, dialog: { width: '100%', maxWidth: 'none', background: '#fff' }, cropper: { height: 250, width: 250, background: '#fff' }, flexparent: { display: 'flex', flexDirection: 'column', flexWrap: 'nowrap', justifyContent: 'space-between', width: '100%' },

flexchild: {} })

export class ImageCropDialog extends Component { constructor(props) { super(props) this.state = { src: undefined, isLoading: false, isUploading: false, uploadProgress: 0, rotate: 0 } }

handlePhotoURLUpload = photo_url => { const { classes, path, fileName, onUploadSuccess, firebaseApp } = this.props

this.setState({ isUploading: true, uploadProgress: 0 })

let uploadTask = firebaseApp
  .storage()
  .ref(`${path}/${fileName}`)
  .putString(photo_url, 'data_url')

uploadTask.on(
  firebase.storage.TaskEvent.STATE_CHANGED,
  snapshot => {
    let progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100
    this.setState({ isUploading: true, uploadProgress: progress })
  },
  error => {
    console.log(error)
  },
  () => {
    this.setState({ isUploading: false, uploadProgress: 100 }, () => {
      onUploadSuccess(uploadTask.snapshot)
    })
  }
)

}

handlePhotoULRChange = e => { e.preventDefault()

this.setState({ isLoading: true })

let files
if (e.dataTransfer) {
  files = e.dataTransfer.files
} else if (e.target) {
  files = e.target.files
}
const reader = new FileReader()
reader.onload = () => {
  this.setState({ src: reader.result, isLoading: false, file: files[0] })
}
reader.readAsDataURL(files[0])
var that = this
EXIF.getData(e.target.files[0], function() {
  var make = EXIF.getTag(this, 'Make')
  var model = EXIF.getTag(this, 'Model')
  var orientation = EXIF.getTag(this, 'Orientation')
  let rotatePic = 0
  switch (orientation) {
  case 8:
    rotatePic = 270
    break
  case 6:
    rotatePic = 90
    break
  case 3:
    rotatePic = 180
    break
  default:
    rotatePic = 0
  }
  that.setState({ rotate: rotatePic })
})

}

handleClose = () => { const { handleClose } = this.props this.setState({ src: undefined }) handleClose() }

setEditorRef = editor => (this.editor = editor)

render() { const { intl, open, title, fullScreen, classes } = this.props

const actions = [
  <Button
    disabled={
      !this.state.src || this.state.isLoading || this.state.isUploading
    }
    label={intl.formatMessage({ id: 'submit' })}
    primary={true}
    onClick={() => {
      this.handlePhotoURLUpload(this.editor.getImage().toDataURL())
    }}
  />,
  <Button
    label={intl.formatMessage({ id: 'cancel' })}
    secondary={true}
    onClick={this.handleClose}
  />
]

return (
  <Dialog
    fullScreen={fullScreen}
    open={open}
    onClose={this.handleClose}
    aria-labelledby="responsive-dialog-title"
    className={styles.dialog}>
    <DialogTitle id="responsive-dialog-title">{title}</DialogTitle>

    <DialogContent>
      <div style={styles.container}>
        <div style={styles.cropper}>
          {(!this.state.src || this.state.isLoading) && (
            <div>
              <Button color="primary" className={classes.ctaMainBlack}>
                Upload Image
              </Button>
              <input
                ref={field => {
                  if (field !== null) {
                    field.click()
                  }
                }}
                type="file"
                accept="image/*"
                //style={{visibility:'hidden'}}
                onChange={this.handlePhotoULRChange}
                className={classes.ctaInput}
              />
            </div>
          )}

          {this.state.isLoading && (
            <CircularProgress size={80} thickness={5} />
          )}

          {this.state.isUploading && (
            <LinearProgress
              mode="determinate"
              value={this.state.uploadProgress}
            />
          )}

          {this.state.src && (
            <center>
              <AvatarEditor
                ref={this.setEditorRef}
                image={this.state ? this.state.src : undefined}
                width={200}
                height={200}
                border={25}
                color={[255, 255, 255, 0.6]}
                scale={1.0}
                rotate={this.state.rotate}
              />
            </center>
          )}
        </div>
      </div>
    </DialogContent>
    <DialogActions>
      <div className={classes.flexparent}>
        <div className={classes.flexchild}>
          <Button
            color="primary"
            onClick={this.handleClose}
            className={classes.ctaMainWhite}>
            {intl.formatMessage({ id: 'cancel' })}
          </Button>
        </div>

        <div className={classes.flexchild}>
          <Button
            color="primary"
            autoFocus
            onClick={() =>
              this.handlePhotoURLUpload(this.editor.getImage().toDataURL())
            }
            className={classes.ctaMainBlack}>
            {intl.formatMessage({ id: 'submit' })}
          </Button>
        </div>
      </div>
    </DialogActions>
  </Dialog>
)

} }

ImageCropDialog.propTypes = { intl: intlShape.isRequired, open: PropTypes.bool.isRequired, title: PropTypes.string, path: PropTypes.string.isRequired, fileName: PropTypes.string.isRequired, onUploadSuccess: PropTypes.func.isRequired, handleClose: PropTypes.func.isRequired }

const mapStateToProps = state => { const { auth } = state return { auth } }

export default connect( mapStateToProps, {} )( injectIntl( withStyles(styles)(withFirebase(withMobileDialog()(ImageCropDialog))) ) ) `

TarikHuber commented 5 years ago

Can you send a PR?