TP-84794 | Deprecate Watermelon DB (#939)
This commit is contained in:
@@ -124,7 +124,7 @@ public class MainApplication extends Application implements ReactApplication {
|
||||
try {
|
||||
Field field = CursorWindow.class.getDeclaredField("sCursorWindowSize");
|
||||
field.setAccessible(true);
|
||||
field.set(null, 20 * 1024 * 1024); // 20MB
|
||||
field.set(null, 40 * 1024 * 1024); // 40MB
|
||||
} catch (Exception e) {
|
||||
if (BuildConfig.DEBUG) {
|
||||
e.printStackTrace();
|
||||
|
||||
@@ -6,7 +6,6 @@ import axiosInstance, {
|
||||
isAxiosError,
|
||||
} from '../components/utlis/apiHelper';
|
||||
import { navigateToScreen } from '../components/utlis/navigationUtlis';
|
||||
import OfflineImageDAO from '../wmDB/dao/OfflineImageDAO';
|
||||
import {
|
||||
resetSelectedTodoList,
|
||||
resetTodoList,
|
||||
@@ -105,7 +104,6 @@ export const syncCaseDetail =
|
||||
offlineCaseKey: payload.data.offlineCaseKey,
|
||||
})
|
||||
);
|
||||
OfflineImageDAO.deleteImages(offlineImageIdList);
|
||||
toast({
|
||||
type: 'success',
|
||||
text1: ToastMessages.FEEDBACK_SUCCESSFUL,
|
||||
@@ -117,6 +115,7 @@ export const syncCaseDetail =
|
||||
.catch((errObj) => {
|
||||
const statusCode = errObj?.response?.status;
|
||||
const errorCode = errObj?.response?.data?.error_code;
|
||||
|
||||
if (isAxiosError(errObj) && statusCode !== API_STATUS_CODE.UNPROCESSABLE_CONTENT) {
|
||||
toast({
|
||||
type: 'error',
|
||||
@@ -186,11 +185,11 @@ export const getSignedApi = async (
|
||||
return new Promise((res) => {
|
||||
if (shouldBatch) {
|
||||
batchSignedApiRequest(signedRequestPayload, (results: any) => {
|
||||
res({ imageUrl: results?.[signedRequestPayload[0].documentReferenceId] || '' });
|
||||
res({ imageUrl: results?.[signedRequestPayload[0].documentReferenceId] || '' });
|
||||
}, skipFirebaseUpdate);
|
||||
} else {
|
||||
makeBulkSignedApiRequest(signedRequestPayload, (results: any) => {
|
||||
res({ imageUrl: results?.[signedRequestPayload[0].documentReferenceId] || '' });
|
||||
res({ imageUrl: results?.[signedRequestPayload[0].documentReferenceId] || '' });
|
||||
}, skipFirebaseUpdate);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1294,6 +1294,14 @@ export const CLICKSTREAM_EVENT_NAMES = {
|
||||
description: 'Feedback nudge closed'
|
||||
},
|
||||
|
||||
FA_FEEDBACK_IMAGE_NOT_FOUND: {
|
||||
name: 'FA_FEEDBACK_IMAGE_NOT_FOUND',
|
||||
description: 'Feedback image not found'
|
||||
},
|
||||
FA_UNSYNC_FEEDBACK_CAPTURED: {
|
||||
name: 'FA_UNSYNC_FEEDBACK_CAPTURED',
|
||||
description: 'Unsync feedback captured'
|
||||
},
|
||||
} as const;
|
||||
|
||||
export enum MimeType {
|
||||
|
||||
@@ -62,7 +62,7 @@ const AddressSelection: React.FC<IAddressSelection> = (props) => {
|
||||
);
|
||||
const caseType = currentCase?.caseType || CaseAllocationType.ADDRESS_VERIFICATION_CASE;
|
||||
const template = useAppSelector((state) => state.case.templateData[caseType]);
|
||||
const question = template.questions[questionId];
|
||||
const question = template?.questions?.[questionId];
|
||||
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
|
||||
@@ -1,290 +0,0 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { Control, Controller } from 'react-hook-form';
|
||||
import {
|
||||
ActivityIndicator,
|
||||
ImageBackground,
|
||||
StyleSheet,
|
||||
TouchableOpacity,
|
||||
View,
|
||||
} from 'react-native';
|
||||
import PhotoUpload, {
|
||||
IImageDetails,
|
||||
LAUNCH_REQUEST,
|
||||
} from '../../../../RN-UI-LIB/src/components/photoUpload/PhotoUpload';
|
||||
import { useSelector } from 'react-redux';
|
||||
import Text from '../../../../RN-UI-LIB/src/components/Text';
|
||||
import DeleteIcon from '../../../../RN-UI-LIB/src/Icons/DeleteIcon';
|
||||
import { GenericStyles } from '../../../../RN-UI-LIB/src/styles';
|
||||
import { COLORS } from '../../../../RN-UI-LIB/src/styles/colors';
|
||||
import { useAppDispatch, useAppSelector } from '../../../hooks';
|
||||
import { RootState } from '../../../store/store';
|
||||
import { AnswerType } from '../interface';
|
||||
import ErrorMessage from './ErrorMessage';
|
||||
import withObservables from '@nozbe/with-observables';
|
||||
import OfflineImageDAO from '../../../wmDB/dao/OfflineImageDAO';
|
||||
import {
|
||||
CLICKSTREAM_EVENT_NAMES,
|
||||
PrefixJpegBase64Image,
|
||||
getPrefixBase64Image,
|
||||
} from '../../../common/Constants';
|
||||
import { addClickstreamEvent } from '../../../services/clickstreamEventService';
|
||||
import { isQuestionMandatory, validateInput } from '../services/validation.service';
|
||||
import { CaseAllocationType } from '../../../screens/allCases/interface';
|
||||
import {
|
||||
addIntermediateDocument,
|
||||
deleteIntermediateDocument,
|
||||
} from '../../../reducer/feedbackImagesSlice';
|
||||
|
||||
interface IOfflineImage {
|
||||
idx: string;
|
||||
imageData: string;
|
||||
originalImageUri: string;
|
||||
}
|
||||
|
||||
interface IImageUpload {
|
||||
questionType: string;
|
||||
questionId: string;
|
||||
widgetId: string;
|
||||
journeyId: string;
|
||||
caseId: string;
|
||||
sectionId: string;
|
||||
control: Control<any, any>;
|
||||
error: any;
|
||||
offlineImages: IOfflineImage[];
|
||||
}
|
||||
|
||||
const getImageUri = (imageList: IOfflineImage[], imageId: string) => {
|
||||
const image = imageList?.find((image) => image?.idx === imageId);
|
||||
let uri = '';
|
||||
if (image) {
|
||||
const { originalImageUri, imageData } = image || {};
|
||||
uri = originalImageUri || imageData || '';
|
||||
}
|
||||
return uri;
|
||||
};
|
||||
|
||||
const ImageUpload: React.FC<IImageUpload> = (props) => {
|
||||
const { questionId, error, sectionId, caseId, journeyId, widgetId, questionType } = props;
|
||||
const [imageId, setImageId] = useState('');
|
||||
const [loading, setImageLoading] = useState(false);
|
||||
const caseType = useAppSelector(
|
||||
(state) =>
|
||||
state.allCases.caseDetails[caseId]?.caseType || CaseAllocationType.ADDRESS_VERIFICATION_CASE
|
||||
);
|
||||
const template = useAppSelector((state) => state.case.templateData[caseType]);
|
||||
const question = template.questions[questionId as keyof typeof template.questions];
|
||||
const dataFromRedux = useSelector(
|
||||
(state: RootState) =>
|
||||
state.case.caseForm?.[caseId]?.[journeyId]?.widgetContext?.[widgetId]?.sectionContext?.[
|
||||
sectionId
|
||||
]?.questionContext?.[questionId]?.answer
|
||||
);
|
||||
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
useEffect(() => {
|
||||
if (dataFromRedux) {
|
||||
setImageId(dataFromRedux);
|
||||
}
|
||||
}, [dataFromRedux]);
|
||||
|
||||
if (!question) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const addOriginalFileUriToDocs = (caseId: string, fileUri: string, questionKey: string) => {
|
||||
if (!fileUri) {
|
||||
return;
|
||||
}
|
||||
dispatch(addIntermediateDocument({ caseId, fileUri, questionKey }));
|
||||
};
|
||||
|
||||
const addImageUploadSuccessClickstream = (openRequest: LAUNCH_REQUEST) => {
|
||||
if (openRequest === LAUNCH_REQUEST.CAMERA) {
|
||||
addClickstreamEvent(CLICKSTREAM_EVENT_NAMES.FA_FEEDBACK_PHOTO_CAPTURED_SUCCESSFULLY, {
|
||||
caseId,
|
||||
questionType,
|
||||
questionId,
|
||||
sectionId,
|
||||
widgetId,
|
||||
});
|
||||
} else if (openRequest === LAUNCH_REQUEST.IMAGE_LIBRARY) {
|
||||
addClickstreamEvent(CLICKSTREAM_EVENT_NAMES.FA_FEEDBACK_PHOTO_UPLOADED_SUCCESSFULLY, {
|
||||
caseId,
|
||||
questionType,
|
||||
questionId,
|
||||
sectionId,
|
||||
widgetId,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const handleChange = async (clickedImage: IImageDetails, onChange: (...event: any[]) => void) => {
|
||||
const { base64 = '', uri = '', openRequest } = clickedImage;
|
||||
addImageUploadSuccessClickstream(openRequest);
|
||||
addOriginalFileUriToDocs(caseId, uri, questionId);
|
||||
if (!base64) {
|
||||
return;
|
||||
}
|
||||
const base64Image = `${PrefixJpegBase64Image}${base64}`;
|
||||
var uniqueId = 'id' + new Date().getTime();
|
||||
setImageId(uniqueId);
|
||||
addClickstreamEvent(CLICKSTREAM_EVENT_NAMES.AV_FORM_ELEMENT_CHANGED, {
|
||||
caseId,
|
||||
questionType,
|
||||
value: uniqueId,
|
||||
questionId,
|
||||
error,
|
||||
sectionId,
|
||||
widgetId,
|
||||
});
|
||||
onChange({
|
||||
answer: uniqueId,
|
||||
type: AnswerType.image,
|
||||
});
|
||||
await OfflineImageDAO.addImage(base64Image, uri, uniqueId);
|
||||
};
|
||||
|
||||
const handleImageDelete = () => {
|
||||
setImageId('');
|
||||
dispatch(deleteIntermediateDocument({ caseId, questionKey: questionId }));
|
||||
};
|
||||
|
||||
const handleError = (error: string) => {
|
||||
addClickstreamEvent(CLICKSTREAM_EVENT_NAMES.FA_PHOTO_UPLOAD_ERROR, {
|
||||
caseId,
|
||||
questionType,
|
||||
questionId,
|
||||
error,
|
||||
sectionId,
|
||||
widgetId,
|
||||
});
|
||||
};
|
||||
|
||||
const handlePictureAction = (openRequest: LAUNCH_REQUEST) => {
|
||||
if (openRequest === LAUNCH_REQUEST.CAMERA) {
|
||||
addClickstreamEvent(CLICKSTREAM_EVENT_NAMES.FA_FEEDBACK_CLICKED_TAKE_PHOTO, {
|
||||
caseId,
|
||||
questionType,
|
||||
questionId,
|
||||
sectionId,
|
||||
widgetId,
|
||||
});
|
||||
} else if (openRequest === LAUNCH_REQUEST.IMAGE_LIBRARY) {
|
||||
addClickstreamEvent(CLICKSTREAM_EVENT_NAMES.FA_FEEDBACK_CLICKED_UPLOAD_PHOTO, {
|
||||
caseId,
|
||||
questionType,
|
||||
questionId,
|
||||
sectionId,
|
||||
widgetId,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// TODO : add the validator back when firestore is fixed.
|
||||
return (
|
||||
<View style={[GenericStyles.mt12]}>
|
||||
<Text dark bold style={GenericStyles.mb4}>
|
||||
{question.text}{' '}
|
||||
{isQuestionMandatory(question) && <Text style={GenericStyles.redText}>*</Text>}
|
||||
</Text>
|
||||
{!imageId ? (
|
||||
<Controller
|
||||
control={props.control}
|
||||
rules={{ validate: (data) => validateInput(data, question.metadata.validators) }}
|
||||
render={({ field: { onChange } }) => (
|
||||
<PhotoUpload
|
||||
onPictureAction={handlePictureAction}
|
||||
onPictureClickSuccess={(clickedImage) => handleChange(clickedImage, onChange)}
|
||||
showUploadFromGalleryOption={true}
|
||||
containerStyle={[GenericStyles.containerStyle, loading ? styles.displayNone : null]}
|
||||
imageLoading={setImageLoading}
|
||||
onError={handleError}
|
||||
/>
|
||||
)}
|
||||
name={`widgetContext.${widgetId}.sectionContext.${props.sectionId}.questionContext.${questionId}`}
|
||||
/>
|
||||
) : (
|
||||
<View>
|
||||
<ImageBackground
|
||||
style={styles.image}
|
||||
imageStyle={styles.br8}
|
||||
source={{
|
||||
uri: getImageUri(props.offlineImages, imageId),
|
||||
}}
|
||||
onError={(error) => handleError('Error in image rendering')}
|
||||
// onLoadStart={() => setImageLoading(true)}
|
||||
// onLoadEnd={() => setImageLoading(false)}
|
||||
>
|
||||
<TouchableOpacity onPress={handleImageDelete} style={styles.deleteButton}>
|
||||
<DeleteIcon />
|
||||
</TouchableOpacity>
|
||||
{loading ? (
|
||||
<ActivityIndicator
|
||||
size={'small'}
|
||||
style={styles.centerAllign}
|
||||
color={COLORS.TEXT.BLUE}
|
||||
/>
|
||||
) : null}
|
||||
</ImageBackground>
|
||||
</View>
|
||||
)}
|
||||
<ErrorMessage
|
||||
show={
|
||||
error?.widgetContext?.[widgetId]?.sectionContext?.[sectionId]?.questionContext?.[
|
||||
questionId
|
||||
]
|
||||
}
|
||||
/>
|
||||
<ImageBackground
|
||||
style={[styles.image, loading ? styles.loadingState : styles.displayNone]}
|
||||
imageStyle={styles.br8}
|
||||
>
|
||||
<ActivityIndicator size={'small'} color={COLORS.TEXT.BLUE} />
|
||||
</ImageBackground>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
image: {
|
||||
width: '100%',
|
||||
height: 350,
|
||||
resizeMode: 'contain',
|
||||
},
|
||||
deleteButton: {
|
||||
position: 'absolute',
|
||||
right: 8,
|
||||
top: 8,
|
||||
backgroundColor: COLORS.BACKGROUND.PRIMARY,
|
||||
height: 28,
|
||||
width: 28,
|
||||
borderRadius: 14,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
borderWidth: 1,
|
||||
borderColor: COLORS.BORDER.PRIMARY,
|
||||
},
|
||||
br8: {
|
||||
borderRadius: 8,
|
||||
},
|
||||
displayNone: {
|
||||
display: 'none',
|
||||
},
|
||||
loadingState: {
|
||||
justifyContent: 'center',
|
||||
backgroundColor: COLORS.BACKGROUND.PRIMARY,
|
||||
alignItems: 'center',
|
||||
borderRadius: 8,
|
||||
},
|
||||
centerAllign: {
|
||||
position: 'absolute',
|
||||
top: '50%',
|
||||
left: '50%',
|
||||
},
|
||||
});
|
||||
const enhance = withObservables([], () => ({
|
||||
offlineImages: OfflineImageDAO.observeOfflineImage(),
|
||||
}));
|
||||
|
||||
export default enhance(ImageUpload);
|
||||
@@ -10,7 +10,6 @@ import { useAppDispatch, useAppSelector } from '../../../../hooks';
|
||||
import { RootState } from '../../../../store/store';
|
||||
import { AnswerType } from '../../interface';
|
||||
import ErrorMessage from '../ErrorMessage';
|
||||
import OfflineImageDAO from '../../../../wmDB/dao/OfflineImageDAO';
|
||||
import { CLICKSTREAM_EVENT_NAMES, PrefixJpegBase64Image } from '../../../../common/Constants';
|
||||
import { addClickstreamEvent, ClickstreamDesc } from '../../../../services/clickstreamEventService';
|
||||
import { isQuestionMandatory, validateInput } from '../../services/validation.service';
|
||||
@@ -205,7 +204,6 @@ const ImageUploadV2: React.FC<IImageUpload> = (props) => {
|
||||
answer: uniqueId,
|
||||
type: AnswerType.image,
|
||||
});
|
||||
await OfflineImageDAO.addImage(base64Image, uri, uniqueId, imageWidth, imageHeight);
|
||||
toast({ type: 'success', text1: 'Geolocation & Timestamp added successfully' });
|
||||
setImageLoading(false);
|
||||
addOriginalFileUriToDocs(caseId, uri, questionId, imageWidth, imageHeight);
|
||||
@@ -221,11 +219,7 @@ const ImageUploadV2: React.FC<IImageUpload> = (props) => {
|
||||
}
|
||||
};
|
||||
|
||||
const {
|
||||
fileUri,
|
||||
imageHeight = 350,
|
||||
imageWidth = 350
|
||||
} = imageDoc || {};
|
||||
const { fileUri, imageHeight = 350, imageWidth = 350 } = imageDoc || {};
|
||||
|
||||
const imageHeightWrtAspectRatio = getImageHeightWrtAspectRatio(
|
||||
imageWidth,
|
||||
@@ -242,13 +236,12 @@ const ImageUploadV2: React.FC<IImageUpload> = (props) => {
|
||||
) => {
|
||||
setImageLoading(false);
|
||||
const { base64 = '', uri = '', openRequest } = clickedImage;
|
||||
const uniqueId = 'id' + new Date().getTime();
|
||||
addImageUploadSuccessClickstream(openRequest);
|
||||
addOriginalFileUriToDocs(caseId, uri, questionId);
|
||||
if (!base64) {
|
||||
return;
|
||||
}
|
||||
const base64Image = `${PrefixJpegBase64Image}${base64}`;
|
||||
var uniqueId = 'id' + new Date().getTime();
|
||||
setImageId(uniqueId);
|
||||
addClickstreamEvent(CLICKSTREAM_EVENT_NAMES.AV_FORM_ELEMENT_CHANGED, {
|
||||
caseId,
|
||||
@@ -263,7 +256,7 @@ const ImageUploadV2: React.FC<IImageUpload> = (props) => {
|
||||
answer: uniqueId,
|
||||
type: AnswerType.image,
|
||||
});
|
||||
await OfflineImageDAO.addImage(base64Image, uri, uniqueId);
|
||||
addOriginalFileUriToDocs(caseId, uri, questionId, imageWidth, imageHeight);
|
||||
};
|
||||
|
||||
const handleImageUpload = async (onChange: (...event: any[]) => void) => {
|
||||
|
||||
@@ -307,6 +307,14 @@ const Widget: React.FC<IWidget> = (props) => {
|
||||
unSyncedCase,
|
||||
nudgeBottomSheetDetails?.showNudgeBottomSheet
|
||||
);
|
||||
if(!transformedPayload?.data?.answers) {
|
||||
toast({
|
||||
type: 'error',
|
||||
text1: ToastMessages.FEEDBACK_IMAGE_NOT_FOUND,
|
||||
});
|
||||
onErrorSubmit({}, transformedPayload)
|
||||
return;
|
||||
}
|
||||
dispatch(
|
||||
syncCaseDetail(transformedPayload, {
|
||||
onSuccessCB: (apiCaseData, interactionId: string) =>
|
||||
|
||||
@@ -10,7 +10,6 @@ import AddressSelection from '../components/AddressSelection';
|
||||
import PhoneNumberSelection from '../components/PhoneNumberSelection';
|
||||
import DateInput from '../components/DateInput';
|
||||
import TimeInput from '../components/TimeInput';
|
||||
import ImageUpload from '../components/ImageUpload';
|
||||
|
||||
export const FormComponentList = {
|
||||
TextInput,
|
||||
|
||||
@@ -49,10 +49,6 @@ export class CaptureGeolocation {
|
||||
if (cachedLocation && Date.now() - (cachedLocation?.location?.timestamp || 0) < cacheTTL) {
|
||||
return resolve(cachedLocation?.location?.coords);
|
||||
}
|
||||
if (cachedLocation && cachedLocation?.isCapturing) {
|
||||
console.info('Capture already in progress. Returning');
|
||||
resolve(undefined);
|
||||
}
|
||||
CaptureGeolocation.setCapturing(resourceId, true);
|
||||
const isLocationOn = await PermissionsAndroid.check(
|
||||
PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION
|
||||
|
||||
@@ -64,6 +64,7 @@ export const ToastMessages = {
|
||||
SUCCESS_COPYING_EMPLOYER_NAME: 'Employer Name Copied Successfully!!',
|
||||
FEEDBACK_SUCCESSFUL: 'Feedback submitted successfully!',
|
||||
FEEDBACK_FAILED: 'Feedback submission failed',
|
||||
FEEDBACK_IMAGE_NOT_FOUND: 'Feedback submission failed. Please try uploading image again',
|
||||
FIRESTORE_SIGNIN_FAILED: 'Error signing in to Firestore',
|
||||
PAYMENT_LINK_ERROR: 'Payment link could not be shared',
|
||||
PAYMENT_LINK_SUCCESS: 'Link has been generated and shared with customer',
|
||||
|
||||
@@ -4,10 +4,7 @@ import { syncCaseDetail } from '../../action/dataActions';
|
||||
import { CLICKSTREAM_EVENT_NAMES } from '../../common/Constants';
|
||||
import { useAppDispatch, useAppSelector } from '../../hooks';
|
||||
import useIsOnline from '../../hooks/useIsOnline';
|
||||
import {
|
||||
getTransformedAvCase,
|
||||
getTransformedCollectionCaseItem,
|
||||
} from '../../services/casePayload.transformer';
|
||||
import { getTransformedCollectionCaseItem } from '../../services/casePayload.transformer';
|
||||
import { addClickstreamEvent } from '../../services/clickstreamEventService';
|
||||
import { CaseAllocationType } from '../allCases/interface';
|
||||
import { CaseDetail } from './interface';
|
||||
@@ -64,12 +61,16 @@ const interactionsHandler = () => {
|
||||
for (const caseItem of notSyncedCases) {
|
||||
if (isOnline) {
|
||||
const caseKey = caseItem.offlineCaseKey || caseItem.id;
|
||||
addClickstreamEvent(CLICKSTREAM_EVENT_NAMES.FA_UNSYNC_FEEDBACK_CAPTURED, {
|
||||
caseId: caseKey,
|
||||
});
|
||||
inProgressCaseIds.current.push(caseKey);
|
||||
let modifiedCaseItem: any;
|
||||
if (caseItem?.caseType === CaseAllocationType.COLLECTION_CASE) {
|
||||
modifiedCaseItem = await getTransformedCollectionCaseItem(caseItem, true);
|
||||
} else {
|
||||
modifiedCaseItem = await getTransformedAvCase(caseItem, templateId);
|
||||
}
|
||||
if (!modifiedCaseItem?.data?.answers) {
|
||||
return;
|
||||
}
|
||||
dispatch(
|
||||
syncCaseDetail(modifiedCaseItem, {
|
||||
|
||||
@@ -1,16 +1,12 @@
|
||||
import { CONTEXT_TASK_STATUSES, CaseDetail } from './../screens/caseDetails/interface';
|
||||
import { CaseDetail } from './../screens/caseDetails/interface';
|
||||
import { AnswerType } from '../components/form/interface';
|
||||
import OfflineImageDAO from '../wmDB/dao/OfflineImageDAO';
|
||||
import {
|
||||
CaseAllocationType,
|
||||
IAvCasePayload,
|
||||
IAvTaskFeedbackItem,
|
||||
IQuestionContextOutput,
|
||||
TaskTitle,
|
||||
} from '../screens/allCases/interface';
|
||||
import { IQuestionContextOutput } from '../screens/allCases/interface';
|
||||
import Geolocation from 'react-native-geolocation-service';
|
||||
|
||||
const AV_TEMPLATE_VERSION_NUMBER = 3;
|
||||
import store from '@store';
|
||||
import RNFS from 'react-native-fs';
|
||||
import { addClickstreamEvent } from './clickstreamEventService';
|
||||
import { CLICKSTREAM_EVENT_NAMES } from '@common/Constants';
|
||||
import ImageResizer from '@bam.tech/react-native-image-resizer';
|
||||
|
||||
interface QuestionContext {
|
||||
answer: string;
|
||||
@@ -36,8 +32,18 @@ interface Answer {
|
||||
allocationReferenceId: string;
|
||||
}
|
||||
|
||||
export const extractQuestionContext = async (answer: Answer): Promise<IQuestionContextOutput[]> => {
|
||||
const IMAGE_QUALITY = 50;
|
||||
const MAX_WIDTH = 500;
|
||||
const MAX_HEIGHT = 500;
|
||||
|
||||
export const extractQuestionContext = async (
|
||||
answer: Answer,
|
||||
caseReferenceId: string
|
||||
): Promise<IQuestionContextOutput[] | null> => {
|
||||
const questionContexts: IQuestionContextOutput[] = [];
|
||||
let isBase64ImageAvailable = true;
|
||||
const docsData =
|
||||
store?.getState()?.feedbackImages?.intermediateDocsToBeUploaded?.[caseReferenceId]?.documents;
|
||||
const { widgetContext } = answer;
|
||||
|
||||
for (const widgetKey in widgetContext) {
|
||||
@@ -64,12 +70,27 @@ export const extractQuestionContext = async (answer: Answer): Promise<IQuestionC
|
||||
answer = { ...answer, type: AnswerType.text };
|
||||
}
|
||||
if (answer.type === AnswerType.image && answer.answer?.length) {
|
||||
const offlineImageId = answer.answer;
|
||||
const data = await getBase64ImageFromOfflineDb(offlineImageId);
|
||||
answer = {
|
||||
...answer,
|
||||
answer: data,
|
||||
};
|
||||
const imageData = docsData?.[questionKey];
|
||||
try {
|
||||
const response = await ImageResizer.createResizedImage(
|
||||
imageData?.fileUri ?? '',
|
||||
MAX_WIDTH,
|
||||
MAX_HEIGHT,
|
||||
'JPEG',
|
||||
IMAGE_QUALITY,
|
||||
undefined,
|
||||
undefined,
|
||||
true
|
||||
);
|
||||
const base64Image = await RNFS.readFile(response?.uri, 'base64');
|
||||
answer = {
|
||||
...answer,
|
||||
answer: `data:image/jpeg;base64,${base64Image}`,
|
||||
};
|
||||
} catch (error) {
|
||||
isBase64ImageAvailable = false;
|
||||
addClickstreamEvent(CLICKSTREAM_EVENT_NAMES.FA_FEEDBACK_IMAGE_NOT_FOUND, { error });
|
||||
}
|
||||
}
|
||||
questionContexts.push({
|
||||
answerContextDTO: answer,
|
||||
@@ -79,16 +100,15 @@ export const extractQuestionContext = async (answer: Answer): Promise<IQuestionC
|
||||
}
|
||||
}
|
||||
|
||||
if (!isBase64ImageAvailable) return null;
|
||||
return questionContexts;
|
||||
};
|
||||
|
||||
export const getImageFromDB = async (imageId: string) => {
|
||||
let imageList = await OfflineImageDAO.getImage(imageId);
|
||||
// returns the latest image in the database
|
||||
return imageList?.[0];
|
||||
}
|
||||
|
||||
export const getImageHeightWrtAspectRatio = (imageWidth: number, imageHeight: number, requiredImageWidth: number) => {
|
||||
export const getImageHeightWrtAspectRatio = (
|
||||
imageWidth: number,
|
||||
imageHeight: number,
|
||||
requiredImageWidth: number
|
||||
) => {
|
||||
if (!imageWidth || !imageHeight) {
|
||||
return 0;
|
||||
}
|
||||
@@ -96,16 +116,6 @@ export const getImageHeightWrtAspectRatio = (imageWidth: number, imageHeight: nu
|
||||
return requiredImageWidth * aspectRatio;
|
||||
};
|
||||
|
||||
export const getBase64ImageFromOfflineDb = async (imageId: string) => {
|
||||
let imageList = await OfflineImageDAO.getImage(imageId);
|
||||
return imageList?.[0]?.imageData;
|
||||
};
|
||||
|
||||
export const getOriginalImageFromOfflineDb = async (imageId: string) => {
|
||||
let imageList = await OfflineImageDAO.getImage(imageId);
|
||||
return imageList?.[0]?.originalImageUri;
|
||||
};
|
||||
|
||||
export interface IGetTransformedCaseItem extends CaseDetail {
|
||||
answer: any;
|
||||
caseId: string;
|
||||
@@ -118,7 +128,10 @@ export const getTransformedCollectionCaseItem = async (
|
||||
forceSubmit = false
|
||||
) => {
|
||||
let cloneCaseItem = { ...caseItem };
|
||||
let answerContextArray = await extractQuestionContext(cloneCaseItem?.answer);
|
||||
let answerContextArray = await extractQuestionContext(
|
||||
cloneCaseItem?.answer,
|
||||
caseItem?.caseReferenceId
|
||||
);
|
||||
let data = {
|
||||
caseReferenceId: caseItem.caseReferenceId,
|
||||
answers: answerContextArray,
|
||||
@@ -129,42 +142,3 @@ export const getTransformedCollectionCaseItem = async (
|
||||
};
|
||||
return { caseType: caseItem.caseType, data, forceSubmit };
|
||||
};
|
||||
|
||||
export const getTransformedAvCase = async (
|
||||
caseItem: IGetTransformedCaseItem,
|
||||
templateId: string
|
||||
) => {
|
||||
const { caseType, allocationReferenceId, caseId, coords } = caseItem;
|
||||
const transformedAvCase: IAvCasePayload = {
|
||||
caseType: caseType || CaseAllocationType.ADDRESS_VERIFICATION_CASE,
|
||||
data: {
|
||||
version: AV_TEMPLATE_VERSION_NUMBER,
|
||||
templateId,
|
||||
allocationReferenceId: allocationReferenceId as string,
|
||||
taskFeedbacks: [],
|
||||
},
|
||||
};
|
||||
const taskContext = caseItem?.context?.taskContext;
|
||||
for (let taskId in taskContext) {
|
||||
const taskItems: any[] = taskContext[taskId];
|
||||
for (const taskItem of taskItems) {
|
||||
const { taskStatus, createdAt } = taskItem;
|
||||
if (taskId !== TaskTitle.CALLING_TASK && taskStatus === CONTEXT_TASK_STATUSES.OPEN) continue;
|
||||
|
||||
let taskFeedbackItem: IAvTaskFeedbackItem = {
|
||||
taskType: taskId as TaskTitle,
|
||||
location: coords,
|
||||
answers: [],
|
||||
taskStatus,
|
||||
capturedAt: createdAt || new Date().getTime(),
|
||||
};
|
||||
|
||||
const answersList = await extractQuestionContext(taskItem);
|
||||
if (!answersList.length) continue;
|
||||
|
||||
taskFeedbackItem.answers = answersList;
|
||||
transformedAvCase.data.taskFeedbacks.push(taskFeedbackItem);
|
||||
}
|
||||
}
|
||||
return transformedAvCase;
|
||||
};
|
||||
|
||||
@@ -1,15 +1,11 @@
|
||||
import { ApiKeys, API_URLS } from './../components/utlis/apiHelper';
|
||||
import { API_URLS } from './../components/utlis/apiHelper';
|
||||
import {
|
||||
getAppVersion,
|
||||
getEventNameFromAPIKey,
|
||||
getKeyByValue,
|
||||
getParamsObject,
|
||||
} from './../components/utlis/commonFunctions';
|
||||
import React from 'react';
|
||||
import axiosInstance from '../components/utlis/apiHelper';
|
||||
import { getNetInfo } from '../components/utlis/commonFunctions';
|
||||
import { GLOBAL } from '../constants/Global';
|
||||
import ClickStreamEventsDAO, { IClickstreamEvent } from '../wmDB/dao/ClickStreamEventsDAO';
|
||||
import {
|
||||
NetInfoCellularGeneration,
|
||||
NetInfoState,
|
||||
@@ -23,8 +19,20 @@ import { SCREEN_HEIGHT, SCREEN_WIDTH } from '@rn-ui-lib/styles';
|
||||
|
||||
export type ClickstreamDesc = { name: string; description: string };
|
||||
|
||||
export interface IClickstreamEvent {
|
||||
event_name: string;
|
||||
description: string;
|
||||
timestamp: number;
|
||||
agentId: string;
|
||||
deviceId: string;
|
||||
attributes?: unknown;
|
||||
networkStatus: string;
|
||||
appVersion: string;
|
||||
isOnline: boolean;
|
||||
batteryLevel: string;
|
||||
}
|
||||
|
||||
const MAX_BUFFER_SIZE_FOR_API = 10;
|
||||
const MAX_BUFFER_SIZE_FOR_DB_WRITE = 20;
|
||||
|
||||
let eventsList: IClickstreamEvent[] = [];
|
||||
let bufferEventsList: IClickstreamEvent[] = [];
|
||||
@@ -48,9 +56,6 @@ const addEvent = async (networkStatus: string) => {
|
||||
if (eventsList.length > MAX_BUFFER_SIZE_FOR_API) {
|
||||
if (networkStatus !== 'offline') {
|
||||
fireClickstreamEvents();
|
||||
} else if (eventsList.length > MAX_BUFFER_SIZE_FOR_DB_WRITE) {
|
||||
await ClickStreamEventsDAO.addEventsBulk(eventsList);
|
||||
eventsList = [];
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -122,40 +127,9 @@ const fireClickstreamEvents = async () => {
|
||||
const url = JANUS_SERVICE_URL;
|
||||
bufferEventsList = [...eventsList];
|
||||
eventsList = [];
|
||||
const payload = await getPayload(bufferEventsList);
|
||||
|
||||
const clickstreamEventsFromDB = await ClickStreamEventsDAO.getAllEvents();
|
||||
|
||||
const events = clickstreamEventsFromDB
|
||||
.map((item: IClickstreamEvent) => {
|
||||
const {
|
||||
deviceId,
|
||||
agentId,
|
||||
event_name,
|
||||
attributes,
|
||||
timestamp,
|
||||
networkStatus,
|
||||
appVersion,
|
||||
isOnline,
|
||||
batteryLevel,
|
||||
} = item;
|
||||
return {
|
||||
deviceId,
|
||||
agentId,
|
||||
event_name,
|
||||
attributes,
|
||||
timestamp,
|
||||
networkStatus,
|
||||
appVersion,
|
||||
isOnline,
|
||||
batteryLevel,
|
||||
};
|
||||
})
|
||||
.concat(bufferEventsList);
|
||||
const payload = await getPayload(events);
|
||||
|
||||
axiosInstance
|
||||
.post(url, payload, { headers: { donotHandleError: true } })
|
||||
.then(() => ClickStreamEventsDAO.deleteAllEvents());
|
||||
axiosInstance.post(url, payload, { headers: { donotHandleError: true } });
|
||||
};
|
||||
|
||||
export const sendApiToClickstreamEvent = (
|
||||
@@ -171,7 +145,7 @@ export const sendApiToClickstreamEvent = (
|
||||
const eventName = getEventNameFromAPIKey(apiKey, isSuccess);
|
||||
addClickstreamEvent(
|
||||
{ name: eventName, description: eventName },
|
||||
{ timeTaken: milliseconds, statusCode, response: statusCode === 400 ? response : '' }
|
||||
{ timeTaken: milliseconds, statusCode, response: statusCode === 400 ? response : '' }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
export enum TableName {
|
||||
OFFLINE_IMAGES = 'offline_image',
|
||||
CUSTOMER_IMAGE = 'customer_image',
|
||||
CLICKSTREAM_EVENTS = 'clickstream_events',
|
||||
}
|
||||
|
||||
export const DB_VERSION = 6;
|
||||
|
||||
export const DB_NAME = 'AVAPP';
|
||||
@@ -1,116 +0,0 @@
|
||||
import { database } from '../db';
|
||||
import { Q } from '@nozbe/watermelondb';
|
||||
import { TableName } from '../const';
|
||||
import { logError } from '../../components/utlis/errorUtils';
|
||||
|
||||
const clickStreamEvents = database.get(TableName.CLICKSTREAM_EVENTS);
|
||||
|
||||
export interface IClickstreamEvent {
|
||||
event_name: string;
|
||||
description: string;
|
||||
timestamp: number;
|
||||
agentId: string;
|
||||
deviceId: string;
|
||||
attributes?: unknown;
|
||||
networkStatus: string;
|
||||
appVersion: string;
|
||||
isOnline: boolean;
|
||||
batteryLevel: string;
|
||||
}
|
||||
|
||||
export default {
|
||||
observeOfflineImage: () => clickStreamEvents.query().observe(),
|
||||
addEvent: async (
|
||||
event_name: string,
|
||||
timestamp: number,
|
||||
description: string,
|
||||
agentId: string,
|
||||
deviceId: string,
|
||||
attributes: any,
|
||||
networkStatus: string,
|
||||
appVersion: string,
|
||||
isOnline: boolean,
|
||||
batteryLevel: string
|
||||
) => {
|
||||
try {
|
||||
return await database.action(async () => {
|
||||
return await clickStreamEvents.create((event: any) => {
|
||||
event.event_name = event_name;
|
||||
event.description = description;
|
||||
event.timestamp = timestamp;
|
||||
event.deviceId = deviceId;
|
||||
event.agentId = agentId;
|
||||
event.attributes = attributes;
|
||||
event.networkStatus = networkStatus;
|
||||
event.appVersion = appVersion;
|
||||
event.isOnline = isOnline;
|
||||
event.batteryLevel = batteryLevel;
|
||||
});
|
||||
});
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
},
|
||||
addEventsBulk: async (events: Array<IClickstreamEvent>) => {
|
||||
function prepareInsertion(events: Array<IClickstreamEvent>) {
|
||||
return events.map((clickStreamEvent) => {
|
||||
const {
|
||||
event_name,
|
||||
deviceId,
|
||||
attributes,
|
||||
agentId,
|
||||
timestamp,
|
||||
description,
|
||||
networkStatus,
|
||||
isOnline,
|
||||
appVersion,
|
||||
batteryLevel,
|
||||
} = clickStreamEvent;
|
||||
try {
|
||||
return clickStreamEvents.prepareCreate((event: any) => {
|
||||
event.event_name = event_name;
|
||||
event.description = description;
|
||||
event.timestamp = timestamp;
|
||||
event.deviceId = deviceId;
|
||||
event.agentId = agentId;
|
||||
event.attributes = attributes;
|
||||
event.networkStatus = networkStatus;
|
||||
event.isOnline = isOnline;
|
||||
event.appVersion = appVersion;
|
||||
event.batteryLevel = batteryLevel;
|
||||
});
|
||||
} catch (e) {
|
||||
logError(e as Error, 'WM DB');
|
||||
}
|
||||
});
|
||||
}
|
||||
try {
|
||||
return await database.action(async () => {
|
||||
const allRecords = prepareInsertion(events);
|
||||
await database.batch(...allRecords);
|
||||
});
|
||||
} catch (e) {
|
||||
logError(e as Error, 'WM DB');
|
||||
}
|
||||
},
|
||||
getAllEvents: async () => {
|
||||
try {
|
||||
return await database.action(async () => {
|
||||
return await clickStreamEvents.query().fetch();
|
||||
});
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
return;
|
||||
}
|
||||
},
|
||||
deleteAllEvents: async () => {
|
||||
try {
|
||||
return await database.action(async () => {
|
||||
await clickStreamEvents.query().destroyAllPermanently();
|
||||
});
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
return;
|
||||
}
|
||||
},
|
||||
};
|
||||
@@ -1,93 +0,0 @@
|
||||
import { database } from '../db';
|
||||
import { Q } from '@nozbe/watermelondb';
|
||||
import { TableName } from '../const';
|
||||
import { logError } from '../../components/utlis/errorUtils';
|
||||
|
||||
const customerImage = database.get(TableName.CUSTOMER_IMAGE);
|
||||
|
||||
interface ICustomerOfflineImage {
|
||||
caseId: string;
|
||||
imageURL: string;
|
||||
image64: string;
|
||||
}
|
||||
|
||||
export default {
|
||||
observeOfflineImage: () => customerImage.query().observe(),
|
||||
addBulkCustomerImage: async (customerImageList: ICustomerOfflineImage[]) => {
|
||||
function prepareInsertion(customerImageList: ICustomerOfflineImage[]) {
|
||||
return customerImageList.map((customerImageItem) => {
|
||||
try {
|
||||
return customerImage.prepareCreate((imageRow: any) => {
|
||||
imageRow.caseId = customerImageItem.caseId;
|
||||
imageRow.imageURL = customerImageItem.imageURL;
|
||||
imageRow.image64 = customerImageItem.image64;
|
||||
});
|
||||
} catch (e) {
|
||||
logError(e as Error, 'WM DB');
|
||||
}
|
||||
});
|
||||
}
|
||||
try {
|
||||
return await database.action(async () => {
|
||||
const allRecords = prepareInsertion(customerImageList);
|
||||
await database.batch(...allRecords);
|
||||
});
|
||||
} catch (e) {
|
||||
logError(e as Error, 'WM DB');
|
||||
}
|
||||
},
|
||||
addCustomerImage: async (customerImageItem: ICustomerOfflineImage) => {
|
||||
try {
|
||||
return await database.action(async () => {
|
||||
return await customerImage.create((imageRow: any) => {
|
||||
imageRow.caseId = customerImageItem.caseId;
|
||||
imageRow.imageURL = customerImageItem.imageURL;
|
||||
imageRow.image64 = customerImageItem.image64;
|
||||
});
|
||||
});
|
||||
} catch (e) {
|
||||
logError(e as Error, 'WM DB');
|
||||
}
|
||||
},
|
||||
getImageByURL: async (imageURL: string) => {
|
||||
try {
|
||||
return await database.action(async () => {
|
||||
return await customerImage.query(Q.where('image_url', imageURL), Q.take(1)).fetch();
|
||||
});
|
||||
} catch (e) {
|
||||
logError(e as Error, 'WM DB');
|
||||
return;
|
||||
}
|
||||
},
|
||||
getImageByCase: async (caseId: string) => {
|
||||
try {
|
||||
return await database.action(async () => {
|
||||
return await customerImage.query(Q.where('case_id', caseId), Q.take(1)).fetch();
|
||||
});
|
||||
} catch (e) {
|
||||
logError(e as Error, 'WM DB');
|
||||
return;
|
||||
}
|
||||
},
|
||||
deleteImages: async (caseIds: Array<string> | string) => {
|
||||
let tCaseIds = Array.isArray(caseIds) ? caseIds : [caseIds];
|
||||
try {
|
||||
return await database.action(async () => {
|
||||
await customerImage.query(Q.where('case_id', Q.oneOf(tCaseIds))).destroyAllPermanently();
|
||||
});
|
||||
} catch (e) {
|
||||
logError(e as Error, 'WM DB');
|
||||
return;
|
||||
}
|
||||
},
|
||||
deleteAll: async () => {
|
||||
try {
|
||||
return await database.action(async () => {
|
||||
await customerImage.query().destroyAllPermanently();
|
||||
});
|
||||
} catch (e) {
|
||||
logError(e as Error, 'WM DB');
|
||||
return;
|
||||
}
|
||||
},
|
||||
};
|
||||
@@ -1,60 +0,0 @@
|
||||
import { database } from '../db';
|
||||
import { Q } from '@nozbe/watermelondb';
|
||||
import { TableName } from '../const';
|
||||
|
||||
const offlineImage = database.get(TableName.OFFLINE_IMAGES);
|
||||
|
||||
export default {
|
||||
observeOfflineImage: () => offlineImage.query().observe(),
|
||||
addImage: async (
|
||||
imageData: string,
|
||||
originalImageUri: string,
|
||||
imageIdx: string,
|
||||
imageWidth: number,
|
||||
imageHeight: number
|
||||
) => {
|
||||
try {
|
||||
return await database.action(async () => {
|
||||
return await offlineImage.create((image: any) => {
|
||||
image.idx = imageIdx;
|
||||
image.imageData = imageData;
|
||||
image.originalImageUri = originalImageUri;
|
||||
image.imageWidth = imageWidth;
|
||||
image.imageHeight = imageHeight;
|
||||
});
|
||||
});
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
},
|
||||
getImage: async (imageId: string) => {
|
||||
try {
|
||||
return await database.action(async () => {
|
||||
return await offlineImage.query(Q.where('idx', imageId), Q.take(1)).fetch();
|
||||
});
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
return;
|
||||
}
|
||||
},
|
||||
deleteImages: async (imageIdList: Array<string>) => {
|
||||
try {
|
||||
return await database.action(async () => {
|
||||
await offlineImage.query(Q.where('idx', Q.oneOf(imageIdList))).destroyAllPermanently();
|
||||
});
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
return;
|
||||
}
|
||||
},
|
||||
deleteAll: async () => {
|
||||
try {
|
||||
return await database.action(async () => {
|
||||
await offlineImage.query().destroyAllPermanently();
|
||||
});
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
return;
|
||||
}
|
||||
},
|
||||
};
|
||||
@@ -1,20 +0,0 @@
|
||||
import { Database } from '@nozbe/watermelondb';
|
||||
import SQLiteAdapter from '@nozbe/watermelondb/adapters/sqlite';
|
||||
import { DB_NAME } from './const';
|
||||
import ClickstreamEvents from './model/ClickstreamEvents';
|
||||
import CustomerImage from './model/CustomerImage';
|
||||
import OfflineImage from './model/OfflineImage';
|
||||
|
||||
import schema from './schema';
|
||||
|
||||
const adapter = new SQLiteAdapter({
|
||||
dbName: DB_NAME,
|
||||
schema,
|
||||
});
|
||||
|
||||
const database = new Database({
|
||||
adapter,
|
||||
modelClasses: [OfflineImage, CustomerImage, ClickstreamEvents],
|
||||
});
|
||||
|
||||
export { database };
|
||||
@@ -1,6 +0,0 @@
|
||||
import PostDAO from './dao/OfflineImageDAO';
|
||||
import CustomerImageDAO from './dao/CustomerImageDAO';
|
||||
import ClickstreamDAO from './dao/ClickStreamEventsDAO';
|
||||
|
||||
export { database } from './db';
|
||||
export { PostDAO, CustomerImageDAO, ClickstreamDAO };
|
||||
@@ -1,20 +0,0 @@
|
||||
import { Model } from '@nozbe/watermelondb';
|
||||
import { field, json } from '@nozbe/watermelondb/decorators';
|
||||
import { TableName } from '../const';
|
||||
|
||||
const sanitizeAttributes = (json: any) => json;
|
||||
|
||||
export default class ClickstreamEvents extends Model {
|
||||
static table = TableName.CLICKSTREAM_EVENTS;
|
||||
|
||||
@field('event_name') event_name!: string;
|
||||
@field('description') description!: string;
|
||||
@field('agent_id') agentId!: string;
|
||||
@field('device_id') deviceId!: string;
|
||||
@field('network_status') networkStatus!: string;
|
||||
@field('timestamp') timestamp!: number;
|
||||
@json('attributes', sanitizeAttributes) attributes: any;
|
||||
@field('app_version') appVersion!: string;
|
||||
@field('is_online') isOnline!: boolean;
|
||||
@field('battery_level') batteryLevel!: string;
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
import { Model } from '@nozbe/watermelondb';
|
||||
import { field, readonly, date } from '@nozbe/watermelondb/decorators';
|
||||
import { TableName } from '../const';
|
||||
|
||||
export default class CustomerImage extends Model {
|
||||
static table = TableName.CUSTOMER_IMAGE;
|
||||
|
||||
@field('case_id') caseId!: string;
|
||||
@field('image_url') imageURL!: string;
|
||||
@field('image_64') image64!: string;
|
||||
@readonly @date('created_at') createdAt!: any;
|
||||
@readonly @date('updated_at') updatedAt!: any;
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
import { Model } from '@nozbe/watermelondb';
|
||||
import { field, readonly, date } from '@nozbe/watermelondb/decorators';
|
||||
import { TableName } from '../const';
|
||||
|
||||
export default class OfflineImage extends Model {
|
||||
static table = TableName.OFFLINE_IMAGES;
|
||||
|
||||
@field('idx') idx!: string;
|
||||
@field('image_data') imageData!: string;
|
||||
@field('original_image_uri') originalImageUri!: string;
|
||||
@field('image_width') imageWidth!: string;
|
||||
@field('image_height') imageHeight!: string;
|
||||
@readonly @date('created_at') createdAt!: any;
|
||||
@readonly @date('updated_at') updatedAt!: any;
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
import { appSchema, tableSchema } from '@nozbe/watermelondb';
|
||||
import { DB_VERSION, TableName } from './const';
|
||||
|
||||
export default appSchema({
|
||||
version: DB_VERSION,
|
||||
tables: [
|
||||
tableSchema({
|
||||
name: TableName.OFFLINE_IMAGES,
|
||||
columns: [
|
||||
{ name: 'idx', type: 'string' },
|
||||
{ name: 'image_data', type: 'string' },
|
||||
{ name: 'original_image_uri', type: 'string' },
|
||||
{ name: 'image_width', type: 'string' },
|
||||
{ name: 'image_height', type: 'string' },
|
||||
],
|
||||
}),
|
||||
tableSchema({
|
||||
name: TableName.CUSTOMER_IMAGE,
|
||||
columns: [
|
||||
{ name: 'case_id', type: 'string' },
|
||||
{ name: 'image_url', type: 'string' },
|
||||
{ name: 'image_64', type: 'string' },
|
||||
],
|
||||
}),
|
||||
tableSchema({
|
||||
name: TableName.CLICKSTREAM_EVENTS,
|
||||
columns: [
|
||||
{ name: 'event_name', type: 'string' },
|
||||
{ name: 'description', type: 'string' },
|
||||
{ name: 'agent_id', type: 'string' },
|
||||
{ name: 'device_id', type: 'string' },
|
||||
{ name: 'attributes', type: 'string' },
|
||||
{ name: 'network_status', type: 'string' },
|
||||
{ name: 'timestamp', type: 'number' },
|
||||
],
|
||||
}),
|
||||
],
|
||||
});
|
||||
Reference in New Issue
Block a user