Skip to content

Commit ad01823

Browse files
authored
Fix: Upload complete event for large files (#47)
- Upload complete event didn't contain correct data for files uploaded through multi-put - Prettier run over all files
1 parent 3b5ff58 commit ad01823

16 files changed

Lines changed: 111 additions & 70 deletions

File tree

src/api/ChunkedUpload.js

Lines changed: 48 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import noop from 'lodash.noop';
88
import Rusha from 'rusha';
99
import Chunk from './Chunk';
1010
import Base from './Base';
11-
import type { StringAnyMap } from '../flowTypes';
11+
import type { BoxItem, StringAnyMap } from '../flowTypes';
1212
import int32ArrayToBase64 from '../util/base64';
1313

1414
const DEFAULT_RETRY_COMMIT_DELAY_MS = 3000; // Wait 3s before retrying a chunk
@@ -201,7 +201,7 @@ class ChunkedUpload extends Base {
201201
sha1: int32ArrayToBase64(new Rusha().rawDigest(buffer)),
202202
totalSize: this.file.size,
203203
successCallback: this.handleChunkSuccess,
204-
errorCallback: this.handleChunkError,
204+
errorCallback: this.handleUploadError,
205205
progressCallback: (progressEvent) => this.handleChunkProgress(chunk, progressEvent)
206206
});
207207

@@ -231,18 +231,6 @@ class ChunkedUpload extends Base {
231231
});
232232
};
233233

234-
/**
235-
* Handles upload error for a chunk.
236-
*
237-
* @private
238-
* @param {Error} error - Progress error
239-
* @return {void}
240-
*/
241-
handleChunkError = (error: Error) => {
242-
this.cancel();
243-
this.errorCallback(error);
244-
};
245-
246234
/**
247235
* Handles upload progress event for a chunk.
248236
*
@@ -251,7 +239,7 @@ class ChunkedUpload extends Base {
251239
* @param {ProgressEvent} event - Progress event
252240
* @return {void}
253241
*/
254-
handleChunkProgress = (chunk: Chunk, event: ProgressEvent) => {
242+
handleChunkProgress = (chunk: Chunk, event: ProgressEvent): void => {
255243
if (!event.lengthComputable) {
256244
return;
257245
}
@@ -306,24 +294,54 @@ class ChunkedUpload extends Base {
306294
Digest: `SHA=${digest}`
307295
};
308296

309-
this.xhr.post(this.getUploadSessionUrl(this.sessionId, 'commit'), postData, headers).then((response) => {
310-
// Retry after a delay since server is still processing chunks
311-
if (response.status === 202) {
312-
this.finished = false;
313-
const retryAfterSec = parseInt(response.headers.get('Retry-After'), 10);
314-
315-
if (isNaN(retryAfterSec)) {
316-
setTimeout(() => this.commitFile(), DEFAULT_RETRY_COMMIT_DELAY_MS);
317-
} else {
318-
setTimeout(() => this.commitFile(), retryAfterSec * 1000);
319-
}
320-
} else {
321-
this.successCallback(response);
322-
}
323-
});
297+
this.xhr
298+
.post(this.getUploadSessionUrl(this.sessionId, 'commit'), postData, headers)
299+
.then(this.handleCommitSuccess)
300+
.catch(this.handleUploadError);
324301
});
325302
}
326303

304+
/**
305+
* Handles a successful commit file response.
306+
*
307+
* @param {Response} response - Fetch response object
308+
* @return {void}
309+
*/
310+
handleCommitSuccess = ({
311+
entries,
312+
headers,
313+
status
314+
}: {
315+
entries: BoxItem[],
316+
headers: Headers,
317+
status: number
318+
}): void => {
319+
// Retry after a delay since server is still processing chunks
320+
if (status === 202) {
321+
this.finished = false;
322+
const retryAfterSec = parseInt(headers.get('Retry-After'), 10);
323+
324+
if (isNaN(retryAfterSec)) {
325+
setTimeout(() => this.commitFile(), DEFAULT_RETRY_COMMIT_DELAY_MS);
326+
} else {
327+
setTimeout(() => this.commitFile(), retryAfterSec * 1000);
328+
}
329+
} else if (entries) {
330+
this.successCallback(entries);
331+
}
332+
};
333+
334+
/**
335+
* Handles an upload error. Cancels the pending upload and executes error callback.
336+
*
337+
* @param {Error} error - Error
338+
* @return {void}
339+
*/
340+
handleUploadError = (error: Error): void => {
341+
this.cancel();
342+
this.errorCallback(error);
343+
};
344+
327345
/**
328346
* Updates SHA1 digest, ensuring that parts are added in the right order.
329347
*

src/components/Breadcrumbs/Breadcrumb.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,13 @@ type Props = {
1818
};
1919

2020
const Breadcrumb = ({ name = '', onClick, isLast, delimiter }: Props) => {
21-
const title = onClick ? <PlainButton onClick={onClick}>{name}</PlainButton> : <span>{name}</span>;
21+
const title = onClick
22+
? <PlainButton onClick={onClick}>
23+
{name}
24+
</PlainButton>
25+
: <span>
26+
{name}
27+
</span>;
2228
return (
2329
<span className='buik-breadcrumb'>
2430
{title}

src/components/Breadcrumbs/BreadcrumbDelimiter.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@ type Props = {
1515

1616
const BreadcrumbDelimiter = ({ delimiter }: Props) =>
1717
delimiter === DELIMITER_CARET
18-
? <span className='buik-breadcrumb-seperator'><IconRightArrow /></span>
18+
? <span className='buik-breadcrumb-seperator'>
19+
<IconRightArrow />
20+
</span>
1921
: <span>/</span>;
2022

2123
export default BreadcrumbDelimiter;

src/components/Breadcrumbs/BreadcrumbDropdown.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,7 @@ type Props = {
1919

2020
const BreadcrumbDropdown = ({ crumbs, onCrumbClick, className = '' }: Props) =>
2121
<DropdownMenu constrainToScrollParent>
22-
<PlainButton className={`buik-breadcrumbs-drop-down ${className}`}>
23-
···
24-
</PlainButton>
22+
<PlainButton className={`buik-breadcrumbs-drop-down ${className}`}>···</PlainButton>
2523
<Menu>
2624
{crumbs.map(({ id, name }: Crumb) =>
2725
<MenuItem key={id} onClick={() => onCrumbClick(id)}>

src/components/Button/Button.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,9 @@ class Button extends PureComponent<DefaultProps, Props, void> {
8888

8989
return (
9090
<button className={styleClassName} type={type} onClick={this.handleClick} {...buttonProps}>
91-
<span className={CLASS_BUTTON_CONTENT_SPAN}>{children}</span>
91+
<span className={CLASS_BUTTON_CONTENT_SPAN}>
92+
{children}
93+
</span>
9294
{isLoading && <LoadingIndicator className='buik-btn-loading-indicator' />}
9395
</button>
9496
);

src/components/Button/__tests__/Button-test.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,11 @@ describe('Button/Button', () => {
1212
it('should correctly render children in button', () => {
1313
const children = 'yooo';
1414

15-
const wrapper = shallow(<Button>{children}</Button>);
15+
const wrapper = shallow(
16+
<Button>
17+
{children}
18+
</Button>
19+
);
1620

1721
assert.isTrue(wrapper.hasClass('buik-btn'));
1822
assert.equal(wrapper.find('.buik-btn-content').length, 1);

src/components/Button/__tests__/PrimaryButton-test.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,11 @@ describe('Button/PrimaryButton', () => {
1212
it('should correctly render children in primary button', () => {
1313
const children = 'yooo';
1414

15-
const wrapper = shallow(<PrimaryButton>{children}</PrimaryButton>);
15+
const wrapper = shallow(
16+
<PrimaryButton>
17+
{children}
18+
</PrimaryButton>
19+
);
1620

1721
assert.equal(wrapper.find(Button).length, 1);
1822
assert.isTrue(wrapper.hasClass('buik-btn-primary'), true);

src/components/ContentPicker/cellRendererHelper.js

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,8 @@ function isRowSelectable(
1717
const shouldAllowSelection: boolean = hasHitSelectionLimit ? !!selected : true;
1818
const isTypeSelectable: boolean = !!type && selectableType.indexOf(type) > -1;
1919
const isFilePicker: boolean = selectableType.indexOf(TYPE_FILE) > -1;
20-
const isExtensionWhitelisted: boolean = isFilePicker && extensionsWhitelist.length
21-
? extensionsWhitelist.indexOf(extension) > -1
22-
: true;
20+
const isExtensionWhitelisted: boolean =
21+
isFilePicker && extensionsWhitelist.length ? extensionsWhitelist.indexOf(extension) > -1 : true;
2322

2423
return shouldAllowSelection && isTypeSelectable && isExtensionWhitelisted;
2524
}

src/components/ContentUploader/ItemName.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ type Props = {
1010
name: string
1111
};
1212

13-
const ItemName = ({ name }: Props) => <span className='bcu-item-label'>{name}</span>;
13+
const ItemName = ({ name }: Props) =>
14+
<span className='bcu-item-label'>
15+
{name}
16+
</span>;
1417

1518
export default ItemName;

src/components/ContentUploader/ItemProgress.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@ type Props = {
1414
const ItemProgress = ({ progress }: Props) =>
1515
<div className='bcu-item-progress'>
1616
<ProgressBar percent={progress} />
17-
<div className='bcu-progress-label'>{progress}%</div>
17+
<div className='bcu-progress-label'>
18+
{progress}%
19+
</div>
1820
</div>;
1921

2022
export default ItemProgress;

0 commit comments

Comments
 (0)