Files
address-verification-app/src/services/imageSyncService.ts
2024-09-10 10:56:40 +05:30

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');
}
};