bigupload-react
v0.9.4
Published
React library to upload files of any size
Downloads
6
Readme
BigUpload
React library to upload files of any size
- Fault tolerant
- Resumable
Quick start
With default options:
import { BigUpload , BigUploadSv } from 'bigupload'
import 'react-bigupload/BigUpload.css'
............
return <BigUploadSv api={apiProxy}>
<OtherProvider>
..............
<BigUpload/>
..............
</OtherProvider>
</BigUploadSv>BigUploadSv is a context provider that do the internal stuff for uploading. The intention of being a provider is to avoid remounts that can cause malfunction.
BigUoload is a visual component intended to interact with users. Can be remounted without problems.
Demo
In the demo and in the source code of demo (App.tsx) you can see all the options of both components.
Live demo
Warning: Demo can fail updating as using a predetermined API url. You can write your own API and use the demo to test it. A PHP implementation of an API is found in the source code of the demo.
Features
- Upload files of any size
- Upload can be paused, continued, stopped
- Multiple files (select or drag and drop), then sequential or concurrent upload
- Adjustable upload speed (per file)
- Adjustable priority in local network
- Optional verification after upload
- Optional user description and name editing
- Possibility of preprocces the file (by chunks) before uploading (see the demo)
API
As BigUpload needs some services from a especific API, a proxy async function must be writen. Can be so simple as:
async function apiProxy(service: string, method: string, body: FormData|null, signal?: AbortSignal) {
try {
const r = await fetch(apiURL+service,
{ method: method,
headers: {auth: auth},
body: body,
signal: signal
} )
if (r.status >= 400)
return false
return await r.json()
} catch (e) {
return false
}
}The example function starts from the existence of an API that implement exacty the required services. Other situation, using REST paths:
async function apiProxy(service: string, method: string, body: FormData|null, signal?: AbortSignal) {
switch (service) {
case 'chunk':
try {
const r = await fetch(`somepath/${
body.get('fileid')}/${
body.get('sha1')/${
body.get('offset')}`,
{ method: method,
headers: {auth: auth},
body: body.get('chunk'),
signal: signal
} )
if (r.status >= 400)
return false
return await r.json()
} catch (e) {
return false
}
case ...
}
}The function MUST:
- Handle errors.
- Return false if error.
- Return the object from the JSON received.
It receives the service requested, the method and the form to be sent in case of POST. Only GET and POST is used for simplicity. Corresponding services must be implementet in the server side. A PHP implementation example is attached in demo source code.
The services are:
init - POST to inform the file to be uploaded.
Formdata:- tag - The file belongs to some tag of BigUpload that share te same BigUploadSv with others
- fileid - File identifier (new).
- fileinfo - from
<input file. - tag
Returns {}
list - GET the list of files already (partially) uploaded as an array of objects:
- fid - fileId.
- info - fileinfo from
init. - completed - true/false
- uploaded - max offset previously wtritten
- desc - user description.
- dtUpled - unix time of last upload.
- tag - from
init
start - POST to inform the start of uploading / verifying Formdata:
- fid - fileId
Returns {}
sha - POST sha1 of the chunk for verification.
Formdata:- fileid - File identifier.
- number - Chunk number 1 ...
- sha1 - Local SHA1 of the chunk in file.
- offset - Of the chunk in the file.
- length - Of the chunk.
Note: if file is preprocessed by
processFile, sha1 is computed on the result of preprocessing, so it matches the sha1 of uploaded file.Returns:
- { "ok": true } if sha1 matches.
- { "ok": false } if sha1 does not match.
chunk - POST a chunk of the file.
Formdata:- fileid - File identifier.
- number - Chunk number 1 ...
- sha1 - Local SHA1 of the chunk in file.
- offset - Of chunk in the file.
- chunk - Blob containing the chunk.
Returns {}
done - POST Informs the end of uploading / verifying
Formdata:- fileid - File identifier.
- status - uploaded|error|verified|stopped
Returns {}
Optional:
adjust - POST adjust the size/date of previous uploaded file, usually before reupload.
Formdata:- fileid - File identifier.
- fileinfo -
infofield from<input file.
Returns {}
delete - POST to delete the file in the server API.
Formdata:- fileid - File identifier.
userdt - POST data suppplied by the user.
Formdata:- fileid - File identifier.
- desc - html - optional - description/comments of the file
- name - text - optional - changed filename
Returns {}
CSS
You can rewrite (partially) the classes found in BigUpload.css and then import your definitions:
import 'react-bigupload/BigUpload.css'
import './App.css'If you need different decorations for differents instances, use wrap classes and condition style. See demo source code.
Custom component
The main work is done by BigUploadSv. User interaction is via BigUpload, if it does not match your needs, you can write your own component using the functions provided by the BigUploadSv context. See the demo source code for a functional basic example.
The context provided by BigUploadSv:
- maxChunks: number, from BigUploadSv prop
- maxChunkSize: number, from BigUploadSv prop
- upEvent: EventTarget, used to send/receive events:
- progress-fid, when chunk is uploaded or verified, or when current uploaded status is computed
- notif-fid, major events: adding, added, start, error, uploaded, verifying, verified ; passed to BigUpload notif
- tag-tag, only for BigUpload, to implement tags
- procQueue, request to process queue
- newFile: (file: File, tag: string) => filTyp
No api call, build the filTyp structure.
Then, you can add client fields - initFile: (fil: filTyp) => Promise
Calls theinitservice, state goes to 'queued' or remains in 'init' if error - upFile: (fil: filTyp) => Promise
Uploads the file sending progress-fid and notif-fid events
Use servicessha,chunk,done - adjFile: (fil: filTyp) => Promise
Ajust the file parameters size and lastModified vía apiadjustservice - deleFile: (fil: filTyp) => Promise
Deletes the uploaded file on server side using apideleteservice - upDtUser: (fil: filTyp, desc: boolean, nom: boolean) => Promise
Updates filename and/or user description - files: React.RefObject<filTyp[]>
Array containing current file descriptor for every file - inited: React.RefObject
BigUploadSv is ready to work - relist: () => Promise
Gets the list of files via apilistservice
Changelog
- 0.9.0 initial release published
- 0.9.2 added: file preprocessing and drag&drop. minor corections
- 0.9.3 multilingual, spanish version
- 0.9.4 refactoring to allow user component (example in demo), filename edition, html in user description, exact speed
TO DO
- Design for mobile
