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.
Uploading file to S3
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);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment