|
|
|
|
@@ -10,7 +10,9 @@ import { axiosAuthInterceptorId } from "../../util/CleanAxios";
|
|
|
|
|
import { fetchImageFromUri, replaceAccents } from '../../util/uploadUtils';
|
|
|
|
|
import { selectBodyshop, selectCurrentUser } from "../user/user.selectors";
|
|
|
|
|
import {
|
|
|
|
|
mediaUploadCompleted,
|
|
|
|
|
mediaUploadFailure,
|
|
|
|
|
mediaUploadProgressBulk,
|
|
|
|
|
mediaUploadProgressOne,
|
|
|
|
|
mediaUploadStart,
|
|
|
|
|
mediaUploadSuccessOne
|
|
|
|
|
@@ -67,24 +69,29 @@ export function* mediaUploadStartAction({ payload: { photos, jobid } }) {
|
|
|
|
|
|
|
|
|
|
const bodyshop = yield select(selectBodyshop);
|
|
|
|
|
|
|
|
|
|
// Process photos in batches to avoid overwhelming the system
|
|
|
|
|
const batchSize = 3; // Upload 3 photos concurrently
|
|
|
|
|
const batches = [];
|
|
|
|
|
if (bodyshop.uselocalmediaserver) {
|
|
|
|
|
yield call(uploadToLocalMediaServer, photos, bodyshop, jobid);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
// Process photos in batches to avoid overwhelming the system
|
|
|
|
|
const batchSize = 3; // Upload 3 photos concurrently
|
|
|
|
|
const batches = [];
|
|
|
|
|
|
|
|
|
|
for (let i = 0; i < photos.length; i += batchSize) {
|
|
|
|
|
batches.push(photos.slice(i, i + batchSize));
|
|
|
|
|
for (let i = 0; i < photos.length; i += batchSize) {
|
|
|
|
|
batches.push(photos.slice(i, i + batchSize));
|
|
|
|
|
}
|
|
|
|
|
// Process each batch sequentially, but photos within batch concurrently
|
|
|
|
|
for (const batch of batches) {
|
|
|
|
|
const uploadTasks = batch.map((photo, index) =>
|
|
|
|
|
fork(uploadSinglePhoto, photo, bodyshop, index, jobid)
|
|
|
|
|
);
|
|
|
|
|
// Wait for current batch to complete before starting next batch
|
|
|
|
|
yield all(uploadTasks);
|
|
|
|
|
// Small delay between batches to prevent overwhelming the server
|
|
|
|
|
yield delay(100);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// Process each batch sequentially, but photos within batch concurrently
|
|
|
|
|
for (const batch of batches) {
|
|
|
|
|
const uploadTasks = batch.map((photo, index) =>
|
|
|
|
|
fork(uploadSinglePhoto, photo, bodyshop, index, jobid)
|
|
|
|
|
);
|
|
|
|
|
// Wait for current batch to complete before starting next batch
|
|
|
|
|
yield all(uploadTasks);
|
|
|
|
|
// Small delay between batches to prevent overwhelming the server
|
|
|
|
|
yield delay(100);
|
|
|
|
|
}
|
|
|
|
|
//yield put(mediaUploadSuccess(photo));
|
|
|
|
|
yield put(mediaUploadCompleted());
|
|
|
|
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.log("Saga Error: upload start", error, error.stack);
|
|
|
|
|
@@ -102,12 +109,7 @@ function* uploadSinglePhoto(photo, bodyshop, index, jobid) {
|
|
|
|
|
const key = `${bodyshop.id}/${jobid}/${replaceAccents(
|
|
|
|
|
photoBlob.data.name
|
|
|
|
|
).replace(/[^A-Z0-9]+/gi, "_")}-${new Date().getTime()}.${extension}`
|
|
|
|
|
|
|
|
|
|
if (bodyshop.uselocalmediaserver) {
|
|
|
|
|
yield call(uploadToLocalMediaServer, photo, photoBlob, extension, key, bodyshop, jobid);
|
|
|
|
|
} else {
|
|
|
|
|
yield call(uploadToImageProxy, photo, photoBlob, extension, key, bodyshop, jobid);
|
|
|
|
|
}
|
|
|
|
|
yield call(uploadToImageProxy, photo, photoBlob, extension, key, bodyshop, jobid);
|
|
|
|
|
|
|
|
|
|
yield put(mediaUploadSuccessOne(photo));
|
|
|
|
|
|
|
|
|
|
@@ -117,40 +119,56 @@ function* uploadSinglePhoto(photo, bodyshop, index, jobid) {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function* uploadToLocalMediaServer(photo, key) {
|
|
|
|
|
function* uploadToLocalMediaServer(photos, bodyshop, jobid) {
|
|
|
|
|
try {
|
|
|
|
|
// yield put(mediaUploadProgress({ photoId, status: 'uploading', progress: 25 }));
|
|
|
|
|
const options = {
|
|
|
|
|
headers: {
|
|
|
|
|
"Content-Type": "multipart/form-data",
|
|
|
|
|
ims_token: bodyshop.localmediatoken,
|
|
|
|
|
},
|
|
|
|
|
onUploadProgress: (e) => {
|
|
|
|
|
put(mediaUploadProgressBulk({ progress: e.loaded / e.total, loaded: e.loaded }));
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// const formData = new FormData();
|
|
|
|
|
// formData.append('file', {
|
|
|
|
|
// uri: photo.uri,
|
|
|
|
|
// type: photo.type || 'image/jpeg',
|
|
|
|
|
// name: photo.fileName || `photo_${Date.now()}.jpg`,
|
|
|
|
|
// });
|
|
|
|
|
const formData = new FormData();
|
|
|
|
|
formData.append("jobid", jobid);
|
|
|
|
|
|
|
|
|
|
// yield put(mediaUploadProgress({ photoId, status: 'uploading', progress: 50 }));
|
|
|
|
|
for (const file of photos) {
|
|
|
|
|
formData.append("file", {
|
|
|
|
|
uri: file.uri,
|
|
|
|
|
type: file.mimeType,
|
|
|
|
|
name: file.fileName,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// const response = yield call(fetch, 'YOUR_LOCAL_MEDIA_SERVER_ENDPOINT', {
|
|
|
|
|
// method: 'POST',
|
|
|
|
|
// body: formData,
|
|
|
|
|
// headers: {
|
|
|
|
|
// 'Content-Type': 'multipart/form-data',
|
|
|
|
|
// },
|
|
|
|
|
// });
|
|
|
|
|
formData.append("skip_thumbnail", true);
|
|
|
|
|
|
|
|
|
|
// yield put(mediaUploadProgress({ photoId, status: 'uploading', progress: 75 }));
|
|
|
|
|
try {
|
|
|
|
|
const imexMediaServerResponse = yield call(axios.post,
|
|
|
|
|
`${bodyshop.localmediaserverhttp}/jobs/upload`,
|
|
|
|
|
formData,
|
|
|
|
|
options
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// if (!response.ok) {
|
|
|
|
|
// throw new Error(`Upload failed: ${response.status}`);
|
|
|
|
|
// }
|
|
|
|
|
if (imexMediaServerResponse.status !== 200) {
|
|
|
|
|
console.log("Error uploading documents:", JSON.stringify(imexMediaServerResponse, null, 2));
|
|
|
|
|
|
|
|
|
|
// const result = yield call([response, 'json']);
|
|
|
|
|
// yield put(mediaUploadProgress({ photoId, status: 'completed', progress: 100 }));
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
|
|
// return result;
|
|
|
|
|
// onSuccess({
|
|
|
|
|
// duration: imexMediaServerResponse.headers["x-response-time"],
|
|
|
|
|
// });
|
|
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
|
|
|
|
console.log("Error uploading documents:", error.message, JSON.stringify(error, null, 2));
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
throw new Error(`Local media server upload failed: ${error.message}`);
|
|
|
|
|
console.log("Uncaught error", error);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -182,10 +200,8 @@ function* uploadToImageProxy(photo, photoBlob, extension, key, bodyshop, jobid)
|
|
|
|
|
xhr.setRequestHeader("Content-Type", photoBlob.type);
|
|
|
|
|
|
|
|
|
|
xhr.upload.onprogress = (e) => {
|
|
|
|
|
console.log("*** ~ awaitnewPromise ~ event:", e);
|
|
|
|
|
if (e.lengthComputable) {
|
|
|
|
|
console.log(`Upload progress for ${photo.uri}:`, e.loaded / e.total);
|
|
|
|
|
put(mediaUploadProgressOne({ ...photo, progress: e.loaded / e.total }));
|
|
|
|
|
put(mediaUploadProgressOne({ ...photo, progress: e.loaded / e.total, loaded: e.loaded }));
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
@@ -217,7 +233,7 @@ function* uploadToImageProxy(photo, photoBlob, extension, key, bodyshop, jobid)
|
|
|
|
|
const [hours, minutes, seconds] = time ? time.split(':') : [];
|
|
|
|
|
const pictureMoment = moment(`${year}-${month}-${day}T${hours}:${minutes}:${seconds}`);
|
|
|
|
|
|
|
|
|
|
const documentInsert = yield call(client.mutate, ({
|
|
|
|
|
yield call(client.mutate, ({
|
|
|
|
|
mutation: INSERT_NEW_DOCUMENT,
|
|
|
|
|
variables: {
|
|
|
|
|
docInput: [
|
|
|
|
|
@@ -236,7 +252,6 @@ function* uploadToImageProxy(photo, photoBlob, extension, key, bodyshop, jobid)
|
|
|
|
|
],
|
|
|
|
|
},
|
|
|
|
|
}));
|
|
|
|
|
console.log("*** ~ uploadToImageProxy ~ documentInsert:", JSON.stringify(documentInsert, null, 2));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|