Created
January 31, 2019 14:29
-
-
Save cowboyd/d2fd3856cc4824abb20613efa15f7fdb to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { Component } from 'react'; | |
import Store from './store' | |
import Uploader from './uploader'; | |
import UploaderController from './uploader-controller'; | |
import { valueOf } from 'microstates'; | |
import { append } from 'funcadelic'; | |
import 'react-json-pretty/themes/monikai.css'; | |
import JSONPretty from 'react-json-pretty'; | |
class App extends Component { | |
render() { | |
return ( | |
<div className="App"> | |
<p> | |
Select one or more files to upload to https://api.frontside.io/dev/null | |
</p> | |
<Store type={Uploader} value={{ uploads: [] }} onChange={UploaderController}> | |
{uploader => { | |
let { ratioCompleted, percentageCompleted } = uploader; | |
return ( | |
<div> | |
<input type="file" multiple onChange={e => uploader.addFiles(e.target.files)}/> | |
<div> | |
<JSONPretty data={append(valueOf(uploader), { ratioCompleted, percentageCompleted })}/> | |
</div> | |
</div> | |
); | |
}} | |
</Store> | |
</div> | |
); | |
} | |
} | |
export default App; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Union from './union'; | |
class Upload { | |
get file() { | |
return this.state.file; | |
} | |
get ratioCompleted() { | |
let { progress } = this.state; | |
if (progress) { | |
return progress.loaded / progress.total; | |
} else { | |
return 0; | |
} | |
} | |
get percentageCompleted() { | |
return this.ratioCompleted.toFixed(2) * 100; | |
} | |
get runningTimeMillis() { | |
let { startedAt, endedAt } = this.state; | |
if (startedAt) { | |
if (endedAt) { | |
return endedAt - startedAt; | |
} else { | |
return Date.now() - startedAt; | |
} | |
} else { | |
return 0; | |
} | |
} | |
} | |
export default Union({ | |
New: Upload => class extends Upload { | |
start() { | |
return this.toStarted({ | |
startedAt: Date.now(), | |
progress: { | |
lengthComputable: true, | |
loaded: 0, | |
total: this.file.size | |
} | |
}); | |
} | |
}, | |
Started: Upload => class extends Upload { | |
progress(progress) { | |
return this.toStarted({ progress }); | |
} | |
finish(xhr) { | |
let { response, responseType } = xhr; | |
return this.toFinished({ | |
response, | |
responseType, | |
endedAt: Date.now(), | |
}) | |
} | |
error(error) { | |
return this.toErrored({ | |
error, | |
endedAt: Date.now() | |
}); | |
} | |
cancel() { | |
return this.toCancelled(); | |
} | |
abort() { | |
return this.toAborted({ | |
endedAt: Date.now() | |
}); | |
} | |
}, | |
Cancelled: Upload => class extends Upload {}, | |
Finished: Upload => class extends Upload {}, | |
Errored: Upload => class extends Upload {}, | |
Aborted: Upload => class extends Upload {} | |
}, Upload); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { current, valueOf } from 'microstates'; | |
const URL = 'https://api.frontside.io/v1/dev/null'; | |
// This is just a normal store callback. | |
// The current(function) accepts a microstate reference and returns the | |
// most recent version of it. | |
export default function UploaderController(uploader) { | |
for (let upload of uploader.uploads) { | |
if (upload.isNew) { | |
let xhr = new XMLHttpRequest(); | |
xhr.open('POST', URL); | |
xhr.onload = () => current(upload).finish(xhr) | |
xhr.upload.onprogress = ({ lengthComputable, loaded, total }) => { | |
current(upload).progress({ lengthComputable, loaded, total }); | |
}; | |
xhr.onabort = () => current(upload).abort(xhr); | |
xhr.send(upload.file); | |
upload.start() | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { reduce } from 'microstates'; | |
import Upload from './upload'; | |
export default class Uploader { | |
uploads = [Upload]; | |
get ratioCompleted() { | |
return reduce(this.uploads, (sum, upload) => { | |
return sum + upload.ratioCompleted / this.uploads.length; | |
}, 0); | |
} | |
get percentageCompleted() { | |
return this.ratioCompleted.toFixed(2) * 100; | |
} | |
addFiles(files) { | |
return reduce(files, (uploader, file) => { | |
let upload = Upload.New.create({ file }); | |
return uploader.uploads.push(upload); | |
}, this); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment