Skip to content

Commit 8982f6b

Browse files
committed
chore: Add onBatchStart
1 parent 5ee22fe commit 8982f6b

File tree

2 files changed

+78
-66
lines changed

2 files changed

+78
-66
lines changed

src/AjaxUploader.tsx

+76-66
Original file line numberDiff line numberDiff line change
@@ -84,105 +84,115 @@ class AjaxUploader extends Component<UploadProps> {
8484
}
8585

8686
uploadFiles = (files: FileList) => {
87+
const { onBatchUpload } = this.props;
8788
const postFiles: Array<RcFile> = Array.prototype.slice.call(files);
88-
postFiles
89+
const startPromiseList = postFiles
8990
.map((file: RcFile & { uid?: string }) => {
9091
// eslint-disable-next-line no-param-reassign
9192
file.uid = getUid();
9293
return file;
9394
})
94-
.forEach(file => {
95-
this.upload(file, postFiles);
96-
});
95+
.map(file => this.upload(file, postFiles));
96+
97+
// Trigger when all files has started
98+
Promise.all(startPromiseList).then(parsedFiles => {
99+
onBatchUpload?.(parsedFiles.filter(f => f));
100+
});
97101
};
98102

99-
upload(file: RcFile, fileList: Array<RcFile>) {
103+
upload(file: RcFile, fileList: Array<RcFile>): Promise<RcFile> {
100104
const { props } = this;
101-
if (!props.beforeUpload) {
105+
const { beforeUpload } = this.props;
106+
if (!beforeUpload) {
102107
// always async in case use react state to keep fileList
103-
Promise.resolve().then(() => {
104-
this.post(file);
105-
});
106-
return;
108+
return Promise.resolve().then(() => this.post(file));
107109
}
108110

109-
const before = props.beforeUpload(file, fileList);
111+
const before = beforeUpload(file, fileList);
110112
if (before && typeof before !== 'boolean' && before.then) {
111-
before
113+
return before
112114
.then(processedFile => {
113115
const processedFileType = Object.prototype.toString.call(processedFile);
114116
if (processedFileType === '[object File]' || processedFileType === '[object Blob]') {
115-
this.post(processedFile);
116-
return;
117+
return this.post(processedFile);
117118
}
118-
this.post(file);
119+
return this.post(file);
119120
})
120121
.catch(e => {
121122
// eslint-disable-next-line no-console
122123
console.log(e);
124+
125+
return null;
123126
});
124-
} else if (before !== false) {
125-
Promise.resolve().then(() => {
126-
this.post(file);
127-
});
128127
}
128+
129+
if (before !== false) {
130+
return Promise.resolve().then(() => this.post(file));
131+
}
132+
133+
return Promise.resolve(file);
129134
}
130135

131-
post(file: RcFile) {
136+
post(file: RcFile): Promise<RcFile> {
132137
if (!this._isMounted) {
133-
return;
138+
return null;
134139
}
135140
const { props } = this;
136141
const { onStart, onProgress, transformFile = originFile => originFile } = props;
137142

138-
onStart(file);
143+
return new Promise(resolveStartFile => {
144+
new Promise(resolveAction => {
145+
let { action } = props;
146+
if (typeof action === 'function') {
147+
action = action(file);
148+
}
149+
return resolveAction(action);
150+
}).then((action: string) => {
151+
const { uid } = file;
152+
const request = props.customRequest || defaultRequest;
153+
const transform = Promise.resolve(transformFile(file))
154+
.then(transformedFile => {
155+
let { data } = props;
156+
if (typeof data === 'function') {
157+
data = data(transformedFile);
158+
}
159+
return Promise.all([transformedFile, data]);
160+
})
161+
.catch(e => {
162+
console.error(e); // eslint-disable-line no-console
163+
});
139164

140-
new Promise(resolve => {
141-
let { action } = props;
142-
if (typeof action === 'function') {
143-
action = action(file);
144-
}
145-
return resolve(action);
146-
}).then((action: string) => {
147-
const { uid } = file;
148-
const request = props.customRequest || defaultRequest;
149-
const transform = Promise.resolve(transformFile(file))
150-
.then(transformedFile => {
151-
let { data } = props;
152-
if (typeof data === 'function') {
153-
data = data(transformedFile);
154-
}
155-
return Promise.all([transformedFile, data]);
156-
})
157-
.catch(e => {
158-
console.error(e); // eslint-disable-line no-console
159-
});
165+
transform.then(([transformedFile, data]: [RcFile, object]) => {
166+
const requestOption = {
167+
action,
168+
filename: props.name,
169+
data,
170+
file: transformedFile,
171+
headers: props.headers,
172+
withCredentials: props.withCredentials,
173+
method: props.method || 'post',
174+
onProgress: onProgress
175+
? (e: UploadProgressEvent) => {
176+
onProgress(e, file);
177+
}
178+
: null,
179+
onSuccess: (ret: any, xhr: XMLHttpRequest) => {
180+
delete this.reqs[uid];
181+
props.onSuccess(ret, file, xhr);
182+
},
183+
onError: (err: UploadRequestError, ret: any) => {
184+
delete this.reqs[uid];
185+
props.onError(err, ret, file);
186+
},
187+
};
160188

161-
transform.then(([transformedFile, data]: [RcFile, object]) => {
162-
const requestOption = {
163-
action,
164-
filename: props.name,
165-
data,
166-
file: transformedFile,
167-
headers: props.headers,
168-
withCredentials: props.withCredentials,
169-
method: props.method || 'post',
170-
onProgress: onProgress
171-
? (e: UploadProgressEvent) => {
172-
onProgress(e, file);
173-
}
174-
: null,
175-
onSuccess: (ret: any, xhr: XMLHttpRequest) => {
176-
delete this.reqs[uid];
177-
props.onSuccess(ret, file, xhr);
178-
},
179-
onError: (err: UploadRequestError, ret: any) => {
180-
delete this.reqs[uid];
181-
props.onError(err, ret, file);
182-
},
183-
};
189+
onStart(file);
184190

185-
this.reqs[uid] = request(requestOption);
191+
this.reqs[uid] = request(requestOption);
192+
193+
// Tell root we have finish start
194+
resolveStartFile(file);
195+
});
186196
});
187197
});
188198
}

src/interface.tsx

+2
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ export interface UploadProps
1414
headers?: UploadRequestHeader;
1515
accept?: string;
1616
multiple?: boolean;
17+
/** @private Trigger when a batch of files upload. Internal usage, do not use in your production! */
18+
onBatchUpload?: (files: RcFile[]) => void;
1719
onStart?: (file: RcFile) => void;
1820
onError?: (error: Error, ret: object, file: RcFile) => void;
1921
onSuccess?: (response: object, file: RcFile, xhr: object) => void;

0 commit comments

Comments
 (0)