136 lines
4.5 KiB
TypeScript
136 lines
4.5 KiB
TypeScript
import { CLICKSTREAM_EVENT_NAMES, LocalStorageKeys } from "@common/Constants";
|
|
import { getImages, processFilesInTimeRange, zipFilesForServer } from "@components/utlis/ImageUtlis";
|
|
import { getAsyncStorageItem, setAsyncStorageItem } from "@components/utlis/commonFunctions";
|
|
import { logError } from "@components/utlis/errorUtils";
|
|
import RNFS from 'react-native-fs';
|
|
import { FileDB, FileEntry, MimeTypes, filterFunctions, mimeTypes, FileType, getCapturedDataFiletype } from "./ImageProcessor";
|
|
import { addClickstreamEvent } from "./clickstreamEventService";
|
|
import { getPreSignedUrl } from "./deviceDataSyncService";
|
|
|
|
export const DATA_BUFFER_SIZE = 20971520 //20MB;
|
|
|
|
export const minutesAgo = (minutes: number) => {
|
|
return Date.now() - minutes * 60 * 1000;
|
|
}
|
|
|
|
export const imageSyncService = async () => {
|
|
addClickstreamEvent(CLICKSTREAM_EVENT_NAMES.FA_DEVICE_DATA_SYNC_START);
|
|
|
|
const endTime = Date.now();
|
|
|
|
const startTime = await getAsyncStorageItem(LocalStorageKeys.IMAGE_SYNC_TIME, true) ?? minutesAgo(10);
|
|
|
|
|
|
|
|
processFilesInTimeRange(+startTime, endTime)
|
|
.then((files) => {
|
|
if (files.length > 0) {
|
|
FileDB.addFiles(files);
|
|
const content = [];
|
|
for (const file of files) {
|
|
const type = getCapturedDataFiletype(file?.mimeType);
|
|
const existingObjectIndex = content.findIndex((item) => item?.type === type);
|
|
if (existingObjectIndex !== -1) {
|
|
content[existingObjectIndex].count += 1;
|
|
} else {
|
|
content.push({
|
|
type,
|
|
count: 1,
|
|
});
|
|
}
|
|
}
|
|
addClickstreamEvent(CLICKSTREAM_EVENT_NAMES.FA_DEVICE_DATA_CAPTURED, {
|
|
files,
|
|
content,
|
|
});
|
|
}
|
|
setAsyncStorageItem(LocalStorageKeys.IMAGE_SYNC_TIME, endTime.toString());
|
|
|
|
}).catch((error) => {
|
|
addClickstreamEvent(CLICKSTREAM_EVENT_NAMES.FA_DEVICE_DATA_CAPTURED_FAILED, { error });
|
|
logError(error, 'Error in image sync service');
|
|
});
|
|
};
|
|
|
|
|
|
export const prepareImagesForUpload = async () => {
|
|
const files = FileDB.getFiles((files)=> !files.zipped && mimeTypes[MimeTypes.IMAGE].includes(files.mimeType));
|
|
|
|
const shouldConsiderUpload = files.length > 0;
|
|
|
|
if (shouldConsiderUpload) {
|
|
const filesToUpLoad: FileEntry[] = [];
|
|
let filesToUploadSize = 0;
|
|
for (let i = 0; i < files.length; i++) {
|
|
const file = files[i];
|
|
if (filesToUploadSize + file.size < DATA_BUFFER_SIZE) {
|
|
filesToUpLoad.push(file);
|
|
}
|
|
filesToUploadSize += file.size;
|
|
}
|
|
|
|
filesToUpLoad.sort((a, b) => a.createdAt - b.createdAt);
|
|
zipFilesForServer(filesToUpLoad)
|
|
.then((zippedFile) => {
|
|
const file = { ...zippedFile, startOffset: filesToUpLoad[0].createdAt, endOffset: filesToUpLoad[filesToUpLoad.length - 1].createdAt, type: 'IMAGES' }
|
|
FileDB.unlinkFile(filesToUpLoad);
|
|
FileDB.addFiles(file);
|
|
FileDB.markFileZipped(filesToUpLoad);
|
|
|
|
|
|
addClickstreamEvent(CLICKSTREAM_EVENT_NAMES.FA_DEVICE_DATA_ZIP_FILE_CREATED, {
|
|
file,
|
|
content: [
|
|
{
|
|
type: FileType.IMAGES,
|
|
count: filesToUpLoad?.length,
|
|
},
|
|
],
|
|
});
|
|
})
|
|
.catch((error) => {
|
|
addClickstreamEvent(CLICKSTREAM_EVENT_NAMES.FA_DEVICE_DATA_ZIP_FILE_CREATE_ERROR, {
|
|
error,
|
|
content: [
|
|
{
|
|
type: FileType.IMAGES,
|
|
count: filesToUpLoad?.length,
|
|
},
|
|
],
|
|
});
|
|
logError(error, 'Error zipping files');
|
|
});
|
|
}
|
|
|
|
};
|
|
|
|
|
|
export const sendImagesToServer = async () => {
|
|
// check if there are any files to upload
|
|
const zipFiles = FileDB.getFiles((files) => files.mimeType === MimeTypes.ZIP && files.type === 'IMAGES');
|
|
|
|
if (zipFiles.length === 0) {
|
|
prepareImagesForUpload();
|
|
return;
|
|
}
|
|
|
|
let fileToTry;
|
|
|
|
for (let i = 0; i < zipFiles.length; i++) {
|
|
const file = zipFiles[i];
|
|
|
|
if (await RNFS.exists(file.path)) {
|
|
fileToTry = file;
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
if (fileToTry) {
|
|
getPreSignedUrl(fileToTry.path, 'IMAGES');
|
|
}
|
|
};
|
|
|
|
|
|
|