Commit f97bac23 authored by charlyjazz's avatar charlyjazz
Browse files

Remove bugs when files are uploading

parent 14a79ae7
# File input in React with SocketIO and Flask
# File input make in React with SocketIO and Flask
Run:
......
import React, { Component } from 'react';
import './App.css';
import { Line } from 'rc-progress';
import DropFileInput from './components/DropFileInput'
import './App.css';
class App extends Component {
constructor(props) {
super(props);
this.state = {}
}
render() {
......
import io from '../helpers/io'
function readFileChunk (ctx, offset) {
let length = 0;
let end_offset = ctx.props.file.size + length; // TODO: What is length?
function readFileChunk (ctx, offset, length) {
let end_offset = offset + length;
if (end_offset > ctx.props.file.size)
end_offset = ctx.props.file.size;
let r = new FileReader();
......@@ -12,23 +11,27 @@ function readFileChunk (ctx, offset) {
onReadError(ctx, 'Error in readFileChunk');
}
else {
onReadSuccess(ctx, end_offset, event.target.result);
onReadSuccess(ctx, end_offset, length, event.target.result);
}
}.bind(r, ctx.props.file, offset, length);
r.readAsArrayBuffer(ctx.props.file.slice(offset, end_offset));
}
const onReadSuccess = (ctx, offset, data) => {
const onReadSuccess = (ctx, offset, length, data) => {
// Read success callback
if (ctx.state.done) return;
io.emit('write-chunk', ctx.state.server_filename, offset, data, function(offset, ack) {
if (!ack) onReadError(ctx, 'Transfer aborted by server')
if (!ack) {
onReadError(ctx, 'Transfer aborted by server');
}
}.bind(this, offset));
let end_offset = offset + length,
color = '#48bd9666',
width = parseInt(300 * end_offset / ctx.props.file.size);
width = ((end_offset / ctx.props.file.size) * 100) < 100
? (end_offset / ctx.props.file.size) * 100
: 100;
ctx.setState({
progress: {
......@@ -39,21 +42,20 @@ const onReadSuccess = (ctx, offset, data) => {
});
if (end_offset < ctx.props.file.size) {
readFileChunk(ctx, ctx.props.chunk_size);
readFileChunk(ctx, end_offset, ctx.props.chunk_size);
}
else {
ctx.state.done = true;
ctx.setState({done: true});
}
};
function onReadError(ctx, message) {
// Read error callback
console.log(message);
ctx.setState({
progress: {
...ctx.state.progress,
color: '#ff000073'
color: '#ff000073',
percent: 100
}
});
......
......@@ -20,28 +20,26 @@ export default class DropFileInput extends Component {
event.preventDefault();
for(let i = 0; i < event.dataTransfer.files.length; i++) {
this.setState({
files: [...this.state.files, ...[event.dataTransfer.files[i]]]
}, () => {console.log(this.state)} )
files: [...this.state.files, ...[event.dataTransfer.files[i]]]
})
}
};
toggleUpload = () => {
this.setState({
uploading: !this.state.uploading
})
this.setState({uploading: !this.state.uploading})
};
render() {
let files = this.state.files.map((file, index) => {
return <File file={file} key={index} chunk_size={this.state.chunk_size} uploading={this.state.uploading}/>
return <File file={file}
key={index}
chunk_size={this.state.chunk_size}
uploading={this.state.uploading}/>
});
return (
<div>
<div className="Drop-input"
onDragOver={this.handlerOnDragOver}
onDrop={this.handlerOnDrop}>
<div className="Drop-input" onDragOver={this.handlerOnDragOver} onDrop={this.handlerOnDrop}>
Drop files here!
</div>
<div className="Div-files">
......@@ -49,7 +47,7 @@ export default class DropFileInput extends Component {
</div>
<div className="Div-Button">
<button onClick={this.toggleUpload}>
{!this.state.uploading ? 'Upload File' : 'Uploading'}
{!this.state.uploading ? 'Upload File' : 'Cancel'}
</button>
</div>
</div>
......
......@@ -17,13 +17,13 @@ export default class File extends Component {
}
};
this.uploadFile = () => readFileChunk(this, 0);
this.onReadError = () => onReadError(this, 'Upload rejected by server');
this.uploadFile = () => readFileChunk(this, 0, props.chunk_size);
this.onReadError = () => onReadError(this, 'Upload rejected by server');
}
componentWillReceiveProps(nextProps) {
const that = this;
if (nextProps.uploading) {
const that = this;
if (nextProps.uploading && !this.state.done) {
io.emit('start-transfer', this.props.file.name, this.props.file.size, function(filename) {
if (!filename) {
// The server rejected the transfer
......@@ -40,17 +40,20 @@ export default class File extends Component {
render() {
return (
<div className="File">
<span className="File-name">Name: {this.props.file.name}</span>
<span className="File-type">Type: {this.props.file.type}</span>
<div className="File">
<span className="File-name">Name: {this.props.file.name}</span>
<span className="File-type">Type: {this.props.file.type || 'unknown'}</span>
<span className="File-type">Size: {this.props.file.size}</span>
{ this.props.uploading &&
<Line percent={this.state.progress.percent}
strokeColor={this.state.progress.color}
strokeWidth="1"
strokeLinecap='square'
trailColor="#2fb9e224"/>
<Line percent={this.state.progress.percent}
strokeColor={this.state.progress.color}
strokeWidth="1"
strokeLinecap='square'
trailColor="#2fb9e224"/>
}
</div>
{ this.state.done && "Done"}
</div>
)
}
}
......@@ -20,6 +20,7 @@
"webpack": "^3.8.1"
},
"dependencies": {
"backbone-collection": "^1.0.10",
"rc-progress": "^2.2.2",
"react": "^16.0.0",
"react-dom": "^16.0.0",
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment