Skip to content

Instantly share code, notes, and snippets.

@dontry
Created May 26, 2019 23:25
Show Gist options
  • Select an option

  • Save dontry/b4f46737231e89a0e0427858db0faf3d to your computer and use it in GitHub Desktop.

Select an option

Save dontry/b4f46737231e89a0e0427858db0faf3d to your computer and use it in GitHub Desktop.

Revisions

  1. dontry created this gist May 26, 2019.
    221 changes: 221 additions & 0 deletions file_upload.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,221 @@
    import React from "react";
    import { connect } from "react-redux";
    import S3 from "aws-s3";
    import {
    DELETE_ATTACHMENT_REQUEST,
    GET_ATTACHMENTS_REQUEST,
    START_UPLOADING,
    UPLOAD_ATTACHMENT_REQUEST
    } from "../actions";
    import {Icon} from "../../../../layout";
    import { Spinner, SpinnerSize } from 'office-ui-fabric-react/lib/Spinner';

    let Blob = require('blob');


    const config = {
    bucketName: process.env.REACT_APP_BUCKET_NAME,
    dirName: process.env.REACT_APP_DIR_NAME,
    region: process.env.REACT_APP_REGION,
    accessKeyId: process.env.REACT_APP_ACCESS_KEY_ID,
    secretAccessKey: process.env.REACT_APP_SECRET_ACCESS_KEY,
    s3Url: process.env.REACT_APP_S3_URL
    };
    const S3Client = new S3(config);

    class FileUploadBar extends React.Component {
    constructor(props) {
    super(props);

    this.state = {
    };
    }

    componentDidMount() {

    this.props.dispatch({
    type: GET_ATTACHMENTS_REQUEST,
    payload: {
    project_id: this.props.project_id,
    owner_id: this.props.user.id
    }
    })
    }

    dataURItoBlob =(dataURI)=> {
    // convert base64/URLEncoded data component to raw binary data held in a string
    let byteString;
    if (dataURI.split(',')[0].indexOf('base64') >= 0)
    byteString = atob(dataURI.split(',')[1]);
    else
    byteString = unescape(dataURI.split(',')[1]);
    // separate out the mime component
    let mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];

    // write the bytes of the string to a typed array
    let ia = new Uint8Array(byteString.length);
    for (let i = 0; i < byteString.length; i++) {
    ia[i] = byteString.charCodeAt(i);
    }
    let blob = new Blob([ia], {type:mimeString});
    return blob
    }
    uploadImage =(e)=> {
    const {user, project_id, dispatch} = this.props;
    dispatch({
    type:START_UPLOADING,
    payload:null
    })
    const filename = e.target.files[0].name;
    const file = e.target.files[0];
    if(file){
    let reader = new FileReader();
    reader.onload = (e) => {
    let img = document.createElement("img");
    img.onload =()=> {
    let canvas = document.createElement("canvas");
    let ctx = canvas.getContext("2d");
    ctx.drawImage(img, 0, 0);

    let MAX_WIDTH = 400;
    let MAX_HEIGHT = 400;
    let width = img.width;
    let height = img.height;
    if (width > height) {
    if (width > MAX_WIDTH) {
    height *= MAX_WIDTH / width;
    width = MAX_WIDTH;
    }
    } else {
    if (height > MAX_HEIGHT) {
    width *= MAX_HEIGHT / height;
    height = MAX_HEIGHT;
    }
    }
    canvas.width = width;
    canvas.height = height;
    ctx = canvas.getContext("2d");
    ctx.drawImage(img, 0, 0, width, height);
    let dataurl = canvas.toDataURL(file.type);
    let new_file = this.dataURItoBlob(dataurl)

    S3Client.uploadFile(new_file)
    .then(data => {
    const url = data.location;
    const attachment = {
    project_id,
    owner_id: user.id,
    url,
    name: filename
    }

    dispatch({
    type: UPLOAD_ATTACHMENT_REQUEST,
    payload: attachment
    })
    })
    .catch(err =>
    console.log("ERR", err)
    );
    }
    img.src = e.target.result;
    }
    reader.readAsDataURL(file);
    }
    }

    copyLink = (link) => {
    let dummy = document.createElement("input");
    document.body.appendChild(dummy);
    dummy.setAttribute("value", link);
    dummy.select();
    document.execCommand("copy");
    document.body.removeChild(dummy);
    };

    deleteAttachment =(attachment)=> {
    this.props.dispatch({
    type: DELETE_ATTACHMENT_REQUEST,
    payload: attachment
    })
    }
    render(){
    let { attachments, uploadingInProgress } = this.props;
    if(!attachments){
    attachments = []
    }
    return (
    <div className="file-upload-bar">
    <div className="add-file-button">
    <input
    type="file"
    name="attachments"
    accept="image/*"
    id="attachments"
    className="input-note-attachments"
    onChange={e => this.uploadImage(e)}
    style={{
    width: "0.1px",
    height: "0.1px",
    opacity: "0",
    overflow: "hidden",
    position: "absolute",
    zIndex: "-1"
    }}
    />
    <label htmlFor="attachments" className="upload-file-label">+ Attachments</label>
    </div>
    <div className="file-list-body" id="xxxx">
    {uploadingInProgress && (
    <div className="spinner-wrapper">
    <Spinner size={SpinnerSize.large} label="Uploading..." />
    </div>

    )}

    {
    attachments.map(attachment => {
    return(
    <div className="attachment">
    <div className="name-wrapper">
    <Icon
    className="bullet-icon"
    icon="Photo2"
    />
    {attachment.name.length > 17 ? (attachment.name.substr(0, 15) + "...") : attachment.name}
    </div>
    <div className="attachment-button-wrapper">
    <Icon
    className="attachment-icon"
    onClick={() => this.copyLink(attachment.url)}
    icon="Copy"
    />
    <Icon
    className="attachment-icon"
    onClick={() => this.deleteAttachment(attachment)}
    icon="Delete"
    />
    </div>
    </div>
    );
    })
    }
    </div>
    </div>
    )

    }
    }

    const mapStateToProps = state => {
    console.log(state)
    return {
    user: state.user.profile,
    project_id: state.projects.selectedId,
    attachments: state.discussions.attachments,
    uploadingInProgress: state.discussions.uploadingInProgress,

    };
    };

    export default connect(mapStateToProps)(FileUploadBar);