Original Image Load Fix, clean code, improve defination of useFetchDocument hook (move onSuccess logic to the hook) (#202)
* TP-23666 | Original Image caching Fix + improve useFetchDocument Hook * TP-23666 | QA bug fixes
This commit is contained in:
committed by
GitHub Enterprise
parent
a87f3cfa11
commit
0e4189a6c8
@@ -1,6 +1,6 @@
|
||||
import AsyncStorage from '@react-native-async-storage/async-storage';
|
||||
import RNFetchBlob from "rn-fetch-blob";
|
||||
import { Address, PhoneNumber, TDocumentObj } from "../../screens/caseDetails/interface";
|
||||
import { Address, DOCUMENT_TYPE, IDocument, PhoneNumber, TDocumentObj } from "../../screens/caseDetails/interface";
|
||||
import { getPrefixBase64Image, LocalStorageKeys, MimeType } from "../../common/Constants";
|
||||
import NetInfo from "@react-native-community/netinfo";
|
||||
import Clipboard from '@react-native-clipboard/clipboard';
|
||||
@@ -12,6 +12,7 @@ import { GenericType } from '../../common/GenericTypes';
|
||||
import { CaseDetail } from '../../screens/caseDetails/interface';
|
||||
import { logError } from './errorUtils';
|
||||
import packageJson from '../../../package.json';
|
||||
import { CaseAllocationType } from '../../screens/allCases/interface';
|
||||
|
||||
|
||||
const fs = RNFetchBlob.fs;
|
||||
@@ -19,7 +20,8 @@ const fs = RNFetchBlob.fs;
|
||||
const RespHeaderContentTypeKey = 'Content-Type';
|
||||
const DEFAULT_TEXT = '--';
|
||||
const MAX_SHEET_HEIGHT_PERCENTAGE = 50;
|
||||
const RELATIVE_PATH_PREFIX = 'file://';
|
||||
|
||||
export const RELATIVE_PATH_PREFIX = 'file://';
|
||||
|
||||
|
||||
export const decideLoadingState = (textData: string): boolean => {
|
||||
@@ -88,7 +90,7 @@ export const fetchCopiedText = async () => {
|
||||
|
||||
export const setAsyncStorageItem = async (key: string, value: any) => {
|
||||
try {
|
||||
const stringifiedValue = stringify(value);
|
||||
const stringifiedValue = JSON.stringify(value);
|
||||
await AsyncStorage.setItem(key, stringifiedValue);
|
||||
} catch(err) {
|
||||
console.error('JSON stringify errored',err);
|
||||
@@ -177,4 +179,14 @@ export const getLoanAccountNumber = (caseDetail: CaseDetail) => {
|
||||
|
||||
export function getAppVersion(): string {
|
||||
return packageJson.version;
|
||||
}
|
||||
}
|
||||
|
||||
export const getDocumentList = (caseDetails: CaseDetail) => {
|
||||
return caseDetails.caseType === CaseAllocationType.ADDRESS_VERIFICATION_CASE ?
|
||||
caseDetails.customerInfo?.documents :
|
||||
caseDetails.documents;
|
||||
}
|
||||
|
||||
export const findDocumentByDocumentType = (documentList: IDocument[] = [], documentType: DOCUMENT_TYPE) => {
|
||||
return documentList?.find((documentItem) => documentItem.type === documentType);
|
||||
}
|
||||
|
||||
@@ -1,23 +1,14 @@
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
import { saveToGlobalDocumentMap, storeImageLocallyReturnRelativePath } from '../components/utlis/commonFunctions';
|
||||
import { CaseDetail, DOCUMENT_TYPE, IDocument, TDocumentObj } from '../screens/caseDetails/interface';
|
||||
import { findDocumentByDocumentType, getDocumentList, RELATIVE_PATH_PREFIX,
|
||||
saveToGlobalDocumentMap, storeImageLocallyReturnRelativePath } from '../components/utlis/commonFunctions';
|
||||
import { CaseDetail, DOCUMENT_TYPE, TDocumentObj } from '../screens/caseDetails/interface';
|
||||
import { getSignedApi, ISignedRequest } from '../action/dataActions';
|
||||
import { GlobalDocumentMap } from '../../App';
|
||||
import { CaseAllocationType } from '../screens/allCases/interface';
|
||||
|
||||
const findDocumentByDocumentType = (documentList: IDocument[] = [], documentType: DOCUMENT_TYPE) => {
|
||||
return documentList?.find((documentItem) => documentItem.type === documentType);
|
||||
}
|
||||
|
||||
const getDocumentList = (caseDetails: CaseDetail) => {
|
||||
return caseDetails.caseType === CaseAllocationType.ADDRESS_VERIFICATION_CASE ?
|
||||
caseDetails.customerInfo?.documents :
|
||||
caseDetails.documents;
|
||||
}
|
||||
|
||||
const getDocumentUrlFromCaseDetails = (caseDetails: CaseDetail, documentType: DOCUMENT_TYPE) => {
|
||||
if (caseDetails?.id && caseDetails.id in GlobalDocumentMap) {
|
||||
return GlobalDocumentMap[caseDetails.id]?.[documentType];
|
||||
if (GlobalDocumentMap?.[caseDetails?.id]?.[documentType]) {
|
||||
return GlobalDocumentMap[caseDetails.id][documentType];
|
||||
}
|
||||
|
||||
const documentList = getDocumentList(caseDetails);
|
||||
@@ -40,74 +31,102 @@ const useFetchDocument = (caseDetails: CaseDetail, documentTypeList: DOCUMENT_TY
|
||||
|
||||
const apiInProgressReferenceIds = useRef<string[]>([]);
|
||||
|
||||
const [retryForDocumentType, setRetryForDocumentType] = useState<DOCUMENT_TYPE>();
|
||||
const [retryForDocuments, setRetryForDocuments] = useState<DOCUMENT_TYPE[]>([]);
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (!retryForDocumentType) return;
|
||||
if (enableCaching) {
|
||||
let localDocumentObj = { ...documentObj } as TDocumentObj;
|
||||
(async () => {
|
||||
(async () => {
|
||||
for (const [documentType, documentValue] of Object.entries(localDocumentObj)) {
|
||||
if (documentValue && documentType in DOCUMENT_TYPE && !documentValue?.startsWith(RELATIVE_PATH_PREFIX)) {
|
||||
const localImagePath = await storeImageLocallyReturnRelativePath(documentValue);
|
||||
localDocumentObj = {
|
||||
...localDocumentObj,
|
||||
[documentType]: localImagePath
|
||||
}
|
||||
}
|
||||
}
|
||||
})().then(async () => {
|
||||
setDocumentObj(localDocumentObj);
|
||||
})
|
||||
})();
|
||||
}
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (enableCaching && documentObj) {
|
||||
(async () => {
|
||||
await saveToGlobalDocumentMap(caseDetails?.id, documentObj);
|
||||
})();
|
||||
}
|
||||
}, [documentObj, enableCaching]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!retryForDocuments?.length) return;
|
||||
|
||||
const documentList = getDocumentList(caseDetails);
|
||||
const imageReferenceId = findDocumentByDocumentType(documentList, retryForDocumentType)?.referenceId;
|
||||
(async () => {
|
||||
if (!imageReferenceId) {
|
||||
setDocumentObj({
|
||||
...documentObj,
|
||||
[retryForDocumentType]: ''
|
||||
})
|
||||
return;
|
||||
}
|
||||
let imageReferenceId: string | undefined;
|
||||
|
||||
if (apiInProgressReferenceIds.current.includes(imageReferenceId)) return;
|
||||
for (let retryForDocumentsItem of retryForDocuments) {
|
||||
imageReferenceId = findDocumentByDocumentType(documentList, retryForDocumentsItem)?.referenceId;
|
||||
|
||||
apiInProgressReferenceIds.current.push(imageReferenceId);
|
||||
|
||||
const signedRequestPayload: ISignedRequest = [
|
||||
{
|
||||
documentReferenceId: imageReferenceId,
|
||||
caseId: caseDetails.id,
|
||||
caseType: caseDetails.caseType,
|
||||
},
|
||||
];
|
||||
|
||||
setLoading(true);
|
||||
const response = await getSignedApi(signedRequestPayload);
|
||||
setLoading(false);
|
||||
|
||||
const url = response?.imageUrl;
|
||||
|
||||
if (!url) {
|
||||
setDocumentObj({
|
||||
...documentObj,
|
||||
[retryForDocumentType]: ''
|
||||
})
|
||||
return;
|
||||
}
|
||||
|
||||
const localImagePath = await storeImageLocallyReturnRelativePath(url);
|
||||
|
||||
if (localImagePath) {
|
||||
setDocumentObj({
|
||||
...documentObj,
|
||||
[retryForDocumentType]: localImagePath
|
||||
});
|
||||
if (enableCaching) {
|
||||
saveToGlobalDocumentMap(caseDetails?.id, {
|
||||
(async () => {
|
||||
if (!imageReferenceId) {
|
||||
setDocumentObj(documentObj => ({
|
||||
...documentObj,
|
||||
[retryForDocumentType]: localImagePath
|
||||
})
|
||||
[retryForDocumentsItem]: ''
|
||||
}))
|
||||
return;
|
||||
}
|
||||
}
|
||||
})();
|
||||
|
||||
if (apiInProgressReferenceIds.current.includes(imageReferenceId)) return;
|
||||
|
||||
apiInProgressReferenceIds.current.push(imageReferenceId);
|
||||
|
||||
const signedRequestPayload: ISignedRequest = [
|
||||
{
|
||||
documentReferenceId: imageReferenceId,
|
||||
caseId: caseDetails.id,
|
||||
caseType: caseDetails.caseType,
|
||||
},
|
||||
];
|
||||
|
||||
setLoading(true);
|
||||
const response = await getSignedApi(signedRequestPayload);
|
||||
setLoading(false);
|
||||
const url = response?.imageUrl;
|
||||
|
||||
if (!url) {
|
||||
setDocumentObj(documentObj => ({
|
||||
...documentObj,
|
||||
[retryForDocumentsItem]: ''
|
||||
}))
|
||||
return;
|
||||
}
|
||||
|
||||
const localImagePath = await storeImageLocallyReturnRelativePath(url);
|
||||
|
||||
if (localImagePath) {
|
||||
setDocumentObj(documentObj => ({
|
||||
...documentObj,
|
||||
[retryForDocumentsItem]: localImagePath
|
||||
}));
|
||||
}
|
||||
})();
|
||||
}
|
||||
|
||||
return () => {
|
||||
apiInProgressReferenceIds.current = apiInProgressReferenceIds.current.filter(item => item !== imageReferenceId);
|
||||
}
|
||||
}, [retryForDocumentType]);
|
||||
}, [retryForDocuments]);
|
||||
|
||||
return {
|
||||
documentObj,
|
||||
setDocumentObj,
|
||||
setRetryForUnsignedDocuments: setRetryForDocumentType,
|
||||
retryForUnsignedDocuments: retryForDocumentType,
|
||||
setRetryForUnsignedDocuments: setRetryForDocuments,
|
||||
retryForUnsignedDocuments: retryForDocuments,
|
||||
loading
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
import React from 'react';
|
||||
import { StyleSheet, View } from 'react-native';
|
||||
import { GlobalDocumentMap } from '../../../App';
|
||||
import Avatar from '../../../RN-UI-LIB/src/components/Avatar';
|
||||
import UnsyncedIcon from '../../../RN-UI-LIB/src/Icons/UnsyncedIcon';
|
||||
import { COLORS } from '../../../RN-UI-LIB/src/styles/colors';
|
||||
import { saveToGlobalDocumentMap, storeImageLocallyReturnRelativePath } from '../../components/utlis/commonFunctions';
|
||||
import { useAppSelector } from '../../hooks';
|
||||
import useFetchDocument from '../../hooks/useFetchDocument';
|
||||
import { DOCUMENT_TYPE } from '../caseDetails/interface';
|
||||
@@ -38,8 +36,9 @@ const CaseItemAvatar: React.FC<ICaseItemAvatar> = ({
|
||||
);
|
||||
|
||||
const requiredDocumentTypeList = [DOCUMENT_TYPE.OPTIMIZED_SELFIE];
|
||||
const isPinned = pinnedList.find(item => item.caseReferenceId === referenceId)?.pinRank;
|
||||
|
||||
if (pinnedList.find(item => item.caseReferenceId === referenceId)?.caseReferenceId) {
|
||||
if (isPinned) {
|
||||
requiredDocumentTypeList.push(DOCUMENT_TYPE.SELFIE)
|
||||
}
|
||||
|
||||
@@ -49,21 +48,7 @@ const CaseItemAvatar: React.FC<ICaseItemAvatar> = ({
|
||||
|
||||
const onError = async () => {
|
||||
if (enableRetry) {
|
||||
setRetryForUnsignedDocuments(DOCUMENT_TYPE.OPTIMIZED_SELFIE);
|
||||
}
|
||||
};
|
||||
|
||||
const onImageLoadSuccess = async () => {
|
||||
|
||||
if (!GlobalDocumentMap?.[caseDetails.id]?.[DOCUMENT_TYPE.OPTIMIZED_SELFIE]) {
|
||||
const localImagePath = await storeImageLocallyReturnRelativePath(documentObj[DOCUMENT_TYPE.OPTIMIZED_SELFIE]);
|
||||
|
||||
if (!localImagePath) return;
|
||||
|
||||
saveToGlobalDocumentMap(caseDetails.id, {
|
||||
...GlobalDocumentMap[caseDetails.id],
|
||||
[DOCUMENT_TYPE.OPTIMIZED_SELFIE]: localImagePath
|
||||
})
|
||||
setRetryForUnsignedDocuments(requiredDocumentTypeList);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -82,7 +67,6 @@ const CaseItemAvatar: React.FC<ICaseItemAvatar> = ({
|
||||
onErrorFallback={onError}
|
||||
style={[showBorder && styles.border]}
|
||||
loading={loading}
|
||||
onSuccess={onImageLoadSuccess}
|
||||
/>
|
||||
{!isSynced ? (
|
||||
<View style={styles.unsyncedIcon}>
|
||||
|
||||
@@ -18,8 +18,9 @@ import CloseIcon from '../../../RN-UI-LIB/src/Icons/CloseIcon';
|
||||
import { GenericStyles } from '../../../RN-UI-LIB/src/styles';
|
||||
import { COLORS } from '../../../RN-UI-LIB/src/styles/colors';
|
||||
import { dateFormat } from '../../../RN-UI-LIB/src/utlis/dates';
|
||||
import { decideLoadingState, saveToGlobalDocumentMap, storeImageLocallyReturnRelativePath } from '../../components/utlis/commonFunctions';
|
||||
import { decideLoadingState, findDocumentByDocumentType, getDocumentList, RELATIVE_PATH_PREFIX } from '../../components/utlis/commonFunctions';
|
||||
import useFetchDocument from '../../hooks/useFetchDocument';
|
||||
import useIsOnline from '../../hooks/useIsOnline';
|
||||
import CaseItemAvatar from '../allCases/CaseItemAvatar';
|
||||
import AvCaseData from './AvCaseData';
|
||||
import CollectionCaseData from './CollectionCaseData';
|
||||
@@ -76,22 +77,19 @@ const UserDetailsSection: React.FC<IUserDetailsSection> = props => {
|
||||
caseDetail?.customerInfo?.customerName ||
|
||||
caseDetail?.customerName;
|
||||
|
||||
const onImageLoadSuccess = async () => {
|
||||
if (!GlobalDocumentMap?.[caseDetail?.id]?.[DOCUMENT_TYPE.SELFIE]) {
|
||||
const localImagePath = await storeImageLocallyReturnRelativePath(documentObj[DOCUMENT_TYPE.SELFIE]);
|
||||
|
||||
if (localImagePath) {
|
||||
saveToGlobalDocumentMap(caseDetail.id, {
|
||||
...GlobalDocumentMap[caseDetail.id],
|
||||
[DOCUMENT_TYPE.SELFIE]: localImagePath
|
||||
})
|
||||
};
|
||||
}
|
||||
};
|
||||
const isOnline = useIsOnline();
|
||||
|
||||
const getImageURI = () => {
|
||||
if (!isOnline) {
|
||||
if (documentObj[DOCUMENT_TYPE.SELFIE]?.startsWith(RELATIVE_PATH_PREFIX)) {
|
||||
return documentObj[DOCUMENT_TYPE.SELFIE];
|
||||
}
|
||||
return documentObj[DOCUMENT_TYPE.OPTIMIZED_SELFIE] || '';
|
||||
}
|
||||
|
||||
return documentObj[DOCUMENT_TYPE.SELFIE] ||
|
||||
documentObj[DOCUMENT_TYPE.OPTIMIZED_SELFIE] ||
|
||||
findDocumentByDocumentType(getDocumentList(caseDetail), DOCUMENT_TYPE.SELFIE)?.uri ||
|
||||
'';
|
||||
}
|
||||
|
||||
@@ -208,11 +206,10 @@ const UserDetailsSection: React.FC<IUserDetailsSection> = props => {
|
||||
source={{ uri: getImageURI() }}
|
||||
resizeMode={'stretch'}
|
||||
onError={() => {
|
||||
setRetryForUnsignedDocuments(DOCUMENT_TYPE.SELFIE)
|
||||
setRetryForUnsignedDocuments([DOCUMENT_TYPE.SELFIE])
|
||||
setErrorModalImage(true)
|
||||
}}
|
||||
onLoadEnd={() => {
|
||||
onImageLoadSuccess()
|
||||
setErrorModalImage(false)
|
||||
}}
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user