1 | # React resumable uploader
|
2 |
|
3 | ## Introduce
|
4 |
|
5 | This uploader is focused on uploading large files with the possibility of renewable download. This library is explicitly designed for modern browsers that support **IndexedDB**, **FileReader API** and **Web Workers API**. The upload of files occurs through the **WebSocket** and for this task the **socket.IO** library is used inside.
|
6 |
|
7 | ## Installation
|
8 | ```
|
9 | npm install react-resumable-uploader -S
|
10 | ```
|
11 | ## To start
|
12 | You need to import two components:
|
13 |
|
14 | #### First component.
|
15 | ```
|
16 | import { UploaderProvider } from 'react-resumable-uploader';
|
17 | ```
|
18 | This component is the root one and it should be wrapped in a component that provides the OnProgress OnError methods. This is done so that you can use any tool to manage the state (Redux or Mobx).
|
19 |
|
20 | This example uses Mobx :
|
21 | ```
|
22 | import { UploaderProvider } from 'react-file-uploader';
|
23 |
|
24 | @inject("uploaderStore", "messagesStore")
|
25 | @observer
|
26 | class UploaderWrapper extends Component {
|
27 | onProgress = (filesState) => {
|
28 | const { setChangedState } = this.props.uploaderStore;
|
29 |
|
30 | setChangedState(filesState);
|
31 | }
|
32 |
|
33 | onError = (error) => {
|
34 | const { setMessage } = this.props.messagesStore;
|
35 |
|
36 | setMessage(error);
|
37 | }
|
38 |
|
39 | complete = (file) => {
|
40 | //to do some action
|
41 | }
|
42 |
|
43 | render() {
|
44 | return (
|
45 | <UploaderProvider
|
46 | {...this.props} //childrens and params
|
47 | onProgress={this.onProgress}
|
48 | onError={this.onError}
|
49 | complete={this.complete}/>
|
50 | );
|
51 | }
|
52 | }
|
53 | ```
|
54 | Then put it in the root of your application.</br>
|
55 | For example:
|
56 | ```
|
57 | class App extends Component {
|
58 | render() {
|
59 | const params = {
|
60 | chunkSize: 5 * 1024 * 1024,
|
61 | maxConnectionAttempts: 5,
|
62 | fileThrottle: 300,
|
63 | mainThrottle: 300,
|
64 | url: 'ws://{hostname}/{endpoint}',
|
65 | events: {
|
66 | GET_LAST_CHUNK: 'get-last-chunk',
|
67 | SEND_NEXT_CHUNK: 'send-next-chunk',
|
68 | SEND_NEXT_CHUNK_SUCCESS: 'send-next-chunk-successful',
|
69 | SEND_FILE_SUCCESS: 'send-file-successful',
|
70 | CANCEL_UPLOAD: 'cancel-upload',
|
71 | SEND_CHUNK_AGAIN: 'send-chunk-again',
|
72 | ERROR: 'error',
|
73 | }
|
74 | };
|
75 |
|
76 | return (
|
77 | <UploaderWrapper params={params}>
|
78 | <div className="App">
|
79 | <Header/>
|
80 | <Menu/>
|
81 | <Main/>
|
82 | </div>
|
83 | </UploaderWrapper>
|
84 | );
|
85 | }
|
86 | }
|
87 | ```
|
88 | #### Second component.
|
89 | ```
|
90 | import { uploaderContext } from 'react-resumable-uploader';
|
91 | ```
|
92 | This component is a higher-order component (HOC) that provides methods **submit(files)**, **pause(fileId)**, **resume(fileId)**, **stop(fileId)**. It can be used anywhere in the application.</br>
|
93 | For example:
|
94 | **If You use** `babel-plugin-transform-decorators-legacy`
|
95 | ```
|
96 | import { uploaderContext } from 'react-resumable-uploader';
|
97 |
|
98 | @uploaderContext
|
99 | class UploadManager extends Component {
|
100 | stop = (fileId) => {
|
101 | return this.props.stop(fileId);
|
102 | }
|
103 |
|
104 | pause = (fileId) => {
|
105 | return this.props.pause(fileId);
|
106 | }
|
107 |
|
108 | resume = (fileId) => {
|
109 | return this.props.resume(fileId);
|
110 | }
|
111 |
|
112 | render() {}
|
113 | }
|
114 |
|
115 | export default UploadManager;
|
116 | ```
|
117 | or if you do not use decorators
|
118 | ```
|
119 | export default uploaderContext(UploadManager);
|
120 | ```
|
121 |
|
122 |
|
123 | ## API
|
124 |
|
125 | Let's start with a description of the methods provided by the **uploaderContext** component:
|
126 |
|
127 | | Method | Parameters | |
|
128 | |---------------|-----------|-------------|
|
129 | |stop |`fileId<string>`|Returns a boolean value if the action was successful|
|
130 | |pause|`fileId<string>`|Returns a boolean value if the action was successful|
|
131 | |resume|`fileId<string>`|Returns a boolean value if the action was successful|
|
132 | |submit|`Array<File>, url<string>`||
|
133 |
|
134 | Parameters for **UploaderProvider** component:
|
135 |
|
136 | **Callbacks**
|
137 |
|
138 | | Parameter | Type | Arguments |
|
139 | |---------------|------------|-------------|
|
140 | |onProgress - provides progress of file upload |`function`| `Array`**`<FileObject>`** [--see below](#fileObject)|
|
141 | |onError |`function`| `errorObject` |
|
142 | |complete |`function`| **`<FileObject>`** [--see below](#fileObject)|
|
143 |
|
144 | **Object params**
|
145 |
|
146 | | Key | Type | Description |
|
147 | |---------------|------------|-------------|
|
148 | |chunkSize |`byte number`| for example - 5 * 1024 * 1024 |
|
149 | |maxConnectionAttempts |`number`| |
|
150 | |fileThrottle |`number<ms>`| to update the status of a single file |
|
151 | |mainThrottle |`number<ms>`| to update the status of all files |
|
152 | |url |`string`| 'ws://{hostname}/{endpoint}' Will be used for all files. Also you can pass URL for each file in the **submit** method |
|
153 | |events |`object`| Contains event names used to communicate using the web socket (are described below) |
|
154 | |events.GET_LAST_CHUNK |`eventName<string> .emit() and .on()<number>`| sends an object of the form `{id: "fileId"}` Accepts data of type `last chunk<number>`|
|
155 | |events.SEND_NEXT_CHUNK |`eventName<string> .emit() file chunk<object>`| Sends data of type **`<PostData>`** [--see below](#postData)|
|
156 | events.SEND_NEXT_CHUNK_SUCCESS |`eventName<string> .on()`| sends the next piece on this event |
|
157 | events.SEND_FILE_SUCCESS |`eventName<string> .on()`| Delete the file from the IndexDB on this event |
|
158 | events.CANCEL_UPLOAD |`eventName<string> .emit()`| Sends `fileId<string>`. Notifies when the upload stops |
|
159 | events.SEND_CHUNK_AGAIN |`eventName<string> .on()`| Starts the upload from the last successful piece |
|
160 | events.ERROR |`eventName<string> .on()`| Accepts any errors from the server and calls **onError** callback |
|
161 |
|
162 | #### <a id="postData" name="postData"></a>
|
163 | <**PostData**> interface (Dispatched to the server)
|
164 |
|
165 | | Key | Type | Description |
|
166 | |---------------|------------|-------------|
|
167 | |chunk |`<ArrayBuffer>`| |
|
168 | |fileId |`<string>`| |
|
169 | |chunkNum |`current chunk<number>`| |
|
170 | |chunkSize |`byteLength<number>`| |
|
171 | |type |`file type<string>`| |
|
172 | |name |`file name<string>`| |
|
173 | |isFinal |`<boolean>`| When the last chunk is sent it's **`true`**|
|
174 |
|
175 | #### <a id="fileObject" name="fileObject"></a>
|
176 | <**FileObject**> interface (Passed to **onProgress** callback function)
|
177 |
|
178 | | Key | Type | Description |
|
179 | |---------------|------------|-------------|
|
180 | |progress |`percent`| |
|
181 | |fileId |`<string>`| |
|
182 | |size |`file size<byte number>`| |
|
183 | |name |`file name<string>`| |
|
184 | |type |`file type<string>`| |
|
185 | |passedBytes |`byte number`| |
|
186 | |currentChunk |`number`| |
|
187 | |isFinal |`<boolean>`| |
|
188 |
|
189 |
|
190 | ## Utils
|
191 |
|
192 | `import {getFileSize, getFileName, getFileFormat} from 'react-file-uploader';`
|
193 |
|
194 | getFileSize(bytes) - translate bytes in a human-readable form;</br>
|
195 | getFileName(name|string) - translate name in a human-readable form;</br>
|
196 | getFileFormat(name|string) - returns file extension;
|
197 |
|
198 |
|
199 | ## License
|
200 | MIT
|