From 330eb8e1d3191518fba40c27fcf8a7d359262c00 Mon Sep 17 00:00:00 2001 From: yashmantri Date: Wed, 13 Sep 2023 14:13:20 +0530 Subject: [PATCH 01/75] TP-38645 | Show Documents On Customer Profile Screen --- App.tsx | 7 +- android/app/build.gradle | 14 ++ .../main/java/com/avapp/MainApplication.java | 1 + .../com/avapp/ScreenshotBlockerModule.java | 59 +++++ .../avapp/ScreenshotBlockerModulePackage.java | 28 +++ package.json | 1 + src/components/utlis/ScreenshotBlocker.ts | 5 + src/screens/auth/ProtectedRouter.tsx | 11 + .../caseDetails/CollectionCaseDetail.tsx | 6 + src/screens/caseDetails/CustomerProfile.tsx | 206 ++++++------------ src/screens/caseDetails/DocumentDetails.tsx | 131 +++++++++++ .../caseDetails/DocumentImageComponent.tsx | 116 ++++++++++ src/screens/caseDetails/PDFFullScreen.tsx | 74 +++++++ src/screens/caseDetails/interface.ts | 11 + .../caseDetails/utils/documentUtils.tsx | 90 ++++++++ yarn.lock | 38 +++- 16 files changed, 652 insertions(+), 146 deletions(-) create mode 100644 android/app/src/main/java/com/avapp/ScreenshotBlockerModule.java create mode 100644 android/app/src/main/java/com/avapp/ScreenshotBlockerModulePackage.java create mode 100644 src/components/utlis/ScreenshotBlocker.ts create mode 100644 src/screens/caseDetails/DocumentDetails.tsx create mode 100644 src/screens/caseDetails/DocumentImageComponent.tsx create mode 100644 src/screens/caseDetails/PDFFullScreen.tsx create mode 100644 src/screens/caseDetails/utils/documentUtils.tsx diff --git a/App.tsx b/App.tsx index 07a85922..42d56e9b 100644 --- a/App.tsx +++ b/App.tsx @@ -1,4 +1,4 @@ -import React, { useState } from 'react'; +import React, { useEffect, useState } from 'react'; import { AppState, LogBox, @@ -38,6 +38,7 @@ import { import usePolling from './src/hooks/usePolling'; import { MILLISECONDS_IN_A_SECOND } from './RN-UI-LIB/src/utlis/common'; import analytics from '@react-native-firebase/analytics'; +import ScreenshotBlocker from './src/components/utlis/ScreenshotBlocker'; initSentry(); @@ -112,6 +113,10 @@ function App() { active: true, }); + useEffect(() => { + ScreenshotBlocker.unblockScreenshots(); + }, []); + React.useEffect(() => { askForPermissions(); const appStateChange = AppState.addEventListener('change', async (change) => { diff --git a/android/app/build.gradle b/android/app/build.gradle index 848437fe..d69d2728 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -135,6 +135,12 @@ def VERSION_CODE = 83 def VERSION_NAME = "2.3.10" android { + packagingOptions { + pickFirst 'lib/x86/libc++_shared.so' + pickFirst 'lib/x86_64/libc++_shared.so' + pickFirst 'lib/armeabi-v7a/libc++_shared.so' + pickFirst 'lib/arm64-v8a/libc++_shared.so' + } ndkVersion rootProject.ext.ndkVersion compileSdkVersion rootProject.ext.compileSdkVersion @@ -217,10 +223,18 @@ android { } signingConfigs { debug { + if (project.hasProperty('MYAPP_UPLOAD_STORE_FILE')) { + storeFile file(MYAPP_UPLOAD_STORE_FILE) + storePassword MYAPP_UPLOAD_STORE_PASSWORD + keyAlias MYAPP_UPLOAD_KEY_ALIAS + keyPassword MYAPP_UPLOAD_KEY_PASSWORD + } + else { storeFile file('debug.keystore') storePassword 'android' keyAlias 'androiddebugkey' keyPassword 'android' + } } release { if (project.hasProperty('MYAPP_UPLOAD_STORE_FILE')) { diff --git a/android/app/src/main/java/com/avapp/MainApplication.java b/android/app/src/main/java/com/avapp/MainApplication.java index 809273f1..d051ff98 100644 --- a/android/app/src/main/java/com/avapp/MainApplication.java +++ b/android/app/src/main/java/com/avapp/MainApplication.java @@ -37,6 +37,7 @@ public class MainApplication extends Application implements ReactApplication { List packages = new PackageList(this).getPackages(); // Packages that cannot be autolinked yet can be added manually here, for example: packages.add(new DeviceUtilsModulePackage()); + packages.add(new ScreenshotBlockerModulePackage()); return packages; } diff --git a/android/app/src/main/java/com/avapp/ScreenshotBlockerModule.java b/android/app/src/main/java/com/avapp/ScreenshotBlockerModule.java new file mode 100644 index 00000000..62280baa --- /dev/null +++ b/android/app/src/main/java/com/avapp/ScreenshotBlockerModule.java @@ -0,0 +1,59 @@ +package com.avapp; + +import android.app.Activity; +import android.view.WindowManager; +import com.facebook.react.bridge.ReactApplicationContext; +import com.facebook.react.bridge.ReactContextBaseJavaModule; +import com.facebook.react.bridge.ReactMethod; +import com.facebook.react.modules.core.DeviceEventManagerModule; + +import android.os.Handler; +import android.os.Looper; + +public class ScreenshotBlockerModule extends ReactContextBaseJavaModule { + private ReactApplicationContext reactContext; + + public ScreenshotBlockerModule(ReactApplicationContext reactContext) { + super(reactContext); + this.reactContext = reactContext; + } + + @Override + public String getName() { + return "ScreenshotBlocker"; + } + + @ReactMethod + public void blockScreenshots() { + new Handler(Looper.getMainLooper()).post(new Runnable() { + Activity activity = getCurrentActivity(); + + @Override + public void run() { + if (activity != null) { + activity.getWindow().setFlags( + WindowManager.LayoutParams.FLAG_SECURE, + WindowManager.LayoutParams.FLAG_SECURE + ); + } + } + }); + } + + @ReactMethod + public void unblockScreenshots() { + new Handler(Looper.getMainLooper()).post(new Runnable() { + Activity activity = getCurrentActivity(); + + @Override + public void run() { + if (activity != null) { + activity.getWindow().clearFlags( + WindowManager.LayoutParams.FLAG_SECURE + ); + } + } + }); + } + +} \ No newline at end of file diff --git a/android/app/src/main/java/com/avapp/ScreenshotBlockerModulePackage.java b/android/app/src/main/java/com/avapp/ScreenshotBlockerModulePackage.java new file mode 100644 index 00000000..f16bdd35 --- /dev/null +++ b/android/app/src/main/java/com/avapp/ScreenshotBlockerModulePackage.java @@ -0,0 +1,28 @@ +package com.avapp; + + +import com.facebook.react.ReactPackage; +import com.facebook.react.bridge.NativeModule; +import com.facebook.react.bridge.ReactApplicationContext; +import com.facebook.react.uimanager.ViewManager; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class ScreenshotBlockerModulePackage implements ReactPackage { + @Override + public List createViewManagers(ReactApplicationContext reactContext) { + return Collections.emptyList(); + } + + @Override + public List createNativeModules( + ReactApplicationContext reactContext) { + List modules = new ArrayList<>(); + + modules.add(new ScreenshotBlockerModule(reactContext)); + + return modules; + } +} \ No newline at end of file diff --git a/package.json b/package.json index 54c608a2..6f3226bf 100644 --- a/package.json +++ b/package.json @@ -67,6 +67,7 @@ "react-native-gzip": "1.0.0", "react-native-image-picker": "4.10.2", "react-native-pager-view": "6.1.2", + "react-native-pdf": "^6.7.1", "react-native-permissions": "3.6.1", "react-native-qrcode-svg": "^6.2.0", "react-native-safe-area-context": "4.4.1", diff --git a/src/components/utlis/ScreenshotBlocker.ts b/src/components/utlis/ScreenshotBlocker.ts new file mode 100644 index 00000000..d0269405 --- /dev/null +++ b/src/components/utlis/ScreenshotBlocker.ts @@ -0,0 +1,5 @@ +import { NativeModules } from 'react-native'; + +const { ScreenshotBlocker } = NativeModules; + +export default ScreenshotBlocker; diff --git a/src/screens/auth/ProtectedRouter.tsx b/src/screens/auth/ProtectedRouter.tsx index e7d4f679..fa0cd8fc 100644 --- a/src/screens/auth/ProtectedRouter.tsx +++ b/src/screens/auth/ProtectedRouter.tsx @@ -32,6 +32,7 @@ import Notifications from '../notifications'; import RegisterPayments from '../registerPayements/RegisterPayments'; import TodoList from '../todoList/TodoList'; import UngroupedAddressContainer from '../addressGeolocation/UngroupedAddressContainer'; +import PDFFullScreen from '../caseDetails/PDFFullScreen'; const Stack = createNativeStackNavigator(); @@ -170,6 +171,16 @@ const ProtectedRouter = () => { }} listeners={getScreenFocusListenerObj} /> + null, + animationDuration: SCREEN_ANIMATION_DURATION, + animation: 'none', + }} + listeners={getScreenFocusListenerObj} + /> = (props) => { }); }; + useFocusEffect(() => { + ScreenshotBlocker.unblockScreenshots(); + }); + return ( diff --git a/src/screens/caseDetails/CustomerProfile.tsx b/src/screens/caseDetails/CustomerProfile.tsx index de202b40..c3376099 100644 --- a/src/screens/caseDetails/CustomerProfile.tsx +++ b/src/screens/caseDetails/CustomerProfile.tsx @@ -1,25 +1,25 @@ -import { ActivityIndicator, Pressable, ScrollView, StyleSheet, View } from 'react-native'; +import { ScrollView, StyleSheet, View } from 'react-native'; import React, { useEffect, useState } from 'react'; import { SafeAreaView } from 'react-native-safe-area-context'; import { GenericStyles, SCREEN_WIDTH } from '../../../RN-UI-LIB/src/styles'; import { COLORS } from '../../../RN-UI-LIB/src/styles/colors'; -import RNFastImage from '../../../RN-UI-LIB/src/components/FastImage'; import NavigationHeader, { Icon } from '../../../RN-UI-LIB/src/components/NavigationHeader'; -import { CaseDetail, DOCUMENT_TYPE, IDocument } from './interface'; +import { CaseDetail, DocumentDetail, DOCUMENT_TYPE, IDocument } from './interface'; import useIsOnline from '../../hooks/useIsOnline'; import useFetchDocument from '../../hooks/useFetchDocument'; import { RELATIVE_PATH_PREFIX, - checkS3Url, findDocumentByDocumentType, getDocumentList, } from '../../components/utlis/commonFunctions'; -import { goBack, navigateToScreen } from '../../components/utlis/navigationUtlis'; -import Text from '../../../RN-UI-LIB/src/components/Text'; -import { ISignedRequest, getSignedApi } from '../../action/dataActions'; -import { useTimeout } from 'react-native-toast-message/lib/src/hooks'; -import { DELAY_FOR_PAINTING_IMAGE } from '../../common/Constants'; -import { isNullOrEmptyString } from '../../../RN-UI-LIB/src/utlis/common'; +import { goBack } from '../../components/utlis/navigationUtlis'; +import SuspenseLoader from '../../../RN-UI-LIB/src/components/suspense_loader/SuspenseLoader'; +import LineLoader from '../../../RN-UI-LIB/src/components/suspense_loader/LineLoader'; +import ScreenshotBlocker from '../../components/utlis/ScreenshotBlocker'; +import { useFocusEffect } from '@react-navigation/native'; +import DocumentImageComponent from './DocumentImageComponent'; +import DocumentDetails from './DocumentDetails'; +import { getDocumentDetails } from './utils/documentUtils'; interface ICustomerProfile { route: { @@ -35,12 +35,9 @@ const CustomerProfile: React.FC = (props) => { params: { caseDetail }, }, } = props; - const [errorModalImage, setErrorModalImage] = useState(false); - const [loading, setLoading] = useState(true); - const { startTimer, isActive, clearTimer } = useTimeout(() => { - setLoading(false); - }, DELAY_FOR_PAINTING_IMAGE); const isOnline = useIsOnline(); + const [isDocumentsLoading, setIsDocumentsLoading] = useState(false); + const { documentObj, setRetryForUnsignedDocuments } = useFetchDocument( { caseId: caseDetail?.id, @@ -51,45 +48,7 @@ const CustomerProfile: React.FC = (props) => { false, false ); - const [vkycUri, setVkycUri] = useState(); - const [showVkyc, setShowVkyc] = useState(false); - - const updateVkycVideo = (uri: string) => { - setVkycUri(uri); - }; - - useEffect(() => { - if (caseDetail) { - const docList: IDocument[] = getDocumentList(caseDetail) || []; - const vkycDoc = findDocumentByDocumentType(docList, DOCUMENT_TYPE.VKYC_VIDEO); - if (!vkycDoc?.referenceId) { - return; - } - setShowVkyc(true); - const vkycUri = vkycDoc?.uri; - async function checkUrl(url: string) { - const result = await checkS3Url(url); - if (result) { - setVkycUri(url); - } else { - const imageReferenceId = vkycDoc?.referenceId!!; - const signedRequestPayload: ISignedRequest = [ - { - documentReferenceId: imageReferenceId, - caseId: caseDetail.id, - caseType: caseDetail.caseType, - }, - ]; - const response = await getSignedApi(signedRequestPayload); - const url = response?.imageUrl || ''; - setVkycUri(url); - } - } - if (vkycUri) { - checkUrl(vkycUri); - } - } - }, [caseDetail]); + const [documentData, setDocumentData] = useState>([]); const getImageURI = () => { if (!isOnline) { @@ -106,72 +65,75 @@ const CustomerProfile: React.FC = (props) => { ); }; - const handleVkycPress = () => { - navigateToScreen('vkycFull', { - vkycUri, - }); - }; + useEffect(() => { + if (caseDetail) { + const docList: IDocument[] = getDocumentList(caseDetail) || []; + const docPromises: Promise[] = []; + // TODO: Add Driver License Enum + const updatedDocList = [ + DOCUMENT_TYPE.VKYC_VIDEO, + DOCUMENT_TYPE.AADHAR, + DOCUMENT_TYPE.PAN, + DOCUMENT_TYPE.AADHAR_PHOTO, + ]; + updatedDocList.forEach((documentType) => { + const document = findDocumentByDocumentType(docList, documentType); + if (document) { + const docPromise = getDocumentDetails(document, caseDetail.id, caseDetail.caseType); + if (docPromise) docPromises.push(docPromise); + } + }); - const onLoadStart = () => { - setLoading(true); - setErrorModalImage(false); - }; - const onLoadEnd = () => { - // added this to show loader for the image is getting painted on screen - startTimer(); - }; + setIsDocumentsLoading(true); + Promise.all(docPromises) + .then((docs: Array) => { + const documents = docs?.filter( + (document: DocumentDetail | null) => document + ) as Array; + setDocumentData(documents); + setIsDocumentsLoading(false); + }) + .catch(() => { + setIsDocumentsLoading(false); + }); + } + }, [caseDetail]); - const onLoad = () => { - clearTimer(); - setLoading(false); - setErrorModalImage(false); - }; + useFocusEffect(() => { + ScreenshotBlocker.blockScreenshots(); + }); const imageUri = getImageURI(); + return ( goBack()} icon={Icon.close} /> - { - setRetryForUnsignedDocuments([DOCUMENT_TYPE.SELFIE]); - setErrorModalImage(true); - }} - onLoadStart={onLoadStart} - onLoad={onLoad} - onLoadEnd={onLoadEnd} + - {loading ? ( - - {!isNullOrEmptyString(imageUri) ? 'Loading Image...' : 'No Image Found'} - - ) : errorModalImage ? ( - - Error loading image - - ) : null} - {showVkyc ? ( - - - VKYC video - - {vkycUri ? ( - - Open video - - ) : ( - - )} - - ) : null} - {/* } /> */} + + {[...Array(4).keys()].map(() => ( + + ))} + + } + > + + ); @@ -190,37 +152,7 @@ const styles = StyleSheet.create({ borderWidth: 1, borderColor: COLORS.BORDER.GREY, }, - imageStyle: { - height: '100%', - }, container: { position: 'relative', }, - errorText: { - position: 'absolute', - top: '50%', - textAlign: 'center', - width: '100%', - color: COLORS.TEXT.RED, - }, - loadingText: { - position: 'absolute', - top: '50%', - textAlign: 'center', - width: '100%', - }, - vkyc: { - marginHorizontal: 16, - paddingHorizontal: 12, - paddingVertical: 18, - borderRadius: 4, - borderWidth: 1, - borderColor: COLORS.BORDER.GREY, - flexDirection: 'row', - alignItems: 'center', - justifyContent: 'space-between', - }, - openVideoTxt: { - color: COLORS.TEXT.BLUE, - }, }); diff --git a/src/screens/caseDetails/DocumentDetails.tsx b/src/screens/caseDetails/DocumentDetails.tsx new file mode 100644 index 00000000..6a590b46 --- /dev/null +++ b/src/screens/caseDetails/DocumentDetails.tsx @@ -0,0 +1,131 @@ +import React, { useState } from 'react'; +import { Pressable, StyleSheet, View } from 'react-native'; +import WebView from 'react-native-webview'; +import Accordion from '../../../RN-UI-LIB/src/components/accordian/Accordian'; +import Text from '../../../RN-UI-LIB/src/components/Text'; +import ArrowSolidDownIcon from '../../../RN-UI-LIB/src/Icons/ArrowSolidDownIcon'; +import { GenericStyles, getShadowStyle } from '../../../RN-UI-LIB/src/styles'; +import { COLORS } from '../../../RN-UI-LIB/src/styles/colors'; +import { navigateToScreen } from '../../components/utlis/navigationUtlis'; +import DocumentImageComponent from './DocumentImageComponent'; +import { DocumentDetail } from './interface'; +import { vkycHtml } from './vkycTemplate'; + +interface DocumentDetails { + documentData: Array; +} + +const DocumentDetails = (props: DocumentDetails) => { + const { documentData } = props; + const [isExpanded, setIsExpanded] = useState(false); + + const handleOpenPdfPress = (url: string) => { + // TODO: Dynamic Url + navigateToScreen('pdfFull', { + pdfUri: 'https://www.africau.edu/images/default/sample.pdf', + }); + }; + + return ( + + {documentData.map((item: any) => + item.docContentType !== 'pdf' ? ( + + {item?.icon} + {item?.title} + + } + customExpandUi={{ + whenCollapsed: ( + + + + ), + whenExpanded: ( + + + + ), + }} + onExpanded={(value) => { + setIsExpanded(value); + }} + > + + {item.docContentType === 'video' ? ( + + ) : ( + + )} + + + ) : ( + + + {item?.icon} + {item?.title} + + handleOpenPdfPress(item.url)}> + Open PDF + + + ) + )} + + ); +}; + +const styles = StyleSheet.create({ + openPdfTxt: { + color: COLORS.TEXT.BLUE, + }, + accordionExpandBtn: { + fontSize: 13, + marginTop: 8, + fontWeight: '500', + lineHeight: 20, + color: COLORS.TEXT.BLUE, + paddingRight: 16, + }, + accordionContentWrapper: { + backgroundColor: '#F7F7F7', + borderBottomLeftRadius: 8, + borderBottomRightRadius: 8, + height: 250, + padding: 16, + }, + rotateBtn: { transform: [{ rotateX: '180deg' }], marginTop: 0 }, + headerWrapper: { + ...GenericStyles.alignCenter, + ...GenericStyles.row, + ...GenericStyles.ph16, + ...GenericStyles.mb12, + }, + accordionStyles: { + ...GenericStyles.pt12, + ...GenericStyles.br8, + ...getShadowStyle(4), + paddingHorizontal: 0, + marginBottom: 16, + }, +}); + +export default DocumentDetails; diff --git a/src/screens/caseDetails/DocumentImageComponent.tsx b/src/screens/caseDetails/DocumentImageComponent.tsx new file mode 100644 index 00000000..43ec0fc6 --- /dev/null +++ b/src/screens/caseDetails/DocumentImageComponent.tsx @@ -0,0 +1,116 @@ +import React, { useState } from 'react'; +import { StyleSheet } from 'react-native'; +import { useTimeout } from 'react-native-toast-message/lib/src/hooks'; +import RNFastImage from '../../../RN-UI-LIB/src/components/FastImage'; +import Text from '../../../RN-UI-LIB/src/components/Text'; +import { GenericStyles } from '../../../RN-UI-LIB/src/styles'; +import { COLORS } from '../../../RN-UI-LIB/src/styles/colors'; +import { isNullOrEmptyString } from '../../../RN-UI-LIB/src/utlis/common'; +import { DELAY_FOR_PAINTING_IMAGE } from '../../common/Constants'; +import { DOCUMENT_TYPE } from './interface'; + +interface DocumentImageComponentProps { + docType: DOCUMENT_TYPE; + url: string; + setRetryForUnsignedDocuments?: React.Dispatch>; +} + +const DocumentImageComponent = (props: DocumentImageComponentProps) => { + const { docType, url, setRetryForUnsignedDocuments } = props; + const [errorModalImage, setErrorModalImage] = useState({ + [DOCUMENT_TYPE.SELFIE]: false, + [DOCUMENT_TYPE.AADHAR]: false, + [DOCUMENT_TYPE.PAN]: false, + }); + + const [loading, setLoading] = useState({ + [DOCUMENT_TYPE.SELFIE]: true, + [DOCUMENT_TYPE.AADHAR]: true, + [DOCUMENT_TYPE.PAN]: true, + }); + + const { startTimer, isActive, clearTimer } = useTimeout(() => { + setLoading({ + [DOCUMENT_TYPE.SELFIE]: false, + [DOCUMENT_TYPE.AADHAR]: false, + [DOCUMENT_TYPE.PAN]: false, + }); + }, DELAY_FOR_PAINTING_IMAGE); + + const onLoadStart = (docType: DOCUMENT_TYPE) => { + setLoading({ + ...loading, + [docType]: true, + }); + setErrorModalImage({ + ...errorModalImage, + [docType]: false, + }); + }; + const onLoadEnd = () => { + // added this to show loader for the image is getting painted on screen + startTimer(); + }; + + const onLoad = (docType: DOCUMENT_TYPE) => { + clearTimer(); + setLoading({ + ...loading, + [docType]: false, + }); + setErrorModalImage({ + ...errorModalImage, + [docType]: false, + }); + }; + + return ( + <> + { + setRetryForUnsignedDocuments?.([docType]); + setErrorModalImage({ + ...errorModalImage, + [docType]: true, + }); + }} + onLoadStart={() => onLoadStart(docType)} + onLoad={() => onLoad(docType)} + onLoadEnd={onLoadEnd} + /> + {loading[docType] ? ( + + {!isNullOrEmptyString(url) ? 'Loading Image...' : 'No Image Found'} + + ) : errorModalImage[docType] ? ( + + Error loading image + + ) : null} + + ); +}; + +const styles = StyleSheet.create({ + imageStyle: { + height: '100%', + }, + errorText: { + ...GenericStyles.absolute, + top: '50%', + textAlign: 'center', + width: '100%', + color: COLORS.TEXT.RED, + }, + loadingText: { + ...GenericStyles.absolute, + top: '50%', + textAlign: 'center', + width: '100%', + }, +}); + +export default DocumentImageComponent; diff --git a/src/screens/caseDetails/PDFFullScreen.tsx b/src/screens/caseDetails/PDFFullScreen.tsx new file mode 100644 index 00000000..64cb58f8 --- /dev/null +++ b/src/screens/caseDetails/PDFFullScreen.tsx @@ -0,0 +1,74 @@ +import { Dimensions, StyleSheet, View } from 'react-native'; +import React, { useState } from 'react'; +import { GenericStyles } from '../../../RN-UI-LIB/src/styles'; +import NavigationHeader, { Icon } from '../../../RN-UI-LIB/src/components/NavigationHeader'; +import { goBack } from '../../components/utlis/navigationUtlis'; +import Pdf from 'react-native-pdf'; +import Text from '../../../RN-UI-LIB/src/components/Text'; +import { COLORS } from '../../../RN-UI-LIB/src/styles/colors'; + +interface ICustomerProfile { + route: { + params: { + pdfUri: string; + }; + }; +} + +const PDFFullScreen: React.FC = (props) => { + const { + route: { + params: { pdfUri }, + }, + } = props; + + const [error, setError] = useState(false); + + return ( + + + + { + return !error ? ( + Loading... + ) : ( + + Error loading pdf + + ); + }} + onError={() => { + setError(true); + }} + style={styles.pdf} + /> + + + ); +}; + +export default PDFFullScreen; + +const styles = StyleSheet.create({ + container: { + flex: 1, + justifyContent: 'flex-start', + alignItems: 'center', + margin: 12, + }, + pdf: { + flex: 1, + width: Dimensions.get('window').width, + height: Dimensions.get('window').height, + }, + errorText: { + ...GenericStyles.absolute, + top: '50%', + textAlign: 'center', + width: '100%', + color: COLORS.TEXT.RED, + }, +}); diff --git a/src/screens/caseDetails/interface.ts b/src/screens/caseDetails/interface.ts index 3acea768..bb7b0c6a 100644 --- a/src/screens/caseDetails/interface.ts +++ b/src/screens/caseDetails/interface.ts @@ -139,6 +139,9 @@ export enum DOCUMENT_TYPE { SELFIE = 'SELFIE', OPTIMIZED_SELFIE = 'OPTIMIZED_SELFIE', VKYC_VIDEO = 'VKYC_VIDEO', + PAN = 'PAN', + AADHAR = 'AADHAR', + AADHAR_PHOTO = 'aadhar_photo', } export type TDocumentObj = { @@ -151,6 +154,14 @@ export interface IDocument { type: DOCUMENT_TYPE; } +export interface DocumentDetail { + icon: React.ReactNode; + title: string; + docType: DOCUMENT_TYPE; + docContentType: string; + url: string; +} + export enum FeedbackStatus { ATTEMPTED = 'ATTEMPTED', NOT_ATTEMPTED = 'NOT_ATTEMPTED', diff --git a/src/screens/caseDetails/utils/documentUtils.tsx b/src/screens/caseDetails/utils/documentUtils.tsx new file mode 100644 index 00000000..1051cadc --- /dev/null +++ b/src/screens/caseDetails/utils/documentUtils.tsx @@ -0,0 +1,90 @@ +import ImageIcon from '../../../../RN-UI-LIB/src/Icons/ImageIcon'; +import PdfIcon from '../../../../RN-UI-LIB/src/Icons/PdfIcon'; +import VideoIcon from '../../../../RN-UI-LIB/src/Icons/VideoIcon'; +import { getSignedApi, ISignedRequest } from '../../../action/dataActions'; +import { checkS3Url } from '../../../components/utlis/commonFunctions'; +import { CaseAllocationType } from '../../allCases/interface'; +import { DOCUMENT_TYPE, IDocument } from '../interface'; + +async function checkUrlData( + url: string, + referenceId: string, + caseId: string, + caseType: CaseAllocationType +) { + const result = await checkS3Url(url); + if (result) { + return url; + } else { + const signedRequestPayload: ISignedRequest = [ + { + documentReferenceId: referenceId!!, + caseId: caseId, + caseType: caseType, + }, + ]; + const response = await getSignedApi(signedRequestPayload); + const url = response?.imageUrl || ''; + return url; + } +} + +export const getDocumentDetails = async ( + document: IDocument, + caseId: string, + caseType: CaseAllocationType +) => { + if (!document.referenceId) { + return null; + } + if (document?.uri) { + try { + const imageUrl = await checkUrlData(document.uri, document.referenceId, caseId, caseType); + if (!imageUrl) return null; + // TODO: Make Dynamic Based on Content type from firestore and add DL Case + switch (document.type) { + case DOCUMENT_TYPE.VKYC_VIDEO: + return { + icon: , + title: 'VKYC video', + docType: DOCUMENT_TYPE.VKYC_VIDEO, + docContentType: 'video', + url: imageUrl, + }; + + case DOCUMENT_TYPE.PAN: + return { + icon: , + title: 'Pan details', + docType: DOCUMENT_TYPE.PAN, + docContentType: 'image', + url: imageUrl, + }; + + case DOCUMENT_TYPE.AADHAR: + return { + icon: , + title: 'Aadhar details', + docType: DOCUMENT_TYPE.AADHAR, + docContentType: 'pdf', + url: imageUrl, + }; + + case DOCUMENT_TYPE.AADHAR_PHOTO: + return { + icon: , + title: 'Aadhar photo', + docType: DOCUMENT_TYPE.AADHAR_PHOTO, + docContentType: 'image', + url: imageUrl, + }; + + default: + break; + } + } catch (error) { + return null; + } + } + return null; +}; diff --git a/yarn.lock b/yarn.lock index 20dab82a..d477678d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1658,16 +1658,16 @@ resolved "https://registry.yarnpkg.com/@react-native/assets/-/assets-1.0.0.tgz#c6f9bf63d274bafc8e970628de24986b30a55c8e" integrity sha512-KrwSpS1tKI70wuKl68DwJZYEvXktDHdZMG0k2AXD/rJVSlB23/X2CB2cutVR0HwNMJIal9HOUOBB2rVfa6UGtQ== +"@react-native/normalize-color@*", "@react-native/normalize-color@^2.0.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@react-native/normalize-color/-/normalize-color-2.1.0.tgz#939b87a9849e81687d3640c5efa2a486ac266f91" + integrity sha512-Z1jQI2NpdFJCVgpY+8Dq/Bt3d+YUi1928Q+/CZm/oh66fzM0RUl54vvuXlPJKybH4pdCZey1eDTPaLHkMPNgWA== + "@react-native/normalize-color@2.0.0": version "2.0.0" resolved "https://registry.yarnpkg.com/@react-native/normalize-color/-/normalize-color-2.0.0.tgz#da955909432474a9a0fe1cbffc66576a0447f567" integrity sha512-Wip/xsc5lw8vsBlmY2MO/gFLp3MvuZ2baBZjDeTjjndMgM0h5sxz7AZR62RDPGgstp8Np7JzjvVqVT7tpFZqsw== -"@react-native/normalize-color@^2.0.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@react-native/normalize-color/-/normalize-color-2.1.0.tgz#939b87a9849e81687d3640c5efa2a486ac266f91" - integrity sha512-Z1jQI2NpdFJCVgpY+8Dq/Bt3d+YUi1928Q+/CZm/oh66fzM0RUl54vvuXlPJKybH4pdCZey1eDTPaLHkMPNgWA== - "@react-native/polyfills@2.0.0": version "2.0.0" resolved "https://registry.yarnpkg.com/@react-native/polyfills/-/polyfills-2.0.0.tgz#4c40b74655c83982c8cf47530ee7dc13d957b6aa" @@ -3339,6 +3339,11 @@ cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3: shebang-command "^2.0.0" which "^2.0.1" +crypto-js@^3.2.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/crypto-js/-/crypto-js-3.3.0.tgz#846dd1cce2f68aacfa156c8578f926a609b7976b" + integrity sha512-DIT51nX0dCfKltpRiXV+/TVZq+Qq2NgF4644+K7Ttnla7zEzqc+kjJyiB96BHNyUTBxyjzRcZYpUdZa+QAqi6Q== + css-select@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/css-select/-/css-select-5.1.0.tgz#b8ebd6554c3637ccc76688804ad3f6a6fdaea8a6" @@ -3404,7 +3409,7 @@ data-urls@^2.0.0: whatwg-mimetype "^2.3.0" whatwg-url "^8.0.0" -dayjs@^1.11.9: +dayjs@1.11.9: version "1.11.9" resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.9.tgz#9ca491933fadd0a60a2c19f6c237c03517d71d1a" integrity sha512-QvzAURSbQ0pKdIye2txOzNaHmxtUBXerpY0FJsFXUMKbIZeFm5ht1LS/jFsrncjnmtv8HsG0W2g6c0zUjZWmpA== @@ -3551,6 +3556,15 @@ depd@2.0.0: resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== +deprecated-react-native-prop-types@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/deprecated-react-native-prop-types/-/deprecated-react-native-prop-types-2.3.0.tgz#c10c6ee75ff2b6de94bb127f142b814e6e08d9ab" + integrity sha512-pWD0voFtNYxrVqvBMYf5gq3NA2GCpfodS1yNynTPc93AYA/KEMGeWDqqeUB6R2Z9ZofVhks2aeJXiuQqKNpesA== + dependencies: + "@react-native/normalize-color" "*" + invariant "*" + prop-types "*" + destroy@1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" @@ -5045,7 +5059,7 @@ internal-slot@^1.0.3: has "^1.0.3" side-channel "^1.0.4" -invariant@2.2.4, invariant@^2.2.2, invariant@^2.2.4: +invariant@*, invariant@2.2.4, invariant@^2.2.2, invariant@^2.2.4: version "2.2.4" resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== @@ -7528,7 +7542,7 @@ prompts@^2.0.1, prompts@^2.4.0: kleur "^3.0.3" sisteransi "^1.0.5" -prop-types@15.8.1, prop-types@^15.7.2, prop-types@^15.8.0, prop-types@^15.8.1: +prop-types@*, prop-types@15.8.1, prop-types@^15.7.2, prop-types@^15.8.0, prop-types@^15.8.1: version "15.8.1" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5" integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== @@ -7762,6 +7776,14 @@ react-native-pager-view@6.1.2: resolved "https://registry.yarnpkg.com/react-native-pager-view/-/react-native-pager-view-6.1.2.tgz#3522079b9a9d6634ca5e8d153bc0b4d660254552" integrity sha512-qs2KSFc+7N7B+UZ6SG2sTvCkppagm5fVyRclv1KFKc7lDtrhXLzN59tXJw575LDP/dRJoXsNwqUAhZJdws6ABQ== +react-native-pdf@^6.7.1: + version "6.7.1" + resolved "https://registry.yarnpkg.com/react-native-pdf/-/react-native-pdf-6.7.1.tgz#198b8ec3e8f1025ceb43ddfc6bc5b422521c4411" + integrity sha512-zszQygtNBYoUfEtP/fV7zhzGeohDlUksh2p3OzshLrxdY9mw7Tm5VXAxYq4d8HsomRJUbFlJ7rHaTU9AQL800g== + dependencies: + crypto-js "^3.2.0" + deprecated-react-native-prop-types "^2.3.0" + react-native-permissions@3.6.1: version "3.6.1" resolved "https://registry.yarnpkg.com/react-native-permissions/-/react-native-permissions-3.6.1.tgz#73adcc1cef8cd57a9ef167b4507405f4ff5749c4" From 536ab9dd035573ce67c77d1cfeb6f9e430057d9d Mon Sep 17 00:00:00 2001 From: yashmantri Date: Thu, 14 Sep 2023 12:46:49 +0530 Subject: [PATCH 02/75] TP-38645 | DocType Handled and Driver License Added --- src/screens/caseDetails/CustomerProfile.tsx | 26 +++---------------- src/screens/caseDetails/DocumentDetails.tsx | 10 +++++-- src/screens/caseDetails/PDFFullScreen.tsx | 14 ++++------ src/screens/caseDetails/interface.ts | 2 ++ .../caseDetails/utils/documentUtils.tsx | 26 +++++++++++++++---- 5 files changed, 40 insertions(+), 38 deletions(-) diff --git a/src/screens/caseDetails/CustomerProfile.tsx b/src/screens/caseDetails/CustomerProfile.tsx index c3376099..121e77bb 100644 --- a/src/screens/caseDetails/CustomerProfile.tsx +++ b/src/screens/caseDetails/CustomerProfile.tsx @@ -36,7 +36,6 @@ const CustomerProfile: React.FC = (props) => { }, } = props; const isOnline = useIsOnline(); - const [isDocumentsLoading, setIsDocumentsLoading] = useState(false); const { documentObj, setRetryForUnsignedDocuments } = useFetchDocument( { @@ -75,6 +74,7 @@ const CustomerProfile: React.FC = (props) => { DOCUMENT_TYPE.AADHAR, DOCUMENT_TYPE.PAN, DOCUMENT_TYPE.AADHAR_PHOTO, + DOCUMENT_TYPE.DRIVING_LICENSE, ]; updatedDocList.forEach((documentType) => { const document = findDocumentByDocumentType(docList, documentType); @@ -84,18 +84,14 @@ const CustomerProfile: React.FC = (props) => { } }); - setIsDocumentsLoading(true); Promise.all(docPromises) .then((docs: Array) => { const documents = docs?.filter( (document: DocumentDetail | null) => document ) as Array; setDocumentData(documents); - setIsDocumentsLoading(false); }) - .catch(() => { - setIsDocumentsLoading(false); - }); + .catch(() => {}); } }, [caseDetail]); @@ -115,25 +111,11 @@ const CustomerProfile: React.FC = (props) => { docType={DOCUMENT_TYPE.SELFIE} url={imageUri} setRetryForUnsignedDocuments={setRetryForUnsignedDocuments} + id={caseDetail.id} /> - - {[...Array(4).keys()].map(() => ( - - ))} - - } - > - - + ); diff --git a/src/screens/caseDetails/DocumentDetails.tsx b/src/screens/caseDetails/DocumentDetails.tsx index 6a590b46..f4d3aefb 100644 --- a/src/screens/caseDetails/DocumentDetails.tsx +++ b/src/screens/caseDetails/DocumentDetails.tsx @@ -23,6 +23,7 @@ const DocumentDetails = (props: DocumentDetails) => { // TODO: Dynamic Url navigateToScreen('pdfFull', { pdfUri: 'https://www.africau.edu/images/default/sample.pdf', + // pdfUri: url, }); }; @@ -57,7 +58,12 @@ const DocumentDetails = (props: DocumentDetails) => { setIsExpanded(value); }} > - + {item.docContentType === 'video' ? ( { mediaPlaybackRequiresUserAction={false} /> ) : ( - + )} diff --git a/src/screens/caseDetails/PDFFullScreen.tsx b/src/screens/caseDetails/PDFFullScreen.tsx index 64cb58f8..4bf480a8 100644 --- a/src/screens/caseDetails/PDFFullScreen.tsx +++ b/src/screens/caseDetails/PDFFullScreen.tsx @@ -31,21 +31,17 @@ const PDFFullScreen: React.FC = (props) => { { - return !error ? ( - Loading... - ) : ( - - Error loading pdf - - ); - }} onError={() => { setError(true); }} style={styles.pdf} /> + {error && ( + + Error loading pdf + + )} ); }; diff --git a/src/screens/caseDetails/interface.ts b/src/screens/caseDetails/interface.ts index bb7b0c6a..19352fa6 100644 --- a/src/screens/caseDetails/interface.ts +++ b/src/screens/caseDetails/interface.ts @@ -142,6 +142,7 @@ export enum DOCUMENT_TYPE { PAN = 'PAN', AADHAR = 'AADHAR', AADHAR_PHOTO = 'aadhar_photo', + DRIVING_LICENSE = 'DRIVING_LICENSE', } export type TDocumentObj = { @@ -152,6 +153,7 @@ export interface IDocument { referenceId: string; uri: string; type: DOCUMENT_TYPE; + docContentType: string; } export interface DocumentDetail { diff --git a/src/screens/caseDetails/utils/documentUtils.tsx b/src/screens/caseDetails/utils/documentUtils.tsx index 1051cadc..51307749 100644 --- a/src/screens/caseDetails/utils/documentUtils.tsx +++ b/src/screens/caseDetails/utils/documentUtils.tsx @@ -29,6 +29,12 @@ async function checkUrlData( } } +const getDocumentType = (docContentType: string) => { + if (!docContentType) return 'image'; + if (docContentType.includes('image')) return 'image'; + return 'pdf'; +}; + export const getDocumentDetails = async ( document: IDocument, caseId: string, @@ -42,6 +48,7 @@ export const getDocumentDetails = async ( const imageUrl = await checkUrlData(document.uri, document.referenceId, caseId, caseType); if (!imageUrl) return null; // TODO: Make Dynamic Based on Content type from firestore and add DL Case + const docType = getDocumentType(document?.docContentType); switch (document.type) { case DOCUMENT_TYPE.VKYC_VIDEO: return { @@ -55,18 +62,18 @@ export const getDocumentDetails = async ( case DOCUMENT_TYPE.PAN: return { icon: , - title: 'Pan details', + title: 'PAN card', docType: DOCUMENT_TYPE.PAN, - docContentType: 'image', + docContentType: docType, url: imageUrl, }; case DOCUMENT_TYPE.AADHAR: return { icon: , - title: 'Aadhar details', + title: 'Aadhar card', docType: DOCUMENT_TYPE.AADHAR, - docContentType: 'pdf', + docContentType: docType, url: imageUrl, }; @@ -75,7 +82,16 @@ export const getDocumentDetails = async ( icon: , title: 'Aadhar photo', docType: DOCUMENT_TYPE.AADHAR_PHOTO, - docContentType: 'image', + docContentType: docType, + url: imageUrl, + }; + + case DOCUMENT_TYPE.DRIVING_LICENSE: + return { + icon: , + title: 'Driving license', + docType: DOCUMENT_TYPE.DRIVING_LICENSE, + docContentType: docType, url: imageUrl, }; From 83feeeacbf4e4c91c90d936067e99ab0deae5844 Mon Sep 17 00:00:00 2001 From: yashmantri Date: Thu, 14 Sep 2023 15:44:00 +0530 Subject: [PATCH 03/75] TP-38645 | Clickstream Events Added --- src/common/Constants.ts | 8 ++++ src/screens/caseDetails/CustomerProfile.tsx | 7 +-- src/screens/caseDetails/DocumentDetails.tsx | 51 +++++++++++++++------ 3 files changed, 50 insertions(+), 16 deletions(-) diff --git a/src/common/Constants.ts b/src/common/Constants.ts index 142e725c..ed8e22d4 100644 --- a/src/common/Constants.ts +++ b/src/common/Constants.ts @@ -411,6 +411,14 @@ export const CLICKSTREAM_EVENT_NAMES = { description: 'FA_VIEW_PAST_FEEDBACK_PREV_PAGE_FAILED', }, FA_VIEW_PHOTO_CLICKED: { name: 'FA_VIEW_PHOTO_CLICKED', description: 'FA_VIEW_PHOTO_CLICKED' }, + FA_CUSTOMER_DOCUMENT_CLICKED: { + name: 'FA_CUSTOMER_DOCUMENT_CLICKED', + description: 'FA_CUSTOMER_DOCUMENT_CLICKED', + }, + FA_CUSTOMER_DOCUMENT_CLOSE_CLICKED: { + name: 'FA_CUSTOMER_DOCUMENT_CLOSE_CLICKED', + description: 'FA_CUSTOMER_DOCUMENT_CLOSE_CLICKED', + }, FA_UNIFIED_ENTITY_REQUESTED: { name: 'FA_UNIFIED_ENTITY_REQUESTED', description: 'FA_UNIFIED_ENTITY_REQUESTED', diff --git a/src/screens/caseDetails/CustomerProfile.tsx b/src/screens/caseDetails/CustomerProfile.tsx index 121e77bb..b18826b1 100644 --- a/src/screens/caseDetails/CustomerProfile.tsx +++ b/src/screens/caseDetails/CustomerProfile.tsx @@ -13,8 +13,6 @@ import { getDocumentList, } from '../../components/utlis/commonFunctions'; import { goBack } from '../../components/utlis/navigationUtlis'; -import SuspenseLoader from '../../../RN-UI-LIB/src/components/suspense_loader/SuspenseLoader'; -import LineLoader from '../../../RN-UI-LIB/src/components/suspense_loader/LineLoader'; import ScreenshotBlocker from '../../components/utlis/ScreenshotBlocker'; import { useFocusEffect } from '@react-navigation/native'; import DocumentImageComponent from './DocumentImageComponent'; @@ -115,7 +113,10 @@ const CustomerProfile: React.FC = (props) => { /> - + ); diff --git a/src/screens/caseDetails/DocumentDetails.tsx b/src/screens/caseDetails/DocumentDetails.tsx index f4d3aefb..f6fe9672 100644 --- a/src/screens/caseDetails/DocumentDetails.tsx +++ b/src/screens/caseDetails/DocumentDetails.tsx @@ -6,18 +6,26 @@ import Text from '../../../RN-UI-LIB/src/components/Text'; import ArrowSolidDownIcon from '../../../RN-UI-LIB/src/Icons/ArrowSolidDownIcon'; import { GenericStyles, getShadowStyle } from '../../../RN-UI-LIB/src/styles'; import { COLORS } from '../../../RN-UI-LIB/src/styles/colors'; +import { CLICKSTREAM_EVENT_NAMES } from '../../common/Constants'; import { navigateToScreen } from '../../components/utlis/navigationUtlis'; +import { useAppSelector } from '../../hooks'; +import { addClickstreamEvent } from '../../services/clickstreamEventService'; import DocumentImageComponent from './DocumentImageComponent'; import { DocumentDetail } from './interface'; import { vkycHtml } from './vkycTemplate'; interface DocumentDetails { documentData: Array; + customerReferenceId: string; } const DocumentDetails = (props: DocumentDetails) => { - const { documentData } = props; - const [isExpanded, setIsExpanded] = useState(false); + const { documentData, customerReferenceId } = props; + const [isExpanded, setIsExpanded] = useState(); + + const { referenceId } = useAppSelector((state) => ({ + referenceId: state.user.user?.referenceId!, + })); const handleOpenPdfPress = (url: string) => { // TODO: Dynamic Url @@ -29,8 +37,8 @@ const DocumentDetails = (props: DocumentDetails) => { return ( - {documentData.map((item: any) => - item.docContentType !== 'pdf' ? ( + {documentData.map((document: DocumentDetail) => + document.docContentType !== 'pdf' ? ( { touchableOpacity={0.8} accordionHeader={ - {item?.icon} - {item?.title} + {document?.icon} + {document?.title} } customExpandUi={{ @@ -55,24 +63,41 @@ const DocumentDetails = (props: DocumentDetails) => { ), }} onExpanded={(value) => { + if (isExpanded !== undefined) { + addClickstreamEvent( + value + ? CLICKSTREAM_EVENT_NAMES.FA_CUSTOMER_DOCUMENT_CLICKED + : CLICKSTREAM_EVENT_NAMES.FA_CUSTOMER_DOCUMENT_CLOSE_CLICKED, + { + agentId: referenceId, + customerId: customerReferenceId, + documentIdentifier: document.docType, + documentType: document.docContentType, + } + ); + } setIsExpanded(value); }} > - {item.docContentType === 'video' ? ( + {document.docContentType === 'video' ? ( ) : ( - + )} @@ -86,10 +111,10 @@ const DocumentDetails = (props: DocumentDetails) => { ]} > - {item?.icon} - {item?.title} + {document?.icon} + {document?.title} - handleOpenPdfPress(item.url)}> + handleOpenPdfPress(document.url)}> Open PDF From 9ad9b0c2310b5ee5a06ab9aaa13f49cc39c50d87 Mon Sep 17 00:00:00 2001 From: yashmantri Date: Thu, 14 Sep 2023 16:35:57 +0530 Subject: [PATCH 04/75] TP-38645 | Code Refactored --- src/screens/caseDetails/CustomerProfile.tsx | 1 - src/screens/caseDetails/DocumentDetails.tsx | 4 +--- src/screens/caseDetails/utils/documentUtils.tsx | 6 ++++-- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/screens/caseDetails/CustomerProfile.tsx b/src/screens/caseDetails/CustomerProfile.tsx index b18826b1..df3ba3af 100644 --- a/src/screens/caseDetails/CustomerProfile.tsx +++ b/src/screens/caseDetails/CustomerProfile.tsx @@ -66,7 +66,6 @@ const CustomerProfile: React.FC = (props) => { if (caseDetail) { const docList: IDocument[] = getDocumentList(caseDetail) || []; const docPromises: Promise[] = []; - // TODO: Add Driver License Enum const updatedDocList = [ DOCUMENT_TYPE.VKYC_VIDEO, DOCUMENT_TYPE.AADHAR, diff --git a/src/screens/caseDetails/DocumentDetails.tsx b/src/screens/caseDetails/DocumentDetails.tsx index f6fe9672..ba67be62 100644 --- a/src/screens/caseDetails/DocumentDetails.tsx +++ b/src/screens/caseDetails/DocumentDetails.tsx @@ -28,10 +28,8 @@ const DocumentDetails = (props: DocumentDetails) => { })); const handleOpenPdfPress = (url: string) => { - // TODO: Dynamic Url navigateToScreen('pdfFull', { - pdfUri: 'https://www.africau.edu/images/default/sample.pdf', - // pdfUri: url, + pdfUri: url, }); }; diff --git a/src/screens/caseDetails/utils/documentUtils.tsx b/src/screens/caseDetails/utils/documentUtils.tsx index 51307749..1fa550ce 100644 --- a/src/screens/caseDetails/utils/documentUtils.tsx +++ b/src/screens/caseDetails/utils/documentUtils.tsx @@ -32,7 +32,9 @@ async function checkUrlData( const getDocumentType = (docContentType: string) => { if (!docContentType) return 'image'; if (docContentType.includes('image')) return 'image'; - return 'pdf'; + if (docContentType.includes('pdf')) return 'pdf'; + + return null; }; export const getDocumentDetails = async ( @@ -47,8 +49,8 @@ export const getDocumentDetails = async ( try { const imageUrl = await checkUrlData(document.uri, document.referenceId, caseId, caseType); if (!imageUrl) return null; - // TODO: Make Dynamic Based on Content type from firestore and add DL Case const docType = getDocumentType(document?.docContentType); + if (!docType) return null; switch (document.type) { case DOCUMENT_TYPE.VKYC_VIDEO: return { From c9b0bd9dae94cdb3992f43dbb2417ca85976d0b3 Mon Sep 17 00:00:00 2001 From: yashmantri Date: Fri, 15 Sep 2023 11:50:48 +0530 Subject: [PATCH 05/75] TP-38645 | Minor Bug Fix --- src/screens/caseDetails/CustomerProfile.tsx | 16 +++--- src/screens/caseDetails/DocumentDetails.tsx | 5 +- .../caseDetails/DocumentImageComponent.tsx | 52 +++++++------------ 3 files changed, 31 insertions(+), 42 deletions(-) diff --git a/src/screens/caseDetails/CustomerProfile.tsx b/src/screens/caseDetails/CustomerProfile.tsx index a74b04f3..58d70cd1 100644 --- a/src/screens/caseDetails/CustomerProfile.tsx +++ b/src/screens/caseDetails/CustomerProfile.tsx @@ -1,4 +1,4 @@ -import { ScrollView, StyleSheet, View } from 'react-native'; +import { ActivityIndicator, Pressable, ScrollView, StyleSheet, View } from 'react-native'; import React, { useEffect, useState } from 'react'; import { SafeAreaView } from 'react-native-safe-area-context'; import { GenericStyles, SCREEN_WIDTH } from '../../../RN-UI-LIB/src/styles'; @@ -15,16 +15,16 @@ import { import { goBack } from '../../components/utlis/navigationUtlis'; import ScreenshotBlocker from '../../components/utlis/ScreenshotBlocker'; import { useFocusEffect } from '@react-navigation/native'; -import DocumentImageComponent from './DocumentImageComponent'; import DocumentDetails from './DocumentDetails'; import { getDocumentDetails } from './utils/documentUtils'; import CachedImage from '../../common/CachedImage'; -import ImagePlaceholder from '../../assets/icons/ImagePlaceholder'; import ImagePlaceholderError from '../../assets/icons/ImagePlaceholderError'; import RetryIcon from '../../assets/icons/RetryIcon'; import FastImage from 'react-native-fast-image'; import { useTimeout } from 'react-native-toast-message/lib/src/hooks'; import { DELAY_FOR_PAINTING_IMAGE } from '../../common/Constants'; +import Text from '../../../RN-UI-LIB/src/components/Text'; +import { isNullOrEmptyString } from '../../../RN-UI-LIB/src/utlis/common'; interface ICustomerProfile { route: { @@ -113,6 +113,7 @@ const CustomerProfile: React.FC = (props) => { setErrorModalImage(false); setIsHighQualityImageLoaded(false); }; + const onLoadEnd = (from: string) => { setLoading(false); // added this to show loader for the image is getting painted on screen @@ -126,10 +127,6 @@ const CustomerProfile: React.FC = (props) => { } }; - useFocusEffect(() => { - ScreenshotBlocker.blockScreenshots(); - }); - const onRetry = () => { setRetry(!retry); }; @@ -149,6 +146,10 @@ const CustomerProfile: React.FC = (props) => { setLoading(false); }; + useFocusEffect(() => { + ScreenshotBlocker.blockScreenshots(); + }); + const imageUri = getImageURI(); return ( @@ -211,6 +212,7 @@ const CustomerProfile: React.FC = (props) => { diff --git a/src/screens/caseDetails/DocumentDetails.tsx b/src/screens/caseDetails/DocumentDetails.tsx index ba67be62..be7972b3 100644 --- a/src/screens/caseDetails/DocumentDetails.tsx +++ b/src/screens/caseDetails/DocumentDetails.tsx @@ -17,10 +17,11 @@ import { vkycHtml } from './vkycTemplate'; interface DocumentDetails { documentData: Array; customerReferenceId: string; + caseId: string; } const DocumentDetails = (props: DocumentDetails) => { - const { documentData, customerReferenceId } = props; + const { documentData, customerReferenceId, caseId } = props; const [isExpanded, setIsExpanded] = useState(); const { referenceId } = useAppSelector((state) => ({ @@ -94,7 +95,7 @@ const DocumentDetails = (props: DocumentDetails) => { )} diff --git a/src/screens/caseDetails/DocumentImageComponent.tsx b/src/screens/caseDetails/DocumentImageComponent.tsx index 43ec0fc6..cf767d21 100644 --- a/src/screens/caseDetails/DocumentImageComponent.tsx +++ b/src/screens/caseDetails/DocumentImageComponent.tsx @@ -1,42 +1,34 @@ import React, { useState } from 'react'; import { StyleSheet } from 'react-native'; -import { useTimeout } from 'react-native-toast-message/lib/src/hooks'; -import RNFastImage from '../../../RN-UI-LIB/src/components/FastImage'; import Text from '../../../RN-UI-LIB/src/components/Text'; import { GenericStyles } from '../../../RN-UI-LIB/src/styles'; import { COLORS } from '../../../RN-UI-LIB/src/styles/colors'; import { isNullOrEmptyString } from '../../../RN-UI-LIB/src/utlis/common'; -import { DELAY_FOR_PAINTING_IMAGE } from '../../common/Constants'; +import CachedImage from '../../common/CachedImage'; import { DOCUMENT_TYPE } from './interface'; interface DocumentImageComponentProps { docType: DOCUMENT_TYPE; url: string; - setRetryForUnsignedDocuments?: React.Dispatch>; + id: string; } const DocumentImageComponent = (props: DocumentImageComponentProps) => { - const { docType, url, setRetryForUnsignedDocuments } = props; + const { docType, url, id } = props; const [errorModalImage, setErrorModalImage] = useState({ - [DOCUMENT_TYPE.SELFIE]: false, [DOCUMENT_TYPE.AADHAR]: false, [DOCUMENT_TYPE.PAN]: false, + [DOCUMENT_TYPE.AADHAR_PHOTO]: false, + [DOCUMENT_TYPE.DRIVING_LICENSE]: false, }); const [loading, setLoading] = useState({ - [DOCUMENT_TYPE.SELFIE]: true, - [DOCUMENT_TYPE.AADHAR]: true, - [DOCUMENT_TYPE.PAN]: true, + [DOCUMENT_TYPE.AADHAR]: false, + [DOCUMENT_TYPE.PAN]: false, + [DOCUMENT_TYPE.AADHAR_PHOTO]: false, + [DOCUMENT_TYPE.DRIVING_LICENSE]: false, }); - const { startTimer, isActive, clearTimer } = useTimeout(() => { - setLoading({ - [DOCUMENT_TYPE.SELFIE]: false, - [DOCUMENT_TYPE.AADHAR]: false, - [DOCUMENT_TYPE.PAN]: false, - }); - }, DELAY_FOR_PAINTING_IMAGE); - const onLoadStart = (docType: DOCUMENT_TYPE) => { setLoading({ ...loading, @@ -47,39 +39,33 @@ const DocumentImageComponent = (props: DocumentImageComponentProps) => { [docType]: false, }); }; - const onLoadEnd = () => { - // added this to show loader for the image is getting painted on screen - startTimer(); - }; - const onLoad = (docType: DOCUMENT_TYPE) => { - clearTimer(); + const onLoadEnd = (docType: DOCUMENT_TYPE) => { + // added this to show loader for the image is getting painted on screen setLoading({ ...loading, [docType]: false, }); - setErrorModalImage({ - ...errorModalImage, - [docType]: false, - }); }; return ( <> - { - setRetryForUnsignedDocuments?.([docType]); setErrorModalImage({ ...errorModalImage, [docType]: true, }); + setLoading({ + ...loading, + [docType]: false, + }); }} onLoadStart={() => onLoadStart(docType)} - onLoad={() => onLoad(docType)} - onLoadEnd={onLoadEnd} + onLoadEnd={() => onLoadEnd(docType)} /> {loading[docType] ? ( From 85c9d3ad4601756a6bdeca51eb144794b6710cdb Mon Sep 17 00:00:00 2001 From: yashmantri Date: Wed, 20 Sep 2023 12:26:32 +0530 Subject: [PATCH 06/75] TP-38645 | Unsigned Uri Changes --- src/action/dataActions.ts | 1 + src/screens/caseDetails/interface.ts | 1 + src/screens/caseDetails/utils/documentUtils.tsx | 15 ++++++--------- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/action/dataActions.ts b/src/action/dataActions.ts index ff57bc11..0ae3677b 100644 --- a/src/action/dataActions.ts +++ b/src/action/dataActions.ts @@ -167,6 +167,7 @@ interface ISignedRequestItem { documentReferenceId: string; caseType: CaseAllocationType; caseId: string; + unSignedUri?: string; } export type ISignedRequest = ISignedRequestItem[]; diff --git a/src/screens/caseDetails/interface.ts b/src/screens/caseDetails/interface.ts index 19352fa6..0a680d8c 100644 --- a/src/screens/caseDetails/interface.ts +++ b/src/screens/caseDetails/interface.ts @@ -154,6 +154,7 @@ export interface IDocument { uri: string; type: DOCUMENT_TYPE; docContentType: string; + unSignedUri: string; } export interface DocumentDetail { diff --git a/src/screens/caseDetails/utils/documentUtils.tsx b/src/screens/caseDetails/utils/documentUtils.tsx index 1fa550ce..8c21b80c 100644 --- a/src/screens/caseDetails/utils/documentUtils.tsx +++ b/src/screens/caseDetails/utils/documentUtils.tsx @@ -6,21 +6,18 @@ import { checkS3Url } from '../../../components/utlis/commonFunctions'; import { CaseAllocationType } from '../../allCases/interface'; import { DOCUMENT_TYPE, IDocument } from '../interface'; -async function checkUrlData( - url: string, - referenceId: string, - caseId: string, - caseType: CaseAllocationType -) { - const result = await checkS3Url(url); +async function checkUrlData(document: IDocument, caseId: string, caseType: CaseAllocationType) { + const { uri, referenceId, unSignedUri } = document || {}; + const result = await checkS3Url(uri); if (result) { - return url; + return uri; } else { const signedRequestPayload: ISignedRequest = [ { documentReferenceId: referenceId!!, caseId: caseId, caseType: caseType, + unSignedUri: unSignedUri, }, ]; const response = await getSignedApi(signedRequestPayload); @@ -47,7 +44,7 @@ export const getDocumentDetails = async ( } if (document?.uri) { try { - const imageUrl = await checkUrlData(document.uri, document.referenceId, caseId, caseType); + const imageUrl = await checkUrlData(document, caseId, caseType); if (!imageUrl) return null; const docType = getDocumentType(document?.docContentType); if (!docType) return null; From ca061571bcbb5109e04b157d14085bbae47576a5 Mon Sep 17 00:00:00 2001 From: yashmantri Date: Wed, 20 Sep 2023 13:41:11 +0530 Subject: [PATCH 07/75] TP-38645 | Pdf View Package Added --- android/app/build.gradle | 6 ------ package.json | 2 +- yarn.lock | 39 +++++++++++---------------------------- 3 files changed, 12 insertions(+), 35 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index f6aeb50b..047ab2e5 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -135,12 +135,6 @@ def VERSION_CODE = 83 def VERSION_NAME = "2.3.10" android { - packagingOptions { - pickFirst 'lib/x86/libc++_shared.so' - pickFirst 'lib/x86_64/libc++_shared.so' - pickFirst 'lib/armeabi-v7a/libc++_shared.so' - pickFirst 'lib/arm64-v8a/libc++_shared.so' - } ndkVersion rootProject.ext.ndkVersion compileSdkVersion rootProject.ext.compileSdkVersion diff --git a/package.json b/package.json index ee1e286d..efc4d23e 100644 --- a/package.json +++ b/package.json @@ -68,7 +68,7 @@ "react-native-gzip": "1.0.0", "react-native-image-picker": "4.10.2", "react-native-pager-view": "6.1.2", - "react-native-pdf": "^6.7.1", + "react-native-pdf-light": "2.4.0", "react-native-permissions": "3.6.1", "react-native-qrcode-svg": "^6.2.0", "react-native-safe-area-context": "4.4.1", diff --git a/yarn.lock b/yarn.lock index 81af7968..e97bde22 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1658,16 +1658,16 @@ resolved "https://registry.yarnpkg.com/@react-native/assets/-/assets-1.0.0.tgz#c6f9bf63d274bafc8e970628de24986b30a55c8e" integrity sha512-KrwSpS1tKI70wuKl68DwJZYEvXktDHdZMG0k2AXD/rJVSlB23/X2CB2cutVR0HwNMJIal9HOUOBB2rVfa6UGtQ== -"@react-native/normalize-color@*", "@react-native/normalize-color@^2.0.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@react-native/normalize-color/-/normalize-color-2.1.0.tgz#939b87a9849e81687d3640c5efa2a486ac266f91" - integrity sha512-Z1jQI2NpdFJCVgpY+8Dq/Bt3d+YUi1928Q+/CZm/oh66fzM0RUl54vvuXlPJKybH4pdCZey1eDTPaLHkMPNgWA== - "@react-native/normalize-color@2.0.0": version "2.0.0" resolved "https://registry.yarnpkg.com/@react-native/normalize-color/-/normalize-color-2.0.0.tgz#da955909432474a9a0fe1cbffc66576a0447f567" integrity sha512-Wip/xsc5lw8vsBlmY2MO/gFLp3MvuZ2baBZjDeTjjndMgM0h5sxz7AZR62RDPGgstp8Np7JzjvVqVT7tpFZqsw== +"@react-native/normalize-color@^2.0.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@react-native/normalize-color/-/normalize-color-2.1.0.tgz#939b87a9849e81687d3640c5efa2a486ac266f91" + integrity sha512-Z1jQI2NpdFJCVgpY+8Dq/Bt3d+YUi1928Q+/CZm/oh66fzM0RUl54vvuXlPJKybH4pdCZey1eDTPaLHkMPNgWA== + "@react-native/polyfills@2.0.0": version "2.0.0" resolved "https://registry.yarnpkg.com/@react-native/polyfills/-/polyfills-2.0.0.tgz#4c40b74655c83982c8cf47530ee7dc13d957b6aa" @@ -3344,11 +3344,6 @@ cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3: shebang-command "^2.0.0" which "^2.0.1" -crypto-js@^3.2.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/crypto-js/-/crypto-js-3.3.0.tgz#846dd1cce2f68aacfa156c8578f926a609b7976b" - integrity sha512-DIT51nX0dCfKltpRiXV+/TVZq+Qq2NgF4644+K7Ttnla7zEzqc+kjJyiB96BHNyUTBxyjzRcZYpUdZa+QAqi6Q== - css-select@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/css-select/-/css-select-5.1.0.tgz#b8ebd6554c3637ccc76688804ad3f6a6fdaea8a6" @@ -3561,15 +3556,6 @@ depd@2.0.0: resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== -deprecated-react-native-prop-types@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/deprecated-react-native-prop-types/-/deprecated-react-native-prop-types-2.3.0.tgz#c10c6ee75ff2b6de94bb127f142b814e6e08d9ab" - integrity sha512-pWD0voFtNYxrVqvBMYf5gq3NA2GCpfodS1yNynTPc93AYA/KEMGeWDqqeUB6R2Z9ZofVhks2aeJXiuQqKNpesA== - dependencies: - "@react-native/normalize-color" "*" - invariant "*" - prop-types "*" - destroy@1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" @@ -5064,7 +5050,7 @@ internal-slot@^1.0.3: has "^1.0.3" side-channel "^1.0.4" -invariant@*, invariant@2.2.4, invariant@^2.2.2, invariant@^2.2.4: +invariant@2.2.4, invariant@^2.2.2, invariant@^2.2.4: version "2.2.4" resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== @@ -7547,7 +7533,7 @@ prompts@^2.0.1, prompts@^2.4.0: kleur "^3.0.3" sisteransi "^1.0.5" -prop-types@*, prop-types@15.8.1, prop-types@^15.7.2, prop-types@^15.8.0, prop-types@^15.8.1: +prop-types@15.8.1, prop-types@^15.7.2, prop-types@^15.8.0, prop-types@^15.8.1: version "15.8.1" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5" integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== @@ -7789,13 +7775,10 @@ react-native-pager-view@6.1.2: resolved "https://registry.yarnpkg.com/react-native-pager-view/-/react-native-pager-view-6.1.2.tgz#3522079b9a9d6634ca5e8d153bc0b4d660254552" integrity sha512-qs2KSFc+7N7B+UZ6SG2sTvCkppagm5fVyRclv1KFKc7lDtrhXLzN59tXJw575LDP/dRJoXsNwqUAhZJdws6ABQ== -react-native-pdf@^6.7.1: - version "6.7.1" - resolved "https://registry.yarnpkg.com/react-native-pdf/-/react-native-pdf-6.7.1.tgz#198b8ec3e8f1025ceb43ddfc6bc5b422521c4411" - integrity sha512-zszQygtNBYoUfEtP/fV7zhzGeohDlUksh2p3OzshLrxdY9mw7Tm5VXAxYq4d8HsomRJUbFlJ7rHaTU9AQL800g== - dependencies: - crypto-js "^3.2.0" - deprecated-react-native-prop-types "^2.3.0" +react-native-pdf-light@2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/react-native-pdf-light/-/react-native-pdf-light-2.4.0.tgz#b703a49fb95b6639d3e5151a519643f1c1c52132" + integrity sha512-Dd3xDAR9ZOiX5bvzuZ4RJZSW8CB5YHEUMdV1u8I777Z03pD7ytO5iugEZHsuhVeW1uDP9IE9iX2M/HF/QCOM+Q== react-native-permissions@3.6.1: version "3.6.1" From 1a99997400ead48ec1f2438bdf3f12e78025ec66 Mon Sep 17 00:00:00 2001 From: "aman.singh" Date: Wed, 20 Sep 2023 13:59:50 +0530 Subject: [PATCH 08/75] TP-31303|PDF viewer, and pdf caching| Aman Singh --- src/screens/caseDetails/PDFFullScreen.tsx | 79 +++++++++++++++++------ 1 file changed, 61 insertions(+), 18 deletions(-) diff --git a/src/screens/caseDetails/PDFFullScreen.tsx b/src/screens/caseDetails/PDFFullScreen.tsx index 4bf480a8..e327dc58 100644 --- a/src/screens/caseDetails/PDFFullScreen.tsx +++ b/src/screens/caseDetails/PDFFullScreen.tsx @@ -1,16 +1,20 @@ -import { Dimensions, StyleSheet, View } from 'react-native'; -import React, { useState } from 'react'; -import { GenericStyles } from '../../../RN-UI-LIB/src/styles'; +import React, { useEffect, useState } from 'react'; +import { ActivityIndicator, StyleSheet, View } from 'react-native'; +import RNFetchBlob from 'react-native-blob-util'; +import RNFS from 'react-native-fs'; +import { Pdf } from 'react-native-pdf-light'; import NavigationHeader, { Icon } from '../../../RN-UI-LIB/src/components/NavigationHeader'; -import { goBack } from '../../components/utlis/navigationUtlis'; -import Pdf from 'react-native-pdf'; -import Text from '../../../RN-UI-LIB/src/components/Text'; +import { GenericStyles, SCREEN_HEIGHT, SCREEN_WIDTH } from '../../../RN-UI-LIB/src/styles'; import { COLORS } from '../../../RN-UI-LIB/src/styles/colors'; +import { goBack } from '../../components/utlis/navigationUtlis'; +import Text from '../../../RN-UI-LIB/src/components/Text'; interface ICustomerProfile { route: { params: { pdfUri: string; + cacheFileKey: string; + screenName: string; }; }; } @@ -18,30 +22,69 @@ interface ICustomerProfile { const PDFFullScreen: React.FC = (props) => { const { route: { - params: { pdfUri }, + params: { pdfUri, cacheFileKey, screenName }, }, } = props; - const [error, setError] = useState(false); + const [isLoading, setIsLoading] = useState(false); + const [imageFilePath, setImageFilePath] = useState(''); + const [error, setError] = useState(false); + + useEffect(() => { + const cacheDirectory = RNFS.CachesDirectoryPath; + const sanitizedHighQualityUri = cacheFileKey; + const cacheFilePath = `${cacheDirectory}/${sanitizedHighQualityUri}.pdf`; + const fetchImage = async () => { + setIsLoading(true); + try { + await RNFS.mkdir(cacheDirectory); + const exists = await RNFS.exists(cacheFilePath); + + if (exists) { + setImageFilePath(cacheFilePath); + setIsLoading(false); + return; + } + + const highQualityResponse = await RNFetchBlob.fetch('GET', pdfUri); + + if (highQualityResponse.respInfo.status !== 200) { + setError(true); + } else if (highQualityResponse.respInfo.status === 200) { + const highQualityImageBase64 = await highQualityResponse.base64(); + RNFS.writeFile(cacheFilePath, highQualityImageBase64, 'base64'); + setImageFilePath(cacheFilePath); + setIsLoading(false); + } + } catch (error) { + setIsLoading(false); + setError(true); + } + }; + + fetchImage(); + }, [pdfUri, cacheFileKey]); return ( - + { setError(true); }} - style={styles.pdf} /> - {error && ( - - Error loading pdf - + {isLoading && ( + )} + {error && Error loading PDF} ); }; @@ -57,8 +100,8 @@ const styles = StyleSheet.create({ }, pdf: { flex: 1, - width: Dimensions.get('window').width, - height: Dimensions.get('window').height, + width: SCREEN_WIDTH, + height: SCREEN_HEIGHT, }, errorText: { ...GenericStyles.absolute, From ef520352f25ae5bef9e33fa7482b435dd69c4385 Mon Sep 17 00:00:00 2001 From: yashmantri Date: Wed, 20 Sep 2023 16:24:52 +0530 Subject: [PATCH 09/75] TP-38645 | Pdf View Fix --- src/screens/caseDetails/DocumentDetails.tsx | 6 +++-- src/screens/caseDetails/PDFFullScreen.tsx | 25 +++++++++------------ 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/src/screens/caseDetails/DocumentDetails.tsx b/src/screens/caseDetails/DocumentDetails.tsx index be7972b3..6d9fa221 100644 --- a/src/screens/caseDetails/DocumentDetails.tsx +++ b/src/screens/caseDetails/DocumentDetails.tsx @@ -28,9 +28,11 @@ const DocumentDetails = (props: DocumentDetails) => { referenceId: state.user.user?.referenceId!, })); - const handleOpenPdfPress = (url: string) => { + const handleOpenPdfPress = (url: string, cacheKey: string) => { navigateToScreen('pdfFull', { pdfUri: url, + cacheFileKey: cacheKey, + screenName: 'Aadhar PDF viewer', }); }; @@ -113,7 +115,7 @@ const DocumentDetails = (props: DocumentDetails) => { {document?.icon} {document?.title} - handleOpenPdfPress(document.url)}> + handleOpenPdfPress(document.url, document.docType + caseId)}> Open PDF diff --git a/src/screens/caseDetails/PDFFullScreen.tsx b/src/screens/caseDetails/PDFFullScreen.tsx index e327dc58..31b2370d 100644 --- a/src/screens/caseDetails/PDFFullScreen.tsx +++ b/src/screens/caseDetails/PDFFullScreen.tsx @@ -27,21 +27,21 @@ const PDFFullScreen: React.FC = (props) => { } = props; const [isLoading, setIsLoading] = useState(false); - const [imageFilePath, setImageFilePath] = useState(''); + const [pdfFilePath, setPdfFilePath] = useState(''); const [error, setError] = useState(false); useEffect(() => { const cacheDirectory = RNFS.CachesDirectoryPath; const sanitizedHighQualityUri = cacheFileKey; const cacheFilePath = `${cacheDirectory}/${sanitizedHighQualityUri}.pdf`; - const fetchImage = async () => { + const fetchPdf = async () => { setIsLoading(true); try { await RNFS.mkdir(cacheDirectory); const exists = await RNFS.exists(cacheFilePath); if (exists) { - setImageFilePath(cacheFilePath); + setPdfFilePath(cacheFilePath); setIsLoading(false); return; } @@ -53,7 +53,7 @@ const PDFFullScreen: React.FC = (props) => { } else if (highQualityResponse.respInfo.status === 200) { const highQualityImageBase64 = await highQualityResponse.base64(); RNFS.writeFile(cacheFilePath, highQualityImageBase64, 'base64'); - setImageFilePath(cacheFilePath); + setPdfFilePath(cacheFilePath); setIsLoading(false); } } catch (error) { @@ -62,26 +62,23 @@ const PDFFullScreen: React.FC = (props) => { } }; - fetchImage(); + fetchPdf(); }, [pdfUri, cacheFileKey]); return ( - - { - setError(true); - }} - /> - + {pdfFilePath && ( + + setError(true)} /> + + )} {isLoading && ( )} {error && Error loading PDF} From 37b0a2b527163b06c93d387b9dafb7d87f908f15 Mon Sep 17 00:00:00 2001 From: Aman Chaturvedi Date: Wed, 20 Sep 2023 18:32:54 +0530 Subject: [PATCH 10/75] TP-39795 | Clustering meta addresses --- .../addressGeolocation/AddressContainer.tsx | 21 +++++++++++++++++-- src/types/addressGeolocation.types.ts | 8 +++++++ 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/src/screens/addressGeolocation/AddressContainer.tsx b/src/screens/addressGeolocation/AddressContainer.tsx index 1b590448..8bdc543f 100644 --- a/src/screens/addressGeolocation/AddressContainer.tsx +++ b/src/screens/addressGeolocation/AddressContainer.tsx @@ -28,6 +28,22 @@ function SeparatorBorderComponent() { return ; } +const getAllAddressIds = (groupedAddress: IGroupedAddressesItem) => { + // this array will have groupedAddress?.metaAddress?.id plus all similar address ids plus there is an array of metaaddresses inside these similar addresses, need to append those ids too. + const addressIds = [groupedAddress?.metaAddress?.id]; + groupedAddress?.similarAddresses?.forEach((similarAddress) => { + if (similarAddress?.id) { + addressIds.push(similarAddress.id); + } + similarAddress.metaAddressReferences?.forEach((metaAddress) => { + if (metaAddress?.addressId) { + addressIds.push(metaAddress.addressId); + } + }); + }); + return addressIds; +}; + const AddressContainer: React.FC = ({ groupedAddressList, caseId, @@ -38,10 +54,11 @@ const AddressContainer: React.FC = ({ currentGeolocationCoordinates: state.foregroundService?.deviceGeolocationCoordinate, })); const handleOpenOldFeedbacks = (groupedAddress: IGroupedAddressesItem) => { - const similarAddressIds = groupedAddress?.similarAddresses?.map((item) => item.id) || []; + const addressIds = getAllAddressIds(groupedAddress); + // const similarAddressIds = groupedAddress?.similarAddresses?.map((item) => item.id) || []; const commonParams = { addressText: groupedAddress?.metaAddress?.addressText, - addressReferenceIds: [groupedAddress?.metaAddress?.id, ...similarAddressIds].join(','), + addressReferenceIds: addressIds.join(','), }; handlePageRouting?.(PageRouteEnum.PAST_FEEDBACK_DETAIL, commonParams); }; diff --git a/src/types/addressGeolocation.types.ts b/src/types/addressGeolocation.types.ts index 98d18a41..592d7706 100644 --- a/src/types/addressGeolocation.types.ts +++ b/src/types/addressGeolocation.types.ts @@ -26,6 +26,13 @@ export enum PrimarySourcesType { ACCOUNT_AGGREGATOR = 'ACCOUNT_AGGREGATOR', } +interface IMetaAddress { + addressId: string; + version: string; + runId: string; + taggedAt: string; +} + export interface IAddress { id: string; pinCode: string; @@ -39,6 +46,7 @@ export interface IAddress { groupId: string; primarySource?: PrimarySourcesType; secondarySource?: string; + metaAddressReferences: IMetaAddress[]; } export interface IGroupedAddressesItem { From c7958049ec107c801d0a4ec0dcfdc3fc637378f4 Mon Sep 17 00:00:00 2001 From: yashmantri Date: Thu, 21 Sep 2023 15:19:06 +0530 Subject: [PATCH 11/75] TP-38645 | Pdf View Fix --- package.json | 2 +- src/common/TrackingComponent.tsx | 2 +- src/screens/caseDetails/PDFFullScreen.tsx | 21 +++++++++++++-------- yarn.lock | 8 ++++---- 4 files changed, 19 insertions(+), 14 deletions(-) diff --git a/package.json b/package.json index efc4d23e..dd0fcbad 100644 --- a/package.json +++ b/package.json @@ -68,7 +68,7 @@ "react-native-gzip": "1.0.0", "react-native-image-picker": "4.10.2", "react-native-pager-view": "6.1.2", - "react-native-pdf-light": "2.4.0", + "react-native-pdf-renderer": "1.1.1", "react-native-permissions": "3.6.1", "react-native-qrcode-svg": "^6.2.0", "react-native-safe-area-context": "4.4.1", diff --git a/src/common/TrackingComponent.tsx b/src/common/TrackingComponent.tsx index 5eabd878..8517cd73 100644 --- a/src/common/TrackingComponent.tsx +++ b/src/common/TrackingComponent.tsx @@ -192,7 +192,7 @@ const TrackingComponent: React.FC = ({ children }) => { .then((files) => { for (const file of files) { const filePath = `${directoryPath}/${file}`; - if (!file.endsWith('jpg')) { + if (!file.endsWith('jpg') || !file.endsWith('pdf')) { continue; } RNFS.stat(filePath) diff --git a/src/screens/caseDetails/PDFFullScreen.tsx b/src/screens/caseDetails/PDFFullScreen.tsx index 31b2370d..1a64f7cc 100644 --- a/src/screens/caseDetails/PDFFullScreen.tsx +++ b/src/screens/caseDetails/PDFFullScreen.tsx @@ -1,13 +1,13 @@ import React, { useEffect, useState } from 'react'; -import { ActivityIndicator, StyleSheet, View } from 'react-native'; +import { ActivityIndicator, SafeAreaView, StyleSheet, View } from 'react-native'; import RNFetchBlob from 'react-native-blob-util'; import RNFS from 'react-native-fs'; -import { Pdf } from 'react-native-pdf-light'; import NavigationHeader, { Icon } from '../../../RN-UI-LIB/src/components/NavigationHeader'; import { GenericStyles, SCREEN_HEIGHT, SCREEN_WIDTH } from '../../../RN-UI-LIB/src/styles'; import { COLORS } from '../../../RN-UI-LIB/src/styles/colors'; import { goBack } from '../../components/utlis/navigationUtlis'; import Text from '../../../RN-UI-LIB/src/components/Text'; +import PdfRendererView from 'react-native-pdf-renderer'; interface ICustomerProfile { route: { @@ -49,6 +49,7 @@ const PDFFullScreen: React.FC = (props) => { const highQualityResponse = await RNFetchBlob.fetch('GET', pdfUri); if (highQualityResponse.respInfo.status !== 200) { + setIsLoading(false); setError(true); } else if (highQualityResponse.respInfo.status === 200) { const highQualityImageBase64 = await highQualityResponse.base64(); @@ -69,10 +70,16 @@ const PDFFullScreen: React.FC = (props) => { {pdfFilePath && ( - - setError(true)} /> - + + + )} + {isLoading && ( Date: Thu, 21 Sep 2023 18:23:22 +0530 Subject: [PATCH 12/75] TP-38645 | Screenshot Tracking --- .../com/avapp/ScreenshotBlockerModule.java | 42 +++++++++++++++++++ src/common/Constants.ts | 4 ++ src/hooks/useScreenshotTracking.ts | 37 ++++++++++++++++ 3 files changed, 83 insertions(+) create mode 100644 src/hooks/useScreenshotTracking.ts diff --git a/android/app/src/main/java/com/avapp/ScreenshotBlockerModule.java b/android/app/src/main/java/com/avapp/ScreenshotBlockerModule.java index 62280baa..37cd1b86 100644 --- a/android/app/src/main/java/com/avapp/ScreenshotBlockerModule.java +++ b/android/app/src/main/java/com/avapp/ScreenshotBlockerModule.java @@ -6,12 +6,20 @@ import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.bridge.ReactContextBaseJavaModule; import com.facebook.react.bridge.ReactMethod; import com.facebook.react.modules.core.DeviceEventManagerModule; +import com.facebook.react.bridge.WritableMap; +import com.facebook.react.bridge.Arguments; import android.os.Handler; import android.os.Looper; +import android.content.ContentResolver; +import android.database.ContentObserver; +import android.net.Uri; +import android.provider.MediaStore; public class ScreenshotBlockerModule extends ReactContextBaseJavaModule { private ReactApplicationContext reactContext; + private ContentObserver contentObserver; + private boolean isTracking = false; public ScreenshotBlockerModule(ReactApplicationContext reactContext) { super(reactContext); @@ -56,4 +64,38 @@ public class ScreenshotBlockerModule extends ReactContextBaseJavaModule { }); } + @ReactMethod + public void startScreenshotTracking() { + if (!isTracking) { + isTracking = true; + ContentResolver contentResolver = getCurrentActivity().getContentResolver(); + contentObserver = new ContentObserver(new Handler(Looper.getMainLooper())) { + long lastEventTimestamp = 0; + + @Override + public void onChange(boolean selfChange, Uri uri) { + long currentTimeMillis = System.currentTimeMillis(); + + if (currentTimeMillis - lastEventTimestamp > 1000) { + sendScreenshotEvent(); + lastEventTimestamp = currentTimeMillis; + } + } + }; + + contentResolver.registerContentObserver( + MediaStore.Images.Media.EXTERNAL_CONTENT_URI, + true, + contentObserver + ); + } + } + + private void sendScreenshotEvent() { + WritableMap params = Arguments.createMap(); + params.putBoolean("isScreenshotDetected", true); + reactContext + .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class) + .emit("screenshotTaken", params); + } } \ No newline at end of file diff --git a/src/common/Constants.ts b/src/common/Constants.ts index b7bb48db..3896a70e 100644 --- a/src/common/Constants.ts +++ b/src/common/Constants.ts @@ -95,6 +95,10 @@ export const CLICKSTREAM_EVENT_NAMES = { name: 'FA_LOGIN_SCREEN_SEND_OTP_API_FAILED', description: 'Send OTP API failed', }, + FA_SCREENSHOT_TAKEN: { + name: 'FA_SCREENSHOT_TAKEN', + description: 'Screenshot atempt detected', + }, // OTP screen AV_OTP_SCREEN_LOAD: { name: 'FA_OTP_SCREEN_LOAD', description: 'OTP screen loaded' }, diff --git a/src/hooks/useScreenshotTracking.ts b/src/hooks/useScreenshotTracking.ts new file mode 100644 index 00000000..f9e5e69f --- /dev/null +++ b/src/hooks/useScreenshotTracking.ts @@ -0,0 +1,37 @@ +import { useEffect, useMemo } from 'react'; +import { NativeEventEmitter } from 'react-native'; +import { useAppSelector } from '.'; +import { CLICKSTREAM_EVENT_NAMES } from '../common/Constants'; +import { getCurrentScreen } from '../components/utlis/navigationUtlis'; +import ScreenshotBlocker from '../components/utlis/ScreenshotBlocker'; +import { addClickstreamEvent } from '../services/clickstreamEventService'; + +const useScreenshotTracking = () => { + const { user } = useAppSelector((state) => state.user); + + const screenshotEventEmitter = useMemo(() => new NativeEventEmitter(ScreenshotBlocker), []); + + useEffect(() => { + ScreenshotBlocker.startScreenshotTracking(); + + const screenshotTakenSubscription = screenshotEventEmitter.addListener( + 'screenshotTaken', + (event) => { + if (event?.isScreenshotDetected) { + addClickstreamEvent(CLICKSTREAM_EVENT_NAMES.FA_SCREENSHOT_TAKEN, { + userId: user?.referenceId, + caseId: '', + page: getCurrentScreen(), + }); + return; + } + } + ); + + return () => { + if (screenshotTakenSubscription) screenshotTakenSubscription.remove(); + }; + }, []); +}; + +export default useScreenshotTracking; From 73caa07fdd381d20d7c08cefc8654647a666d384 Mon Sep 17 00:00:00 2001 From: yashmantri Date: Thu, 21 Sep 2023 18:30:49 +0530 Subject: [PATCH 13/75] TP-38645 | Loading Screen --- src/screens/caseDetails/CustomerProfile.tsx | 6 +- src/screens/caseDetails/DocumentDetails.tsx | 180 +++++++++++--------- 2 files changed, 105 insertions(+), 81 deletions(-) diff --git a/src/screens/caseDetails/CustomerProfile.tsx b/src/screens/caseDetails/CustomerProfile.tsx index 58d70cd1..3687e238 100644 --- a/src/screens/caseDetails/CustomerProfile.tsx +++ b/src/screens/caseDetails/CustomerProfile.tsx @@ -45,6 +45,7 @@ const CustomerProfile: React.FC = (props) => { const [retry, setRetry] = useState(true); const [errorCount, setErrorCount] = useState(0); const [isHighQualityImageLoaded, setIsHighQualityImageLoaded] = useState(false); + const [documentsLoading, setDocumentsLoading] = useState(false); const [showLoadingState, setShowLoadingState] = useState(false); const { startTimer, isActive, clearTimer } = useTimeout(() => { setLoading(false); @@ -80,6 +81,7 @@ const CustomerProfile: React.FC = (props) => { useEffect(() => { if (caseDetail) { + setDocumentsLoading(true); const docList: IDocument[] = getDocumentList(caseDetail) || []; const docPromises: Promise[] = []; const updatedDocList = [ @@ -104,7 +106,8 @@ const CustomerProfile: React.FC = (props) => { ) as Array; setDocumentData(documents); }) - .catch(() => {}); + .catch(() => {}) + .finally(() => setDocumentsLoading(false)); } }, [caseDetail]); @@ -213,6 +216,7 @@ const CustomerProfile: React.FC = (props) => { documentData={documentData} customerReferenceId={caseDetail.customerReferenceId} caseId={caseDetail.id} + documentsLoading={documentsLoading} /> diff --git a/src/screens/caseDetails/DocumentDetails.tsx b/src/screens/caseDetails/DocumentDetails.tsx index 6d9fa221..6e2df237 100644 --- a/src/screens/caseDetails/DocumentDetails.tsx +++ b/src/screens/caseDetails/DocumentDetails.tsx @@ -2,6 +2,8 @@ import React, { useState } from 'react'; import { Pressable, StyleSheet, View } from 'react-native'; import WebView from 'react-native-webview'; import Accordion from '../../../RN-UI-LIB/src/components/accordian/Accordian'; +import LineLoader from '../../../RN-UI-LIB/src/components/suspense_loader/LineLoader'; +import SuspenseLoader from '../../../RN-UI-LIB/src/components/suspense_loader/SuspenseLoader'; import Text from '../../../RN-UI-LIB/src/components/Text'; import ArrowSolidDownIcon from '../../../RN-UI-LIB/src/Icons/ArrowSolidDownIcon'; import { GenericStyles, getShadowStyle } from '../../../RN-UI-LIB/src/styles'; @@ -18,10 +20,11 @@ interface DocumentDetails { documentData: Array; customerReferenceId: string; caseId: string; + documentsLoading: boolean; } const DocumentDetails = (props: DocumentDetails) => { - const { documentData, customerReferenceId, caseId } = props; + const { documentData, customerReferenceId, caseId, documentsLoading } = props; const [isExpanded, setIsExpanded] = useState(); const { referenceId } = useAppSelector((state) => ({ @@ -38,89 +41,106 @@ const DocumentDetails = (props: DocumentDetails) => { return ( - {documentData.map((document: DocumentDetail) => - document.docContentType !== 'pdf' ? ( - + + {[...Array(3).keys()].map(() => ( + + ))} + + } + > + {documentData.map((document: DocumentDetail) => + document.docContentType !== 'pdf' ? ( + + {document?.icon} + {document?.title} + + } + customExpandUi={{ + whenCollapsed: ( + + + + ), + whenExpanded: ( + + + + ), + }} + onExpanded={(value) => { + if (isExpanded !== undefined) { + addClickstreamEvent( + value + ? CLICKSTREAM_EVENT_NAMES.FA_CUSTOMER_DOCUMENT_CLICKED + : CLICKSTREAM_EVENT_NAMES.FA_CUSTOMER_DOCUMENT_CLOSE_CLICKED, + { + agentId: referenceId, + customerId: customerReferenceId, + documentIdentifier: document.docType, + documentType: document.docContentType, + } + ); + } + setIsExpanded(value); + }} + > + + {document.docContentType === 'video' ? ( + + ) : ( + + )} + + + ) : ( + + {document?.icon} {document?.title} - } - customExpandUi={{ - whenCollapsed: ( - - - - ), - whenExpanded: ( - - - - ), - }} - onExpanded={(value) => { - if (isExpanded !== undefined) { - addClickstreamEvent( - value - ? CLICKSTREAM_EVENT_NAMES.FA_CUSTOMER_DOCUMENT_CLICKED - : CLICKSTREAM_EVENT_NAMES.FA_CUSTOMER_DOCUMENT_CLOSE_CLICKED, - { - agentId: referenceId, - customerId: customerReferenceId, - documentIdentifier: document.docType, - documentType: document.docContentType, - } - ); - } - setIsExpanded(value); - }} - > - - {document.docContentType === 'video' ? ( - - ) : ( - - )} + handleOpenPdfPress(document.url, document.docType + caseId)} + > + Open PDF + - - ) : ( - - - {document?.icon} - {document?.title} - - handleOpenPdfPress(document.url, document.docType + caseId)}> - Open PDF - - - ) - )} + ) + )} + ); }; From ad35c411bc687498a2a64e8a89c28ecad9a48344 Mon Sep 17 00:00:00 2001 From: yashmantri Date: Fri, 22 Sep 2023 16:23:54 +0530 Subject: [PATCH 14/75] TP-38645 | Caching Issue Fixed + URL Validation --- src/hooks/useS3UrlCheck.ts | 37 +++++++++ src/screens/caseDetails/CustomerProfile.tsx | 14 +++- src/screens/caseDetails/DocumentDetails.tsx | 41 +++++----- .../caseDetails/DocumentImageComponent.tsx | 80 +++++++++++++------ src/screens/caseDetails/PDFFullScreen.tsx | 19 ++++- src/screens/caseDetails/interface.ts | 2 + src/screens/caseDetails/utils/VKYCVideo.tsx | 22 +++++ .../caseDetails/utils/documentUtils.tsx | 34 +++----- 8 files changed, 176 insertions(+), 73 deletions(-) create mode 100644 src/hooks/useS3UrlCheck.ts create mode 100644 src/screens/caseDetails/utils/VKYCVideo.tsx diff --git a/src/hooks/useS3UrlCheck.ts b/src/hooks/useS3UrlCheck.ts new file mode 100644 index 00000000..dee914e3 --- /dev/null +++ b/src/hooks/useS3UrlCheck.ts @@ -0,0 +1,37 @@ +import { useEffect } from 'react'; +import { getSignedApi, ISignedRequest } from '../action/dataActions'; +import { checkS3Url } from '../components/utlis/commonFunctions'; +import { CaseAllocationType } from '../screens/allCases/interface'; + +const useS3UrlCheck = ( + url: string, + documentRefId: string, + caseId: string, + caseType: CaseAllocationType, + unSignedUri: string, + callbackFn: (val: string) => void +) => { + useEffect(() => { + async function checkUrlData() { + const result = await checkS3Url(url); + if (result) { + return url; + } else { + const signedRequestPayload: ISignedRequest = [ + { + documentReferenceId: documentRefId!!, + caseId: caseId, + caseType: caseType, + unSignedUri: unSignedUri, + }, + ]; + const response = await getSignedApi(signedRequestPayload); + const url = response?.imageUrl || ''; + return url; + } + } + checkUrlData().then((res) => callbackFn?.(res)); + }, [url]); +}; + +export default useS3UrlCheck; diff --git a/src/screens/caseDetails/CustomerProfile.tsx b/src/screens/caseDetails/CustomerProfile.tsx index 3687e238..a74d02cd 100644 --- a/src/screens/caseDetails/CustomerProfile.tsx +++ b/src/screens/caseDetails/CustomerProfile.tsx @@ -1,5 +1,5 @@ import { ActivityIndicator, Pressable, ScrollView, StyleSheet, View } from 'react-native'; -import React, { useEffect, useState } from 'react'; +import React, { useEffect, useRef, useState } from 'react'; import { SafeAreaView } from 'react-native-safe-area-context'; import { GenericStyles, SCREEN_WIDTH } from '../../../RN-UI-LIB/src/styles'; import { COLORS } from '../../../RN-UI-LIB/src/styles/colors'; @@ -155,10 +155,18 @@ const CustomerProfile: React.FC = (props) => { const imageUri = getImageURI(); + const scrollRef = useRef(null); + + const scrollByOffset = (scrollY: number) => { + if (scrollRef.current) { + scrollRef?.current?.scrollTo({ x: 0, y: scrollY, animated: true }); + } + }; + return ( goBack()} icon={Icon.close} /> - + {!isHighQualityImageLoaded && ( @@ -216,7 +224,9 @@ const CustomerProfile: React.FC = (props) => { documentData={documentData} customerReferenceId={caseDetail.customerReferenceId} caseId={caseDetail.id} + caseType={caseDetail.caseType} documentsLoading={documentsLoading} + scrollByOffset={scrollByOffset} /> diff --git a/src/screens/caseDetails/DocumentDetails.tsx b/src/screens/caseDetails/DocumentDetails.tsx index 6e2df237..bcd6a955 100644 --- a/src/screens/caseDetails/DocumentDetails.tsx +++ b/src/screens/caseDetails/DocumentDetails.tsx @@ -1,6 +1,5 @@ import React, { useState } from 'react'; import { Pressable, StyleSheet, View } from 'react-native'; -import WebView from 'react-native-webview'; import Accordion from '../../../RN-UI-LIB/src/components/accordian/Accordian'; import LineLoader from '../../../RN-UI-LIB/src/components/suspense_loader/LineLoader'; import SuspenseLoader from '../../../RN-UI-LIB/src/components/suspense_loader/SuspenseLoader'; @@ -12,29 +11,41 @@ import { CLICKSTREAM_EVENT_NAMES } from '../../common/Constants'; import { navigateToScreen } from '../../components/utlis/navigationUtlis'; import { useAppSelector } from '../../hooks'; import { addClickstreamEvent } from '../../services/clickstreamEventService'; +import { CaseAllocationType } from '../allCases/interface'; import DocumentImageComponent from './DocumentImageComponent'; import { DocumentDetail } from './interface'; -import { vkycHtml } from './vkycTemplate'; +import VKYCVideo from './utils/VKYCVideo'; interface DocumentDetails { documentData: Array; customerReferenceId: string; caseId: string; documentsLoading: boolean; + scrollByOffset: (val: number) => void; + caseType: CaseAllocationType; } const DocumentDetails = (props: DocumentDetails) => { - const { documentData, customerReferenceId, caseId, documentsLoading } = props; + const { documentData, customerReferenceId, caseId, documentsLoading, scrollByOffset, caseType } = + props; const [isExpanded, setIsExpanded] = useState(); const { referenceId } = useAppSelector((state) => ({ referenceId: state.user.user?.referenceId!, })); - const handleOpenPdfPress = (url: string, cacheKey: string) => { + const handleOpenPdfPress = ( + document: DocumentDetail, + caseId: string, + caseType: CaseAllocationType + ) => { navigateToScreen('pdfFull', { - pdfUri: url, - cacheFileKey: cacheKey, + pdfUri: document.url, + referenceId: document.documentRefId, + cacheFileKey: document.docType + caseId, + unSignedUri: document.unSignedUri, + caseId, + caseType, screenName: 'Aadhar PDF viewer', }); }; @@ -80,6 +91,7 @@ const DocumentDetails = (props: DocumentDetails) => { ), }} + scrollByOffset={scrollByOffset} onExpanded={(value) => { if (isExpanded !== undefined) { addClickstreamEvent( @@ -104,18 +116,9 @@ const DocumentDetails = (props: DocumentDetails) => { ]} > {document.docContentType === 'video' ? ( - + ) : ( - + )} @@ -132,9 +135,7 @@ const DocumentDetails = (props: DocumentDetails) => { {document?.icon} {document?.title} - handleOpenPdfPress(document.url, document.docType + caseId)} - > + handleOpenPdfPress(document, caseId, caseType)}> Open PDF diff --git a/src/screens/caseDetails/DocumentImageComponent.tsx b/src/screens/caseDetails/DocumentImageComponent.tsx index cf767d21..b80ceeef 100644 --- a/src/screens/caseDetails/DocumentImageComponent.tsx +++ b/src/screens/caseDetails/DocumentImageComponent.tsx @@ -1,20 +1,25 @@ import React, { useState } from 'react'; -import { StyleSheet } from 'react-native'; +import { Modal, StyleSheet, TouchableOpacity } from 'react-native'; import Text from '../../../RN-UI-LIB/src/components/Text'; import { GenericStyles } from '../../../RN-UI-LIB/src/styles'; import { COLORS } from '../../../RN-UI-LIB/src/styles/colors'; import { isNullOrEmptyString } from '../../../RN-UI-LIB/src/utlis/common'; import CachedImage from '../../common/CachedImage'; -import { DOCUMENT_TYPE } from './interface'; +import ExpandableImage from '../../components/expandableImage/ExpandableImage'; +import useS3UrlCheck from '../../hooks/useS3UrlCheck'; +import { CaseAllocationType } from '../allCases/interface'; +import { DocumentDetail, DOCUMENT_TYPE } from './interface'; interface DocumentImageComponentProps { - docType: DOCUMENT_TYPE; - url: string; - id: string; + document: DocumentDetail; + caseId: string; + caseType: CaseAllocationType; } const DocumentImageComponent = (props: DocumentImageComponentProps) => { - const { docType, url, id } = props; + const { document, caseId, caseType } = props; + const { url, docType, unSignedUri, documentRefId } = document; + const [imageUrl, setImageUrl] = useState(url); const [errorModalImage, setErrorModalImage] = useState({ [DOCUMENT_TYPE.AADHAR]: false, [DOCUMENT_TYPE.PAN]: false, @@ -29,6 +34,16 @@ const DocumentImageComponent = (props: DocumentImageComponentProps) => { [DOCUMENT_TYPE.DRIVING_LICENSE]: false, }); + const [isImageExpanded, setIsImageExpanded] = useState(false); + + const handleExpandImage = () => { + setIsImageExpanded(true); + }; + + const handleExpandedImageClose = () => { + setIsImageExpanded(false); + }; + const onLoadStart = (docType: DOCUMENT_TYPE) => { setLoading({ ...loading, @@ -48,34 +63,51 @@ const DocumentImageComponent = (props: DocumentImageComponentProps) => { }); }; + useS3UrlCheck(url, documentRefId, caseId, caseType, unSignedUri, setImageUrl); + return ( <> - { - setErrorModalImage({ - ...errorModalImage, - [docType]: true, - }); - setLoading({ - ...loading, - [docType]: false, - }); - }} - onLoadStart={() => onLoadStart(docType)} - onLoadEnd={() => onLoadEnd(docType)} - /> + + { + setErrorModalImage({ + ...errorModalImage, + [docType]: true, + }); + setLoading({ + ...loading, + [docType]: false, + }); + }} + onLoadStart={() => onLoadStart(docType)} + onLoadEnd={() => onLoadEnd(docType)} + /> + {loading[docType] ? ( - {!isNullOrEmptyString(url) ? 'Loading Image...' : 'No Image Found'} + {!isNullOrEmptyString(imageUrl) ? 'Loading Image...' : 'No Image Found'} ) : errorModalImage[docType] ? ( Error loading image ) : null} + + + ); }; diff --git a/src/screens/caseDetails/PDFFullScreen.tsx b/src/screens/caseDetails/PDFFullScreen.tsx index 1a64f7cc..a24d15a1 100644 --- a/src/screens/caseDetails/PDFFullScreen.tsx +++ b/src/screens/caseDetails/PDFFullScreen.tsx @@ -8,13 +8,19 @@ import { COLORS } from '../../../RN-UI-LIB/src/styles/colors'; import { goBack } from '../../components/utlis/navigationUtlis'; import Text from '../../../RN-UI-LIB/src/components/Text'; import PdfRendererView from 'react-native-pdf-renderer'; +import { CaseAllocationType } from '../allCases/interface'; +import useS3UrlCheck from '../../hooks/useS3UrlCheck'; interface ICustomerProfile { route: { params: { pdfUri: string; + referenceId: string; cacheFileKey: string; screenName: string; + caseId: string; + caseType: CaseAllocationType; + unSignedUri: string; }; }; } @@ -22,13 +28,16 @@ interface ICustomerProfile { const PDFFullScreen: React.FC = (props) => { const { route: { - params: { pdfUri, cacheFileKey, screenName }, + params: { pdfUri, referenceId, cacheFileKey, screenName, caseId, caseType, unSignedUri }, }, } = props; const [isLoading, setIsLoading] = useState(false); const [pdfFilePath, setPdfFilePath] = useState(''); const [error, setError] = useState(false); + const [pdfUrl, setPdfUrl] = useState(pdfUri); + + useS3UrlCheck(pdfUri, referenceId, caseId, caseType, unSignedUri, setPdfUrl); useEffect(() => { const cacheDirectory = RNFS.CachesDirectoryPath; @@ -36,6 +45,7 @@ const PDFFullScreen: React.FC = (props) => { const cacheFilePath = `${cacheDirectory}/${sanitizedHighQualityUri}.pdf`; const fetchPdf = async () => { setIsLoading(true); + setError(false); try { await RNFS.mkdir(cacheDirectory); const exists = await RNFS.exists(cacheFilePath); @@ -43,10 +53,10 @@ const PDFFullScreen: React.FC = (props) => { if (exists) { setPdfFilePath(cacheFilePath); setIsLoading(false); + setError(false); return; } - - const highQualityResponse = await RNFetchBlob.fetch('GET', pdfUri); + const highQualityResponse = await RNFetchBlob.fetch('GET', pdfUrl); if (highQualityResponse.respInfo.status !== 200) { setIsLoading(false); @@ -56,6 +66,7 @@ const PDFFullScreen: React.FC = (props) => { RNFS.writeFile(cacheFilePath, highQualityImageBase64, 'base64'); setPdfFilePath(cacheFilePath); setIsLoading(false); + setError(false); } } catch (error) { setIsLoading(false); @@ -64,7 +75,7 @@ const PDFFullScreen: React.FC = (props) => { }; fetchPdf(); - }, [pdfUri, cacheFileKey]); + }, [pdfUrl, cacheFileKey]); return ( diff --git a/src/screens/caseDetails/interface.ts b/src/screens/caseDetails/interface.ts index 0a680d8c..839cdb88 100644 --- a/src/screens/caseDetails/interface.ts +++ b/src/screens/caseDetails/interface.ts @@ -163,6 +163,8 @@ export interface DocumentDetail { docType: DOCUMENT_TYPE; docContentType: string; url: string; + unSignedUri: string; + documentRefId: string; } export enum FeedbackStatus { diff --git a/src/screens/caseDetails/utils/VKYCVideo.tsx b/src/screens/caseDetails/utils/VKYCVideo.tsx new file mode 100644 index 00000000..aa77deb8 --- /dev/null +++ b/src/screens/caseDetails/utils/VKYCVideo.tsx @@ -0,0 +1,22 @@ +import React, { useState } from 'react'; +import WebView from 'react-native-webview'; +import useS3UrlCheck from '../../../hooks/useS3UrlCheck'; +import { vkycHtml } from '../vkycTemplate'; + +const VKYCVideo = ({ document, caseId, caseType }: any) => { + const { url, unSignedUri, documentRefId } = document; + const [videoUrl, setVideoUrl] = useState(url); + + useS3UrlCheck(url, documentRefId, caseId, caseType, unSignedUri, setVideoUrl); + + return ( + + ); +}; + +export default VKYCVideo; diff --git a/src/screens/caseDetails/utils/documentUtils.tsx b/src/screens/caseDetails/utils/documentUtils.tsx index 8c21b80c..325be12a 100644 --- a/src/screens/caseDetails/utils/documentUtils.tsx +++ b/src/screens/caseDetails/utils/documentUtils.tsx @@ -1,31 +1,9 @@ import ImageIcon from '../../../../RN-UI-LIB/src/Icons/ImageIcon'; import PdfIcon from '../../../../RN-UI-LIB/src/Icons/PdfIcon'; import VideoIcon from '../../../../RN-UI-LIB/src/Icons/VideoIcon'; -import { getSignedApi, ISignedRequest } from '../../../action/dataActions'; -import { checkS3Url } from '../../../components/utlis/commonFunctions'; import { CaseAllocationType } from '../../allCases/interface'; import { DOCUMENT_TYPE, IDocument } from '../interface'; -async function checkUrlData(document: IDocument, caseId: string, caseType: CaseAllocationType) { - const { uri, referenceId, unSignedUri } = document || {}; - const result = await checkS3Url(uri); - if (result) { - return uri; - } else { - const signedRequestPayload: ISignedRequest = [ - { - documentReferenceId: referenceId!!, - caseId: caseId, - caseType: caseType, - unSignedUri: unSignedUri, - }, - ]; - const response = await getSignedApi(signedRequestPayload); - const url = response?.imageUrl || ''; - return url; - } -} - const getDocumentType = (docContentType: string) => { if (!docContentType) return 'image'; if (docContentType.includes('image')) return 'image'; @@ -44,7 +22,7 @@ export const getDocumentDetails = async ( } if (document?.uri) { try { - const imageUrl = await checkUrlData(document, caseId, caseType); + const imageUrl = document.uri; if (!imageUrl) return null; const docType = getDocumentType(document?.docContentType); if (!docType) return null; @@ -56,6 +34,8 @@ export const getDocumentDetails = async ( docType: DOCUMENT_TYPE.VKYC_VIDEO, docContentType: 'video', url: imageUrl, + unSignedUri: document.unSignedUri, + documentRefId: document.referenceId, }; case DOCUMENT_TYPE.PAN: @@ -65,6 +45,8 @@ export const getDocumentDetails = async ( docType: DOCUMENT_TYPE.PAN, docContentType: docType, url: imageUrl, + unSignedUri: document.unSignedUri, + documentRefId: document.referenceId, }; case DOCUMENT_TYPE.AADHAR: @@ -74,6 +56,8 @@ export const getDocumentDetails = async ( docType: DOCUMENT_TYPE.AADHAR, docContentType: docType, url: imageUrl, + unSignedUri: document.unSignedUri, + documentRefId: document.referenceId, }; case DOCUMENT_TYPE.AADHAR_PHOTO: @@ -83,6 +67,8 @@ export const getDocumentDetails = async ( docType: DOCUMENT_TYPE.AADHAR_PHOTO, docContentType: docType, url: imageUrl, + unSignedUri: document.unSignedUri, + documentRefId: document.referenceId, }; case DOCUMENT_TYPE.DRIVING_LICENSE: @@ -92,6 +78,8 @@ export const getDocumentDetails = async ( docType: DOCUMENT_TYPE.DRIVING_LICENSE, docContentType: docType, url: imageUrl, + unSignedUri: document.unSignedUri, + documentRefId: document.referenceId, }; default: From 03b0c317daf100b809e5ca7b002cc6762416beea Mon Sep 17 00:00:00 2001 From: yashmantri Date: Fri, 22 Sep 2023 16:49:01 +0530 Subject: [PATCH 15/75] TP-38645 | Case Id Added For screenshot tracking --- src/components/utlis/commonFunctions.ts | 4 ++-- src/hooks/useScreenshotTracking.ts | 9 ++++++--- src/reducer/allCasesSlice.ts | 6 ++++++ src/screens/auth/AuthRouter.tsx | 2 ++ src/screens/caseDetails/CollectionCaseDetail.tsx | 9 +++++++++ 5 files changed, 25 insertions(+), 5 deletions(-) diff --git a/src/components/utlis/commonFunctions.ts b/src/components/utlis/commonFunctions.ts index caf22894..7cfd9a0d 100644 --- a/src/components/utlis/commonFunctions.ts +++ b/src/components/utlis/commonFunctions.ts @@ -239,8 +239,8 @@ export const findDocumentByDocumentType = ( export const checkS3Url = async (url: string): Promise => { try { - const response = await fetch(url, { method: 'HEAD' }); - return response.ok; + const response = await fetch(url, { method: 'GET' }); + return response?.ok; } catch (error) { return false; } diff --git a/src/hooks/useScreenshotTracking.ts b/src/hooks/useScreenshotTracking.ts index f9e5e69f..c7b32372 100644 --- a/src/hooks/useScreenshotTracking.ts +++ b/src/hooks/useScreenshotTracking.ts @@ -7,7 +7,10 @@ import ScreenshotBlocker from '../components/utlis/ScreenshotBlocker'; import { addClickstreamEvent } from '../services/clickstreamEventService'; const useScreenshotTracking = () => { - const { user } = useAppSelector((state) => state.user); + const { user, allCases } = useAppSelector((state) => ({ + user: state.user, + allCases: state.allCases, + })); const screenshotEventEmitter = useMemo(() => new NativeEventEmitter(ScreenshotBlocker), []); @@ -19,8 +22,8 @@ const useScreenshotTracking = () => { (event) => { if (event?.isScreenshotDetected) { addClickstreamEvent(CLICKSTREAM_EVENT_NAMES.FA_SCREENSHOT_TAKEN, { - userId: user?.referenceId, - caseId: '', + userId: user?.user?.referenceId, + caseId: allCases?.selectedCaseId, page: getCurrentScreen(), }); return; diff --git a/src/reducer/allCasesSlice.ts b/src/reducer/allCasesSlice.ts index bf1ffab6..fae5f5f4 100644 --- a/src/reducer/allCasesSlice.ts +++ b/src/reducer/allCasesSlice.ts @@ -44,6 +44,7 @@ interface IAllCasesSlice { completedList: ICaseItem[]; pinnedList: ICaseItem[]; newVisitedCases: string[]; + selectedCaseId: string; } const initialState: IAllCasesSlice = { @@ -67,6 +68,7 @@ const initialState: IAllCasesSlice = { completedList: [], pinnedList: [], newVisitedCases: [], + selectedCaseId: '', }; const getCaseListComponents = (casesList: ICaseItem[], caseDetails: Record) => { @@ -563,6 +565,9 @@ const allCasesSlice = createSlice({ } }); }, + setSelectedCaseId: (state, action) => { + state.selectedCaseId = action.payload; + }, }, }); @@ -584,6 +589,7 @@ export const { resetNewVisitedCases, syncCasesByFallback, setCasesImageUri, + setSelectedCaseId, } = allCasesSlice.actions; export default allCasesSlice.reducer; diff --git a/src/screens/auth/AuthRouter.tsx b/src/screens/auth/AuthRouter.tsx index a3ab5e9c..26d5ae47 100644 --- a/src/screens/auth/AuthRouter.tsx +++ b/src/screens/auth/AuthRouter.tsx @@ -15,6 +15,7 @@ import useFCM from '../../hooks/useFCM'; import { NetworkStatusService } from '../../services/network-monitoring.service'; import BlockerScreen from '../../common/BlockerScreen'; import CosmosForegroundService from '../../services/foregroundServices/foreground.service'; +import useScreenshotTracking from '../../hooks/useScreenshotTracking'; const AuthRouter = () => { const dispatch = useAppDispatch(); @@ -61,6 +62,7 @@ const AuthRouter = () => { // Firebase cloud messaging listener useFCM(); + useScreenshotTracking(); return isLoggedIn ? ( diff --git a/src/screens/caseDetails/CollectionCaseDetail.tsx b/src/screens/caseDetails/CollectionCaseDetail.tsx index 8027942d..807ed6f1 100644 --- a/src/screens/caseDetails/CollectionCaseDetail.tsx +++ b/src/screens/caseDetails/CollectionCaseDetail.tsx @@ -44,6 +44,7 @@ import { CollectionCaseWidgetId } from '../../types/template.types'; import { useFocusEffect } from '@react-navigation/native'; import ScreenshotBlocker from '../../components/utlis/ScreenshotBlocker'; import { useIsFocused } from '@react-navigation/native'; +import { setSelectedCaseId } from '../../reducer/allCasesSlice'; interface ICaseDetails { route: { @@ -80,6 +81,14 @@ const CollectionCaseDetails: React.FC = (props) => { }, } = props; + useEffect(() => { + dispatch(setSelectedCaseId(caseId)); + + return () => { + dispatch(setSelectedCaseId('')); + }; + }, []); + const dispatch = useAppDispatch(); const isFocused = useIsFocused(); const isOnline = useIsOnline(); From 642ae2673e6e5be95a3f08c6864a660711223d61 Mon Sep 17 00:00:00 2001 From: yashmantri Date: Wed, 27 Sep 2023 11:17:37 +0530 Subject: [PATCH 16/75] TP-38645 | Cached Image Viewed in Image Viewer + Bug Fix --- src/hooks/useS3UrlCheck.ts | 10 +++- .../caseDetails/CollectionCaseDetail.tsx | 4 +- src/screens/caseDetails/CustomerProfile.tsx | 59 +++++++++++++++---- src/screens/caseDetails/DocumentDetails.tsx | 12 +++- .../caseDetails/DocumentImageComponent.tsx | 20 ++++--- src/screens/caseDetails/PDFFullScreen.tsx | 7 ++- .../caseDetails/utils/documentUtils.tsx | 10 ++++ 7 files changed, 94 insertions(+), 28 deletions(-) diff --git a/src/hooks/useS3UrlCheck.ts b/src/hooks/useS3UrlCheck.ts index dee914e3..f8e91c8d 100644 --- a/src/hooks/useS3UrlCheck.ts +++ b/src/hooks/useS3UrlCheck.ts @@ -9,7 +9,8 @@ const useS3UrlCheck = ( caseId: string, caseType: CaseAllocationType, unSignedUri: string, - callbackFn: (val: string) => void + callbackFn: (val: string) => void, + setValidator?: (val: boolean) => void ) => { useEffect(() => { async function checkUrlData() { @@ -30,8 +31,11 @@ const useS3UrlCheck = ( return url; } } - checkUrlData().then((res) => callbackFn?.(res)); - }, [url]); + setValidator?.(true); + checkUrlData() + .then((res) => callbackFn?.(res)) + .finally(() => setValidator?.(false)); + }, []); }; export default useS3UrlCheck; diff --git a/src/screens/caseDetails/CollectionCaseDetail.tsx b/src/screens/caseDetails/CollectionCaseDetail.tsx index 807ed6f1..e658383e 100644 --- a/src/screens/caseDetails/CollectionCaseDetail.tsx +++ b/src/screens/caseDetails/CollectionCaseDetail.tsx @@ -82,12 +82,12 @@ const CollectionCaseDetails: React.FC = (props) => { } = props; useEffect(() => { - dispatch(setSelectedCaseId(caseId)); + if (caseId) dispatch(setSelectedCaseId(caseId)); return () => { dispatch(setSelectedCaseId('')); }; - }, []); + }, [caseId]); const dispatch = useAppDispatch(); const isFocused = useIsFocused(); diff --git a/src/screens/caseDetails/CustomerProfile.tsx b/src/screens/caseDetails/CustomerProfile.tsx index a74d02cd..bd15ab89 100644 --- a/src/screens/caseDetails/CustomerProfile.tsx +++ b/src/screens/caseDetails/CustomerProfile.tsx @@ -1,4 +1,12 @@ -import { ActivityIndicator, Pressable, ScrollView, StyleSheet, View } from 'react-native'; +import { + ActivityIndicator, + Modal, + Pressable, + ScrollView, + StyleSheet, + TouchableOpacity, + View, +} from 'react-native'; import React, { useEffect, useRef, useState } from 'react'; import { SafeAreaView } from 'react-native-safe-area-context'; import { GenericStyles, SCREEN_WIDTH } from '../../../RN-UI-LIB/src/styles'; @@ -16,7 +24,7 @@ import { goBack } from '../../components/utlis/navigationUtlis'; import ScreenshotBlocker from '../../components/utlis/ScreenshotBlocker'; import { useFocusEffect } from '@react-navigation/native'; import DocumentDetails from './DocumentDetails'; -import { getDocumentDetails } from './utils/documentUtils'; +import { getCachedImageBase64, getDocumentDetails } from './utils/documentUtils'; import CachedImage from '../../common/CachedImage'; import ImagePlaceholderError from '../../assets/icons/ImagePlaceholderError'; import RetryIcon from '../../assets/icons/RetryIcon'; @@ -25,6 +33,7 @@ import { useTimeout } from 'react-native-toast-message/lib/src/hooks'; import { DELAY_FOR_PAINTING_IMAGE } from '../../common/Constants'; import Text from '../../../RN-UI-LIB/src/components/Text'; import { isNullOrEmptyString } from '../../../RN-UI-LIB/src/utlis/common'; +import ExpandableImage from '../../components/expandableImage/ExpandableImage'; interface ICustomerProfile { route: { @@ -47,6 +56,8 @@ const CustomerProfile: React.FC = (props) => { const [isHighQualityImageLoaded, setIsHighQualityImageLoaded] = useState(false); const [documentsLoading, setDocumentsLoading] = useState(false); const [showLoadingState, setShowLoadingState] = useState(false); + const [cachedImageBase64, setCachedImageBase64] = useState(''); + const { startTimer, isActive, clearTimer } = useTimeout(() => { setLoading(false); }, DELAY_FOR_PAINTING_IMAGE); @@ -163,6 +174,17 @@ const CustomerProfile: React.FC = (props) => { } }; + const [isImageExpanded, setIsImageExpanded] = useState(false); + + const handleExpandImage = () => { + getCachedImageBase64(caseDetail.id, setCachedImageBase64); + setIsImageExpanded(true); + }; + + const handleExpandedImageClose = () => { + setIsImageExpanded(false); + }; + return ( goBack()} icon={Icon.close} /> @@ -184,15 +206,17 @@ const CustomerProfile: React.FC = (props) => { onError={onErrorLowResImage} /> )} - + + + {loading ? ( {!isNullOrEmptyString(imageUri) ? '' : 'No Image Found'} @@ -229,6 +253,19 @@ const CustomerProfile: React.FC = (props) => { scrollByOffset={scrollByOffset} /> + + + ); }; diff --git a/src/screens/caseDetails/DocumentDetails.tsx b/src/screens/caseDetails/DocumentDetails.tsx index bcd6a955..bb027880 100644 --- a/src/screens/caseDetails/DocumentDetails.tsx +++ b/src/screens/caseDetails/DocumentDetails.tsx @@ -128,14 +128,19 @@ const DocumentDetails = (props: DocumentDetails) => { styles.accordionStyles, GenericStyles.row, GenericStyles.justifyContentSpaceBetween, - { marginBottom: 12, backgroundColor: COLORS.TEXT.WHITE, paddingHorizontal: 16 }, + GenericStyles.mb12, + GenericStyles.whiteBackground, + styles.pt0, ]} > - + {document?.icon} {document?.title} - handleOpenPdfPress(document, caseId, caseType)}> + handleOpenPdfPress(document, caseId, caseType)} + style={[GenericStyles.ph16, GenericStyles.pt12]} + > Open PDF @@ -179,6 +184,7 @@ const styles = StyleSheet.create({ paddingHorizontal: 0, marginBottom: 16, }, + pt0: { paddingTop: 0 }, }); export default DocumentDetails; diff --git a/src/screens/caseDetails/DocumentImageComponent.tsx b/src/screens/caseDetails/DocumentImageComponent.tsx index b80ceeef..856dda62 100644 --- a/src/screens/caseDetails/DocumentImageComponent.tsx +++ b/src/screens/caseDetails/DocumentImageComponent.tsx @@ -9,6 +9,7 @@ import ExpandableImage from '../../components/expandableImage/ExpandableImage'; import useS3UrlCheck from '../../hooks/useS3UrlCheck'; import { CaseAllocationType } from '../allCases/interface'; import { DocumentDetail, DOCUMENT_TYPE } from './interface'; +import { getCachedImageBase64 } from './utils/documentUtils'; interface DocumentImageComponentProps { document: DocumentDetail; @@ -20,6 +21,8 @@ const DocumentImageComponent = (props: DocumentImageComponentProps) => { const { document, caseId, caseType } = props; const { url, docType, unSignedUri, documentRefId } = document; const [imageUrl, setImageUrl] = useState(url); + const [isValidating, setIsValidating] = useState(false); + const [cachedImageBase64, setCachedImageBase64] = useState(''); const [errorModalImage, setErrorModalImage] = useState({ [DOCUMENT_TYPE.AADHAR]: false, [DOCUMENT_TYPE.PAN]: false, @@ -37,6 +40,7 @@ const DocumentImageComponent = (props: DocumentImageComponentProps) => { const [isImageExpanded, setIsImageExpanded] = useState(false); const handleExpandImage = () => { + getCachedImageBase64(docType + caseId, setCachedImageBase64); setIsImageExpanded(true); }; @@ -63,7 +67,7 @@ const DocumentImageComponent = (props: DocumentImageComponentProps) => { }); }; - useS3UrlCheck(url, documentRefId, caseId, caseType, unSignedUri, setImageUrl); + useS3UrlCheck(url, documentRefId, caseId, caseType, unSignedUri, setImageUrl, setIsValidating); return ( <> @@ -86,15 +90,17 @@ const DocumentImageComponent = (props: DocumentImageComponentProps) => { onLoadEnd={() => onLoadEnd(docType)} /> - {loading[docType] ? ( + {loading[docType] && ( {!isNullOrEmptyString(imageUrl) ? 'Loading Image...' : 'No Image Found'} - ) : errorModalImage[docType] ? ( + )} + {errorModalImage[docType] && ( - Error loading image + Error loading image{isValidating && '. Retrying !!'} - ) : null} + )} + { animationType="fade" > diff --git a/src/screens/caseDetails/PDFFullScreen.tsx b/src/screens/caseDetails/PDFFullScreen.tsx index a24d15a1..0983a62a 100644 --- a/src/screens/caseDetails/PDFFullScreen.tsx +++ b/src/screens/caseDetails/PDFFullScreen.tsx @@ -36,8 +36,9 @@ const PDFFullScreen: React.FC = (props) => { const [pdfFilePath, setPdfFilePath] = useState(''); const [error, setError] = useState(false); const [pdfUrl, setPdfUrl] = useState(pdfUri); + const [isValidating, setIsValidating] = useState(false); - useS3UrlCheck(pdfUri, referenceId, caseId, caseType, unSignedUri, setPdfUrl); + useS3UrlCheck(pdfUri, referenceId, caseId, caseType, unSignedUri, setPdfUrl, setIsValidating); useEffect(() => { const cacheDirectory = RNFS.CachesDirectoryPath; @@ -99,7 +100,9 @@ const PDFFullScreen: React.FC = (props) => { color={COLORS.BASE.BLUE} /> )} - {error && Error loading PDF} + {error && ( + Error loading PDF{isValidating && '. Retrying !!'} + )} ); }; diff --git a/src/screens/caseDetails/utils/documentUtils.tsx b/src/screens/caseDetails/utils/documentUtils.tsx index 325be12a..a50cd65a 100644 --- a/src/screens/caseDetails/utils/documentUtils.tsx +++ b/src/screens/caseDetails/utils/documentUtils.tsx @@ -3,6 +3,7 @@ import PdfIcon from '../../../../RN-UI-LIB/src/Icons/PdfIcon'; import VideoIcon from '../../../../RN-UI-LIB/src/Icons/VideoIcon'; import { CaseAllocationType } from '../../allCases/interface'; import { DOCUMENT_TYPE, IDocument } from '../interface'; +import RNFS from 'react-native-fs'; const getDocumentType = (docContentType: string) => { if (!docContentType) return 'image'; @@ -91,3 +92,12 @@ export const getDocumentDetails = async ( } return null; }; + +export const getCachedImageBase64 = (cacheKey: string, callbackFn: (val: string) => void) => { + const cacheDirectory = RNFS.CachesDirectoryPath; + const cacheFilePath = `${cacheDirectory}/${cacheKey}.jpg`; + + RNFS.readFile(cacheFilePath, 'base64').then((data) => { + callbackFn(`data:image/png;base64,${data}`); + }); +}; From b687f9cb6b8b46fb0ada91f77b28631d714d558a Mon Sep 17 00:00:00 2001 From: yashmantri Date: Wed, 27 Sep 2023 14:20:12 +0530 Subject: [PATCH 17/75] TP-38645 | Screenshot Tracking Fix --- src/hooks/useScreenshotTracking.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/hooks/useScreenshotTracking.ts b/src/hooks/useScreenshotTracking.ts index c7b32372..13db1aca 100644 --- a/src/hooks/useScreenshotTracking.ts +++ b/src/hooks/useScreenshotTracking.ts @@ -22,9 +22,9 @@ const useScreenshotTracking = () => { (event) => { if (event?.isScreenshotDetected) { addClickstreamEvent(CLICKSTREAM_EVENT_NAMES.FA_SCREENSHOT_TAKEN, { - userId: user?.user?.referenceId, - caseId: allCases?.selectedCaseId, - page: getCurrentScreen(), + userId: user?.user?.referenceId ?? '', + caseId: allCases.selectedCaseId ?? '', + page: getCurrentScreen()?.name, }); return; } @@ -34,7 +34,7 @@ const useScreenshotTracking = () => { return () => { if (screenshotTakenSubscription) screenshotTakenSubscription.remove(); }; - }, []); + }, [allCases?.selectedCaseId, user?.user?.referenceId]); }; export default useScreenshotTracking; From 7e9adc434e30f8ca89a97737c9ca935ed7d80de6 Mon Sep 17 00:00:00 2001 From: yashmantri Date: Wed, 27 Sep 2023 15:43:38 +0530 Subject: [PATCH 18/75] TP-38645 | Screenshot bug fix --- src/screens/auth/ProtectedRouter.tsx | 11 ++++++ src/screens/caseDetails/CustomerProfile.tsx | 25 +------------ .../caseDetails/DocumentImageComponent.tsx | 27 ++------------ src/screens/caseDetails/ImageViewer.tsx | 35 +++++++++++++++++++ src/screens/caseDetails/PDFFullScreen.tsx | 4 +-- .../caseDetails/utils/documentUtils.tsx | 8 +++-- 6 files changed, 57 insertions(+), 53 deletions(-) create mode 100644 src/screens/caseDetails/ImageViewer.tsx diff --git a/src/screens/auth/ProtectedRouter.tsx b/src/screens/auth/ProtectedRouter.tsx index 11615cf2..46ab3068 100644 --- a/src/screens/auth/ProtectedRouter.tsx +++ b/src/screens/auth/ProtectedRouter.tsx @@ -34,6 +34,7 @@ import TodoList from '../todoList/TodoList'; import UngroupedAddressContainer from '../addressGeolocation/UngroupedAddressContainer'; import { getAgentDetail } from '../../action/authActions'; import PDFFullScreen from '../caseDetails/PDFFullScreen'; +import ImageViewer from '../caseDetails/ImageViewer'; const Stack = createNativeStackNavigator(); @@ -187,6 +188,16 @@ const ProtectedRouter = () => { }} listeners={getScreenFocusListenerObj} /> + null, + animationDuration: SCREEN_ANIMATION_DURATION, + animation: 'none', + }} + listeners={getScreenFocusListenerObj} + /> = (props) => { const [isHighQualityImageLoaded, setIsHighQualityImageLoaded] = useState(false); const [documentsLoading, setDocumentsLoading] = useState(false); const [showLoadingState, setShowLoadingState] = useState(false); - const [cachedImageBase64, setCachedImageBase64] = useState(''); const { startTimer, isActive, clearTimer } = useTimeout(() => { setLoading(false); @@ -174,15 +171,8 @@ const CustomerProfile: React.FC = (props) => { } }; - const [isImageExpanded, setIsImageExpanded] = useState(false); - const handleExpandImage = () => { - getCachedImageBase64(caseDetail.id, setCachedImageBase64); - setIsImageExpanded(true); - }; - - const handleExpandedImageClose = () => { - setIsImageExpanded(false); + getCachedImageBase64(caseDetail.id); }; return ( @@ -253,19 +243,6 @@ const CustomerProfile: React.FC = (props) => { scrollByOffset={scrollByOffset} /> - - - ); }; diff --git a/src/screens/caseDetails/DocumentImageComponent.tsx b/src/screens/caseDetails/DocumentImageComponent.tsx index 856dda62..04bedb6d 100644 --- a/src/screens/caseDetails/DocumentImageComponent.tsx +++ b/src/screens/caseDetails/DocumentImageComponent.tsx @@ -1,11 +1,10 @@ import React, { useState } from 'react'; -import { Modal, StyleSheet, TouchableOpacity } from 'react-native'; +import { StyleSheet, TouchableOpacity } from 'react-native'; import Text from '../../../RN-UI-LIB/src/components/Text'; import { GenericStyles } from '../../../RN-UI-LIB/src/styles'; import { COLORS } from '../../../RN-UI-LIB/src/styles/colors'; import { isNullOrEmptyString } from '../../../RN-UI-LIB/src/utlis/common'; import CachedImage from '../../common/CachedImage'; -import ExpandableImage from '../../components/expandableImage/ExpandableImage'; import useS3UrlCheck from '../../hooks/useS3UrlCheck'; import { CaseAllocationType } from '../allCases/interface'; import { DocumentDetail, DOCUMENT_TYPE } from './interface'; @@ -22,7 +21,6 @@ const DocumentImageComponent = (props: DocumentImageComponentProps) => { const { url, docType, unSignedUri, documentRefId } = document; const [imageUrl, setImageUrl] = useState(url); const [isValidating, setIsValidating] = useState(false); - const [cachedImageBase64, setCachedImageBase64] = useState(''); const [errorModalImage, setErrorModalImage] = useState({ [DOCUMENT_TYPE.AADHAR]: false, [DOCUMENT_TYPE.PAN]: false, @@ -37,15 +35,8 @@ const DocumentImageComponent = (props: DocumentImageComponentProps) => { [DOCUMENT_TYPE.DRIVING_LICENSE]: false, }); - const [isImageExpanded, setIsImageExpanded] = useState(false); - const handleExpandImage = () => { - getCachedImageBase64(docType + caseId, setCachedImageBase64); - setIsImageExpanded(true); - }; - - const handleExpandedImageClose = () => { - setIsImageExpanded(false); + getCachedImageBase64(docType + caseId); }; const onLoadStart = (docType: DOCUMENT_TYPE) => { @@ -100,20 +91,6 @@ const DocumentImageComponent = (props: DocumentImageComponentProps) => { Error loading image{isValidating && '. Retrying !!'} )} - - - - ); }; diff --git a/src/screens/caseDetails/ImageViewer.tsx b/src/screens/caseDetails/ImageViewer.tsx new file mode 100644 index 00000000..18d5b2c8 --- /dev/null +++ b/src/screens/caseDetails/ImageViewer.tsx @@ -0,0 +1,35 @@ +import React from 'react'; +import { View } from 'react-native'; +import { GenericStyles } from '../../../RN-UI-LIB/src/styles'; +import { goBack } from '../../components/utlis/navigationUtlis'; +import ExpandableImage from '../../components/expandableImage/ExpandableImage'; + +interface ImageViewer { + route: { + params: { + imageUrl: string; + headerTitle: string; + }; + }; +} + +const ImageViewer: React.FC = (props) => { + const { + route: { + params: { imageUrl, headerTitle }, + }, + } = props; + + return ( + + + + ); +}; + +export default ImageViewer; diff --git a/src/screens/caseDetails/PDFFullScreen.tsx b/src/screens/caseDetails/PDFFullScreen.tsx index 0983a62a..10c82116 100644 --- a/src/screens/caseDetails/PDFFullScreen.tsx +++ b/src/screens/caseDetails/PDFFullScreen.tsx @@ -11,7 +11,7 @@ import PdfRendererView from 'react-native-pdf-renderer'; import { CaseAllocationType } from '../allCases/interface'; import useS3UrlCheck from '../../hooks/useS3UrlCheck'; -interface ICustomerProfile { +interface IPdfFullScreen { route: { params: { pdfUri: string; @@ -25,7 +25,7 @@ interface ICustomerProfile { }; } -const PDFFullScreen: React.FC = (props) => { +const PDFFullScreen: React.FC = (props) => { const { route: { params: { pdfUri, referenceId, cacheFileKey, screenName, caseId, caseType, unSignedUri }, diff --git a/src/screens/caseDetails/utils/documentUtils.tsx b/src/screens/caseDetails/utils/documentUtils.tsx index a50cd65a..a3894acb 100644 --- a/src/screens/caseDetails/utils/documentUtils.tsx +++ b/src/screens/caseDetails/utils/documentUtils.tsx @@ -4,6 +4,7 @@ import VideoIcon from '../../../../RN-UI-LIB/src/Icons/VideoIcon'; import { CaseAllocationType } from '../../allCases/interface'; import { DOCUMENT_TYPE, IDocument } from '../interface'; import RNFS from 'react-native-fs'; +import { navigateToScreen } from '../../../components/utlis/navigationUtlis'; const getDocumentType = (docContentType: string) => { if (!docContentType) return 'image'; @@ -93,11 +94,14 @@ export const getDocumentDetails = async ( return null; }; -export const getCachedImageBase64 = (cacheKey: string, callbackFn: (val: string) => void) => { +export const getCachedImageBase64 = (cacheKey: string) => { const cacheDirectory = RNFS.CachesDirectoryPath; const cacheFilePath = `${cacheDirectory}/${cacheKey}.jpg`; RNFS.readFile(cacheFilePath, 'base64').then((data) => { - callbackFn(`data:image/png;base64,${data}`); + navigateToScreen('imageFull', { + imageUrl: `data:image/png;base64,${data}`, + headerTitle: 'Image Viewer', + }); }); }; From 7dd6a2c7692399adac6ebd43ec47fa8c2d5814af Mon Sep 17 00:00:00 2001 From: ShriPrakashBajpai Date: Wed, 4 Oct 2023 13:04:17 +0530 Subject: [PATCH 19/75] Fetching from remote config --- App.tsx | 1 + src/common/BlacklistedAppsList.tsx | 7 +++++++ src/services/blacklistedApps.service.ts | 14 ++++++++++++++ src/services/firebaseFetchAndUpdate.service.ts | 8 +++++++- 4 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 src/common/BlacklistedAppsList.tsx create mode 100644 src/services/blacklistedApps.service.ts diff --git a/App.tsx b/App.tsx index 5539ee6b..6293ff41 100644 --- a/App.tsx +++ b/App.tsx @@ -44,6 +44,7 @@ import { GlobalImageMap, hydrateGlobalImageMap } from './src/common/CachedImage' import analytics from '@react-native-firebase/analytics'; import handleUpdatedConfigureValuesFromFirebase from './src/services/firebaseFetchAndUpdate.service'; import { addClickstreamEvent } from './src/services/clickstreamEventService'; +import handleBlacklistedAppsForBlockingCosmos from '@services/blacklistedApps.service'; initSentry(); diff --git a/src/common/BlacklistedAppsList.tsx b/src/common/BlacklistedAppsList.tsx new file mode 100644 index 00000000..b0493041 --- /dev/null +++ b/src/common/BlacklistedAppsList.tsx @@ -0,0 +1,7 @@ +let BLACKLISTED_APPS_LIST: string[] = []; + +export const getBlacklistedAppsList = () => BLACKLISTED_APPS_LIST; + +export const setBlacklistedAppsList = (blacklistedAppsString: string) => { + BLACKLISTED_APPS_LIST = blacklistedAppsString.split(','); +}; diff --git a/src/services/blacklistedApps.service.ts b/src/services/blacklistedApps.service.ts new file mode 100644 index 00000000..fea99157 --- /dev/null +++ b/src/services/blacklistedApps.service.ts @@ -0,0 +1,14 @@ +import { getBlacklistedAppsList } from '@common/BlacklistedAppsList'; +import { getAllInstalledApp } from '@components/utlis/DeviceUtils'; +import remoteConfig from '@react-native-firebase/remote-config'; +import { get } from 'react-hook-form'; + +const handleBlacklistedAppsForBlockingCosmos = () => { + const blacklistedApps = getBlacklistedAppsList(); + console.log({ blacklistedApps }); + getAllInstalledApp().then((apps) => { + console.log(apps); + }); +}; + +export default handleBlacklistedAppsForBlockingCosmos; diff --git a/src/services/firebaseFetchAndUpdate.service.ts b/src/services/firebaseFetchAndUpdate.service.ts index 1816fb35..09d7991a 100644 --- a/src/services/firebaseFetchAndUpdate.service.ts +++ b/src/services/firebaseFetchAndUpdate.service.ts @@ -4,8 +4,11 @@ import { setActivityTimeWindowHigh, setActivityTimeWindowMedium, } from '../common/AgentActivityConfigurableConstants'; +import { setBlacklistedAppsList } from '@common/BlacklistedAppsList'; +import handleBlacklistedAppsForBlockingCosmos from './blacklistedApps.service'; -const FIREBASE_FETCH_TIME = 15 * 60; +// const FIREBASE_FETCH_TIME = 15 * 60; +const FIREBASE_FETCH_TIME = 1; async function handleUpdatedConfigureValuesFromFirebase() { await remoteConfig().fetch(FIREBASE_FETCH_TIME); //15 minutes remoteConfig() @@ -28,9 +31,12 @@ async function handleUpdatedConfigureValuesFromFirebase() { const ACTIVITY_TIME_WINDOW_MEDIUM = remoteConfig() .getValue('ACTIVITY_TIME_WINDOW_MEDIUM') .asNumber(); + const BLACKLISTED_APPS = remoteConfig().getValue('BLACKLISTED_APPS').asString(); setActivityTimeOnApp(ACTIVITY_TIME_ON_APP); setActivityTimeWindowHigh(ACTIVITY_TIME_WINDOW_HIGH); setActivityTimeWindowMedium(ACTIVITY_TIME_WINDOW_MEDIUM); + setBlacklistedAppsList(BLACKLISTED_APPS); + handleBlacklistedAppsForBlockingCosmos(); }); } From 0210dcdf3bf57eef7ef3bcc406beb4f83863e6c8 Mon Sep 17 00:00:00 2001 From: ShriPrakashBajpai Date: Wed, 4 Oct 2023 15:38:23 +0530 Subject: [PATCH 20/75] Handled blacklisted apps --- src/services/blacklistedApps.service.ts | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/services/blacklistedApps.service.ts b/src/services/blacklistedApps.service.ts index fea99157..61097e57 100644 --- a/src/services/blacklistedApps.service.ts +++ b/src/services/blacklistedApps.service.ts @@ -3,11 +3,22 @@ import { getAllInstalledApp } from '@components/utlis/DeviceUtils'; import remoteConfig from '@react-native-firebase/remote-config'; import { get } from 'react-hook-form'; +function isBlacklistAppPresent(installedApps: string[], blacklistedApps: string[]) { + const installedAppsSet = new Set(installedApps); + for (const app of blacklistedApps) { + if (installedAppsSet.has(app)) { + return true; + } + } + return false; +} + const handleBlacklistedAppsForBlockingCosmos = () => { const blacklistedApps = getBlacklistedAppsList(); - console.log({ blacklistedApps }); getAllInstalledApp().then((apps) => { - console.log(apps); + const appsArray = JSON.parse(apps); + const installedApps = appsArray.map((app) => app.packageName); + console.log(isBlacklistAppPresent(installedApps, blacklistedApps)); }); }; From 8c0ad7647d4a7bbff65a2c18ef5f5263e9084153 Mon Sep 17 00:00:00 2001 From: ShriPrakashBajpai Date: Wed, 4 Oct 2023 18:15:48 +0530 Subject: [PATCH 21/75] List obtained with names of app --- App.tsx | 6 +- .../java/com/avapp/DeviceUtilsModule.java | 11 ++ src/assets/images/BlacklistAppsImage.tsx | 110 ++++++++++++++++++ src/screens/permissions/BlockerScreen.tsx | 60 ++++++++++ src/services/blacklistedApps.service.ts | 21 ++-- 5 files changed, 198 insertions(+), 10 deletions(-) create mode 100644 src/assets/images/BlacklistAppsImage.tsx create mode 100644 src/screens/permissions/BlockerScreen.tsx diff --git a/App.tsx b/App.tsx index 6293ff41..bedf713c 100644 --- a/App.tsx +++ b/App.tsx @@ -45,6 +45,7 @@ import analytics from '@react-native-firebase/analytics'; import handleUpdatedConfigureValuesFromFirebase from './src/services/firebaseFetchAndUpdate.service'; import { addClickstreamEvent } from './src/services/clickstreamEventService'; import handleBlacklistedAppsForBlockingCosmos from '@services/blacklistedApps.service'; +import BlockerScreen from './src/screens/permissions/BlockerScreen'; initSentry(); @@ -154,7 +155,7 @@ function App() { loading={} persistor={persistor} > - { const currentRouteName = getActiveRouteName(state); @@ -182,7 +183,8 @@ function App() { } /> - + */} + ); diff --git a/android/app/src/main/java/com/avapp/DeviceUtilsModule.java b/android/app/src/main/java/com/avapp/DeviceUtilsModule.java index 879a05fe..d626fbab 100644 --- a/android/app/src/main/java/com/avapp/DeviceUtilsModule.java +++ b/android/app/src/main/java/com/avapp/DeviceUtilsModule.java @@ -95,11 +95,22 @@ public class DeviceUtilsModule extends ReactContextBaseJavaModule { List packages = packageManager.getInstalledApplications(PackageManager.GET_META_DATA); JSONArray jsonArray = new JSONArray(); for (PackageInfo packageInfo : installedPackages) { + + final PackageManager pm = RNContext.getApplicationContext().getPackageManager(); + ApplicationInfo ai; + try { + ai = pm.getApplicationInfo( packageInfo.packageName, 0); + } catch (final PackageManager.NameNotFoundException e) { + ai = null; + } + final String applicationName = (String) (ai != null ? pm.getApplicationLabel(ai) : "(unknown)"); + JSONObject mainObject = new JSONObject(); JSONObject appObject = new JSONObject(); appObject.put("appName",packageInfo.applicationInfo.processName); appObject.put("firstInstallTime", packageInfo.firstInstallTime); appObject.put("lastUpdateTime", packageInfo.lastUpdateTime); + appObject.put("applicationName", applicationName); mainObject.put("packageName", packageInfo.packageName); mainObject.put("appDetails", appObject); jsonArray.put(mainObject); diff --git a/src/assets/images/BlacklistAppsImage.tsx b/src/assets/images/BlacklistAppsImage.tsx new file mode 100644 index 00000000..7d0d81ec --- /dev/null +++ b/src/assets/images/BlacklistAppsImage.tsx @@ -0,0 +1,110 @@ +import * as React from 'react'; +import Svg, { Path, Ellipse } from 'react-native-svg'; + +const BlacklistAppsImage = () => ( + + + + + + + + + + + + + + + + +); + +export default BlacklistAppsImage; diff --git a/src/screens/permissions/BlockerScreen.tsx b/src/screens/permissions/BlockerScreen.tsx new file mode 100644 index 00000000..cfec56e6 --- /dev/null +++ b/src/screens/permissions/BlockerScreen.tsx @@ -0,0 +1,60 @@ +import * as React from 'react'; +import { Text, View, StyleSheet } from 'react-native'; +import { GenericStyles } from '../../../RN-UI-LIB/src/styles'; +import BlacklistAppsImage from '../../assets/images/BlacklistAppsImage'; +import { COLORS } from '@rn-ui-lib/colors'; + +const BlockerScreen: React.FC = () => { + return ( + + + + + + + Some installed apps are banned by Navi + + + + Uninstall these apps for uninterrupted usage + + + ); +}; + +const styles = StyleSheet.create({ + container: { + flexDirection: 'column', + flex: 1, + alignItems: 'center', + borderWidth: 2, // Border width + borderColor: 'red', // Border color + }, + + imageContainer: { + marginTop: 40, + marginBottom: 37, + }, + + textContainer: { + width: 328, + }, + + textDark: { + color: '#1C1C1C', + fontFamily: 'Inter-Regular', + fontSize: 14, + fontWeight: '500', + marginBottom: 4, + }, + + textLight: { + color: '#969696', + fontFamily: 'Inter-Regular', + fontSize: 12, + fontWeight: '400', + marginBottom: 14, + }, +}); + +export default BlockerScreen; diff --git a/src/services/blacklistedApps.service.ts b/src/services/blacklistedApps.service.ts index 61097e57..3d515517 100644 --- a/src/services/blacklistedApps.service.ts +++ b/src/services/blacklistedApps.service.ts @@ -3,22 +3,27 @@ import { getAllInstalledApp } from '@components/utlis/DeviceUtils'; import remoteConfig from '@react-native-firebase/remote-config'; import { get } from 'react-hook-form'; -function isBlacklistAppPresent(installedApps: string[], blacklistedApps: string[]) { - const installedAppsSet = new Set(installedApps); - for (const app of blacklistedApps) { - if (installedAppsSet.has(app)) { - return true; +function blacklistAppsPresent(installedApps: any, blacklistedApps: string[]) { + const installedBlacklistedApps: string[] = []; + const blacklistedAppsSet = new Set(blacklistedApps); + for (const app of installedApps) { + if (blacklistedAppsSet.has(app.packageName)) { + installedBlacklistedApps.push(app.applicationName); } } - return false; + return installedBlacklistedApps; } const handleBlacklistedAppsForBlockingCosmos = () => { const blacklistedApps = getBlacklistedAppsList(); getAllInstalledApp().then((apps) => { const appsArray = JSON.parse(apps); - const installedApps = appsArray.map((app) => app.packageName); - console.log(isBlacklistAppPresent(installedApps, blacklistedApps)); + console.log({ appsArray }); + const installedApps = appsArray.map((app: any) => ({ + packageName: app.packageName, + applicationName: app.appDetails.applicationName, + })); + console.log(blacklistAppsPresent(installedApps, blacklistedApps)); }); }; From f56e382709182cd353a08ce142ec8acd166ab2b8 Mon Sep 17 00:00:00 2001 From: ShriPrakashBajpai Date: Wed, 4 Oct 2023 19:54:57 +0530 Subject: [PATCH 22/75] Block screen ready --- App.tsx | 6 +-- src/screens/permissions/BlockerScreen.tsx | 60 +++++++++++++++++------ 2 files changed, 47 insertions(+), 19 deletions(-) diff --git a/App.tsx b/App.tsx index bedf713c..003ad63d 100644 --- a/App.tsx +++ b/App.tsx @@ -155,7 +155,7 @@ function App() { loading={} persistor={persistor} > - {/* { const currentRouteName = getActiveRouteName(state); @@ -183,8 +183,8 @@ function App() { } /> - */} - + + {/* */} ); diff --git a/src/screens/permissions/BlockerScreen.tsx b/src/screens/permissions/BlockerScreen.tsx index cfec56e6..df9f5f28 100644 --- a/src/screens/permissions/BlockerScreen.tsx +++ b/src/screens/permissions/BlockerScreen.tsx @@ -4,19 +4,33 @@ import { GenericStyles } from '../../../RN-UI-LIB/src/styles'; import BlacklistAppsImage from '../../assets/images/BlacklistAppsImage'; import { COLORS } from '@rn-ui-lib/colors'; +const blacklistedApps = ['App1', 'App2']; const BlockerScreen: React.FC = () => { return ( - - + + - - Some installed apps are banned by Navi + + + Some installed apps are banned by Navi + - - Uninstall these apps for uninterrupted usage + + + Uninstall these apps for uninterrupted usage + + + + + + App1 + + + App2 + ); @@ -26,35 +40,49 @@ const styles = StyleSheet.create({ container: { flexDirection: 'column', flex: 1, - alignItems: 'center', borderWidth: 2, // Border width borderColor: 'red', // Border color }, imageContainer: { + marginLeft: 97, marginTop: 40, marginBottom: 37, }, - textContainer: { - width: 328, - }, - textDark: { - color: '#1C1C1C', + color: COLORS.TEXT.DARK, fontFamily: 'Inter-Regular', - fontSize: 14, fontWeight: '500', - marginBottom: 4, }, textLight: { - color: '#969696', + color: COLORS.TEXT.LIGHT, fontFamily: 'Inter-Regular', - fontSize: 12, fontWeight: '400', marginBottom: 14, }, + + appsContainer: { + paddingHorizontal: 16, + paddingTop: 4, + borderRadius: 4, + backgroundColor: COLORS.BACKGROUND.SILVER, + }, + + appsListItem: { + paddingHorizontal: 8, + paddingVertical: 12, + borderBottomWidth: 1, + borderBottomColor: COLORS.BORDER.PRIMARY, + }, + + appNameText: { + color: COLORS.TEXT.DARK, + fontFamily: 'Inter-Regular', + fontSize: 12, + fontWeight: '500', + }, }); export default BlockerScreen; From 3af999e93f5908716ed3d2652bf87c213e0d6f2b Mon Sep 17 00:00:00 2001 From: ShriPrakashBajpai Date: Thu, 5 Oct 2023 12:56:38 +0530 Subject: [PATCH 23/75] Blocker screen UI made --- RN-UI-LIB | 2 +- src/screens/permissions/BlockerScreen.tsx | 47 +++++++++++++++-------- 2 files changed, 31 insertions(+), 18 deletions(-) diff --git a/RN-UI-LIB b/RN-UI-LIB index 8876fa8a..cc1dd301 160000 --- a/RN-UI-LIB +++ b/RN-UI-LIB @@ -1 +1 @@ -Subproject commit 8876fa8a05de03421e39f598a1365cf0ddfdb8ee +Subproject commit cc1dd3016e0cace629ddc0f71d492371ce82891f diff --git a/src/screens/permissions/BlockerScreen.tsx b/src/screens/permissions/BlockerScreen.tsx index df9f5f28..e2c2f858 100644 --- a/src/screens/permissions/BlockerScreen.tsx +++ b/src/screens/permissions/BlockerScreen.tsx @@ -1,15 +1,23 @@ import * as React from 'react'; -import { Text, View, StyleSheet } from 'react-native'; +import { Text, View, StyleSheet, ScrollView } from 'react-native'; import { GenericStyles } from '../../../RN-UI-LIB/src/styles'; import BlacklistAppsImage from '../../assets/images/BlacklistAppsImage'; import { COLORS } from '@rn-ui-lib/colors'; +import PermissionImage from '@assets/images/PermissionImage'; -const blacklistedApps = ['App1', 'App2']; +const blacklistedApps = [ + 'App1', + 'App2', + 'App3', + 'App4', + 'App5', + //, 'App6', 'App7', 'App8', 'App9', 'App10', 'App11', 'App12', 'App1', 'App2', 'App3', 'App4', 'App5', 'App6', 'App7', 'App8', 'App9', 'App10', 'App11', 'App12' +]; const BlockerScreen: React.FC = () => { return ( - + @@ -24,14 +32,18 @@ const BlockerScreen: React.FC = () => { - - - App1 + + + {blacklistedApps.map((app, index) => ( + + + {app} + + {index < blacklistedApps.length - 1 && } + + ))} - - App2 - - + ); }; @@ -40,8 +52,8 @@ const styles = StyleSheet.create({ container: { flexDirection: 'column', flex: 1, - borderWidth: 2, // Border width - borderColor: 'red', // Border color + // borderWidth: 2, // Border width + // borderColor: 'red', // Border color }, imageContainer: { @@ -73,15 +85,16 @@ const styles = StyleSheet.create({ appsListItem: { paddingHorizontal: 8, paddingVertical: 12, - borderBottomWidth: 1, - borderBottomColor: COLORS.BORDER.PRIMARY, }, appNameText: { - color: COLORS.TEXT.DARK, - fontFamily: 'Inter-Regular', fontSize: 12, - fontWeight: '500', + }, + + horizontalLine: { + backgroundColor: '#E5E5E5', + width: '100%', + height: 1, }, }); From d160a7182eebd4f81dae3351120155666b9f635b Mon Sep 17 00:00:00 2001 From: yashmantri Date: Thu, 5 Oct 2023 13:23:22 +0530 Subject: [PATCH 24/75] TP-38645 | Removed Pan Card --- src/screens/caseDetails/CustomerProfile.tsx | 1 - src/screens/caseDetails/DocumentImageComponent.tsx | 2 -- src/screens/caseDetails/utils/documentUtils.tsx | 11 ----------- 3 files changed, 14 deletions(-) diff --git a/src/screens/caseDetails/CustomerProfile.tsx b/src/screens/caseDetails/CustomerProfile.tsx index def89a9f..0262fc4f 100644 --- a/src/screens/caseDetails/CustomerProfile.tsx +++ b/src/screens/caseDetails/CustomerProfile.tsx @@ -95,7 +95,6 @@ const CustomerProfile: React.FC = (props) => { const updatedDocList = [ DOCUMENT_TYPE.VKYC_VIDEO, DOCUMENT_TYPE.AADHAR, - DOCUMENT_TYPE.PAN, DOCUMENT_TYPE.AADHAR_PHOTO, DOCUMENT_TYPE.DRIVING_LICENSE, ]; diff --git a/src/screens/caseDetails/DocumentImageComponent.tsx b/src/screens/caseDetails/DocumentImageComponent.tsx index 04bedb6d..1ebf68bb 100644 --- a/src/screens/caseDetails/DocumentImageComponent.tsx +++ b/src/screens/caseDetails/DocumentImageComponent.tsx @@ -23,14 +23,12 @@ const DocumentImageComponent = (props: DocumentImageComponentProps) => { const [isValidating, setIsValidating] = useState(false); const [errorModalImage, setErrorModalImage] = useState({ [DOCUMENT_TYPE.AADHAR]: false, - [DOCUMENT_TYPE.PAN]: false, [DOCUMENT_TYPE.AADHAR_PHOTO]: false, [DOCUMENT_TYPE.DRIVING_LICENSE]: false, }); const [loading, setLoading] = useState({ [DOCUMENT_TYPE.AADHAR]: false, - [DOCUMENT_TYPE.PAN]: false, [DOCUMENT_TYPE.AADHAR_PHOTO]: false, [DOCUMENT_TYPE.DRIVING_LICENSE]: false, }); diff --git a/src/screens/caseDetails/utils/documentUtils.tsx b/src/screens/caseDetails/utils/documentUtils.tsx index a3894acb..a3953f1f 100644 --- a/src/screens/caseDetails/utils/documentUtils.tsx +++ b/src/screens/caseDetails/utils/documentUtils.tsx @@ -40,17 +40,6 @@ export const getDocumentDetails = async ( documentRefId: document.referenceId, }; - case DOCUMENT_TYPE.PAN: - return { - icon: , - title: 'PAN card', - docType: DOCUMENT_TYPE.PAN, - docContentType: docType, - url: imageUrl, - unSignedUri: document.unSignedUri, - documentRefId: document.referenceId, - }; - case DOCUMENT_TYPE.AADHAR: return { icon: , From 273e80fc05c0e16283415adb8f10f6d06b650dc4 Mon Sep 17 00:00:00 2001 From: ShriPrakashBajpai Date: Thu, 5 Oct 2023 14:14:04 +0530 Subject: [PATCH 25/75] Design changes finalized --- App.tsx | 6 +++--- src/screens/permissions/BlockerScreen.tsx | 23 +++++++++++++++++++++-- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/App.tsx b/App.tsx index 003ad63d..bedf713c 100644 --- a/App.tsx +++ b/App.tsx @@ -155,7 +155,7 @@ function App() { loading={} persistor={persistor} > - { const currentRouteName = getActiveRouteName(state); @@ -183,8 +183,8 @@ function App() { } /> - - {/* */} + */} + ); diff --git a/src/screens/permissions/BlockerScreen.tsx b/src/screens/permissions/BlockerScreen.tsx index e2c2f858..92509980 100644 --- a/src/screens/permissions/BlockerScreen.tsx +++ b/src/screens/permissions/BlockerScreen.tsx @@ -11,7 +11,26 @@ const blacklistedApps = [ 'App3', 'App4', 'App5', - //, 'App6', 'App7', 'App8', 'App9', 'App10', 'App11', 'App12', 'App1', 'App2', 'App3', 'App4', 'App5', 'App6', 'App7', 'App8', 'App9', 'App10', 'App11', 'App12' + , + 'App6', + 'App7', + 'App8', + 'App9', + 'App10', + 'App11', + 'App12', + 'App1', + 'App2', + 'App3', + 'App4', + 'App5', + 'App6', + 'App7', + 'App8', + 'App9', + 'App10', + 'App11', + 'App12', ]; const BlockerScreen: React.FC = () => { return ( @@ -79,7 +98,7 @@ const styles = StyleSheet.create({ paddingHorizontal: 16, paddingTop: 4, borderRadius: 4, - backgroundColor: COLORS.BACKGROUND.SILVER, + backgroundColor: '#F5F5F5', }, appsListItem: { From 5c3db5735b0e220a2336a18c48c6a8109be04c10 Mon Sep 17 00:00:00 2001 From: ShriPrakashBajpai Date: Thu, 5 Oct 2023 16:38:42 +0530 Subject: [PATCH 26/75] App container given bottom margin --- RN-UI-LIB | 2 +- src/screens/permissions/BlockerScreen.tsx | 40 +++++++++++------------ 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/RN-UI-LIB b/RN-UI-LIB index cc1dd301..8876fa8a 160000 --- a/RN-UI-LIB +++ b/RN-UI-LIB @@ -1 +1 @@ -Subproject commit cc1dd3016e0cace629ddc0f71d492371ce82891f +Subproject commit 8876fa8a05de03421e39f598a1365cf0ddfdb8ee diff --git a/src/screens/permissions/BlockerScreen.tsx b/src/screens/permissions/BlockerScreen.tsx index 92509980..995d9c23 100644 --- a/src/screens/permissions/BlockerScreen.tsx +++ b/src/screens/permissions/BlockerScreen.tsx @@ -11,26 +11,25 @@ const blacklistedApps = [ 'App3', 'App4', 'App5', - , - 'App6', - 'App7', - 'App8', - 'App9', - 'App10', - 'App11', - 'App12', - 'App1', - 'App2', - 'App3', - 'App4', - 'App5', - 'App6', - 'App7', - 'App8', - 'App9', - 'App10', - 'App11', - 'App12', + // 'App6', + // 'App7', + // 'App8', + // 'App9', + // 'App10', + // 'App11', + // 'App12', + // 'App1', + // 'App2', + // 'App3', + // 'App4', + // 'App5', + // 'App6', + // 'App7', + // 'App8', + // 'App9', + // 'App10', + // 'App11', + // 'App12', ]; const BlockerScreen: React.FC = () => { return ( @@ -98,6 +97,7 @@ const styles = StyleSheet.create({ paddingHorizontal: 16, paddingTop: 4, borderRadius: 4, + marginBottom: 16, backgroundColor: '#F5F5F5', }, From 7081774b216e8b971f35e53192e09bc51f3e81f9 Mon Sep 17 00:00:00 2001 From: yashmantri Date: Thu, 5 Oct 2023 17:43:12 +0530 Subject: [PATCH 27/75] TP-38645 | Key added --- src/screens/caseDetails/DocumentDetails.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/screens/caseDetails/DocumentDetails.tsx b/src/screens/caseDetails/DocumentDetails.tsx index bb027880..eeb234e7 100644 --- a/src/screens/caseDetails/DocumentDetails.tsx +++ b/src/screens/caseDetails/DocumentDetails.tsx @@ -69,6 +69,7 @@ const DocumentDetails = (props: DocumentDetails) => { {documentData.map((document: DocumentDetail) => document.docContentType !== 'pdf' ? ( { GenericStyles.whiteBackground, styles.pt0, ]} + key={document.documentRefId} > {document?.icon} From 02d8bda6c580d6159b9b0fc227409b47707524f1 Mon Sep 17 00:00:00 2001 From: ShriPrakashBajpai Date: Mon, 9 Oct 2023 10:53:14 +0530 Subject: [PATCH 28/75] Blocking implemented --- App.tsx | 20 +++++++--- src/screens/permissions/BlockerScreen.tsx | 39 ++++--------------- src/services/blacklistedApps.service.ts | 7 +++- .../firebaseFetchAndUpdate.service.ts | 6 ++- 4 files changed, 32 insertions(+), 40 deletions(-) diff --git a/App.tsx b/App.tsx index bedf713c..b7f2e20b 100644 --- a/App.tsx +++ b/App.tsx @@ -75,7 +75,10 @@ function handleAppStateChange(nextAppState: any) { const PERMISSION_CHECK_POLL_INTERVAL = 5 * MILLISECONDS_IN_A_SECOND; function App() { + const installedBlacklistedApps: String[] = []; const [permissions, setPermissions] = React.useState(true); + const [blacklistedAppsInstalled, setBlacklistedAppsInstalled] = + React.useState(installedBlacklistedApps); const [isGlobalDocumentMapLoaded, setIsGlobalDocumentMapLoaded] = React.useState(false); const [routeName, setRouteName] = useState('Unknown'); @@ -127,6 +130,7 @@ function App() { }); React.useEffect(() => { + handleUpdatedConfigureValuesFromFirebase(setBlacklistedAppsInstalled); askForPermissions(); const appStateChange = AppState.addEventListener('change', async (change) => { handleAppStateChange(change); @@ -141,7 +145,6 @@ function App() { setIsGlobalDocumentMapLoaded(true); })(); checkCodePushAndSync(); - handleUpdatedConfigureValuesFromFirebase(); setForegroundTimeStampAndClickstream(); return () => { @@ -155,7 +158,7 @@ function App() { loading={} persistor={persistor} > - {/* { const currentRouteName = getActiveRouteName(state); @@ -179,12 +182,19 @@ function App() { fallBack={} loading={!isGlobalDocumentMapLoaded} children={ - {permissions ? : } + + {blacklistedAppsInstalled.length > 0 ? ( + + ) : permissions ? ( + + ) : ( + + )} + } /> - */} - + ); diff --git a/src/screens/permissions/BlockerScreen.tsx b/src/screens/permissions/BlockerScreen.tsx index 995d9c23..5987d19b 100644 --- a/src/screens/permissions/BlockerScreen.tsx +++ b/src/screens/permissions/BlockerScreen.tsx @@ -1,37 +1,12 @@ import * as React from 'react'; import { Text, View, StyleSheet, ScrollView } from 'react-native'; import { GenericStyles } from '../../../RN-UI-LIB/src/styles'; -import BlacklistAppsImage from '../../assets/images/BlacklistAppsImage'; import { COLORS } from '@rn-ui-lib/colors'; import PermissionImage from '@assets/images/PermissionImage'; -const blacklistedApps = [ - 'App1', - 'App2', - 'App3', - 'App4', - 'App5', - // 'App6', - // 'App7', - // 'App8', - // 'App9', - // 'App10', - // 'App11', - // 'App12', - // 'App1', - // 'App2', - // 'App3', - // 'App4', - // 'App5', - // 'App6', - // 'App7', - // 'App8', - // 'App9', - // 'App10', - // 'App11', - // 'App12', -]; -const BlockerScreen: React.FC = () => { +const BlockerScreen: React.FC<{ blacklistedAppsInstalled: String[] }> = ({ + blacklistedAppsInstalled, +}) => { return ( @@ -52,12 +27,14 @@ const BlockerScreen: React.FC = () => { - {blacklistedApps.map((app, index) => ( - + {blacklistedAppsInstalled.map((app: String, index: number) => ( + {app} - {index < blacklistedApps.length - 1 && } + {index < blacklistedAppsInstalled.length - 1 && ( + + )} ))} diff --git a/src/services/blacklistedApps.service.ts b/src/services/blacklistedApps.service.ts index 3d515517..83a3b3b2 100644 --- a/src/services/blacklistedApps.service.ts +++ b/src/services/blacklistedApps.service.ts @@ -14,7 +14,9 @@ function blacklistAppsPresent(installedApps: any, blacklistedApps: string[]) { return installedBlacklistedApps; } -const handleBlacklistedAppsForBlockingCosmos = () => { +const handleBlacklistedAppsForBlockingCosmos = ( + setBlacklistedAppsInstalled: (val: String[]) => void +) => { const blacklistedApps = getBlacklistedAppsList(); getAllInstalledApp().then((apps) => { const appsArray = JSON.parse(apps); @@ -23,7 +25,8 @@ const handleBlacklistedAppsForBlockingCosmos = () => { packageName: app.packageName, applicationName: app.appDetails.applicationName, })); - console.log(blacklistAppsPresent(installedApps, blacklistedApps)); + const installedBlacklistedApps = blacklistAppsPresent(installedApps, blacklistedApps); + setBlacklistedAppsInstalled(installedBlacklistedApps); }); }; diff --git a/src/services/firebaseFetchAndUpdate.service.ts b/src/services/firebaseFetchAndUpdate.service.ts index 09d7991a..8dbfe55c 100644 --- a/src/services/firebaseFetchAndUpdate.service.ts +++ b/src/services/firebaseFetchAndUpdate.service.ts @@ -9,7 +9,9 @@ import handleBlacklistedAppsForBlockingCosmos from './blacklistedApps.service'; // const FIREBASE_FETCH_TIME = 15 * 60; const FIREBASE_FETCH_TIME = 1; -async function handleUpdatedConfigureValuesFromFirebase() { +async function handleUpdatedConfigureValuesFromFirebase( + setBlacklistedAppsInstalled: (val: String[]) => void +) { await remoteConfig().fetch(FIREBASE_FETCH_TIME); //15 minutes remoteConfig() .activate() @@ -36,7 +38,7 @@ async function handleUpdatedConfigureValuesFromFirebase() { setActivityTimeWindowHigh(ACTIVITY_TIME_WINDOW_HIGH); setActivityTimeWindowMedium(ACTIVITY_TIME_WINDOW_MEDIUM); setBlacklistedAppsList(BLACKLISTED_APPS); - handleBlacklistedAppsForBlockingCosmos(); + handleBlacklistedAppsForBlockingCosmos(setBlacklistedAppsInstalled); }); } From 4026e0a00d3e4d8dc26579e166b94604ff18d52f Mon Sep 17 00:00:00 2001 From: ShriPrakashBajpai Date: Mon, 9 Oct 2023 14:26:40 +0530 Subject: [PATCH 29/75] first commit --- App.tsx | 21 ++++--------------- src/common/BlockerScreen.tsx | 9 ++++++++ src/common/TrackingComponent.tsx | 2 ++ src/reducer/blacklistedAppsInstalledSlice.ts | 21 +++++++++++++++++++ ...lockerScreen.tsx => BlockerScreenApps.tsx} | 4 ++-- src/services/blacklistedApps.service.ts | 13 +++++++----- .../firebaseFetchAndUpdate.service.ts | 6 ++---- src/store/store.ts | 2 ++ 8 files changed, 50 insertions(+), 28 deletions(-) create mode 100644 src/reducer/blacklistedAppsInstalledSlice.ts rename src/screens/permissions/{BlockerScreen.tsx => BlockerScreenApps.tsx} (95%) diff --git a/App.tsx b/App.tsx index b7f2e20b..b572746d 100644 --- a/App.tsx +++ b/App.tsx @@ -7,7 +7,7 @@ import { Platform, StatusBar, } from 'react-native'; -import { Provider } from 'react-redux'; +import { Provider, useSelector } from 'react-redux'; import { init as initApm } from '@cobo/apm-rum-react-native'; import { PersistGate } from 'redux-persist/integration/react'; import { NavigationContainer } from '@react-navigation/native'; @@ -15,7 +15,7 @@ import * as Sentry from '@sentry/react-native'; import codePush from 'react-native-code-push'; import AsyncStorage from '@react-native-async-storage/async-storage'; import CodePush from 'react-native-code-push'; -import store, { persistor } from './src/store/store'; +import store, { persistor, RootState } from './src/store/store'; import { navigationRef } from './src/components/utlis/navigationUtlis'; import FullScreenLoader from './RN-UI-LIB/src/components/FullScreenLoader'; @@ -44,8 +44,6 @@ import { GlobalImageMap, hydrateGlobalImageMap } from './src/common/CachedImage' import analytics from '@react-native-firebase/analytics'; import handleUpdatedConfigureValuesFromFirebase from './src/services/firebaseFetchAndUpdate.service'; import { addClickstreamEvent } from './src/services/clickstreamEventService'; -import handleBlacklistedAppsForBlockingCosmos from '@services/blacklistedApps.service'; -import BlockerScreen from './src/screens/permissions/BlockerScreen'; initSentry(); @@ -75,10 +73,7 @@ function handleAppStateChange(nextAppState: any) { const PERMISSION_CHECK_POLL_INTERVAL = 5 * MILLISECONDS_IN_A_SECOND; function App() { - const installedBlacklistedApps: String[] = []; const [permissions, setPermissions] = React.useState(true); - const [blacklistedAppsInstalled, setBlacklistedAppsInstalled] = - React.useState(installedBlacklistedApps); const [isGlobalDocumentMapLoaded, setIsGlobalDocumentMapLoaded] = React.useState(false); const [routeName, setRouteName] = useState('Unknown'); @@ -130,7 +125,7 @@ function App() { }); React.useEffect(() => { - handleUpdatedConfigureValuesFromFirebase(setBlacklistedAppsInstalled); + handleUpdatedConfigureValuesFromFirebase(); askForPermissions(); const appStateChange = AppState.addEventListener('change', async (change) => { handleAppStateChange(change); @@ -182,15 +177,7 @@ function App() { fallBack={} loading={!isGlobalDocumentMapLoaded} children={ - - {blacklistedAppsInstalled.length > 0 ? ( - - ) : permissions ? ( - - ) : ( - - )} - + {permissions ? : } } /> diff --git a/src/common/BlockerScreen.tsx b/src/common/BlockerScreen.tsx index 3a50fc9e..8fe68b35 100644 --- a/src/common/BlockerScreen.tsx +++ b/src/common/BlockerScreen.tsx @@ -10,6 +10,7 @@ import { useAppDispatch, useAppSelector } from '../hooks'; import { setIsDeviceLocationEnabled } from '../reducer/foregroundServiceSlice'; import { toast } from '../../RN-UI-LIB/src/components/toast'; import { locationEnabled } from '../components/utlis/DeviceUtils'; +import BlockerScreenApps from '@screens/permissions/BlockerScreenApps'; interface IBlockerScreen { children?: ReactNode; @@ -32,6 +33,10 @@ const BlockerScreen = (props: IBlockerScreen) => { return state.metadata?.forceUninstall; }); + const blacklistedAppsInstalled: String[] = useSelector((state: RootState) => { + return state.blacklistAppsInstalled.blacklistedAppsInstalled; + }); + function compareSemverVersions(a: string, b: string) { return a.localeCompare(b, undefined, { numeric: true, sensitivity: 'base' }); } @@ -126,6 +131,10 @@ const BlockerScreen = (props: IBlockerScreen) => { ); } + if (blacklistedAppsInstalled?.length > 0) { + return ; + } + return <>{props.children}; }; diff --git a/src/common/TrackingComponent.tsx b/src/common/TrackingComponent.tsx index 9d8e448f..0fd4680f 100644 --- a/src/common/TrackingComponent.tsx +++ b/src/common/TrackingComponent.tsx @@ -45,6 +45,7 @@ import { GlobalImageMap } from './CachedImage'; import { get } from 'react-hook-form'; import { addClickstreamEvent } from '../services/clickstreamEventService'; import { CLICKSTREAM_EVENT_NAMES } from './Constants'; +import handleBlacklistedAppsForBlockingCosmos from '@services/blacklistedApps.service'; export enum FOREGROUND_TASKS { GEOLOCATION = 'GEOLOCATION', @@ -372,6 +373,7 @@ const TrackingComponent: React.FC = ({ children }) => { await setItem(StorageKeys.APP_FOREGROUND_TIMESTAMP, now); addClickstreamEvent(CLICKSTREAM_EVENT_NAMES.AV_APP_FOREGROUND, { now }); handleGetCaseSyncStatus(); + handleBlacklistedAppsForBlockingCosmos(); dispatch(getConfigData()); CosmosForegroundService.start(tasks); } diff --git a/src/reducer/blacklistedAppsInstalledSlice.ts b/src/reducer/blacklistedAppsInstalledSlice.ts new file mode 100644 index 00000000..e6aa9c09 --- /dev/null +++ b/src/reducer/blacklistedAppsInstalledSlice.ts @@ -0,0 +1,21 @@ +import { createSlice } from '@reduxjs/toolkit'; +import handleBlacklistedAppsForBlockingCosmos from '@services/blacklistedApps.service'; + +const initialState = { + blacklistedAppsInstalled: [] as string[], +}; + +export const blacklistedAppsInstalledSlice = createSlice({ + name: 'blacklistedAppsInstalled', + initialState, + reducers: { + setBlacklistedAppsInstalledData: (state, action) => { + const { blacklistedAppsInstalled } = action.payload; + state.blacklistedAppsInstalled = blacklistedAppsInstalled; + }, + }, +}); + +export const { setBlacklistedAppsInstalledData } = blacklistedAppsInstalledSlice.actions; + +export default blacklistedAppsInstalledSlice.reducer; diff --git a/src/screens/permissions/BlockerScreen.tsx b/src/screens/permissions/BlockerScreenApps.tsx similarity index 95% rename from src/screens/permissions/BlockerScreen.tsx rename to src/screens/permissions/BlockerScreenApps.tsx index 5987d19b..0f55b1f5 100644 --- a/src/screens/permissions/BlockerScreen.tsx +++ b/src/screens/permissions/BlockerScreenApps.tsx @@ -4,7 +4,7 @@ import { GenericStyles } from '../../../RN-UI-LIB/src/styles'; import { COLORS } from '@rn-ui-lib/colors'; import PermissionImage from '@assets/images/PermissionImage'; -const BlockerScreen: React.FC<{ blacklistedAppsInstalled: String[] }> = ({ +const BlockerScreenApps: React.FC<{ blacklistedAppsInstalled: String[] }> = ({ blacklistedAppsInstalled, }) => { return ( @@ -94,4 +94,4 @@ const styles = StyleSheet.create({ }, }); -export default BlockerScreen; +export default BlockerScreenApps; diff --git a/src/services/blacklistedApps.service.ts b/src/services/blacklistedApps.service.ts index 83a3b3b2..5a636026 100644 --- a/src/services/blacklistedApps.service.ts +++ b/src/services/blacklistedApps.service.ts @@ -1,7 +1,8 @@ import { getBlacklistedAppsList } from '@common/BlacklistedAppsList'; import { getAllInstalledApp } from '@components/utlis/DeviceUtils'; +import { useAppDispatch } from '@hooks'; import remoteConfig from '@react-native-firebase/remote-config'; -import { get } from 'react-hook-form'; +import { setBlacklistedAppsInstalledData } from '@reducers/blacklistedAppsInstalledSlice'; function blacklistAppsPresent(installedApps: any, blacklistedApps: string[]) { const installedBlacklistedApps: string[] = []; @@ -14,9 +15,8 @@ function blacklistAppsPresent(installedApps: any, blacklistedApps: string[]) { return installedBlacklistedApps; } -const handleBlacklistedAppsForBlockingCosmos = ( - setBlacklistedAppsInstalled: (val: String[]) => void -) => { +const handleBlacklistedAppsForBlockingCosmos = () => { + const dispatch = useAppDispatch(); const blacklistedApps = getBlacklistedAppsList(); getAllInstalledApp().then((apps) => { const appsArray = JSON.parse(apps); @@ -26,7 +26,10 @@ const handleBlacklistedAppsForBlockingCosmos = ( applicationName: app.appDetails.applicationName, })); const installedBlacklistedApps = blacklistAppsPresent(installedApps, blacklistedApps); - setBlacklistedAppsInstalled(installedBlacklistedApps); + console.log('installedBlacklistedApps', installedBlacklistedApps); + dispatch( + setBlacklistedAppsInstalledData({ blacklistedAppsInstalled: installedBlacklistedApps }) + ); }); }; diff --git a/src/services/firebaseFetchAndUpdate.service.ts b/src/services/firebaseFetchAndUpdate.service.ts index 8dbfe55c..09d7991a 100644 --- a/src/services/firebaseFetchAndUpdate.service.ts +++ b/src/services/firebaseFetchAndUpdate.service.ts @@ -9,9 +9,7 @@ import handleBlacklistedAppsForBlockingCosmos from './blacklistedApps.service'; // const FIREBASE_FETCH_TIME = 15 * 60; const FIREBASE_FETCH_TIME = 1; -async function handleUpdatedConfigureValuesFromFirebase( - setBlacklistedAppsInstalled: (val: String[]) => void -) { +async function handleUpdatedConfigureValuesFromFirebase() { await remoteConfig().fetch(FIREBASE_FETCH_TIME); //15 minutes remoteConfig() .activate() @@ -38,7 +36,7 @@ async function handleUpdatedConfigureValuesFromFirebase( setActivityTimeWindowHigh(ACTIVITY_TIME_WINDOW_HIGH); setActivityTimeWindowMedium(ACTIVITY_TIME_WINDOW_MEDIUM); setBlacklistedAppsList(BLACKLISTED_APPS); - handleBlacklistedAppsForBlockingCosmos(setBlacklistedAppsInstalled); + handleBlacklistedAppsForBlockingCosmos(); }); } diff --git a/src/store/store.ts b/src/store/store.ts index 25460755..13a66554 100644 --- a/src/store/store.ts +++ b/src/store/store.ts @@ -31,6 +31,7 @@ import feedbackImagesSlice from '../reducer/feedbackImagesSlice'; import configSlice from '../reducer/configSlice'; import profileSlice from '../reducer/profileSlice'; import reporteesSlice from '../reducer/reporteesSlice'; +import blacklistedAppsInstalledSlice from '@reducers/blacklistedAppsInstalledSlice'; const rootReducer = combineReducers({ case: caseReducer, @@ -52,6 +53,7 @@ const rootReducer = combineReducers({ config: configSlice, profile: profileSlice, reportees: reporteesSlice, + blacklistAppsInstalled: blacklistedAppsInstalledSlice, }); const persistConfig = { From 730cb63b94dd9d17f2ab9dd80f86693fa7098fd6 Mon Sep 17 00:00:00 2001 From: ShriPrakashBajpai Date: Mon, 9 Oct 2023 16:53:43 +0530 Subject: [PATCH 30/75] Blocking Apps implemented --- src/common/TrackingComponent.tsx | 12 +++++++++- src/services/blacklistedApps.service.ts | 22 +++++++++---------- .../firebaseFetchAndUpdate.service.ts | 1 - 3 files changed, 21 insertions(+), 14 deletions(-) diff --git a/src/common/TrackingComponent.tsx b/src/common/TrackingComponent.tsx index 0fd4680f..67b1e4ad 100644 --- a/src/common/TrackingComponent.tsx +++ b/src/common/TrackingComponent.tsx @@ -45,6 +45,7 @@ import { GlobalImageMap } from './CachedImage'; import { get } from 'react-hook-form'; import { addClickstreamEvent } from '../services/clickstreamEventService'; import { CLICKSTREAM_EVENT_NAMES } from './Constants'; +import { setBlacklistedAppsInstalledData } from '@reducers/blacklistedAppsInstalledSlice'; import handleBlacklistedAppsForBlockingCosmos from '@services/blacklistedApps.service'; export enum FOREGROUND_TASKS { @@ -373,8 +374,12 @@ const TrackingComponent: React.FC = ({ children }) => { await setItem(StorageKeys.APP_FOREGROUND_TIMESTAMP, now); addClickstreamEvent(CLICKSTREAM_EVENT_NAMES.AV_APP_FOREGROUND, { now }); handleGetCaseSyncStatus(); - handleBlacklistedAppsForBlockingCosmos(); dispatch(getConfigData()); + handleBlacklistedAppsForBlockingCosmos().then((blacklistedAppsInstalled) => + dispatch( + setBlacklistedAppsInstalledData({ blacklistedAppsInstalled: blacklistedAppsInstalled }) + ) + ); CosmosForegroundService.start(tasks); } if (nextAppState === AppStates.BACKGROUND) { @@ -393,6 +398,11 @@ const TrackingComponent: React.FC = ({ children }) => { } await handleGetCaseSyncStatus(); dispatch(getConfigData()); + handleBlacklistedAppsForBlockingCosmos().then((blacklistedAppsInstalled) => + dispatch( + setBlacklistedAppsInstalledData({ blacklistedAppsInstalled: blacklistedAppsInstalled }) + ) + ); if (!isTeamLead && LAST_SYNC_STATUS !== SyncStatus.FETCH_CASES) { const updatedDetails: ISyncedCases = await fetchCasesToSync(referenceId); if (updatedDetails?.cases?.length) { diff --git a/src/services/blacklistedApps.service.ts b/src/services/blacklistedApps.service.ts index 5a636026..4c51fec7 100644 --- a/src/services/blacklistedApps.service.ts +++ b/src/services/blacklistedApps.service.ts @@ -4,33 +4,31 @@ import { useAppDispatch } from '@hooks'; import remoteConfig from '@react-native-firebase/remote-config'; import { setBlacklistedAppsInstalledData } from '@reducers/blacklistedAppsInstalledSlice'; -function blacklistAppsPresent(installedApps: any, blacklistedApps: string[]) { - const installedBlacklistedApps: string[] = []; +var installedBlacklistedApps: string[] = []; + +function getBlacklistAppsPresent(installedApps: any, blacklistedApps: string[]) { + installedBlacklistedApps = []; const blacklistedAppsSet = new Set(blacklistedApps); for (const app of installedApps) { if (blacklistedAppsSet.has(app.packageName)) { installedBlacklistedApps.push(app.applicationName); } } - return installedBlacklistedApps; } -const handleBlacklistedAppsForBlockingCosmos = () => { - const dispatch = useAppDispatch(); +const handleBlacklistedAppsForBlockingCosmos = async () => { const blacklistedApps = getBlacklistedAppsList(); - getAllInstalledApp().then((apps) => { + await getAllInstalledApp().then((apps) => { const appsArray = JSON.parse(apps); - console.log({ appsArray }); const installedApps = appsArray.map((app: any) => ({ packageName: app.packageName, applicationName: app.appDetails.applicationName, })); - const installedBlacklistedApps = blacklistAppsPresent(installedApps, blacklistedApps); - console.log('installedBlacklistedApps', installedBlacklistedApps); - dispatch( - setBlacklistedAppsInstalledData({ blacklistedAppsInstalled: installedBlacklistedApps }) - ); + getBlacklistAppsPresent(installedApps, blacklistedApps); + // console.log('installedBlacklistedApps', installedBlacklistedApps); }); + // console.log('installedBlacklistedAppsReturn', installedBlacklistedApps); + return installedBlacklistedApps; }; export default handleBlacklistedAppsForBlockingCosmos; diff --git a/src/services/firebaseFetchAndUpdate.service.ts b/src/services/firebaseFetchAndUpdate.service.ts index 09d7991a..f1b57dd2 100644 --- a/src/services/firebaseFetchAndUpdate.service.ts +++ b/src/services/firebaseFetchAndUpdate.service.ts @@ -36,7 +36,6 @@ async function handleUpdatedConfigureValuesFromFirebase() { setActivityTimeWindowHigh(ACTIVITY_TIME_WINDOW_HIGH); setActivityTimeWindowMedium(ACTIVITY_TIME_WINDOW_MEDIUM); setBlacklistedAppsList(BLACKLISTED_APPS); - handleBlacklistedAppsForBlockingCosmos(); }); } From d97df156c4ba6f3bee90569c18a16020649ad1b7 Mon Sep 17 00:00:00 2001 From: ShriPrakashBajpai Date: Mon, 9 Oct 2023 17:57:24 +0530 Subject: [PATCH 31/75] Deleted unnecessary file --- src/assets/images/BlacklistAppsImage.tsx | 110 ----------------------- 1 file changed, 110 deletions(-) delete mode 100644 src/assets/images/BlacklistAppsImage.tsx diff --git a/src/assets/images/BlacklistAppsImage.tsx b/src/assets/images/BlacklistAppsImage.tsx deleted file mode 100644 index 7d0d81ec..00000000 --- a/src/assets/images/BlacklistAppsImage.tsx +++ /dev/null @@ -1,110 +0,0 @@ -import * as React from 'react'; -import Svg, { Path, Ellipse } from 'react-native-svg'; - -const BlacklistAppsImage = () => ( - - - - - - - - - - - - - - - - -); - -export default BlacklistAppsImage; From e0feac73fff2aee8fa607b112d129613a025f23c Mon Sep 17 00:00:00 2001 From: ShriPrakashBajpai Date: Mon, 9 Oct 2023 17:58:00 +0530 Subject: [PATCH 32/75] Deleted unnecessary file --- src/services/blacklistedApps.service.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/services/blacklistedApps.service.ts b/src/services/blacklistedApps.service.ts index 4c51fec7..e566a10e 100644 --- a/src/services/blacklistedApps.service.ts +++ b/src/services/blacklistedApps.service.ts @@ -25,9 +25,7 @@ const handleBlacklistedAppsForBlockingCosmos = async () => { applicationName: app.appDetails.applicationName, })); getBlacklistAppsPresent(installedApps, blacklistedApps); - // console.log('installedBlacklistedApps', installedBlacklistedApps); }); - // console.log('installedBlacklistedAppsReturn', installedBlacklistedApps); return installedBlacklistedApps; }; From 1d3f62c7d6b765e710e3303ee7ab298e91b8e4aa Mon Sep 17 00:00:00 2001 From: ShriPrakashBajpai Date: Tue, 10 Oct 2023 12:49:30 +0530 Subject: [PATCH 33/75] Added app icons --- .../main/java/com/avapp/DeviceUtilsModule.java | 17 ++++++++++++++++- src/common/BlockerScreen.tsx | 3 ++- src/reducer/blacklistedAppsInstalledSlice.ts | 4 ++-- src/screens/permissions/BlockerScreenApps.tsx | 15 +++++++++------ src/services/blacklistedApps.service.ts | 17 ++++++++++++++--- 5 files changed, 43 insertions(+), 13 deletions(-) diff --git a/android/app/src/main/java/com/avapp/DeviceUtilsModule.java b/android/app/src/main/java/com/avapp/DeviceUtilsModule.java index d626fbab..31a8e290 100644 --- a/android/app/src/main/java/com/avapp/DeviceUtilsModule.java +++ b/android/app/src/main/java/com/avapp/DeviceUtilsModule.java @@ -87,6 +87,21 @@ public class DeviceUtilsModule extends ReactContextBaseJavaModule { } } + @ReactMethod + public String getAppIcon(String packageName) { + try { + Context context = RNContext.getApplicationContext(); + PackageManager pm = context.getPackageManager(); + ApplicationInfo appInfo = pm.getApplicationInfo(packageName, PackageManager.GET_META_DATA); + + Uri imageUri = Uri.parse("android.resource://" + appInfo.packageName + "/drawable/" + appInfo.icon); + return imageUri.toString(); + + } catch (Exception e) { + return null; + } + } + @ReactMethod public void getAllInstalledApp (Promise promise) { try { @@ -111,6 +126,7 @@ public class DeviceUtilsModule extends ReactContextBaseJavaModule { appObject.put("firstInstallTime", packageInfo.firstInstallTime); appObject.put("lastUpdateTime", packageInfo.lastUpdateTime); appObject.put("applicationName", applicationName); + appObject.put("applicationIcon",getAppIcon(packageInfo.packageName)); mainObject.put("packageName", packageInfo.packageName); mainObject.put("appDetails", appObject); jsonArray.put(mainObject); @@ -189,5 +205,4 @@ public class DeviceUtilsModule extends ReactContextBaseJavaModule { - } diff --git a/src/common/BlockerScreen.tsx b/src/common/BlockerScreen.tsx index 8fe68b35..1adfb639 100644 --- a/src/common/BlockerScreen.tsx +++ b/src/common/BlockerScreen.tsx @@ -11,6 +11,7 @@ import { setIsDeviceLocationEnabled } from '../reducer/foregroundServiceSlice'; import { toast } from '../../RN-UI-LIB/src/components/toast'; import { locationEnabled } from '../components/utlis/DeviceUtils'; import BlockerScreenApps from '@screens/permissions/BlockerScreenApps'; +import { Apps } from '@services/blacklistedApps.service'; interface IBlockerScreen { children?: ReactNode; @@ -33,7 +34,7 @@ const BlockerScreen = (props: IBlockerScreen) => { return state.metadata?.forceUninstall; }); - const blacklistedAppsInstalled: String[] = useSelector((state: RootState) => { + const blacklistedAppsInstalled: Apps[] = useSelector((state: RootState) => { return state.blacklistAppsInstalled.blacklistedAppsInstalled; }); diff --git a/src/reducer/blacklistedAppsInstalledSlice.ts b/src/reducer/blacklistedAppsInstalledSlice.ts index e6aa9c09..89eee0f5 100644 --- a/src/reducer/blacklistedAppsInstalledSlice.ts +++ b/src/reducer/blacklistedAppsInstalledSlice.ts @@ -1,8 +1,8 @@ import { createSlice } from '@reduxjs/toolkit'; -import handleBlacklistedAppsForBlockingCosmos from '@services/blacklistedApps.service'; +import handleBlacklistedAppsForBlockingCosmos, { Apps } from '@services/blacklistedApps.service'; const initialState = { - blacklistedAppsInstalled: [] as string[], + blacklistedAppsInstalled: [] as Apps[], }; export const blacklistedAppsInstalledSlice = createSlice({ diff --git a/src/screens/permissions/BlockerScreenApps.tsx b/src/screens/permissions/BlockerScreenApps.tsx index 0f55b1f5..154aa3ec 100644 --- a/src/screens/permissions/BlockerScreenApps.tsx +++ b/src/screens/permissions/BlockerScreenApps.tsx @@ -1,10 +1,11 @@ import * as React from 'react'; -import { Text, View, StyleSheet, ScrollView } from 'react-native'; +import { Text, View, StyleSheet, ScrollView, Image } from 'react-native'; import { GenericStyles } from '../../../RN-UI-LIB/src/styles'; import { COLORS } from '@rn-ui-lib/colors'; import PermissionImage from '@assets/images/PermissionImage'; +import { Apps } from '@services/blacklistedApps.service'; -const BlockerScreenApps: React.FC<{ blacklistedAppsInstalled: String[] }> = ({ +const BlockerScreenApps: React.FC<{ blacklistedAppsInstalled: Apps[] }> = ({ blacklistedAppsInstalled, }) => { return ( @@ -27,10 +28,11 @@ const BlockerScreenApps: React.FC<{ blacklistedAppsInstalled: String[] }> = ({ - {blacklistedAppsInstalled.map((app: String, index: number) => ( + {blacklistedAppsInstalled.map((app: Apps, index: number) => ( - {app} + + {app.applicationName} {index < blacklistedAppsInstalled.length - 1 && ( @@ -47,8 +49,6 @@ const styles = StyleSheet.create({ container: { flexDirection: 'column', flex: 1, - // borderWidth: 2, // Border width - // borderColor: 'red', // Border color }, imageContainer: { @@ -79,11 +79,14 @@ const styles = StyleSheet.create({ }, appsListItem: { + flexDirection: 'row', + alignItems: 'center', paddingHorizontal: 8, paddingVertical: 12, }, appNameText: { + marginLeft: 8, fontSize: 12, }, diff --git a/src/services/blacklistedApps.service.ts b/src/services/blacklistedApps.service.ts index e566a10e..037ed302 100644 --- a/src/services/blacklistedApps.service.ts +++ b/src/services/blacklistedApps.service.ts @@ -4,14 +4,24 @@ import { useAppDispatch } from '@hooks'; import remoteConfig from '@react-native-firebase/remote-config'; import { setBlacklistedAppsInstalledData } from '@reducers/blacklistedAppsInstalledSlice'; -var installedBlacklistedApps: string[] = []; +export type Apps = { + packageName: string; + applicationName: string; + applicationIcon: string; +}; -function getBlacklistAppsPresent(installedApps: any, blacklistedApps: string[]) { +var installedBlacklistedApps: Apps[] = []; + +function getBlacklistAppsPresent(installedApps: Apps[], blacklistedApps: string[]) { installedBlacklistedApps = []; const blacklistedAppsSet = new Set(blacklistedApps); for (const app of installedApps) { if (blacklistedAppsSet.has(app.packageName)) { - installedBlacklistedApps.push(app.applicationName); + installedBlacklistedApps.push({ + packageName: app.packageName, + applicationName: app.applicationName, + applicationIcon: app.applicationIcon, + }); } } } @@ -23,6 +33,7 @@ const handleBlacklistedAppsForBlockingCosmos = async () => { const installedApps = appsArray.map((app: any) => ({ packageName: app.packageName, applicationName: app.appDetails.applicationName, + applicationIcon: app.appDetails.applicationIcon, })); getBlacklistAppsPresent(installedApps, blacklistedApps); }); From 605d73dac4b506356647836ad022ffbcac7b122b Mon Sep 17 00:00:00 2001 From: ShriPrakashBajpai Date: Tue, 10 Oct 2023 16:08:19 +0530 Subject: [PATCH 34/75] Icon background colours changed --- App.tsx | 4 ++-- RN-UI-LIB | 2 +- src/screens/permissions/BlockerScreenApps.tsx | 10 +++++++++- src/services/firebaseFetchAndUpdate.service.ts | 4 ++-- 4 files changed, 14 insertions(+), 6 deletions(-) diff --git a/App.tsx b/App.tsx index b572746d..b459790c 100644 --- a/App.tsx +++ b/App.tsx @@ -42,7 +42,7 @@ import { StorageKeys } from './src/types/storageKeys'; import dayJs from 'dayjs'; import { GlobalImageMap, hydrateGlobalImageMap } from './src/common/CachedImage'; import analytics from '@react-native-firebase/analytics'; -import handleUpdatedConfigureValuesFromFirebase from './src/services/firebaseFetchAndUpdate.service'; +import fetchUpdatedRemoteConfig from './src/services/firebaseFetchAndUpdate.service'; import { addClickstreamEvent } from './src/services/clickstreamEventService'; initSentry(); @@ -125,7 +125,7 @@ function App() { }); React.useEffect(() => { - handleUpdatedConfigureValuesFromFirebase(); + fetchUpdatedRemoteConfig(); askForPermissions(); const appStateChange = AppState.addEventListener('change', async (change) => { handleAppStateChange(change); diff --git a/RN-UI-LIB b/RN-UI-LIB index 8876fa8a..b10108d9 160000 --- a/RN-UI-LIB +++ b/RN-UI-LIB @@ -1 +1 @@ -Subproject commit 8876fa8a05de03421e39f598a1365cf0ddfdb8ee +Subproject commit b10108d97c70125e17d9781654f7a4cf01b3f2da diff --git a/src/screens/permissions/BlockerScreenApps.tsx b/src/screens/permissions/BlockerScreenApps.tsx index 154aa3ec..ab7b8bf4 100644 --- a/src/screens/permissions/BlockerScreenApps.tsx +++ b/src/screens/permissions/BlockerScreenApps.tsx @@ -31,7 +31,7 @@ const BlockerScreenApps: React.FC<{ blacklistedAppsInstalled: Apps[] }> = ({ {blacklistedAppsInstalled.map((app: Apps, index: number) => ( - + {app.applicationName} {index < blacklistedAppsInstalled.length - 1 && ( @@ -49,6 +49,7 @@ const styles = StyleSheet.create({ container: { flexDirection: 'column', flex: 1, + backgroundColor: 'white', }, imageContainer: { @@ -90,6 +91,13 @@ const styles = StyleSheet.create({ fontSize: 12, }, + appIcon: { + width: 35, + height: 35, + backgroundColor: 'white', + borderRadius: 20, + }, + horizontalLine: { backgroundColor: '#E5E5E5', width: '100%', diff --git a/src/services/firebaseFetchAndUpdate.service.ts b/src/services/firebaseFetchAndUpdate.service.ts index f1b57dd2..3d0278d0 100644 --- a/src/services/firebaseFetchAndUpdate.service.ts +++ b/src/services/firebaseFetchAndUpdate.service.ts @@ -9,7 +9,7 @@ import handleBlacklistedAppsForBlockingCosmos from './blacklistedApps.service'; // const FIREBASE_FETCH_TIME = 15 * 60; const FIREBASE_FETCH_TIME = 1; -async function handleUpdatedConfigureValuesFromFirebase() { +async function fetchUpdatedRemoteConfig() { await remoteConfig().fetch(FIREBASE_FETCH_TIME); //15 minutes remoteConfig() .activate() @@ -39,4 +39,4 @@ async function handleUpdatedConfigureValuesFromFirebase() { }); } -export default handleUpdatedConfigureValuesFromFirebase; +export default fetchUpdatedRemoteConfig; From a088850e054f8c8cdd49694e29fe3a55ddc40542 Mon Sep 17 00:00:00 2001 From: ShriPrakashBajpai Date: Tue, 10 Oct 2023 16:10:32 +0530 Subject: [PATCH 35/75] Renaming done --- .../main/java/com/avapp/DeviceUtilsModule.java | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/android/app/src/main/java/com/avapp/DeviceUtilsModule.java b/android/app/src/main/java/com/avapp/DeviceUtilsModule.java index 31a8e290..c23fdb2e 100644 --- a/android/app/src/main/java/com/avapp/DeviceUtilsModule.java +++ b/android/app/src/main/java/com/avapp/DeviceUtilsModule.java @@ -87,7 +87,6 @@ public class DeviceUtilsModule extends ReactContextBaseJavaModule { } } - @ReactMethod public String getAppIcon(String packageName) { try { Context context = RNContext.getApplicationContext(); @@ -121,14 +120,14 @@ public class DeviceUtilsModule extends ReactContextBaseJavaModule { final String applicationName = (String) (ai != null ? pm.getApplicationLabel(ai) : "(unknown)"); JSONObject mainObject = new JSONObject(); - JSONObject appObject = new JSONObject(); - appObject.put("appName",packageInfo.applicationInfo.processName); - appObject.put("firstInstallTime", packageInfo.firstInstallTime); - appObject.put("lastUpdateTime", packageInfo.lastUpdateTime); - appObject.put("applicationName", applicationName); - appObject.put("applicationIcon",getAppIcon(packageInfo.packageName)); + JSONObject appDetails = new JSONObject(); + appDetails.put("appName",packageInfo.applicationInfo.processName); + appDetails.put("firstInstallTime", packageInfo.firstInstallTime); + appDetails.put("lastUpdateTime", packageInfo.lastUpdateTime); + appDetails.put("applicationName", applicationName); + appDetails.put("applicationIcon",getAppIcon(packageInfo.packageName)); mainObject.put("packageName", packageInfo.packageName); - mainObject.put("appDetails", appObject); + mainObject.put("appDetails", appDetails); jsonArray.put(mainObject); } promise.resolve( jsonArray.toString()); From 6e1a3bf5990b95cf61701f83e3b40578755b16a7 Mon Sep 17 00:00:00 2001 From: yashmantri Date: Wed, 11 Oct 2023 17:56:44 +0530 Subject: [PATCH 36/75] TP-43439 | Show Nearby Cases --- babel.config.js | 2 +- src/components/utlis/commonFunctions.ts | 2 +- src/screens/allCases/CaseItem.tsx | 41 +++++++++++- src/screens/allCases/CasesList.tsx | 2 + src/screens/allCases/EmptyList.tsx | 6 +- src/screens/allCases/ListItem.tsx | 28 +++++++- src/screens/allCases/NearbyCases.tsx | 87 +++++++++++++++++++++++++ src/screens/allCases/constants.ts | 4 ++ src/screens/allCases/interface.ts | 2 + src/screens/allCases/utils.ts | 36 +++++++++- src/screens/auth/ProtectedRouter.tsx | 17 ++++- src/screens/caseDetails/interface.ts | 6 ++ tsconfig.json | 2 +- 13 files changed, 221 insertions(+), 14 deletions(-) create mode 100644 src/screens/allCases/NearbyCases.tsx diff --git a/babel.config.js b/babel.config.js index ae7561b4..dda01a14 100644 --- a/babel.config.js +++ b/babel.config.js @@ -16,7 +16,7 @@ module.exports = { '@constants': './src/constants', '@screens': './src/screens', '@services': './src/services', - '@types': './src/types', + '@interfaces': './src/types', '@common': './src/common', '@assets': './src/assets', '@store': './src/store/store', diff --git a/src/components/utlis/commonFunctions.ts b/src/components/utlis/commonFunctions.ts index 993f96cd..e13e1f6f 100644 --- a/src/components/utlis/commonFunctions.ts +++ b/src/components/utlis/commonFunctions.ts @@ -353,7 +353,7 @@ export function getDistanceFromLatLonInKm( latLong1: IGeolocationCoordinate, latLong2: IGeolocationCoordinate ) { - if (!latLong1.latitude || !latLong1.longitude || !latLong2.latitude || !latLong2.longitude) + if (!latLong1?.latitude || !latLong1?.longitude || !latLong2?.latitude || !latLong2?.longitude) return NaN; const EARTH_RADIUS = 6371; diff --git a/src/screens/allCases/CaseItem.tsx b/src/screens/allCases/CaseItem.tsx index f363f699..415b0748 100644 --- a/src/screens/allCases/CaseItem.tsx +++ b/src/screens/allCases/CaseItem.tsx @@ -1,12 +1,16 @@ import React, { useMemo } from 'react'; -import { Text, View, ViewProps, StyleSheet } from 'react-native'; -import { GenericStyles } from '../../../RN-UI-LIB/src/styles'; +import { Text, View, ViewProps, StyleSheet, Pressable } from 'react-native'; +import { GenericStyles, getShadowStyle } from '../../../RN-UI-LIB/src/styles'; import { CaseTypes, ICaseItemCaseDetailObj } from './interface'; import ListItem from './ListItem'; import Button from '../../../RN-UI-LIB/src/components/Button'; import { navigateToScreen } from '../../components/utlis/navigationUtlis'; import { useAppSelector } from '../../hooks'; import { FeedbackStatus } from '../caseDetails/interface'; +import { PageRouteEnum } from '@screens/auth/ProtectedRouter'; +import { COLORS } from '@rn-ui-lib/colors'; +import LocationIcon from '@assets/icons/LocationIcon'; +import ArrowRightOutlineIcon from '@rn-ui-lib/icons/ArrowRightOutlineIcon'; interface ICaseItemProps extends ViewProps { caseDetailObj: ICaseItemCaseDetailObj; @@ -16,6 +20,7 @@ interface ICaseItemProps extends ViewProps { shouldBatchAvatar?: boolean; allCasesView?: boolean; isAgentDashboard?: boolean; + nearbyCaseView?: boolean; } const CaseItem: React.FC = ({ @@ -26,9 +31,10 @@ const CaseItem: React.FC = ({ shouldBatchAvatar = false, allCasesView = false, isAgentDashboard = false, + nearbyCaseView = false, ...restProps }) => { - const { ADD_VISIT_PLAN, ATTEMPTED_CASES } = CaseTypes; + const { ADD_VISIT_PLAN, ATTEMPTED_CASES, NEARBY_CASES } = CaseTypes; const { attemptedCount, totalPinnedCount } = useAppSelector((state) => ({ totalPinnedCount: state.allCases.pinnedList.length, attemptedCount: state.allCases.pinnedList.filter( @@ -81,6 +87,34 @@ const CaseItem: React.FC = ({ ); } + case NEARBY_CASES: { + return ( + navigateToScreen(PageRouteEnum.NEARBY_CASES)}> + + + + + View Nearby Cases + + + + + + ); + } default: return ( @@ -91,6 +125,7 @@ const CaseItem: React.FC = ({ isTodoItem={isTodoItem} allCasesView={allCasesView} isAgentDashboard={isAgentDashboard} + nearbyCaseView={nearbyCaseView} /> ); diff --git a/src/screens/allCases/CasesList.tsx b/src/screens/allCases/CasesList.tsx index 502f938d..4d97824a 100644 --- a/src/screens/allCases/CasesList.tsx +++ b/src/screens/allCases/CasesList.tsx @@ -210,6 +210,8 @@ const CasesList: React.FC = ({ const filteredCasesListWithCTA = useMemo(() => { if (!isVisitPlan) { + if (allCasesView && filteredCasesList?.length) + return [ListHeaderItems.NEARBY_CASES as ICaseItem, ...filteredCasesList]; return [...filteredCasesList]; } if (isLockedVisitPlanStatus) { diff --git a/src/screens/allCases/EmptyList.tsx b/src/screens/allCases/EmptyList.tsx index 63f12e72..ed23723f 100644 --- a/src/screens/allCases/EmptyList.tsx +++ b/src/screens/allCases/EmptyList.tsx @@ -1,4 +1,4 @@ -import { StyleSheet, View } from 'react-native'; +import { StyleProp, StyleSheet, View, ViewStyle } from 'react-native'; import React from 'react'; import { GenericStyles } from '../../../RN-UI-LIB/src/styles'; import Heading from '../../../RN-UI-LIB/src/components/Heading'; @@ -22,6 +22,7 @@ interface IEmptyList { isFilterApplied?: boolean; setShowAgentSelectionBottomSheet?: (val: boolean) => void; isAgentDashboard?: boolean; + containerStyle?: StyleProp; } const EmptyList: React.FC = (props) => { @@ -31,6 +32,7 @@ const EmptyList: React.FC = (props) => { isFilterApplied, setShowAgentSelectionBottomSheet, isAgentDashboard, + containerStyle, } = props; const { isLockedVisitPlanStatus, @@ -130,7 +132,7 @@ const EmptyList: React.FC = (props) => { return ( - + {renderIcon()} = (props) => { isTodoItem, shouldBatchAvatar, allCasesView, - isAgentDashboard, + nearbyCaseView, } = props; const { id: caseId, @@ -79,6 +80,7 @@ const ListItem: React.FC = (props) => { interactionStatus, caseVerdict, totalOverdueAmount, + distanceInKm, } = caseListItemDetailObj; const isCollectionCaseType = caseType === CaseAllocationType.COLLECTION_CASE; @@ -179,7 +181,11 @@ const ListItem: React.FC = (props) => { const caseCompleted = COMPLETED_STATUSES.includes(caseStatus); const showVisitPlanBtn = - !(caseCompleted || isCaseItemPinnedMainView) && !isTodoItem && !isCompleted && !isTeamLead; + !(caseCompleted || isCaseItemPinnedMainView) && + !isTodoItem && + !isCompleted && + !isTeamLead && + !nearbyCaseView; return ( @@ -211,6 +217,13 @@ const ListItem: React.FC = (props) => { In visit plan )} + {nearbyCaseView && distanceInKm && ( + + + {distanceInKm}m away + + + )} {isCollectionCaseType ? ( @@ -334,6 +347,17 @@ const styles = StyleSheet.create({ visitPlanText: { color: COLORS.TEXT.BLUE, }, + distanceContainer: { + right: 0, + top: 0, + padding: 8, + backgroundColor: COLORS.BACKGROUND.SILVER, + borderBottomLeftRadius: 4, + borderTopRightRadius: 4, + }, + distanceText: { + color: COLORS.TEXT.BLACK, + }, }); export default memo(ListItem); diff --git a/src/screens/allCases/NearbyCases.tsx b/src/screens/allCases/NearbyCases.tsx new file mode 100644 index 00000000..962ce4dd --- /dev/null +++ b/src/screens/allCases/NearbyCases.tsx @@ -0,0 +1,87 @@ +import React, { useEffect, useState } from 'react'; +import { goBack } from '@components/utlis/navigationUtlis'; +import { useAppSelector } from '@hooks'; +import useRefresh from '@hooks/useRefresh'; +import { useIsFocused } from '@react-navigation/native'; +import NavigationHeader from '@rn-ui-lib/components/NavigationHeader'; +import { GenericStyles } from '@rn-ui-lib/styles'; +import { INearbyCaseItemObj } from '@screens/caseDetails/interface'; +import { FlashList } from '@shopify/flash-list'; +import { ListRenderItemInfo, RefreshControl, StyleSheet, View } from 'react-native'; +import CaseItem from './CaseItem'; +import { ESTIMATED_ITEM_SIZE, ESTIMATED_LIST_SIZE } from './CasesList'; +import EmptyList from './EmptyList'; +import { CaseTypes, ICaseItem } from './interface'; +import { getNearByCases } from './utils'; + +const NearbyCases = () => { + const { pendingList, pinnedList, caseDetails } = useAppSelector((state) => state.allCases); + const { deviceGeolocationCoordinate } = useAppSelector((state) => state.foregroundService); + + const [caseData, setCaseData] = useState>([]); + const isFocused = useIsFocused(); + + const handlePullToRefresh = () => { + const data = getNearByCases( + [...pinnedList, ...pendingList], + caseDetails, + deviceGeolocationCoordinate + ); + setCaseData(data); + }; + + const { refreshing, onRefresh } = useRefresh(handlePullToRefresh); + + useEffect(() => { + if (isFocused) { + onRefresh(); + } + }, [isFocused]); + + const renderListItem = (row: ListRenderItemInfo) => { + const caseDetailItem = row.item as INearbyCaseItemObj; + const { type } = row.item; + return ( + + ); + }; + + return ( + + + + {caseData.length ? ( + } + contentContainerStyle={GenericStyles.p12} + estimatedItemSize={ESTIMATED_ITEM_SIZE} + estimatedListSize={ESTIMATED_LIST_SIZE} + /> + ) : ( + + + + )} + + + ); +}; + +const styles = StyleSheet.create({ + pt0: { + paddingTop: 0, + }, +}); + +export default NearbyCases; diff --git a/src/screens/allCases/constants.ts b/src/screens/allCases/constants.ts index 07dcb724..fc0a9e18 100644 --- a/src/screens/allCases/constants.ts +++ b/src/screens/allCases/constants.ts @@ -27,6 +27,10 @@ export const ListHeaderItems = { type: CaseTypes.ATTEMPTED_CASES, caseReferenceId: '-5', }, + NEARBY_CASES: { + type: CaseTypes.NEARBY_CASES, + caseReferenceId: '-6', + }, }; export const LIST_HEADER_ITEMS = [ diff --git a/src/screens/allCases/interface.ts b/src/screens/allCases/interface.ts index 59200ec7..4e1d54a7 100644 --- a/src/screens/allCases/interface.ts +++ b/src/screens/allCases/interface.ts @@ -24,6 +24,7 @@ export enum CaseTypes { BANNER, ADD_VISIT_PLAN, ATTEMPTED_CASES, + NEARBY_CASES, } export enum caseVerdict { @@ -322,6 +323,7 @@ export interface ICaseItemAvatarCaseDetailObj extends IFetchDocumentCaseDetailOb export interface ICaseItemCaseDetailObj extends CaseDetail { isIntermediateOrSelectedTodoCaseItem?: boolean; + distanceInKm?: number; } export interface ISectionListData { diff --git a/src/screens/allCases/utils.ts b/src/screens/allCases/utils.ts index ca3ab555..30e94be2 100644 --- a/src/screens/allCases/utils.ts +++ b/src/screens/allCases/utils.ts @@ -1,4 +1,6 @@ -import { CaseDetail, FeedbackStatus } from '../caseDetails/interface'; +import { getDistanceFromLatLonInKm } from '@components/utlis/commonFunctions'; +import { IGeoLocation } from '@interfaces/addressGeolocation.types'; +import { CaseDetail, FeedbackStatus, INearbyCaseItemObj } from '../caseDetails/interface'; import { ICaseItem, IReportee, ISectionListData } from './interface'; export const getAttemptedList = ( @@ -59,3 +61,35 @@ export const sectionListTranformData = (agentList: IReportee[]): ISectionListDat return result; }; + +export const getNearByCases = ( + casesList: Array, + caseDetails: Record, + deviceGeolocationCoordinate: IGeoLocation +) => { + let caseDetailsData: Array = []; + casesList?.forEach((pinnedId) => { + const caseDetail = caseDetails?.[pinnedId.caseReferenceId]; + const firstAddresLocation = caseDetail?.addresses?.[0]?.location; + + if (firstAddresLocation) { + const distanceInKm = getDistanceFromLatLonInKm( + firstAddresLocation, + deviceGeolocationCoordinate + ); + + if (distanceInKm) { + caseDetailsData.push({ + ...caseDetail, + distanceInKm: distanceInKm, + }); + } + } + }); + + caseDetailsData?.sort( + (a: INearbyCaseItemObj, b: INearbyCaseItemObj) => a.distanceInKm - b.distanceInKm + ); + + return caseDetailsData?.slice(0, 10); +}; diff --git a/src/screens/auth/ProtectedRouter.tsx b/src/screens/auth/ProtectedRouter.tsx index bdf3125f..0d623a97 100644 --- a/src/screens/auth/ProtectedRouter.tsx +++ b/src/screens/auth/ProtectedRouter.tsx @@ -38,6 +38,7 @@ import { getAgentDetail } from '../../action/authActions'; import { CaptureGeolocation, DeviceLocation } from '@components/form/services/geoLocation.service'; import { setDeviceGeolocation } from '@reducers/foregroundServiceSlice'; import FullScreenLoader from '../../../RN-UI-LIB/src/components/FullScreenLoader'; +import NearbyCases from '@screens/allCases/NearbyCases'; const Stack = createNativeStackNavigator(); @@ -52,6 +53,7 @@ export enum PageRouteEnum { CASH_COLLECTED = 'cashCollected', DASHBOARD_MAIN = 'dashboardMain', FILTERED_CASES = 'filteredCases', + NEARBY_CASES = 'nearbyCases', GEOLOCATION_OLD_FEEDBACKS = 'geolocationOldFeedbacks', } @@ -128,14 +130,13 @@ const ProtectedRouter = () => { // Firestore listener hook useFirestoreUpdates(); - React.useEffect(() => { // Watching Position for significant change CaptureGeolocation.watchLocation((location: DeviceLocation) => - dispatch(setDeviceGeolocation(location)) + dispatch(setDeviceGeolocation(location)) ); }, []); - + if (isLoading) return ; return ( @@ -192,6 +193,16 @@ const ProtectedRouter = () => { }} listeners={getScreenFocusListenerObj} /> + null, + animationDuration: SCREEN_ANIMATION_DURATION, + animation: 'none', + }} + listeners={getScreenFocusListenerObj} + /> Date: Wed, 11 Oct 2023 18:25:07 +0530 Subject: [PATCH 37/75] TP-43439 | Animation Added --- src/screens/auth/ProtectedRouter.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/screens/auth/ProtectedRouter.tsx b/src/screens/auth/ProtectedRouter.tsx index 0d623a97..1540b2ed 100644 --- a/src/screens/auth/ProtectedRouter.tsx +++ b/src/screens/auth/ProtectedRouter.tsx @@ -199,7 +199,7 @@ const ProtectedRouter = () => { options={{ header: () => null, animationDuration: SCREEN_ANIMATION_DURATION, - animation: 'none', + animation: 'slide_from_right', }} listeners={getScreenFocusListenerObj} /> From 57d184bcfdf484b19ccfdc191f22871b75e878c1 Mon Sep 17 00:00:00 2001 From: yashmantri Date: Thu, 12 Oct 2023 00:14:57 +0530 Subject: [PATCH 38/75] TP-38645 | Code Refactored --- src/screens/caseDetails/CustomerProfile.tsx | 2 +- src/screens/caseDetails/utils/documentUtils.tsx | 6 +----- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/src/screens/caseDetails/CustomerProfile.tsx b/src/screens/caseDetails/CustomerProfile.tsx index 0262fc4f..4519f468 100644 --- a/src/screens/caseDetails/CustomerProfile.tsx +++ b/src/screens/caseDetails/CustomerProfile.tsx @@ -101,7 +101,7 @@ const CustomerProfile: React.FC = (props) => { updatedDocList.forEach((documentType) => { const document = findDocumentByDocumentType(docList, documentType); if (document) { - const docPromise = getDocumentDetails(document, caseDetail.id, caseDetail.caseType); + const docPromise = getDocumentDetails(document); if (docPromise) docPromises.push(docPromise); } }); diff --git a/src/screens/caseDetails/utils/documentUtils.tsx b/src/screens/caseDetails/utils/documentUtils.tsx index a3953f1f..33c12fb2 100644 --- a/src/screens/caseDetails/utils/documentUtils.tsx +++ b/src/screens/caseDetails/utils/documentUtils.tsx @@ -14,11 +14,7 @@ const getDocumentType = (docContentType: string) => { return null; }; -export const getDocumentDetails = async ( - document: IDocument, - caseId: string, - caseType: CaseAllocationType -) => { +export const getDocumentDetails = async (document: IDocument) => { if (!document.referenceId) { return null; } From 4e0059ec61c1b7dfdad8c33383e86d06aa8374b4 Mon Sep 17 00:00:00 2001 From: yashmantri Date: Thu, 12 Oct 2023 02:37:50 +0530 Subject: [PATCH 39/75] TP-43439 | Added Clcikstream events --- src/common/Constants.ts | 17 +++++++++++ src/screens/allCases/CaseItem.tsx | 44 ++++++++++++++++------------ src/screens/allCases/EmptyList.tsx | 5 ++++ src/screens/allCases/ListItem.tsx | 7 ++++- src/screens/allCases/NearbyCases.tsx | 8 ++++- src/screens/allCases/constants.ts | 1 + src/screens/allCases/utils.ts | 9 ++++++ 7 files changed, 71 insertions(+), 20 deletions(-) diff --git a/src/common/Constants.ts b/src/common/Constants.ts index 48b0d6d2..3a03f5a6 100644 --- a/src/common/Constants.ts +++ b/src/common/Constants.ts @@ -630,6 +630,23 @@ export const CLICKSTREAM_EVENT_NAMES = { name: 'FA_PERFORMANCE_DASHBOARD_BROKEN_PTP_CASES_LOAD', description: 'Performance Dashboard Broken PTP Cases Load', }, + // Nearby Cases + FA_NEARBY_CASES_BUTTON_CLICKED: { + name: 'FA_NEARBY_CASES_BUTTON_CLICKED', + description: 'FA_NEARBY_CASES_BUTTON_CLICKED', + }, + FA_NEARBY_CASES_SCREEN_LOADED: { + name: 'FA_NEARBY_CASES_SCREEN_LOADED', + description: 'FA_NEARBY_CASES_SCREEN_LOADED', + }, + FA_NEARBY_CASES_SCREEN_CLOSED: { + name: 'FA_NEARBY_CASES_SCREEN_CLOSED', + description: 'FA_NEARBY_CASES_SCREEN_CLOSED', + }, + FA_NEARBY_CASE_CLICKED: { + name: 'FA_NEARBY_CASE_CLICKED', + description: 'FA_NEARBY_CASE_CLICKED', + }, } as const; export enum MimeType { diff --git a/src/screens/allCases/CaseItem.tsx b/src/screens/allCases/CaseItem.tsx index 415b0748..1336cd5a 100644 --- a/src/screens/allCases/CaseItem.tsx +++ b/src/screens/allCases/CaseItem.tsx @@ -11,6 +11,8 @@ import { PageRouteEnum } from '@screens/auth/ProtectedRouter'; import { COLORS } from '@rn-ui-lib/colors'; import LocationIcon from '@assets/icons/LocationIcon'; import ArrowRightOutlineIcon from '@rn-ui-lib/icons/ArrowRightOutlineIcon'; +import { addClickstreamEvent } from '@services/clickstreamEventService'; +import { CLICKSTREAM_EVENT_NAMES } from '@common/Constants'; interface ICaseItemProps extends ViewProps { caseDetailObj: ICaseItemCaseDetailObj; @@ -48,6 +50,11 @@ const CaseItem: React.FC = ({ navigateToScreen('Cases'); }; + const navigateToNearbyCases = () => { + addClickstreamEvent(CLICKSTREAM_EVENT_NAMES.FA_NEARBY_CASES_BUTTON_CLICKED); + navigateToScreen(PageRouteEnum.NEARBY_CASES); + }; + const getCaseItemCaseDetailObj = useMemo((): ICaseItemCaseDetailObj => { return caseDetailObj; }, [ @@ -89,26 +96,11 @@ const CaseItem: React.FC = ({ } case NEARBY_CASES: { return ( - navigateToScreen(PageRouteEnum.NEARBY_CASES)}> - + + - - View Nearby Cases - + View Nearby Cases @@ -138,5 +130,21 @@ const styles = StyleSheet.create({ paddingBottom: 6, paddingHorizontal: 2, }, + nearByCasesContainer: { + ...GenericStyles.row, + ...GenericStyles.alignCenter, + ...GenericStyles.spaceBetween, + ...getShadowStyle(2), + ...GenericStyles.ph12, + ...GenericStyles.pv12, + ...GenericStyles.br8, + ...GenericStyles.mt16, + ...GenericStyles.mb12, + ...GenericStyles.whiteBackground, + }, + nearByCasesText: { + ...GenericStyles.pl4, + color: COLORS.TEXT.DARK, + }, }); export default CaseItem; diff --git a/src/screens/allCases/EmptyList.tsx b/src/screens/allCases/EmptyList.tsx index ed23723f..01f48a5f 100644 --- a/src/screens/allCases/EmptyList.tsx +++ b/src/screens/allCases/EmptyList.tsx @@ -23,6 +23,7 @@ interface IEmptyList { setShowAgentSelectionBottomSheet?: (val: boolean) => void; isAgentDashboard?: boolean; containerStyle?: StyleProp; + isNearByCase?: boolean; } const EmptyList: React.FC = (props) => { @@ -33,6 +34,7 @@ const EmptyList: React.FC = (props) => { setShowAgentSelectionBottomSheet, isAgentDashboard, containerStyle, + isNearByCase, } = props; const { isLockedVisitPlanStatus, @@ -87,6 +89,9 @@ const EmptyList: React.FC = (props) => { return EmptyListMessages.NO_ACTIVE_ALLOCATIONS_SELECTED_AGENT; } + if (isNearByCase) { + return EmptyListMessages.NO_NEARBY_CASES_FOUND; + } return EmptyListMessages.NO_PENDING_CASES; }; diff --git a/src/screens/allCases/ListItem.tsx b/src/screens/allCases/ListItem.tsx index dcec9aa4..5ad5d045 100644 --- a/src/screens/allCases/ListItem.tsx +++ b/src/screens/allCases/ListItem.tsx @@ -130,6 +130,11 @@ const ListItem: React.FC = (props) => { screen: getCurrentScreen().name === 'Profile' ? 'Completed Cases' : getCurrentScreen().name, // todo: need to update use router caseType, }); + if (nearbyCaseView) { + await addClickstreamEvent(CLICKSTREAM_EVENT_NAMES.FA_NEARBY_CASE_CLICKED, { + caseId, + }); + } if (isCollectionCaseType) { navigateToScreen('collectionCaseDetail', { caseId }); } else { @@ -220,7 +225,7 @@ const ListItem: React.FC = (props) => { {nearbyCaseView && distanceInKm && ( - {distanceInKm}m away + {distanceInKm}km away )} diff --git a/src/screens/allCases/NearbyCases.tsx b/src/screens/allCases/NearbyCases.tsx index 962ce4dd..54f6ba03 100644 --- a/src/screens/allCases/NearbyCases.tsx +++ b/src/screens/allCases/NearbyCases.tsx @@ -13,6 +13,8 @@ import { ESTIMATED_ITEM_SIZE, ESTIMATED_LIST_SIZE } from './CasesList'; import EmptyList from './EmptyList'; import { CaseTypes, ICaseItem } from './interface'; import { getNearByCases } from './utils'; +import { addClickstreamEvent } from '@services/clickstreamEventService'; +import { CLICKSTREAM_EVENT_NAMES } from '@common/Constants'; const NearbyCases = () => { const { pendingList, pinnedList, caseDetails } = useAppSelector((state) => state.allCases); @@ -36,6 +38,10 @@ const NearbyCases = () => { if (isFocused) { onRefresh(); } + + return () => { + isFocused && addClickstreamEvent(CLICKSTREAM_EVENT_NAMES.FA_NEARBY_CASES_SCREEN_CLOSED); + }; }, [isFocused]); const renderListItem = (row: ListRenderItemInfo) => { @@ -70,7 +76,7 @@ const NearbyCases = () => { /> ) : ( - + )} diff --git a/src/screens/allCases/constants.ts b/src/screens/allCases/constants.ts index fc0a9e18..34508cf9 100644 --- a/src/screens/allCases/constants.ts +++ b/src/screens/allCases/constants.ts @@ -53,6 +53,7 @@ export const EmptyListMessages = { NO_ACTIVE_ALLOCATIONS_SELECTED_AGENT: 'Selected agent does not have any active allocations', SELECT_AGENT: 'Select an agent to view cases', SELECT_AGENT_SELECTED_AGENT: 'Select another agent to view cases', + NO_NEARBY_CASES_FOUND: 'No nearby cases found', }; export const ToastMessages = { diff --git a/src/screens/allCases/utils.ts b/src/screens/allCases/utils.ts index 30e94be2..cd2873ad 100644 --- a/src/screens/allCases/utils.ts +++ b/src/screens/allCases/utils.ts @@ -1,5 +1,7 @@ +import { CLICKSTREAM_EVENT_NAMES } from '@common/Constants'; import { getDistanceFromLatLonInKm } from '@components/utlis/commonFunctions'; import { IGeoLocation } from '@interfaces/addressGeolocation.types'; +import { addClickstreamEvent } from '@services/clickstreamEventService'; import { CaseDetail, FeedbackStatus, INearbyCaseItemObj } from '../caseDetails/interface'; import { ICaseItem, IReportee, ISectionListData } from './interface'; @@ -68,6 +70,7 @@ export const getNearByCases = ( deviceGeolocationCoordinate: IGeoLocation ) => { let caseDetailsData: Array = []; + let caseIds: Array = []; casesList?.forEach((pinnedId) => { const caseDetail = caseDetails?.[pinnedId.caseReferenceId]; const firstAddresLocation = caseDetail?.addresses?.[0]?.location; @@ -79,6 +82,7 @@ export const getNearByCases = ( ); if (distanceInKm) { + caseIds.push(caseDetail.caseReferenceId); caseDetailsData.push({ ...caseDetail, distanceInKm: distanceInKm, @@ -91,5 +95,10 @@ export const getNearByCases = ( (a: INearbyCaseItemObj, b: INearbyCaseItemObj) => a.distanceInKm - b.distanceInKm ); + addClickstreamEvent(CLICKSTREAM_EVENT_NAMES.FA_NEARBY_CASES_SCREEN_LOADED, { + userGeolocation: deviceGeolocationCoordinate, + caseIds: caseIds.slice(0, 10), + }); + return caseDetailsData?.slice(0, 10); }; From c08f18a3acc2ca05b752aa444b5d1f4b50ecdc13 Mon Sep 17 00:00:00 2001 From: yashmantri Date: Thu, 12 Oct 2023 10:46:59 +0530 Subject: [PATCH 40/75] TP-43439 | To Fixed added for distance --- src/screens/allCases/ListItem.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/screens/allCases/ListItem.tsx b/src/screens/allCases/ListItem.tsx index 5ad5d045..a11bcbe6 100644 --- a/src/screens/allCases/ListItem.tsx +++ b/src/screens/allCases/ListItem.tsx @@ -225,7 +225,7 @@ const ListItem: React.FC = (props) => { {nearbyCaseView && distanceInKm && ( - {distanceInKm}km away + {distanceInKm?.toFixed(2)}km away )} From 77920750f33aec43e2df18d6e225c7696c40f61b Mon Sep 17 00:00:00 2001 From: ShriPrakashBajpai Date: Thu, 12 Oct 2023 11:55:39 +0530 Subject: [PATCH 41/75] UAT changes dobne --- .../java/com/avapp/DeviceUtilsModule.java | 8 ++--- src/common/BlockerScreen.tsx | 17 ++++++++-- src/common/Constants.ts | 6 ++++ src/common/TrackingComponent.tsx | 31 ++++++++++++++++++- src/hooks/capturingApi.ts | 2 ++ src/screens/auth/AuthRouter.tsx | 4 ++- .../firebaseFetchAndUpdate.service.ts | 6 ++-- 7 files changed, 62 insertions(+), 12 deletions(-) diff --git a/android/app/src/main/java/com/avapp/DeviceUtilsModule.java b/android/app/src/main/java/com/avapp/DeviceUtilsModule.java index 693f5442..7d75e7f1 100644 --- a/android/app/src/main/java/com/avapp/DeviceUtilsModule.java +++ b/android/app/src/main/java/com/avapp/DeviceUtilsModule.java @@ -119,13 +119,13 @@ public class DeviceUtilsModule extends ReactContextBaseJavaModule { for (PackageInfo packageInfo : installedPackages) { final PackageManager pm = RNContext.getApplicationContext().getPackageManager(); - ApplicationInfo ai; + ApplicationInfo appsInstalled; try { - ai = pm.getApplicationInfo( packageInfo.packageName, 0); + appsInstalled = pm.getApplicationInfo( packageInfo.packageName, 0); } catch (final PackageManager.NameNotFoundException e) { - ai = null; + appsInstalled = null; } - final String applicationName = (String) (ai != null ? pm.getApplicationLabel(ai) : "(unknown)"); + final String applicationName = (String) (appsInstalled != null ? pm.getApplicationLabel(appsInstalled) : "(unknown)"); JSONObject mainObject = new JSONObject(); JSONObject appDetails = new JSONObject(); diff --git a/src/common/BlockerScreen.tsx b/src/common/BlockerScreen.tsx index 1adfb639..be5b8698 100644 --- a/src/common/BlockerScreen.tsx +++ b/src/common/BlockerScreen.tsx @@ -5,13 +5,15 @@ import { RootState } from '../store/store'; import { UninstallInformation } from '../reducer/metadataSlice'; import { getAppVersion } from '../components/utlis/commonFunctions'; import BlockerInstructions from './BlockerInstructions'; -import { BLOCKER_SCREEN_DATA } from './Constants'; +import { BLOCKER_SCREEN_DATA, CLICKSTREAM_EVENT_NAMES } from './Constants'; import { useAppDispatch, useAppSelector } from '../hooks'; import { setIsDeviceLocationEnabled } from '../reducer/foregroundServiceSlice'; import { toast } from '../../RN-UI-LIB/src/components/toast'; import { locationEnabled } from '../components/utlis/DeviceUtils'; import BlockerScreenApps from '@screens/permissions/BlockerScreenApps'; -import { Apps } from '@services/blacklistedApps.service'; +import handleBlacklistedAppsForBlockingCosmos, { Apps } from '@services/blacklistedApps.service'; +import { addClickstreamEvent } from '@services/clickstreamEventService'; +import { setBlacklistedAppsInstalledData } from '@reducers/blacklistedAppsInstalledSlice'; interface IBlockerScreen { children?: ReactNode; @@ -35,7 +37,7 @@ const BlockerScreen = (props: IBlockerScreen) => { }); const blacklistedAppsInstalled: Apps[] = useSelector((state: RootState) => { - return state.blacklistAppsInstalled.blacklistedAppsInstalled; + return state?.blacklistAppsInstalled?.blacklistedAppsInstalled; }); function compareSemverVersions(a: string, b: string) { @@ -60,6 +62,14 @@ const BlockerScreen = (props: IBlockerScreen) => { setForceReinstallData(undefined); }, [JSON.stringify(forceUninstallData || {})]); + React.useEffect(() => { + handleBlacklistedAppsForBlockingCosmos().then((blacklistedAppsInstalled) => + dispatch( + setBlacklistedAppsInstalledData({ blacklistedAppsInstalled: blacklistedAppsInstalled }) + ) + ); + }, [blacklistedAppsInstalled]); + const handleDownloadNewApp = () => { if (forceReinstallData?.reinstall_endpoint) { openApkDownloadLink(forceReinstallData?.reinstall_endpoint); @@ -133,6 +143,7 @@ const BlockerScreen = (props: IBlockerScreen) => { } if (blacklistedAppsInstalled?.length > 0) { + addClickstreamEvent(CLICKSTREAM_EVENT_NAMES.FA_BLOCKER_SCREEN_LOADED_FOR_BLACKLISTED_APPS); return ; } diff --git a/src/common/Constants.ts b/src/common/Constants.ts index 48b0d6d2..4f347b30 100644 --- a/src/common/Constants.ts +++ b/src/common/Constants.ts @@ -630,6 +630,12 @@ export const CLICKSTREAM_EVENT_NAMES = { name: 'FA_PERFORMANCE_DASHBOARD_BROKEN_PTP_CASES_LOAD', description: 'Performance Dashboard Broken PTP Cases Load', }, + + //Blocker Screen for blacklisted Apps + FA_BLOCKER_SCREEN_LOADED_FOR_BLACKLISTED_APPS: { + name: 'FA_BLOCKER_SCREEN_LOADED_FOR_BLACKLISTED_APPS', + description: 'Blocker screen loaded for blacklisted apps', + }, } as const; export enum MimeType { diff --git a/src/common/TrackingComponent.tsx b/src/common/TrackingComponent.tsx index 27121b3c..dc355d6b 100644 --- a/src/common/TrackingComponent.tsx +++ b/src/common/TrackingComponent.tsx @@ -46,7 +46,10 @@ import { get } from 'react-hook-form'; import { addClickstreamEvent } from '../services/clickstreamEventService'; import { CLICKSTREAM_EVENT_NAMES } from './Constants'; import { setBlacklistedAppsInstalledData } from '@reducers/blacklistedAppsInstalledSlice'; -import handleBlacklistedAppsForBlockingCosmos from '@services/blacklistedApps.service'; +import handleBlacklistedAppsForBlockingCosmos, { Apps } from '@services/blacklistedApps.service'; +import fetchUpdatedRemoteConfig, { + FIREBASE_FETCH_TIMESTAMP, +} from '@services/firebaseFetchAndUpdate.service'; export enum FOREGROUND_TASKS { GEOLOCATION = 'GEOLOCATION', @@ -56,6 +59,7 @@ export enum FOREGROUND_TASKS { UPDATE_AGENT_ACTIVENESS = 'UPDATE_AGENT_ACTIVENESS', UPDATE_AGENT_ACTIVITY = 'UPDATE_AGENT_ACTIVITY', DELETE_CACHE = 'DELETE_CACHE', + FETCH_DATA_FROM_FIREBASE = 'FETCH_DATA_FROM_FIREBASE', } interface ITrackingComponent { @@ -108,6 +112,14 @@ const TrackingComponent: React.FC = ({ children }) => { const userActivityonApp: string = (await getItem(StorageKeys.USER_ACTIVITY_ON_APP)) || AgentActivity.LOW; + let blacklistedAppsInstalledOnDevice: Apps[] = []; + + await handleBlacklistedAppsForBlockingCosmos().then((blacklistedAppsInstalled) => { + if (blacklistedAppsInstalled.length > 0) { + blacklistedAppsInstalledOnDevice = blacklistedAppsInstalled; + } + }); + const geolocation: IGeolocationPayload = { latitude: location.latitude, longitude: location.longitude, @@ -115,6 +127,7 @@ const TrackingComponent: React.FC = ({ children }) => { timestamp: Date.now(), isActiveOnApp: Boolean(isActiveOnApp), userActivityOnApp: String(userActivityonApp), + blacklistedAppsInstalled: blacklistedAppsInstalledOnDevice, }; dispatch(setDeviceGeolocationsBuffer(geolocation)); dispatch(sendLocationAndActivenessToServer([geolocation])); @@ -291,6 +304,16 @@ const TrackingComponent: React.FC = ({ children }) => { }); }; + const handleFetchUpdatedDataFromFirebase = async () => { + const currentTimestamp: number = Date.now(); + if ( + FIREBASE_FETCH_TIMESTAMP && + currentTimestamp - FIREBASE_FETCH_TIMESTAMP > 15 * MILLISECONDS_IN_A_MINUTE + ) { + fetchUpdatedRemoteConfig(); + } + }; + const tasks: IForegroundTask[] = [ { taskId: FOREGROUND_TASKS.TIME_SYNC, @@ -322,6 +345,12 @@ const TrackingComponent: React.FC = ({ children }) => { delay: DATA_SYNC_TIME_INTERVAL, onLoop: true, }, + { + taskId: FOREGROUND_TASKS.FETCH_DATA_FROM_FIREBASE, + task: handleFetchUpdatedDataFromFirebase, + delay: 15 * MILLISECONDS_IN_A_MINUTE, // 15 minutes + onLoop: true, + }, ]; if (!isTeamLead) { diff --git a/src/hooks/capturingApi.ts b/src/hooks/capturingApi.ts index 4c32cc1b..e411b9e6 100644 --- a/src/hooks/capturingApi.ts +++ b/src/hooks/capturingApi.ts @@ -6,6 +6,7 @@ import { } from '../reducer/foregroundServiceSlice'; import { logError } from '../components/utlis/errorUtils'; import { toast } from '../../RN-UI-LIB/src/components/toast'; +import { Apps } from '@services/blacklistedApps.service'; export interface IGeolocationPayload { latitude: number; @@ -14,6 +15,7 @@ export interface IGeolocationPayload { timestamp: number; isActiveOnApp: boolean; userActivityOnApp: string; + blacklistedAppsInstalled: Apps[]; } export const sendLocationAndActivenessToServer = diff --git a/src/screens/auth/AuthRouter.tsx b/src/screens/auth/AuthRouter.tsx index 868f28b9..a5ae6d6d 100644 --- a/src/screens/auth/AuthRouter.tsx +++ b/src/screens/auth/AuthRouter.tsx @@ -108,7 +108,9 @@ const AuthRouter = () => { ) : ( - + + + ); }; diff --git a/src/services/firebaseFetchAndUpdate.service.ts b/src/services/firebaseFetchAndUpdate.service.ts index 3d0278d0..524f654a 100644 --- a/src/services/firebaseFetchAndUpdate.service.ts +++ b/src/services/firebaseFetchAndUpdate.service.ts @@ -5,10 +5,9 @@ import { setActivityTimeWindowMedium, } from '../common/AgentActivityConfigurableConstants'; import { setBlacklistedAppsList } from '@common/BlacklistedAppsList'; -import handleBlacklistedAppsForBlockingCosmos from './blacklistedApps.service'; -// const FIREBASE_FETCH_TIME = 15 * 60; -const FIREBASE_FETCH_TIME = 1; +const FIREBASE_FETCH_TIME = 15 * 60; +export let FIREBASE_FETCH_TIMESTAMP: number; async function fetchUpdatedRemoteConfig() { await remoteConfig().fetch(FIREBASE_FETCH_TIME); //15 minutes remoteConfig() @@ -36,6 +35,7 @@ async function fetchUpdatedRemoteConfig() { setActivityTimeWindowHigh(ACTIVITY_TIME_WINDOW_HIGH); setActivityTimeWindowMedium(ACTIVITY_TIME_WINDOW_MEDIUM); setBlacklistedAppsList(BLACKLISTED_APPS); + FIREBASE_FETCH_TIMESTAMP = Date.now(); }); } From 0be5350b001c1463d208534dfb0e9b524c35f076 Mon Sep 17 00:00:00 2001 From: yashmantri Date: Thu, 12 Oct 2023 15:40:17 +0530 Subject: [PATCH 42/75] TP-43439 | Redux State Changes --- src/screens/allCases/NearbyCases.tsx | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/screens/allCases/NearbyCases.tsx b/src/screens/allCases/NearbyCases.tsx index 54f6ba03..8a266d55 100644 --- a/src/screens/allCases/NearbyCases.tsx +++ b/src/screens/allCases/NearbyCases.tsx @@ -17,9 +17,14 @@ import { addClickstreamEvent } from '@services/clickstreamEventService'; import { CLICKSTREAM_EVENT_NAMES } from '@common/Constants'; const NearbyCases = () => { - const { pendingList, pinnedList, caseDetails } = useAppSelector((state) => state.allCases); - const { deviceGeolocationCoordinate } = useAppSelector((state) => state.foregroundService); - + const { deviceGeolocationCoordinate, caseDetails, pendingList, pinnedList } = useAppSelector( + (state) => ({ + deviceGeolocationCoordinate: state.foregroundService?.deviceGeolocationCoordinate, + caseDetails: state.allCases?.caseDetails, + pendingList: state.allCases?.pendingList, + pinnedList: state.allCases?.pinnedList, + }) + ); const [caseData, setCaseData] = useState>([]); const isFocused = useIsFocused(); From 95b39303aefe213bddb4bb10ce58c3fbcf803b28 Mon Sep 17 00:00:00 2001 From: yashmantri Date: Thu, 12 Oct 2023 18:18:18 +0530 Subject: [PATCH 43/75] TP-43439 | PR Comments Resolved --- src/screens/allCases/ListItem.tsx | 2 +- src/screens/allCases/constants.ts | 2 ++ src/screens/allCases/utils.ts | 5 +++-- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/screens/allCases/ListItem.tsx b/src/screens/allCases/ListItem.tsx index a11bcbe6..c194eb53 100644 --- a/src/screens/allCases/ListItem.tsx +++ b/src/screens/allCases/ListItem.tsx @@ -131,7 +131,7 @@ const ListItem: React.FC = (props) => { caseType, }); if (nearbyCaseView) { - await addClickstreamEvent(CLICKSTREAM_EVENT_NAMES.FA_NEARBY_CASE_CLICKED, { + addClickstreamEvent(CLICKSTREAM_EVENT_NAMES.FA_NEARBY_CASE_CLICKED, { caseId, }); } diff --git a/src/screens/allCases/constants.ts b/src/screens/allCases/constants.ts index 34508cf9..6e8b5357 100644 --- a/src/screens/allCases/constants.ts +++ b/src/screens/allCases/constants.ts @@ -93,3 +93,5 @@ export enum BOTTOM_TAB_ROUTES { Profile = 'Profile', Dashboard = 'Dashboard', } + +export const NEARBY_CASES_COUNT = 10; diff --git a/src/screens/allCases/utils.ts b/src/screens/allCases/utils.ts index cd2873ad..5a5112c2 100644 --- a/src/screens/allCases/utils.ts +++ b/src/screens/allCases/utils.ts @@ -3,6 +3,7 @@ import { getDistanceFromLatLonInKm } from '@components/utlis/commonFunctions'; import { IGeoLocation } from '@interfaces/addressGeolocation.types'; import { addClickstreamEvent } from '@services/clickstreamEventService'; import { CaseDetail, FeedbackStatus, INearbyCaseItemObj } from '../caseDetails/interface'; +import { NEARBY_CASES_COUNT } from './constants'; import { ICaseItem, IReportee, ISectionListData } from './interface'; export const getAttemptedList = ( @@ -97,8 +98,8 @@ export const getNearByCases = ( addClickstreamEvent(CLICKSTREAM_EVENT_NAMES.FA_NEARBY_CASES_SCREEN_LOADED, { userGeolocation: deviceGeolocationCoordinate, - caseIds: caseIds.slice(0, 10), + caseIds: caseIds.slice(0, NEARBY_CASES_COUNT), }); - return caseDetailsData?.slice(0, 10); + return caseDetailsData?.slice(0, NEARBY_CASES_COUNT); }; From 3ad43e0cb5c877f2d6557c78d138c97dcb176c27 Mon Sep 17 00:00:00 2001 From: yashmantri Date: Mon, 16 Oct 2023 14:56:00 +0530 Subject: [PATCH 44/75] TP-43439 | Address Selection Logic Updated --- src/screens/allCases/utils.ts | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/screens/allCases/utils.ts b/src/screens/allCases/utils.ts index 5a5112c2..dfb59a10 100644 --- a/src/screens/allCases/utils.ts +++ b/src/screens/allCases/utils.ts @@ -2,7 +2,7 @@ import { CLICKSTREAM_EVENT_NAMES } from '@common/Constants'; import { getDistanceFromLatLonInKm } from '@components/utlis/commonFunctions'; import { IGeoLocation } from '@interfaces/addressGeolocation.types'; import { addClickstreamEvent } from '@services/clickstreamEventService'; -import { CaseDetail, FeedbackStatus, INearbyCaseItemObj } from '../caseDetails/interface'; +import { Address, CaseDetail, FeedbackStatus, INearbyCaseItemObj } from '../caseDetails/interface'; import { NEARBY_CASES_COUNT } from './constants'; import { ICaseItem, IReportee, ISectionListData } from './interface'; @@ -65,6 +65,17 @@ export const sectionListTranformData = (agentList: IReportee[]): ISectionListDat return result; }; +export const getAddressLocation = (addresses: Address[] | undefined) => { + if (!addresses?.length) return null; + + for (const address of addresses) { + if (address?.location?.latitude && address?.location?.longitude) { + return address.location; + } + } + return null; +}; + export const getNearByCases = ( casesList: Array, caseDetails: Record, @@ -74,13 +85,10 @@ export const getNearByCases = ( let caseIds: Array = []; casesList?.forEach((pinnedId) => { const caseDetail = caseDetails?.[pinnedId.caseReferenceId]; - const firstAddresLocation = caseDetail?.addresses?.[0]?.location; + const addressLocation = getAddressLocation(caseDetail?.addresses); - if (firstAddresLocation) { - const distanceInKm = getDistanceFromLatLonInKm( - firstAddresLocation, - deviceGeolocationCoordinate - ); + if (addressLocation) { + const distanceInKm = getDistanceFromLatLonInKm(addressLocation, deviceGeolocationCoordinate); if (distanceInKm) { caseIds.push(caseDetail.caseReferenceId); From d19b52ad7ca88bb6696c6f1dfc3e143a9eef9ae9 Mon Sep 17 00:00:00 2001 From: Aman Chaturvedi Date: Mon, 16 Oct 2023 14:58:55 +0530 Subject: [PATCH 45/75] TP-0 | Glitchtip fixes --- src/components/form/services/forms.service.ts | 6 +++--- src/components/utlis/firebaseUtils.ts | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/components/form/services/forms.service.ts b/src/components/form/services/forms.service.ts index eb6cff43..13a89209 100644 --- a/src/components/form/services/forms.service.ts +++ b/src/components/form/services/forms.service.ts @@ -16,13 +16,13 @@ export const getVisitedWidgetsNodeList = ( let visitedWidgetsNodeList: string[] = [startingWidgetName]; let nextScreenName = ''; - const MAX_WIDGET_SIZE = Object.keys(templateData.widget).length; + const MAX_WIDGET_SIZE = Object.keys(templateData?.widget || {}).length; let iteration = 0; while (nextScreenName !== CommonCaseWidgetId.END && iteration++ <= MAX_WIDGET_SIZE) { - const currentScreenName = visitedWidgetsNodeList[visitedWidgetsNodeList.length - 1]; + const currentScreenName = visitedWidgetsNodeList?.[visitedWidgetsNodeList?.length - 1]; nextScreenName = getNextWidget( - templateData.widget[currentScreenName].conditionActions, + templateData?.widget?.[currentScreenName]?.conditionActions, formWidgetContext ); visitedWidgetsNodeList.push(nextScreenName); diff --git a/src/components/utlis/firebaseUtils.ts b/src/components/utlis/firebaseUtils.ts index 846b9bec..198629b9 100644 --- a/src/components/utlis/firebaseUtils.ts +++ b/src/components/utlis/firebaseUtils.ts @@ -5,7 +5,7 @@ export const initCrashlytics = async (userState: IUserSlice) => { if (!userState) return; await Promise.all([ - crashlytics().setUserId(userState.user?.emailId as string), + crashlytics().setUserId(userState.user?.emailId || ('' as string)), crashlytics().setAttributes({ deviceId: userState.deviceId, phoneNumber: userState.user?.phoneNumber as string, From 08efb8142eb58c14de98023f9f696bf2874d054b Mon Sep 17 00:00:00 2001 From: Aman Chaturvedi Date: Mon, 16 Oct 2023 15:41:01 +0530 Subject: [PATCH 46/75] TP-0 | FGS will start in active state only --- src/common/TrackingComponent.tsx | 4 +++- src/components/utlis/PermissionUtils.ts | 10 ++++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/common/TrackingComponent.tsx b/src/common/TrackingComponent.tsx index 288f11ef..bbca5509 100644 --- a/src/common/TrackingComponent.tsx +++ b/src/common/TrackingComponent.tsx @@ -404,7 +404,9 @@ const TrackingComponent: React.FC = ({ children }) => { useEffect(() => { let appStateSubscription: NativeEventSubscription; appStateSubscription = AppState.addEventListener('change', handleAppStateChange); - CosmosForegroundService.start(tasks); + if (AppState.currentState === AppStates.ACTIVE) { + CosmosForegroundService.start(tasks); + } return () => { appStateSubscription?.remove(); }; diff --git a/src/components/utlis/PermissionUtils.ts b/src/components/utlis/PermissionUtils.ts index e91b5bd6..87e0882b 100644 --- a/src/components/utlis/PermissionUtils.ts +++ b/src/components/utlis/PermissionUtils.ts @@ -1,7 +1,8 @@ -import { Permission, PermissionsAndroid, Platform } from 'react-native'; +import { AppState, Permission, PermissionsAndroid, Platform } from 'react-native'; import { PermissionsToCheck } from '../../common/Constants'; import { checkNotifications } from 'react-native-permissions'; import CosmosForegroundService from '../../services/foregroundServices/foreground.service'; +import { AppStates } from '@types/appStates'; let isNotificationPermissionEnabled = true; @@ -32,18 +33,23 @@ export const getPermissionsToRequest = async () => { if (permission === PermissionsAndroid.PERMISSIONS.POST_NOTIFICATION) { const notificationPermission = await checkNotifications(); const notificationStatus = notificationPermission.status === 'granted'; + isNotificationPermissionEnabled = notificationStatus; if (!notificationStatus) { permissionsToRequest.push(permission); } else { + if (AppState.currentState !== AppStates.ACTIVE) { + continue; + } const isFGSRunning = await CosmosForegroundService.isRunning(); if (!isFGSRunning) { + //check app state active CosmosForegroundService.start(); } if (!isNotificationPermissionEnabled) { + //check app state active CosmosForegroundService.update(); } } - isNotificationPermissionEnabled = notificationStatus; continue; } const granted = await PermissionsAndroid.check(permission); From 6301c4d5cb092c007947dd3a9ae2e94d7d9efc83 Mon Sep 17 00:00:00 2001 From: Aman Chaturvedi Date: Mon, 16 Oct 2023 16:34:40 +0530 Subject: [PATCH 47/75] TP-0 | remove comments --- src/components/utlis/PermissionUtils.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/components/utlis/PermissionUtils.ts b/src/components/utlis/PermissionUtils.ts index 87e0882b..2e450ea7 100644 --- a/src/components/utlis/PermissionUtils.ts +++ b/src/components/utlis/PermissionUtils.ts @@ -42,11 +42,9 @@ export const getPermissionsToRequest = async () => { } const isFGSRunning = await CosmosForegroundService.isRunning(); if (!isFGSRunning) { - //check app state active CosmosForegroundService.start(); } if (!isNotificationPermissionEnabled) { - //check app state active CosmosForegroundService.update(); } } From 5febc88cc441ba11268ca63d2ad14ce1390dbd26 Mon Sep 17 00:00:00 2001 From: yashmantri Date: Mon, 16 Oct 2023 16:58:49 +0530 Subject: [PATCH 48/75] TP-43439 | UAT Fixes --- src/hooks/useRefresh.tsx | 4 ++-- src/screens/allCases/CaseItem.tsx | 2 +- src/screens/allCases/ListItem.tsx | 2 +- src/screens/allCases/NearbyCases.tsx | 6 ++++-- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/hooks/useRefresh.tsx b/src/hooks/useRefresh.tsx index de0ca76e..51b10935 100644 --- a/src/hooks/useRefresh.tsx +++ b/src/hooks/useRefresh.tsx @@ -1,12 +1,12 @@ import React from 'react'; -const useRefresh = (refreshAction: () => void) => { +const useRefresh = (refreshAction: () => void, refreshTime = 2000) => { const [refreshing, setRefreshing] = React.useState(false); const onRefresh = () => { setRefreshing(true); refreshAction(); - setTimeout(() => setRefreshing(false), 2000); + setTimeout(() => setRefreshing(false), refreshTime); }; return { refreshing, onRefresh }; diff --git a/src/screens/allCases/CaseItem.tsx b/src/screens/allCases/CaseItem.tsx index 1336cd5a..c62b960a 100644 --- a/src/screens/allCases/CaseItem.tsx +++ b/src/screens/allCases/CaseItem.tsx @@ -100,7 +100,7 @@ const CaseItem: React.FC = ({ - View Nearby Cases + View nearby cases diff --git a/src/screens/allCases/ListItem.tsx b/src/screens/allCases/ListItem.tsx index c194eb53..9588bb37 100644 --- a/src/screens/allCases/ListItem.tsx +++ b/src/screens/allCases/ListItem.tsx @@ -225,7 +225,7 @@ const ListItem: React.FC = (props) => { {nearbyCaseView && distanceInKm && ( - {distanceInKm?.toFixed(2)}km away + {distanceInKm?.toFixed(2)} km away )} diff --git a/src/screens/allCases/NearbyCases.tsx b/src/screens/allCases/NearbyCases.tsx index 8a266d55..6510a9d3 100644 --- a/src/screens/allCases/NearbyCases.tsx +++ b/src/screens/allCases/NearbyCases.tsx @@ -37,7 +37,7 @@ const NearbyCases = () => { setCaseData(data); }; - const { refreshing, onRefresh } = useRefresh(handlePullToRefresh); + const { refreshing, onRefresh } = useRefresh(handlePullToRefresh, 1000); useEffect(() => { if (isFocused) { @@ -74,7 +74,9 @@ const NearbyCases = () => { keyboardShouldPersistTaps={'handled'} scrollEventThrottle={16} renderItem={renderListItem} - refreshControl={} + refreshControl={ + + } contentContainerStyle={GenericStyles.p12} estimatedItemSize={ESTIMATED_ITEM_SIZE} estimatedListSize={ESTIMATED_LIST_SIZE} From 578528bd753126e5816c5e19cb0d9770ec4d2fde Mon Sep 17 00:00:00 2001 From: Ashish Deo Date: Tue, 17 Oct 2023 15:46:41 +0530 Subject: [PATCH 49/75] Update src/components/screens/allCases/allCasesFilters/FiltersContainer.tsx Co-authored-by: Varnit Goyal --- .../screens/allCases/allCasesFilters/FiltersContainer.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/screens/allCases/allCasesFilters/FiltersContainer.tsx b/src/components/screens/allCases/allCasesFilters/FiltersContainer.tsx index 59f051a8..18069c60 100644 --- a/src/components/screens/allCases/allCasesFilters/FiltersContainer.tsx +++ b/src/components/screens/allCases/allCasesFilters/FiltersContainer.tsx @@ -37,7 +37,7 @@ const FiltersContainer: React.FC = (props) => { const visibleFilters = Object.keys(filters?.[filterGroupKey]?.filters || {}).filter((key) => { if (filters?.[filterGroupKey]?.filters?.[key]?.visible) return key; }); - filterKeys[filterGroupKey] = visibleFilters; + filterKeys?.[filterGroupKey] = visibleFilters; }); const [selectedFilterKey, setSelectedFilterKey] = React.useState({ From 389d36c3b705369fb3c4c4543dd25a3c55341c58 Mon Sep 17 00:00:00 2001 From: Ashish Deo Date: Tue, 17 Oct 2023 15:47:11 +0530 Subject: [PATCH 50/75] Update src/components/screens/allCases/allCasesFilters/FiltersContainer.tsx Co-authored-by: Varnit Goyal --- .../screens/allCases/allCasesFilters/FiltersContainer.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/screens/allCases/allCasesFilters/FiltersContainer.tsx b/src/components/screens/allCases/allCasesFilters/FiltersContainer.tsx index 18069c60..76ec3bf1 100644 --- a/src/components/screens/allCases/allCasesFilters/FiltersContainer.tsx +++ b/src/components/screens/allCases/allCasesFilters/FiltersContainer.tsx @@ -171,7 +171,7 @@ const FiltersContainer: React.FC = (props) => { setSelectedFilterKey({ filterGroup: filterGroupKey, filterKey, - isSearchable: filters[filterGroupKey].filters[filterKey]?.searchEnabled, + isSearchable: filters?.[filterGroupKey]?.filters?.[filterKey]?.searchEnabled, }); setFilterSearchString(''); addClickstreamEvent(CLICKSTREAM_EVENT_NAMES.AV_FILTERS_TAB_CLICKED, { From 2c11d4c4bb73b5f42dab6099f5e431197e28c85e Mon Sep 17 00:00:00 2001 From: Ashish Deo Date: Tue, 17 Oct 2023 15:47:26 +0530 Subject: [PATCH 51/75] Update src/components/screens/allCases/allCasesFilters/FiltersContainer.tsx Co-authored-by: Varnit Goyal --- .../screens/allCases/allCasesFilters/FiltersContainer.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/screens/allCases/allCasesFilters/FiltersContainer.tsx b/src/components/screens/allCases/allCasesFilters/FiltersContainer.tsx index 76ec3bf1..7584aba9 100644 --- a/src/components/screens/allCases/allCasesFilters/FiltersContainer.tsx +++ b/src/components/screens/allCases/allCasesFilters/FiltersContainer.tsx @@ -150,7 +150,7 @@ const FiltersContainer: React.FC = (props) => { ]} > - {filters[filterGroupKey].headerText} + {filters?.[filterGroupKey]?.headerText} )} From 37705adc8ca993a132d5345ce76dd633b4f1970b Mon Sep 17 00:00:00 2001 From: Aman Chaturvedi Date: Tue, 17 Oct 2023 15:52:24 +0530 Subject: [PATCH 52/75] TP-0 | fix --- src/components/utlis/firebaseUtils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/utlis/firebaseUtils.ts b/src/components/utlis/firebaseUtils.ts index 198629b9..18cd76ca 100644 --- a/src/components/utlis/firebaseUtils.ts +++ b/src/components/utlis/firebaseUtils.ts @@ -5,7 +5,7 @@ export const initCrashlytics = async (userState: IUserSlice) => { if (!userState) return; await Promise.all([ - crashlytics().setUserId(userState.user?.emailId || ('' as string)), + crashlytics().setUserId((userState.user?.emailId || '') as string), crashlytics().setAttributes({ deviceId: userState.deviceId, phoneNumber: userState.user?.phoneNumber as string, From a75e0fdcdd5b3d21037e5e08ae13bb210e427986 Mon Sep 17 00:00:00 2001 From: Aman Chaturvedi Date: Tue, 17 Oct 2023 16:54:48 +0530 Subject: [PATCH 53/75] TP-0 | fixes --- src/common/TrackingComponent.tsx | 4 +--- src/components/utlis/PermissionUtils.ts | 3 --- src/services/foregroundServices/foreground.service.ts | 8 ++++++++ 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/common/TrackingComponent.tsx b/src/common/TrackingComponent.tsx index bbca5509..288f11ef 100644 --- a/src/common/TrackingComponent.tsx +++ b/src/common/TrackingComponent.tsx @@ -404,9 +404,7 @@ const TrackingComponent: React.FC = ({ children }) => { useEffect(() => { let appStateSubscription: NativeEventSubscription; appStateSubscription = AppState.addEventListener('change', handleAppStateChange); - if (AppState.currentState === AppStates.ACTIVE) { - CosmosForegroundService.start(tasks); - } + CosmosForegroundService.start(tasks); return () => { appStateSubscription?.remove(); }; diff --git a/src/components/utlis/PermissionUtils.ts b/src/components/utlis/PermissionUtils.ts index 2e450ea7..c4ea066f 100644 --- a/src/components/utlis/PermissionUtils.ts +++ b/src/components/utlis/PermissionUtils.ts @@ -37,9 +37,6 @@ export const getPermissionsToRequest = async () => { if (!notificationStatus) { permissionsToRequest.push(permission); } else { - if (AppState.currentState !== AppStates.ACTIVE) { - continue; - } const isFGSRunning = await CosmosForegroundService.isRunning(); if (!isFGSRunning) { CosmosForegroundService.start(); diff --git a/src/services/foregroundServices/foreground.service.ts b/src/services/foregroundServices/foreground.service.ts index f40965ba..dca532c4 100644 --- a/src/services/foregroundServices/foreground.service.ts +++ b/src/services/foregroundServices/foreground.service.ts @@ -1,6 +1,8 @@ import ForegroundService from '@supersami/rn-foreground-service'; import { logError } from '../../components/utlis/errorUtils'; import { GLOBAL } from '../../constants/Global'; +import { AppState } from 'react-native'; +import { AppStates } from '@types/appStates'; export interface IForegroundTask { task: () => void; @@ -34,6 +36,9 @@ class CosmosForegroundService { private constructor() {} static async start(tasks?: IForegroundTask[]) { + if (AppState.currentState !== AppStates.ACTIVE) { + return; + } if (GLOBAL.IS_IMPERSONATED) { return; } @@ -60,6 +65,9 @@ class CosmosForegroundService { } static async update() { + if (AppState.currentState !== AppStates.ACTIVE) { + return; + } if (GLOBAL.IS_IMPERSONATED) { return; } From 683ce43e06ca2b4bb77182c2acdb2b69b9b3b973 Mon Sep 17 00:00:00 2001 From: yashmantri Date: Tue, 17 Oct 2023 17:03:39 +0530 Subject: [PATCH 54/75] TP-43439 | UAT Fixes --- .../addressGeolocation/AddressItem.tsx | 51 +++++++++---------- .../addressGeolocation/SimilarAddressItem.tsx | 7 ++- .../utils/relativeDistanceFormatter.ts | 4 +- src/screens/allCases/ListItem.tsx | 3 +- 4 files changed, 34 insertions(+), 31 deletions(-) diff --git a/src/screens/addressGeolocation/AddressItem.tsx b/src/screens/addressGeolocation/AddressItem.tsx index cba805e8..a6c8da79 100644 --- a/src/screens/addressGeolocation/AddressItem.tsx +++ b/src/screens/addressGeolocation/AddressItem.tsx @@ -73,16 +73,15 @@ function AddressItem({ let relativeDistanceBwLatLong = 0; - if (isGroupedAddress) { - const addressGeolocationCoordinated: IGeolocationCoordinate = { - latitude: addressItem.latitude, - longitude: addressItem.longitude, - }; - relativeDistanceBwLatLong = getDistanceFromLatLonInKm( - currentGeolocationCoordinates, - addressGeolocationCoordinated - ); - } + const addressGeolocationCoordinated: IGeolocationCoordinate = { + latitude: addressItem.latitude, + longitude: addressItem.longitude, + }; + relativeDistanceBwLatLong = getDistanceFromLatLonInKm( + currentGeolocationCoordinates, + addressGeolocationCoordinated + ); + const handleAddFeedback = () => { if (prefilledAddressScreenTemplate != null) { const addressKey = '{{addressReferenceId}}'; @@ -138,22 +137,22 @@ function AddressItem({ - - - {sanitizeString([addressItem?.pinCode, addressItem?.city].filter(Boolean).join(', '))} - - - {showRelativeDistance && relativeDistanceBwLatLong ? ( - <>({relativeDistanceFormatter(relativeDistanceBwLatLong)} km away) - ) : ( - '--' - )} - - + {addressItem?.pinCode || addressItem?.city || relativeDistanceBwLatLong ? ( + + + {sanitizeString([addressItem?.pinCode, addressItem?.city].filter(Boolean).join(', '))} + + + {showRelativeDistance && relativeDistanceBwLatLong ? ( + <>({relativeDistanceFormatter(relativeDistanceBwLatLong)} km away) + ) : null} + + + ) : null} {lastFeedbackForAddress?.feedbackPresent ? ( diff --git a/src/screens/addressGeolocation/SimilarAddressItem.tsx b/src/screens/addressGeolocation/SimilarAddressItem.tsx index 9e15de40..73a10c8e 100644 --- a/src/screens/addressGeolocation/SimilarAddressItem.tsx +++ b/src/screens/addressGeolocation/SimilarAddressItem.tsx @@ -29,6 +29,7 @@ import { type GenericFunctionArgs } from '../../common/GenericTypes'; import { toast } from '../../../RN-UI-LIB/src/components/toast'; import { ToastMessages } from '../allCases/constants'; import AddressSource from './AddressSource'; +import relativeDistanceFormatter from './utils/relativeDistanceFormatter'; interface IAddressItem { addressItem: IAddress; @@ -167,8 +168,10 @@ function SimilarAddressItem({ {showRelativeDistance && relativeDistanceBwLatLong ? ( <>   ●   - {!isNaN(relativeDistanceBwLatLong) ? relativeDistanceBwLatLong.toFixed(2) : '--'} km - away + {!isNaN(relativeDistanceBwLatLong) + ? relativeDistanceFormatter(relativeDistanceBwLatLong) + : '--'}{' '} + km away ) : null} {showSource ? : null} diff --git a/src/screens/addressGeolocation/utils/relativeDistanceFormatter.ts b/src/screens/addressGeolocation/utils/relativeDistanceFormatter.ts index 34805f5a..80a89aed 100644 --- a/src/screens/addressGeolocation/utils/relativeDistanceFormatter.ts +++ b/src/screens/addressGeolocation/utils/relativeDistanceFormatter.ts @@ -4,10 +4,10 @@ const relativeDistanceFormatter = (relativeDistance: number) => { return '--'; } if (relativeDistance >= MAXIMUM_DISTANCE_WITH_DECIMAL) { - return Math.round(relativeDistance, 0); + return Math.round(relativeDistance); } - return relativeDistance.toFixed(2); + return relativeDistance.toFixed(1); }; export default relativeDistanceFormatter; diff --git a/src/screens/allCases/ListItem.tsx b/src/screens/allCases/ListItem.tsx index 9588bb37..2ae1b246 100644 --- a/src/screens/allCases/ListItem.tsx +++ b/src/screens/allCases/ListItem.tsx @@ -33,6 +33,7 @@ import { toast } from '../../../RN-UI-LIB/src/components/toast'; import { COMPLETED_STATUSES, ToastMessages } from './constants'; import { VisitPlanStatus } from '../../reducer/userSlice'; import { PaymentStatus } from '../caseDetails/interface'; +import relativeDistanceFormatter from '@screens/addressGeolocation/utils/relativeDistanceFormatter'; interface IListItem { caseListItemDetailObj: ICaseItemCaseDetailObj; @@ -225,7 +226,7 @@ const ListItem: React.FC = (props) => { {nearbyCaseView && distanceInKm && ( - {distanceInKm?.toFixed(2)} km away + {relativeDistanceFormatter(distanceInKm)} km away )} From 5023e7be12115d6c18a5148791a71b38d05f518c Mon Sep 17 00:00:00 2001 From: yashmantri Date: Tue, 17 Oct 2023 17:08:17 +0530 Subject: [PATCH 55/75] TP-43439 | Null Issue Fix --- src/screens/addressGeolocation/AddressItem.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/screens/addressGeolocation/AddressItem.tsx b/src/screens/addressGeolocation/AddressItem.tsx index a6c8da79..97a380e5 100644 --- a/src/screens/addressGeolocation/AddressItem.tsx +++ b/src/screens/addressGeolocation/AddressItem.tsx @@ -144,7 +144,9 @@ function AddressItem({ ellipsizeMode="tail" style={[styles.textContainer, styles.cardBoldTitle, { fontWeight: 'bold' }]} > - {sanitizeString([addressItem?.pinCode, addressItem?.city].filter(Boolean).join(', '))} + {sanitizeString( + [addressItem?.pinCode ?? '', addressItem?.city ?? ''].filter(Boolean).join(', ') + )} {showRelativeDistance && relativeDistanceBwLatLong ? ( From 22a3baefc8e1f1244efbb9166e6482029174eaf3 Mon Sep 17 00:00:00 2001 From: yashmantri Date: Tue, 17 Oct 2023 17:19:43 +0530 Subject: [PATCH 56/75] TP-38645 | Removed Aadhar Details --- src/screens/caseDetails/CustomerProfile.tsx | 1 - src/screens/caseDetails/DocumentImageComponent.tsx | 2 -- src/screens/caseDetails/utils/documentUtils.tsx | 11 ----------- 3 files changed, 14 deletions(-) diff --git a/src/screens/caseDetails/CustomerProfile.tsx b/src/screens/caseDetails/CustomerProfile.tsx index 4519f468..7c683fd2 100644 --- a/src/screens/caseDetails/CustomerProfile.tsx +++ b/src/screens/caseDetails/CustomerProfile.tsx @@ -94,7 +94,6 @@ const CustomerProfile: React.FC = (props) => { const docPromises: Promise[] = []; const updatedDocList = [ DOCUMENT_TYPE.VKYC_VIDEO, - DOCUMENT_TYPE.AADHAR, DOCUMENT_TYPE.AADHAR_PHOTO, DOCUMENT_TYPE.DRIVING_LICENSE, ]; diff --git a/src/screens/caseDetails/DocumentImageComponent.tsx b/src/screens/caseDetails/DocumentImageComponent.tsx index 1ebf68bb..a7ce206a 100644 --- a/src/screens/caseDetails/DocumentImageComponent.tsx +++ b/src/screens/caseDetails/DocumentImageComponent.tsx @@ -22,13 +22,11 @@ const DocumentImageComponent = (props: DocumentImageComponentProps) => { const [imageUrl, setImageUrl] = useState(url); const [isValidating, setIsValidating] = useState(false); const [errorModalImage, setErrorModalImage] = useState({ - [DOCUMENT_TYPE.AADHAR]: false, [DOCUMENT_TYPE.AADHAR_PHOTO]: false, [DOCUMENT_TYPE.DRIVING_LICENSE]: false, }); const [loading, setLoading] = useState({ - [DOCUMENT_TYPE.AADHAR]: false, [DOCUMENT_TYPE.AADHAR_PHOTO]: false, [DOCUMENT_TYPE.DRIVING_LICENSE]: false, }); diff --git a/src/screens/caseDetails/utils/documentUtils.tsx b/src/screens/caseDetails/utils/documentUtils.tsx index 33c12fb2..9eaa9ff0 100644 --- a/src/screens/caseDetails/utils/documentUtils.tsx +++ b/src/screens/caseDetails/utils/documentUtils.tsx @@ -36,17 +36,6 @@ export const getDocumentDetails = async (document: IDocument) => { documentRefId: document.referenceId, }; - case DOCUMENT_TYPE.AADHAR: - return { - icon: , - title: 'Aadhar card', - docType: DOCUMENT_TYPE.AADHAR, - docContentType: docType, - url: imageUrl, - unSignedUri: document.unSignedUri, - documentRefId: document.referenceId, - }; - case DOCUMENT_TYPE.AADHAR_PHOTO: return { icon: , From 949738a8f2e2d2aa89a967336bab3c371a54bccd Mon Sep 17 00:00:00 2001 From: yashmantri Date: Tue, 17 Oct 2023 17:28:46 +0530 Subject: [PATCH 57/75] TP-38645 | RN updated --- RN-UI-LIB | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RN-UI-LIB b/RN-UI-LIB index 8876fa8a..9f4a3ae2 160000 --- a/RN-UI-LIB +++ b/RN-UI-LIB @@ -1 +1 @@ -Subproject commit 8876fa8a05de03421e39f598a1365cf0ddfdb8ee +Subproject commit 9f4a3ae2675e913bbbbe3326d49c52ab987b3339 From 42d5bf0d490b9befd4dde50a770650bb91217c8d Mon Sep 17 00:00:00 2001 From: yashmantri Date: Tue, 17 Oct 2023 17:30:21 +0530 Subject: [PATCH 58/75] TP-38645 | RN-UI-LIB Updated --- RN-UI-LIB | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RN-UI-LIB b/RN-UI-LIB index 9f4a3ae2..99ea2097 160000 --- a/RN-UI-LIB +++ b/RN-UI-LIB @@ -1 +1 @@ -Subproject commit 9f4a3ae2675e913bbbbe3326d49c52ab987b3339 +Subproject commit 99ea2097a0186866cff21c98200494915088050f From 004385f2775007ae9869ca09fb728181a4e67aca Mon Sep 17 00:00:00 2001 From: yashmantri Date: Tue, 17 Oct 2023 17:36:16 +0530 Subject: [PATCH 59/75] TP-38645 | Bug Fix --- .../screens/allCases/allCasesFilters/FiltersContainer.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/screens/allCases/allCasesFilters/FiltersContainer.tsx b/src/components/screens/allCases/allCasesFilters/FiltersContainer.tsx index dca38d49..4e04e8a8 100644 --- a/src/components/screens/allCases/allCasesFilters/FiltersContainer.tsx +++ b/src/components/screens/allCases/allCasesFilters/FiltersContainer.tsx @@ -37,7 +37,7 @@ const FiltersContainer: React.FC = (props) => { const visibleFilters = Object.keys(filters?.[filterGroupKey]?.filters || {}).filter((key) => { if (filters?.[filterGroupKey]?.filters?.[key]?.visible) return key; }); - filterKeys?.[filterGroupKey] = visibleFilters; + filterKeys[filterGroupKey] = visibleFilters; }); const [selectedFilterKey, setSelectedFilterKey] = React.useState({ From f74aee3efa979f0d2c0a57261405c1131d18f592 Mon Sep 17 00:00:00 2001 From: yashmantri Date: Tue, 17 Oct 2023 17:56:06 +0530 Subject: [PATCH 60/75] TP-0 | Version Bump + Interfaces Fix --- android/app/build.gradle | 4 ++-- package.json | 2 +- src/components/utlis/PermissionUtils.ts | 2 +- src/services/foregroundServices/foreground.service.ts | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index 0b4a2be9..518122c7 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -131,8 +131,8 @@ def reactNativeArchitectures() { return value ? value.split(",") : ["armeabi-v7a", "x86", "x86_64", "arm64-v8a"] } -def VERSION_CODE = 93 -def VERSION_NAME = "2.4.9" +def VERSION_CODE = 94 +def VERSION_NAME = "2.4.10" android { ndkVersion rootProject.ext.ndkVersion diff --git a/package.json b/package.json index bf7e4b5c..3f3d3d68 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "AV_APP", - "version": "2.4.9", + "version": "2.4.10", "private": true, "scripts": { "android:dev": "yarn move:dev && react-native run-android", diff --git a/src/components/utlis/PermissionUtils.ts b/src/components/utlis/PermissionUtils.ts index c4ea066f..2a7f52df 100644 --- a/src/components/utlis/PermissionUtils.ts +++ b/src/components/utlis/PermissionUtils.ts @@ -2,7 +2,7 @@ import { AppState, Permission, PermissionsAndroid, Platform } from 'react-native import { PermissionsToCheck } from '../../common/Constants'; import { checkNotifications } from 'react-native-permissions'; import CosmosForegroundService from '../../services/foregroundServices/foreground.service'; -import { AppStates } from '@types/appStates'; +import { AppStates } from '@interfaces/appStates'; let isNotificationPermissionEnabled = true; diff --git a/src/services/foregroundServices/foreground.service.ts b/src/services/foregroundServices/foreground.service.ts index dca532c4..575ad1bc 100644 --- a/src/services/foregroundServices/foreground.service.ts +++ b/src/services/foregroundServices/foreground.service.ts @@ -2,7 +2,7 @@ import ForegroundService from '@supersami/rn-foreground-service'; import { logError } from '../../components/utlis/errorUtils'; import { GLOBAL } from '../../constants/Global'; import { AppState } from 'react-native'; -import { AppStates } from '@types/appStates'; +import { AppStates } from '@interfaces/appStates'; export interface IForegroundTask { task: () => void; From 0fb5976fff41f8712aca3fb46f228005c5818706 Mon Sep 17 00:00:00 2001 From: ShriPrakashBajpai Date: Tue, 17 Oct 2023 18:08:22 +0530 Subject: [PATCH 61/75] PR reviews fixed --- App.tsx | 2 +- RN-UI-LIB | 2 +- src/common/BlacklistedAppsList.tsx | 7 --- src/screens/permissions/BlockerScreenApps.tsx | 13 +++-- src/services/blacklistedApps.service.ts | 49 +++++++++++++------ .../firebaseFetchAndUpdate.service.ts | 2 +- 6 files changed, 44 insertions(+), 31 deletions(-) delete mode 100644 src/common/BlacklistedAppsList.tsx diff --git a/App.tsx b/App.tsx index b459790c..cf5d3f01 100644 --- a/App.tsx +++ b/App.tsx @@ -7,7 +7,7 @@ import { Platform, StatusBar, } from 'react-native'; -import { Provider, useSelector } from 'react-redux'; +import { Provider } from 'react-redux'; import { init as initApm } from '@cobo/apm-rum-react-native'; import { PersistGate } from 'redux-persist/integration/react'; import { NavigationContainer } from '@react-navigation/native'; diff --git a/RN-UI-LIB b/RN-UI-LIB index b10108d9..64db024f 160000 --- a/RN-UI-LIB +++ b/RN-UI-LIB @@ -1 +1 @@ -Subproject commit b10108d97c70125e17d9781654f7a4cf01b3f2da +Subproject commit 64db024f2d7de7ccdec44a2c18f3e6df1ffce8e0 diff --git a/src/common/BlacklistedAppsList.tsx b/src/common/BlacklistedAppsList.tsx deleted file mode 100644 index b0493041..00000000 --- a/src/common/BlacklistedAppsList.tsx +++ /dev/null @@ -1,7 +0,0 @@ -let BLACKLISTED_APPS_LIST: string[] = []; - -export const getBlacklistedAppsList = () => BLACKLISTED_APPS_LIST; - -export const setBlacklistedAppsList = (blacklistedAppsString: string) => { - BLACKLISTED_APPS_LIST = blacklistedAppsString.split(','); -}; diff --git a/src/screens/permissions/BlockerScreenApps.tsx b/src/screens/permissions/BlockerScreenApps.tsx index ab7b8bf4..045833d3 100644 --- a/src/screens/permissions/BlockerScreenApps.tsx +++ b/src/screens/permissions/BlockerScreenApps.tsx @@ -1,9 +1,10 @@ import * as React from 'react'; -import { Text, View, StyleSheet, ScrollView, Image } from 'react-native'; +import { View, StyleSheet, ScrollView, Image } from 'react-native'; import { GenericStyles } from '../../../RN-UI-LIB/src/styles'; import { COLORS } from '@rn-ui-lib/colors'; import PermissionImage from '@assets/images/PermissionImage'; import { Apps } from '@services/blacklistedApps.service'; +import Text from '@rn-ui-lib/components/Text'; const BlockerScreenApps: React.FC<{ blacklistedAppsInstalled: Apps[] }> = ({ blacklistedAppsInstalled, @@ -49,7 +50,7 @@ const styles = StyleSheet.create({ container: { flexDirection: 'column', flex: 1, - backgroundColor: 'white', + backgroundColor: COLORS.BACKGROUND.PRIMARY, }, imageContainer: { @@ -60,13 +61,11 @@ const styles = StyleSheet.create({ textDark: { color: COLORS.TEXT.DARK, - fontFamily: 'Inter-Regular', fontWeight: '500', }, textLight: { color: COLORS.TEXT.LIGHT, - fontFamily: 'Inter-Regular', fontWeight: '400', marginBottom: 14, }, @@ -76,7 +75,7 @@ const styles = StyleSheet.create({ paddingTop: 4, borderRadius: 4, marginBottom: 16, - backgroundColor: '#F5F5F5', + backgroundColor: COLORS.BACKGROUND.SILVER_LIGHT, }, appsListItem: { @@ -94,12 +93,12 @@ const styles = StyleSheet.create({ appIcon: { width: 35, height: 35, - backgroundColor: 'white', + backgroundColor: COLORS.BACKGROUND.PRIMARY, borderRadius: 20, }, horizontalLine: { - backgroundColor: '#E5E5E5', + backgroundColor: COLORS.BACKGROUND.SILVER_LIGHT_2, width: '100%', height: 1, }, diff --git a/src/services/blacklistedApps.service.ts b/src/services/blacklistedApps.service.ts index 037ed302..5222bb44 100644 --- a/src/services/blacklistedApps.service.ts +++ b/src/services/blacklistedApps.service.ts @@ -1,8 +1,4 @@ -import { getBlacklistedAppsList } from '@common/BlacklistedAppsList'; import { getAllInstalledApp } from '@components/utlis/DeviceUtils'; -import { useAppDispatch } from '@hooks'; -import remoteConfig from '@react-native-firebase/remote-config'; -import { setBlacklistedAppsInstalledData } from '@reducers/blacklistedAppsInstalledSlice'; export type Apps = { packageName: string; @@ -10,7 +6,24 @@ export type Apps = { applicationIcon: string; }; -var installedBlacklistedApps: Apps[] = []; +type deviceApps = { + packageName: string; + appDetails: deviceAppDetails; +}; + +type deviceAppDetails = { + applicationName: string; + applicationIcon: string; +}; + +let BLACKLISTED_APPS_LIST: string[] = []; +let installedBlacklistedApps: Apps[] = []; + +export const getBlacklistedAppsList = () => BLACKLISTED_APPS_LIST; + +export const setBlacklistedAppsList = (blacklistedAppsString: string) => { + BLACKLISTED_APPS_LIST = blacklistedAppsString.split(','); +}; function getBlacklistAppsPresent(installedApps: Apps[], blacklistedApps: string[]) { installedBlacklistedApps = []; @@ -28,15 +41,23 @@ function getBlacklistAppsPresent(installedApps: Apps[], blacklistedApps: string[ const handleBlacklistedAppsForBlockingCosmos = async () => { const blacklistedApps = getBlacklistedAppsList(); - await getAllInstalledApp().then((apps) => { - const appsArray = JSON.parse(apps); - const installedApps = appsArray.map((app: any) => ({ - packageName: app.packageName, - applicationName: app.appDetails.applicationName, - applicationIcon: app.appDetails.applicationIcon, - })); - getBlacklistAppsPresent(installedApps, blacklistedApps); - }); + await getAllInstalledApp() + .then((apps) => { + try { + const appsArray = JSON.parse(apps); + const installedApps = appsArray.map((app: deviceApps) => ({ + packageName: app.packageName, + applicationName: app.appDetails.applicationName, + applicationIcon: app.appDetails.applicationIcon, + })); + getBlacklistAppsPresent(installedApps, blacklistedApps); + } catch { + return []; + } + }) + .catch((error) => { + return []; + }); return installedBlacklistedApps; }; diff --git a/src/services/firebaseFetchAndUpdate.service.ts b/src/services/firebaseFetchAndUpdate.service.ts index 524f654a..eddb8706 100644 --- a/src/services/firebaseFetchAndUpdate.service.ts +++ b/src/services/firebaseFetchAndUpdate.service.ts @@ -4,7 +4,7 @@ import { setActivityTimeWindowHigh, setActivityTimeWindowMedium, } from '../common/AgentActivityConfigurableConstants'; -import { setBlacklistedAppsList } from '@common/BlacklistedAppsList'; +import { setBlacklistedAppsList } from './blacklistedApps.service'; const FIREBASE_FETCH_TIME = 15 * 60; export let FIREBASE_FETCH_TIMESTAMP: number; From 957982eda4a2cf492ada65693617eb6373639991 Mon Sep 17 00:00:00 2001 From: Aman Singh Date: Tue, 17 Oct 2023 19:07:47 +0530 Subject: [PATCH 62/75] Update newBuild.yml --- .github/workflows/newBuild.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/newBuild.yml b/.github/workflows/newBuild.yml index ddc37bbe..06ed1001 100644 --- a/.github/workflows/newBuild.yml +++ b/.github/workflows/newBuild.yml @@ -42,6 +42,9 @@ jobs: with: token: ${{ secrets.MY_REPO_PAT }} submodules: recursive + - name: update codepush key QA + if: (github.event.inputs.environment == 'QA' || inputs.environment == 'QA') + run: sed -i "s/pastethekeyhere/${{ secrets.CODEPUSH_QA_KEY }}/" android/app/src/main/res/values/strings.xml && cat android/app/src/main/res/values/strings.xml - name: Generate keystore if: (github.event.inputs.type == 'release' || inputs.type == 'release') run: echo "${{ secrets.KEY_STORE }}" > keystore.asc && gpg -d --passphrase "${{ secrets.PASSPHARASE }}" --batch keystore.asc > android/app/my-upload-key.keystore From 6e7594deef8c25170ea8acfc0d0d3857622a03b3 Mon Sep 17 00:00:00 2001 From: Aman Singh Date: Tue, 17 Oct 2023 19:13:13 +0530 Subject: [PATCH 63/75] updated codepush version --- .github/workflows/newBuild.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/newBuild.yml b/.github/workflows/newBuild.yml index 06ed1001..b1d8b8e3 100644 --- a/.github/workflows/newBuild.yml +++ b/.github/workflows/newBuild.yml @@ -45,6 +45,9 @@ jobs: - name: update codepush key QA if: (github.event.inputs.environment == 'QA' || inputs.environment == 'QA') run: sed -i "s/pastethekeyhere/${{ secrets.CODEPUSH_QA_KEY }}/" android/app/src/main/res/values/strings.xml && cat android/app/src/main/res/values/strings.xml + - name: update codepush key PROD + if: (github.event.inputs.environment == 'Prod' || inputs.environment == 'Prod') + run: sed -i "s/pastethekeyhere/${{ secrets.CODEPUSH_PROD_KEY }}/" android/app/src/main/res/values/strings.xml && cat android/app/src/main/res/values/strings.xml - name: Generate keystore if: (github.event.inputs.type == 'release' || inputs.type == 'release') run: echo "${{ secrets.KEY_STORE }}" > keystore.asc && gpg -d --passphrase "${{ secrets.PASSPHARASE }}" --batch keystore.asc > android/app/my-upload-key.keystore From 57ed97f5d0fc0a003f49619aae9fc90b5680810c Mon Sep 17 00:00:00 2001 From: Mantri Ramkishor Date: Tue, 17 Oct 2023 19:52:39 +0530 Subject: [PATCH 64/75] Revert "Tp 41687 blacklisted apps v3" --- App.tsx | 6 +- RN-UI-LIB | 2 +- .../java/com/avapp/DeviceUtilsModule.java | 40 ++----- src/common/BlockerScreen.tsx | 23 +--- src/common/Constants.ts | 7 -- src/common/TrackingComponent.tsx | 41 ------- src/hooks/capturingApi.ts | 2 - src/reducer/blacklistedAppsInstalledSlice.ts | 21 ---- src/screens/auth/AuthRouter.tsx | 4 +- src/screens/permissions/BlockerScreenApps.tsx | 107 ------------------ src/services/blacklistedApps.service.ts | 64 ----------- .../firebaseFetchAndUpdate.service.ts | 9 +- src/store/store.ts | 2 - 13 files changed, 15 insertions(+), 313 deletions(-) delete mode 100644 src/reducer/blacklistedAppsInstalledSlice.ts delete mode 100644 src/screens/permissions/BlockerScreenApps.tsx delete mode 100644 src/services/blacklistedApps.service.ts diff --git a/App.tsx b/App.tsx index 29db2845..4f03242e 100644 --- a/App.tsx +++ b/App.tsx @@ -15,7 +15,7 @@ import * as Sentry from '@sentry/react-native'; import codePush from 'react-native-code-push'; import AsyncStorage from '@react-native-async-storage/async-storage'; import CodePush from 'react-native-code-push'; -import store, { persistor, RootState } from './src/store/store'; +import store, { persistor } from './src/store/store'; import { navigationRef } from './src/components/utlis/navigationUtlis'; import FullScreenLoader from './RN-UI-LIB/src/components/FullScreenLoader'; @@ -42,7 +42,7 @@ import { StorageKeys } from './src/types/storageKeys'; import dayJs from 'dayjs'; import { GlobalImageMap, hydrateGlobalImageMap } from './src/common/CachedImage'; import analytics from '@react-native-firebase/analytics'; -import fetchUpdatedRemoteConfig from './src/services/firebaseFetchAndUpdate.service'; +import handleUpdatedConfigureValuesFromFirebase from './src/services/firebaseFetchAndUpdate.service'; import { addClickstreamEvent } from './src/services/clickstreamEventService'; import ScreenshotBlocker from './src/components/utlis/ScreenshotBlocker'; @@ -130,7 +130,6 @@ function App() { }, []); React.useEffect(() => { - fetchUpdatedRemoteConfig(); askForPermissions(); const appStateChange = AppState.addEventListener('change', async (change) => { handleAppStateChange(change); @@ -145,6 +144,7 @@ function App() { setIsGlobalDocumentMapLoaded(true); })(); checkCodePushAndSync(); + handleUpdatedConfigureValuesFromFirebase(); setForegroundTimeStampAndClickstream(); return () => { diff --git a/RN-UI-LIB b/RN-UI-LIB index 64db024f..99ea2097 160000 --- a/RN-UI-LIB +++ b/RN-UI-LIB @@ -1 +1 @@ -Subproject commit 64db024f2d7de7ccdec44a2c18f3e6df1ffce8e0 +Subproject commit 99ea2097a0186866cff21c98200494915088050f diff --git a/android/app/src/main/java/com/avapp/DeviceUtilsModule.java b/android/app/src/main/java/com/avapp/DeviceUtilsModule.java index c91bb2da..478a84f3 100644 --- a/android/app/src/main/java/com/avapp/DeviceUtilsModule.java +++ b/android/app/src/main/java/com/avapp/DeviceUtilsModule.java @@ -100,20 +100,6 @@ public class DeviceUtilsModule extends ReactContextBaseJavaModule { } } - public String getAppIcon(String packageName) { - try { - Context context = RNContext.getApplicationContext(); - PackageManager pm = context.getPackageManager(); - ApplicationInfo appInfo = pm.getApplicationInfo(packageName, PackageManager.GET_META_DATA); - - Uri imageUri = Uri.parse("android.resource://" + appInfo.packageName + "/drawable/" + appInfo.icon); - return imageUri.toString(); - - } catch (Exception e) { - return null; - } - } - @ReactMethod public void getAllInstalledApp(Promise promise) { try { @@ -122,26 +108,13 @@ public class DeviceUtilsModule extends ReactContextBaseJavaModule { List packages = packageManager.getInstalledApplications(PackageManager.GET_META_DATA); JSONArray jsonArray = new JSONArray(); for (PackageInfo packageInfo : installedPackages) { - - final PackageManager pm = RNContext.getApplicationContext().getPackageManager(); - ApplicationInfo appsInstalled; - try { - appsInstalled = pm.getApplicationInfo( packageInfo.packageName, 0); - } catch (final PackageManager.NameNotFoundException e) { - appsInstalled = null; - } - final String applicationName = (String) (appsInstalled != null ? pm.getApplicationLabel(appsInstalled) : "(unknown)"); - JSONObject mainObject = new JSONObject(); - JSONObject appDetails = new JSONObject(); - appDetails.put("appName",packageInfo.applicationInfo.processName); - appDetails.put("firstInstallTime", packageInfo.firstInstallTime); - appDetails.put("lastUpdateTime", packageInfo.lastUpdateTime); - appDetails.put("applicationName", applicationName); - appDetails.put("applicationIcon",getAppIcon(packageInfo.packageName)); - mainObject.put("packageName", packageInfo.packageName); - mainObject.put("appDetails", appDetails); - + JSONObject appObject = new JSONObject(); + appObject.put("appName", packageInfo.applicationInfo.processName); + appObject.put("firstInstallTime", packageInfo.firstInstallTime); + appObject.put("lastUpdateTime", packageInfo.lastUpdateTime); + mainObject.put("packageName", packageInfo.packageName); + mainObject.put("appDetails", appObject); jsonArray.put(mainObject); } promise.resolve(jsonArray.toString()); @@ -319,4 +292,5 @@ public class DeviceUtilsModule extends ReactContextBaseJavaModule { + } diff --git a/src/common/BlockerScreen.tsx b/src/common/BlockerScreen.tsx index be5b8698..3a50fc9e 100644 --- a/src/common/BlockerScreen.tsx +++ b/src/common/BlockerScreen.tsx @@ -5,15 +5,11 @@ import { RootState } from '../store/store'; import { UninstallInformation } from '../reducer/metadataSlice'; import { getAppVersion } from '../components/utlis/commonFunctions'; import BlockerInstructions from './BlockerInstructions'; -import { BLOCKER_SCREEN_DATA, CLICKSTREAM_EVENT_NAMES } from './Constants'; +import { BLOCKER_SCREEN_DATA } from './Constants'; import { useAppDispatch, useAppSelector } from '../hooks'; import { setIsDeviceLocationEnabled } from '../reducer/foregroundServiceSlice'; import { toast } from '../../RN-UI-LIB/src/components/toast'; import { locationEnabled } from '../components/utlis/DeviceUtils'; -import BlockerScreenApps from '@screens/permissions/BlockerScreenApps'; -import handleBlacklistedAppsForBlockingCosmos, { Apps } from '@services/blacklistedApps.service'; -import { addClickstreamEvent } from '@services/clickstreamEventService'; -import { setBlacklistedAppsInstalledData } from '@reducers/blacklistedAppsInstalledSlice'; interface IBlockerScreen { children?: ReactNode; @@ -36,10 +32,6 @@ const BlockerScreen = (props: IBlockerScreen) => { return state.metadata?.forceUninstall; }); - const blacklistedAppsInstalled: Apps[] = useSelector((state: RootState) => { - return state?.blacklistAppsInstalled?.blacklistedAppsInstalled; - }); - function compareSemverVersions(a: string, b: string) { return a.localeCompare(b, undefined, { numeric: true, sensitivity: 'base' }); } @@ -62,14 +54,6 @@ const BlockerScreen = (props: IBlockerScreen) => { setForceReinstallData(undefined); }, [JSON.stringify(forceUninstallData || {})]); - React.useEffect(() => { - handleBlacklistedAppsForBlockingCosmos().then((blacklistedAppsInstalled) => - dispatch( - setBlacklistedAppsInstalledData({ blacklistedAppsInstalled: blacklistedAppsInstalled }) - ) - ); - }, [blacklistedAppsInstalled]); - const handleDownloadNewApp = () => { if (forceReinstallData?.reinstall_endpoint) { openApkDownloadLink(forceReinstallData?.reinstall_endpoint); @@ -142,11 +126,6 @@ const BlockerScreen = (props: IBlockerScreen) => { ); } - if (blacklistedAppsInstalled?.length > 0) { - addClickstreamEvent(CLICKSTREAM_EVENT_NAMES.FA_BLOCKER_SCREEN_LOADED_FOR_BLACKLISTED_APPS); - return ; - } - return <>{props.children}; }; diff --git a/src/common/Constants.ts b/src/common/Constants.ts index f857289a..b44688ee 100644 --- a/src/common/Constants.ts +++ b/src/common/Constants.ts @@ -638,13 +638,6 @@ export const CLICKSTREAM_EVENT_NAMES = { name: 'FA_PERFORMANCE_DASHBOARD_BROKEN_PTP_CASES_LOAD', description: 'Performance Dashboard Broken PTP Cases Load', }, - - //Blocker Screen for blacklisted Apps - FA_BLOCKER_SCREEN_LOADED_FOR_BLACKLISTED_APPS: { - name: 'FA_BLOCKER_SCREEN_LOADED_FOR_BLACKLISTED_APPS', - description: 'Blocker screen loaded for blacklisted apps', - }, - // Nearby Cases FA_NEARBY_CASES_BUTTON_CLICKED: { name: 'FA_NEARBY_CASES_BUTTON_CLICKED', diff --git a/src/common/TrackingComponent.tsx b/src/common/TrackingComponent.tsx index aa7c085b..4206a7b4 100644 --- a/src/common/TrackingComponent.tsx +++ b/src/common/TrackingComponent.tsx @@ -45,11 +45,6 @@ import { GlobalImageMap } from './CachedImage'; import { get } from 'react-hook-form'; import { addClickstreamEvent } from '../services/clickstreamEventService'; import { CLICKSTREAM_EVENT_NAMES } from './Constants'; -import { setBlacklistedAppsInstalledData } from '@reducers/blacklistedAppsInstalledSlice'; -import handleBlacklistedAppsForBlockingCosmos, { Apps } from '@services/blacklistedApps.service'; -import fetchUpdatedRemoteConfig, { - FIREBASE_FETCH_TIMESTAMP, -} from '@services/firebaseFetchAndUpdate.service'; export enum FOREGROUND_TASKS { GEOLOCATION = 'GEOLOCATION', @@ -59,7 +54,6 @@ export enum FOREGROUND_TASKS { UPDATE_AGENT_ACTIVENESS = 'UPDATE_AGENT_ACTIVENESS', UPDATE_AGENT_ACTIVITY = 'UPDATE_AGENT_ACTIVITY', DELETE_CACHE = 'DELETE_CACHE', - FETCH_DATA_FROM_FIREBASE = 'FETCH_DATA_FROM_FIREBASE', } interface ITrackingComponent { @@ -112,14 +106,6 @@ const TrackingComponent: React.FC = ({ children }) => { const userActivityonApp: string = (await getItem(StorageKeys.USER_ACTIVITY_ON_APP)) || AgentActivity.LOW; - let blacklistedAppsInstalledOnDevice: Apps[] = []; - - await handleBlacklistedAppsForBlockingCosmos().then((blacklistedAppsInstalled) => { - if (blacklistedAppsInstalled.length > 0) { - blacklistedAppsInstalledOnDevice = blacklistedAppsInstalled; - } - }); - const geolocation: IGeolocationPayload = { latitude: location.latitude, longitude: location.longitude, @@ -127,7 +113,6 @@ const TrackingComponent: React.FC = ({ children }) => { timestamp: Date.now(), isActiveOnApp: Boolean(isActiveOnApp), userActivityOnApp: String(userActivityonApp), - blacklistedAppsInstalled: blacklistedAppsInstalledOnDevice, }; dispatch(setDeviceGeolocationsBuffer(geolocation)); dispatch(sendLocationAndActivenessToServer([geolocation])); @@ -304,16 +289,6 @@ const TrackingComponent: React.FC = ({ children }) => { }); }; - const handleFetchUpdatedDataFromFirebase = async () => { - const currentTimestamp: number = Date.now(); - if ( - FIREBASE_FETCH_TIMESTAMP && - currentTimestamp - FIREBASE_FETCH_TIMESTAMP > 15 * MILLISECONDS_IN_A_MINUTE - ) { - fetchUpdatedRemoteConfig(); - } - }; - const tasks: IForegroundTask[] = [ { taskId: FOREGROUND_TASKS.TIME_SYNC, @@ -345,12 +320,6 @@ const TrackingComponent: React.FC = ({ children }) => { delay: DATA_SYNC_TIME_INTERVAL, onLoop: true, }, - { - taskId: FOREGROUND_TASKS.FETCH_DATA_FROM_FIREBASE, - task: handleFetchUpdatedDataFromFirebase, - delay: 15 * MILLISECONDS_IN_A_MINUTE, // 15 minutes - onLoop: true, - }, ]; if (!isTeamLead) { @@ -405,11 +374,6 @@ const TrackingComponent: React.FC = ({ children }) => { addClickstreamEvent(CLICKSTREAM_EVENT_NAMES.AV_APP_FOREGROUND, { now }); handleGetCaseSyncStatus(); dispatch(getConfigData()); - handleBlacklistedAppsForBlockingCosmos().then((blacklistedAppsInstalled) => - dispatch( - setBlacklistedAppsInstalledData({ blacklistedAppsInstalled: blacklistedAppsInstalled }) - ) - ); CosmosForegroundService.start(tasks); } if (nextAppState === AppStates.BACKGROUND) { @@ -428,11 +392,6 @@ const TrackingComponent: React.FC = ({ children }) => { } await handleGetCaseSyncStatus(); dispatch(getConfigData()); - handleBlacklistedAppsForBlockingCosmos().then((blacklistedAppsInstalled) => - dispatch( - setBlacklistedAppsInstalledData({ blacklistedAppsInstalled: blacklistedAppsInstalled }) - ) - ); if (!isTeamLead && LAST_SYNC_STATUS !== SyncStatus.FETCH_CASES) { const updatedDetails: ISyncedCases = await fetchCasesToSync(referenceId); if (updatedDetails?.cases?.length) { diff --git a/src/hooks/capturingApi.ts b/src/hooks/capturingApi.ts index e411b9e6..4c32cc1b 100644 --- a/src/hooks/capturingApi.ts +++ b/src/hooks/capturingApi.ts @@ -6,7 +6,6 @@ import { } from '../reducer/foregroundServiceSlice'; import { logError } from '../components/utlis/errorUtils'; import { toast } from '../../RN-UI-LIB/src/components/toast'; -import { Apps } from '@services/blacklistedApps.service'; export interface IGeolocationPayload { latitude: number; @@ -15,7 +14,6 @@ export interface IGeolocationPayload { timestamp: number; isActiveOnApp: boolean; userActivityOnApp: string; - blacklistedAppsInstalled: Apps[]; } export const sendLocationAndActivenessToServer = diff --git a/src/reducer/blacklistedAppsInstalledSlice.ts b/src/reducer/blacklistedAppsInstalledSlice.ts deleted file mode 100644 index 89eee0f5..00000000 --- a/src/reducer/blacklistedAppsInstalledSlice.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { createSlice } from '@reduxjs/toolkit'; -import handleBlacklistedAppsForBlockingCosmos, { Apps } from '@services/blacklistedApps.service'; - -const initialState = { - blacklistedAppsInstalled: [] as Apps[], -}; - -export const blacklistedAppsInstalledSlice = createSlice({ - name: 'blacklistedAppsInstalled', - initialState, - reducers: { - setBlacklistedAppsInstalledData: (state, action) => { - const { blacklistedAppsInstalled } = action.payload; - state.blacklistedAppsInstalled = blacklistedAppsInstalled; - }, - }, -}); - -export const { setBlacklistedAppsInstalledData } = blacklistedAppsInstalledSlice.actions; - -export default blacklistedAppsInstalledSlice.reducer; diff --git a/src/screens/auth/AuthRouter.tsx b/src/screens/auth/AuthRouter.tsx index a5ae6d6d..868f28b9 100644 --- a/src/screens/auth/AuthRouter.tsx +++ b/src/screens/auth/AuthRouter.tsx @@ -108,9 +108,7 @@ const AuthRouter = () => { ) : ( - - - + ); }; diff --git a/src/screens/permissions/BlockerScreenApps.tsx b/src/screens/permissions/BlockerScreenApps.tsx deleted file mode 100644 index 045833d3..00000000 --- a/src/screens/permissions/BlockerScreenApps.tsx +++ /dev/null @@ -1,107 +0,0 @@ -import * as React from 'react'; -import { View, StyleSheet, ScrollView, Image } from 'react-native'; -import { GenericStyles } from '../../../RN-UI-LIB/src/styles'; -import { COLORS } from '@rn-ui-lib/colors'; -import PermissionImage from '@assets/images/PermissionImage'; -import { Apps } from '@services/blacklistedApps.service'; -import Text from '@rn-ui-lib/components/Text'; - -const BlockerScreenApps: React.FC<{ blacklistedAppsInstalled: Apps[] }> = ({ - blacklistedAppsInstalled, -}) => { - return ( - - - - - - - - Some installed apps are banned by Navi - - - - - - Uninstall these apps for uninterrupted usage - - - - - - {blacklistedAppsInstalled.map((app: Apps, index: number) => ( - - - - {app.applicationName} - - {index < blacklistedAppsInstalled.length - 1 && ( - - )} - - ))} - - - - ); -}; - -const styles = StyleSheet.create({ - container: { - flexDirection: 'column', - flex: 1, - backgroundColor: COLORS.BACKGROUND.PRIMARY, - }, - - imageContainer: { - marginLeft: 97, - marginTop: 40, - marginBottom: 37, - }, - - textDark: { - color: COLORS.TEXT.DARK, - fontWeight: '500', - }, - - textLight: { - color: COLORS.TEXT.LIGHT, - fontWeight: '400', - marginBottom: 14, - }, - - appsContainer: { - paddingHorizontal: 16, - paddingTop: 4, - borderRadius: 4, - marginBottom: 16, - backgroundColor: COLORS.BACKGROUND.SILVER_LIGHT, - }, - - appsListItem: { - flexDirection: 'row', - alignItems: 'center', - paddingHorizontal: 8, - paddingVertical: 12, - }, - - appNameText: { - marginLeft: 8, - fontSize: 12, - }, - - appIcon: { - width: 35, - height: 35, - backgroundColor: COLORS.BACKGROUND.PRIMARY, - borderRadius: 20, - }, - - horizontalLine: { - backgroundColor: COLORS.BACKGROUND.SILVER_LIGHT_2, - width: '100%', - height: 1, - }, -}); - -export default BlockerScreenApps; diff --git a/src/services/blacklistedApps.service.ts b/src/services/blacklistedApps.service.ts deleted file mode 100644 index 5222bb44..00000000 --- a/src/services/blacklistedApps.service.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { getAllInstalledApp } from '@components/utlis/DeviceUtils'; - -export type Apps = { - packageName: string; - applicationName: string; - applicationIcon: string; -}; - -type deviceApps = { - packageName: string; - appDetails: deviceAppDetails; -}; - -type deviceAppDetails = { - applicationName: string; - applicationIcon: string; -}; - -let BLACKLISTED_APPS_LIST: string[] = []; -let installedBlacklistedApps: Apps[] = []; - -export const getBlacklistedAppsList = () => BLACKLISTED_APPS_LIST; - -export const setBlacklistedAppsList = (blacklistedAppsString: string) => { - BLACKLISTED_APPS_LIST = blacklistedAppsString.split(','); -}; - -function getBlacklistAppsPresent(installedApps: Apps[], blacklistedApps: string[]) { - installedBlacklistedApps = []; - const blacklistedAppsSet = new Set(blacklistedApps); - for (const app of installedApps) { - if (blacklistedAppsSet.has(app.packageName)) { - installedBlacklistedApps.push({ - packageName: app.packageName, - applicationName: app.applicationName, - applicationIcon: app.applicationIcon, - }); - } - } -} - -const handleBlacklistedAppsForBlockingCosmos = async () => { - const blacklistedApps = getBlacklistedAppsList(); - await getAllInstalledApp() - .then((apps) => { - try { - const appsArray = JSON.parse(apps); - const installedApps = appsArray.map((app: deviceApps) => ({ - packageName: app.packageName, - applicationName: app.appDetails.applicationName, - applicationIcon: app.appDetails.applicationIcon, - })); - getBlacklistAppsPresent(installedApps, blacklistedApps); - } catch { - return []; - } - }) - .catch((error) => { - return []; - }); - return installedBlacklistedApps; -}; - -export default handleBlacklistedAppsForBlockingCosmos; diff --git a/src/services/firebaseFetchAndUpdate.service.ts b/src/services/firebaseFetchAndUpdate.service.ts index eddb8706..1816fb35 100644 --- a/src/services/firebaseFetchAndUpdate.service.ts +++ b/src/services/firebaseFetchAndUpdate.service.ts @@ -4,11 +4,9 @@ import { setActivityTimeWindowHigh, setActivityTimeWindowMedium, } from '../common/AgentActivityConfigurableConstants'; -import { setBlacklistedAppsList } from './blacklistedApps.service'; const FIREBASE_FETCH_TIME = 15 * 60; -export let FIREBASE_FETCH_TIMESTAMP: number; -async function fetchUpdatedRemoteConfig() { +async function handleUpdatedConfigureValuesFromFirebase() { await remoteConfig().fetch(FIREBASE_FETCH_TIME); //15 minutes remoteConfig() .activate() @@ -30,13 +28,10 @@ async function fetchUpdatedRemoteConfig() { const ACTIVITY_TIME_WINDOW_MEDIUM = remoteConfig() .getValue('ACTIVITY_TIME_WINDOW_MEDIUM') .asNumber(); - const BLACKLISTED_APPS = remoteConfig().getValue('BLACKLISTED_APPS').asString(); setActivityTimeOnApp(ACTIVITY_TIME_ON_APP); setActivityTimeWindowHigh(ACTIVITY_TIME_WINDOW_HIGH); setActivityTimeWindowMedium(ACTIVITY_TIME_WINDOW_MEDIUM); - setBlacklistedAppsList(BLACKLISTED_APPS); - FIREBASE_FETCH_TIMESTAMP = Date.now(); }); } -export default fetchUpdatedRemoteConfig; +export default handleUpdatedConfigureValuesFromFirebase; diff --git a/src/store/store.ts b/src/store/store.ts index 44cca84a..43ee523f 100644 --- a/src/store/store.ts +++ b/src/store/store.ts @@ -31,7 +31,6 @@ import feedbackImagesSlice from '../reducer/feedbackImagesSlice'; import configSlice from '../reducer/configSlice'; import profileSlice from '../reducer/profileSlice'; import reporteesSlice from '../reducer/reporteesSlice'; -import blacklistedAppsInstalledSlice from '@reducers/blacklistedAppsInstalledSlice'; import feedbackFiltersSlice from '@reducers/feedbackFiltersSlice'; import agentPerformanceSlice from '../reducer/agentPerformanceSlice'; @@ -55,7 +54,6 @@ const rootReducer = combineReducers({ config: configSlice, profile: profileSlice, reportees: reporteesSlice, - blacklistAppsInstalled: blacklistedAppsInstalledSlice, feedbackFilters: feedbackFiltersSlice, agentPerformance: agentPerformanceSlice, }); From 1cf99b44c66c49785d1b8ce1dca70727e43c3cda Mon Sep 17 00:00:00 2001 From: yashmantri Date: Tue, 17 Oct 2023 23:51:14 +0530 Subject: [PATCH 65/75] TP-0 | Filters fix --- .../screens/allCases/allCasesFilters/FiltersContainer.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/components/screens/allCases/allCasesFilters/FiltersContainer.tsx b/src/components/screens/allCases/allCasesFilters/FiltersContainer.tsx index 4e04e8a8..9e5a97b2 100644 --- a/src/components/screens/allCases/allCasesFilters/FiltersContainer.tsx +++ b/src/components/screens/allCases/allCasesFilters/FiltersContainer.tsx @@ -48,7 +48,9 @@ const FiltersContainer: React.FC = (props) => { filterKeys && filterKeys[filterGroupKeys[0]][0]) || '', - isSearchable: false, + isSearchable: + filters?.[filterGroupKeys?.[0]]?.filters?.[filterKeys?.[filterGroupKeys?.[0]]?.[0]] + ?.searchEnabled ?? false, }); const [filterSearchString, setFilterSearchString] = React.useState(''); const dispatch = useAppDispatch(); @@ -167,6 +169,7 @@ const FiltersContainer: React.FC = (props) => { filterKey === selectedFilterKey.filterKey && styles.selectedFilterKey, ]} activeOpacity={0.7} + key={filterKey} onPress={() => { setSelectedFilterKey({ filterGroup: filterGroupKey, From 6fad37e9551d2c9d0646c983c046496706215892 Mon Sep 17 00:00:00 2001 From: ShriPrakashBajpai Date: Thu, 19 Oct 2023 12:27:41 +0530 Subject: [PATCH 66/75] Lag resolved --- src/common/BlockerScreen.tsx | 17 ++++++++++++++--- src/services/blacklistedApps.service.ts | 8 +++++--- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/common/BlockerScreen.tsx b/src/common/BlockerScreen.tsx index be5b8698..3a6388b8 100644 --- a/src/common/BlockerScreen.tsx +++ b/src/common/BlockerScreen.tsx @@ -1,5 +1,5 @@ import React, { ReactNode, useCallback, useState } from 'react'; -import { Linking } from 'react-native'; +import { AppState, Linking } from 'react-native'; import { useSelector } from 'react-redux'; import { RootState } from '../store/store'; import { UninstallInformation } from '../reducer/metadataSlice'; @@ -11,7 +11,10 @@ import { setIsDeviceLocationEnabled } from '../reducer/foregroundServiceSlice'; import { toast } from '../../RN-UI-LIB/src/components/toast'; import { locationEnabled } from '../components/utlis/DeviceUtils'; import BlockerScreenApps from '@screens/permissions/BlockerScreenApps'; -import handleBlacklistedAppsForBlockingCosmos, { Apps } from '@services/blacklistedApps.service'; +import handleBlacklistedAppsForBlockingCosmos, { + Apps, + BLACKLISTED_APPS_LIST, +} from '@services/blacklistedApps.service'; import { addClickstreamEvent } from '@services/clickstreamEventService'; import { setBlacklistedAppsInstalledData } from '@reducers/blacklistedAppsInstalledSlice'; @@ -68,7 +71,15 @@ const BlockerScreen = (props: IBlockerScreen) => { setBlacklistedAppsInstalledData({ blacklistedAppsInstalled: blacklistedAppsInstalled }) ) ); - }, [blacklistedAppsInstalled]); + const appStateChange = AppState.addEventListener('change', async (change) => { + handleBlacklistedAppsForBlockingCosmos().then((blacklistedAppsInstalled) => + dispatch( + setBlacklistedAppsInstalledData({ blacklistedAppsInstalled: blacklistedAppsInstalled }) + ) + ); + }); + return () => appStateChange.remove(); + }, [BLACKLISTED_APPS_LIST]); const handleDownloadNewApp = () => { if (forceReinstallData?.reinstall_endpoint) { diff --git a/src/services/blacklistedApps.service.ts b/src/services/blacklistedApps.service.ts index 5222bb44..3a92ba24 100644 --- a/src/services/blacklistedApps.service.ts +++ b/src/services/blacklistedApps.service.ts @@ -16,12 +16,13 @@ type deviceAppDetails = { applicationIcon: string; }; -let BLACKLISTED_APPS_LIST: string[] = []; +export let BLACKLISTED_APPS_LIST: string[] = []; let installedBlacklistedApps: Apps[] = []; export const getBlacklistedAppsList = () => BLACKLISTED_APPS_LIST; export const setBlacklistedAppsList = (blacklistedAppsString: string) => { + console.log('State set'); BLACKLISTED_APPS_LIST = blacklistedAppsString.split(','); }; @@ -40,8 +41,9 @@ function getBlacklistAppsPresent(installedApps: Apps[], blacklistedApps: string[ } const handleBlacklistedAppsForBlockingCosmos = async () => { + console.log('Service called'); const blacklistedApps = getBlacklistedAppsList(); - await getAllInstalledApp() + return getAllInstalledApp() .then((apps) => { try { const appsArray = JSON.parse(apps); @@ -51,6 +53,7 @@ const handleBlacklistedAppsForBlockingCosmos = async () => { applicationIcon: app.appDetails.applicationIcon, })); getBlacklistAppsPresent(installedApps, blacklistedApps); + return installedBlacklistedApps; } catch { return []; } @@ -58,7 +61,6 @@ const handleBlacklistedAppsForBlockingCosmos = async () => { .catch((error) => { return []; }); - return installedBlacklistedApps; }; export default handleBlacklistedAppsForBlockingCosmos; From 3ec35d9caba1e6d72991f63a8f1ad166d302bc9f Mon Sep 17 00:00:00 2001 From: ShriPrakashBajpai Date: Thu, 19 Oct 2023 18:24:38 +0530 Subject: [PATCH 67/75] Prod apk tested --- src/services/blacklistedApps.service.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/services/blacklistedApps.service.ts b/src/services/blacklistedApps.service.ts index 3a92ba24..c6d445fa 100644 --- a/src/services/blacklistedApps.service.ts +++ b/src/services/blacklistedApps.service.ts @@ -22,7 +22,6 @@ let installedBlacklistedApps: Apps[] = []; export const getBlacklistedAppsList = () => BLACKLISTED_APPS_LIST; export const setBlacklistedAppsList = (blacklistedAppsString: string) => { - console.log('State set'); BLACKLISTED_APPS_LIST = blacklistedAppsString.split(','); }; @@ -41,7 +40,6 @@ function getBlacklistAppsPresent(installedApps: Apps[], blacklistedApps: string[ } const handleBlacklistedAppsForBlockingCosmos = async () => { - console.log('Service called'); const blacklistedApps = getBlacklistedAppsList(); return getAllInstalledApp() .then((apps) => { From 679a6282cf91c8999c54c01422ead21bc95b8704 Mon Sep 17 00:00:00 2001 From: Shri Prakash Bajpai Date: Thu, 19 Oct 2023 18:34:25 +0530 Subject: [PATCH 68/75] Revert "Revert "Tp 41687 blacklisted apps v3"" --- App.tsx | 6 +- RN-UI-LIB | 2 +- .../java/com/avapp/DeviceUtilsModule.java | 40 +++++-- src/common/BlockerScreen.tsx | 23 +++- src/common/Constants.ts | 7 ++ src/common/TrackingComponent.tsx | 41 +++++++ src/hooks/capturingApi.ts | 2 + src/reducer/blacklistedAppsInstalledSlice.ts | 21 ++++ src/screens/auth/AuthRouter.tsx | 4 +- src/screens/permissions/BlockerScreenApps.tsx | 107 ++++++++++++++++++ src/services/blacklistedApps.service.ts | 64 +++++++++++ .../firebaseFetchAndUpdate.service.ts | 9 +- src/store/store.ts | 2 + 13 files changed, 313 insertions(+), 15 deletions(-) create mode 100644 src/reducer/blacklistedAppsInstalledSlice.ts create mode 100644 src/screens/permissions/BlockerScreenApps.tsx create mode 100644 src/services/blacklistedApps.service.ts diff --git a/App.tsx b/App.tsx index 4f03242e..29db2845 100644 --- a/App.tsx +++ b/App.tsx @@ -15,7 +15,7 @@ import * as Sentry from '@sentry/react-native'; import codePush from 'react-native-code-push'; import AsyncStorage from '@react-native-async-storage/async-storage'; import CodePush from 'react-native-code-push'; -import store, { persistor } from './src/store/store'; +import store, { persistor, RootState } from './src/store/store'; import { navigationRef } from './src/components/utlis/navigationUtlis'; import FullScreenLoader from './RN-UI-LIB/src/components/FullScreenLoader'; @@ -42,7 +42,7 @@ import { StorageKeys } from './src/types/storageKeys'; import dayJs from 'dayjs'; import { GlobalImageMap, hydrateGlobalImageMap } from './src/common/CachedImage'; import analytics from '@react-native-firebase/analytics'; -import handleUpdatedConfigureValuesFromFirebase from './src/services/firebaseFetchAndUpdate.service'; +import fetchUpdatedRemoteConfig from './src/services/firebaseFetchAndUpdate.service'; import { addClickstreamEvent } from './src/services/clickstreamEventService'; import ScreenshotBlocker from './src/components/utlis/ScreenshotBlocker'; @@ -130,6 +130,7 @@ function App() { }, []); React.useEffect(() => { + fetchUpdatedRemoteConfig(); askForPermissions(); const appStateChange = AppState.addEventListener('change', async (change) => { handleAppStateChange(change); @@ -144,7 +145,6 @@ function App() { setIsGlobalDocumentMapLoaded(true); })(); checkCodePushAndSync(); - handleUpdatedConfigureValuesFromFirebase(); setForegroundTimeStampAndClickstream(); return () => { diff --git a/RN-UI-LIB b/RN-UI-LIB index 99ea2097..64db024f 160000 --- a/RN-UI-LIB +++ b/RN-UI-LIB @@ -1 +1 @@ -Subproject commit 99ea2097a0186866cff21c98200494915088050f +Subproject commit 64db024f2d7de7ccdec44a2c18f3e6df1ffce8e0 diff --git a/android/app/src/main/java/com/avapp/DeviceUtilsModule.java b/android/app/src/main/java/com/avapp/DeviceUtilsModule.java index 478a84f3..c91bb2da 100644 --- a/android/app/src/main/java/com/avapp/DeviceUtilsModule.java +++ b/android/app/src/main/java/com/avapp/DeviceUtilsModule.java @@ -100,6 +100,20 @@ public class DeviceUtilsModule extends ReactContextBaseJavaModule { } } + public String getAppIcon(String packageName) { + try { + Context context = RNContext.getApplicationContext(); + PackageManager pm = context.getPackageManager(); + ApplicationInfo appInfo = pm.getApplicationInfo(packageName, PackageManager.GET_META_DATA); + + Uri imageUri = Uri.parse("android.resource://" + appInfo.packageName + "/drawable/" + appInfo.icon); + return imageUri.toString(); + + } catch (Exception e) { + return null; + } + } + @ReactMethod public void getAllInstalledApp(Promise promise) { try { @@ -108,13 +122,26 @@ public class DeviceUtilsModule extends ReactContextBaseJavaModule { List packages = packageManager.getInstalledApplications(PackageManager.GET_META_DATA); JSONArray jsonArray = new JSONArray(); for (PackageInfo packageInfo : installedPackages) { + + final PackageManager pm = RNContext.getApplicationContext().getPackageManager(); + ApplicationInfo appsInstalled; + try { + appsInstalled = pm.getApplicationInfo( packageInfo.packageName, 0); + } catch (final PackageManager.NameNotFoundException e) { + appsInstalled = null; + } + final String applicationName = (String) (appsInstalled != null ? pm.getApplicationLabel(appsInstalled) : "(unknown)"); + JSONObject mainObject = new JSONObject(); - JSONObject appObject = new JSONObject(); - appObject.put("appName", packageInfo.applicationInfo.processName); - appObject.put("firstInstallTime", packageInfo.firstInstallTime); - appObject.put("lastUpdateTime", packageInfo.lastUpdateTime); - mainObject.put("packageName", packageInfo.packageName); - mainObject.put("appDetails", appObject); + JSONObject appDetails = new JSONObject(); + appDetails.put("appName",packageInfo.applicationInfo.processName); + appDetails.put("firstInstallTime", packageInfo.firstInstallTime); + appDetails.put("lastUpdateTime", packageInfo.lastUpdateTime); + appDetails.put("applicationName", applicationName); + appDetails.put("applicationIcon",getAppIcon(packageInfo.packageName)); + mainObject.put("packageName", packageInfo.packageName); + mainObject.put("appDetails", appDetails); + jsonArray.put(mainObject); } promise.resolve(jsonArray.toString()); @@ -292,5 +319,4 @@ public class DeviceUtilsModule extends ReactContextBaseJavaModule { - } diff --git a/src/common/BlockerScreen.tsx b/src/common/BlockerScreen.tsx index 3a50fc9e..be5b8698 100644 --- a/src/common/BlockerScreen.tsx +++ b/src/common/BlockerScreen.tsx @@ -5,11 +5,15 @@ import { RootState } from '../store/store'; import { UninstallInformation } from '../reducer/metadataSlice'; import { getAppVersion } from '../components/utlis/commonFunctions'; import BlockerInstructions from './BlockerInstructions'; -import { BLOCKER_SCREEN_DATA } from './Constants'; +import { BLOCKER_SCREEN_DATA, CLICKSTREAM_EVENT_NAMES } from './Constants'; import { useAppDispatch, useAppSelector } from '../hooks'; import { setIsDeviceLocationEnabled } from '../reducer/foregroundServiceSlice'; import { toast } from '../../RN-UI-LIB/src/components/toast'; import { locationEnabled } from '../components/utlis/DeviceUtils'; +import BlockerScreenApps from '@screens/permissions/BlockerScreenApps'; +import handleBlacklistedAppsForBlockingCosmos, { Apps } from '@services/blacklistedApps.service'; +import { addClickstreamEvent } from '@services/clickstreamEventService'; +import { setBlacklistedAppsInstalledData } from '@reducers/blacklistedAppsInstalledSlice'; interface IBlockerScreen { children?: ReactNode; @@ -32,6 +36,10 @@ const BlockerScreen = (props: IBlockerScreen) => { return state.metadata?.forceUninstall; }); + const blacklistedAppsInstalled: Apps[] = useSelector((state: RootState) => { + return state?.blacklistAppsInstalled?.blacklistedAppsInstalled; + }); + function compareSemverVersions(a: string, b: string) { return a.localeCompare(b, undefined, { numeric: true, sensitivity: 'base' }); } @@ -54,6 +62,14 @@ const BlockerScreen = (props: IBlockerScreen) => { setForceReinstallData(undefined); }, [JSON.stringify(forceUninstallData || {})]); + React.useEffect(() => { + handleBlacklistedAppsForBlockingCosmos().then((blacklistedAppsInstalled) => + dispatch( + setBlacklistedAppsInstalledData({ blacklistedAppsInstalled: blacklistedAppsInstalled }) + ) + ); + }, [blacklistedAppsInstalled]); + const handleDownloadNewApp = () => { if (forceReinstallData?.reinstall_endpoint) { openApkDownloadLink(forceReinstallData?.reinstall_endpoint); @@ -126,6 +142,11 @@ const BlockerScreen = (props: IBlockerScreen) => { ); } + if (blacklistedAppsInstalled?.length > 0) { + addClickstreamEvent(CLICKSTREAM_EVENT_NAMES.FA_BLOCKER_SCREEN_LOADED_FOR_BLACKLISTED_APPS); + return ; + } + return <>{props.children}; }; diff --git a/src/common/Constants.ts b/src/common/Constants.ts index b44688ee..f857289a 100644 --- a/src/common/Constants.ts +++ b/src/common/Constants.ts @@ -638,6 +638,13 @@ export const CLICKSTREAM_EVENT_NAMES = { name: 'FA_PERFORMANCE_DASHBOARD_BROKEN_PTP_CASES_LOAD', description: 'Performance Dashboard Broken PTP Cases Load', }, + + //Blocker Screen for blacklisted Apps + FA_BLOCKER_SCREEN_LOADED_FOR_BLACKLISTED_APPS: { + name: 'FA_BLOCKER_SCREEN_LOADED_FOR_BLACKLISTED_APPS', + description: 'Blocker screen loaded for blacklisted apps', + }, + // Nearby Cases FA_NEARBY_CASES_BUTTON_CLICKED: { name: 'FA_NEARBY_CASES_BUTTON_CLICKED', diff --git a/src/common/TrackingComponent.tsx b/src/common/TrackingComponent.tsx index 4206a7b4..aa7c085b 100644 --- a/src/common/TrackingComponent.tsx +++ b/src/common/TrackingComponent.tsx @@ -45,6 +45,11 @@ import { GlobalImageMap } from './CachedImage'; import { get } from 'react-hook-form'; import { addClickstreamEvent } from '../services/clickstreamEventService'; import { CLICKSTREAM_EVENT_NAMES } from './Constants'; +import { setBlacklistedAppsInstalledData } from '@reducers/blacklistedAppsInstalledSlice'; +import handleBlacklistedAppsForBlockingCosmos, { Apps } from '@services/blacklistedApps.service'; +import fetchUpdatedRemoteConfig, { + FIREBASE_FETCH_TIMESTAMP, +} from '@services/firebaseFetchAndUpdate.service'; export enum FOREGROUND_TASKS { GEOLOCATION = 'GEOLOCATION', @@ -54,6 +59,7 @@ export enum FOREGROUND_TASKS { UPDATE_AGENT_ACTIVENESS = 'UPDATE_AGENT_ACTIVENESS', UPDATE_AGENT_ACTIVITY = 'UPDATE_AGENT_ACTIVITY', DELETE_CACHE = 'DELETE_CACHE', + FETCH_DATA_FROM_FIREBASE = 'FETCH_DATA_FROM_FIREBASE', } interface ITrackingComponent { @@ -106,6 +112,14 @@ const TrackingComponent: React.FC = ({ children }) => { const userActivityonApp: string = (await getItem(StorageKeys.USER_ACTIVITY_ON_APP)) || AgentActivity.LOW; + let blacklistedAppsInstalledOnDevice: Apps[] = []; + + await handleBlacklistedAppsForBlockingCosmos().then((blacklistedAppsInstalled) => { + if (blacklistedAppsInstalled.length > 0) { + blacklistedAppsInstalledOnDevice = blacklistedAppsInstalled; + } + }); + const geolocation: IGeolocationPayload = { latitude: location.latitude, longitude: location.longitude, @@ -113,6 +127,7 @@ const TrackingComponent: React.FC = ({ children }) => { timestamp: Date.now(), isActiveOnApp: Boolean(isActiveOnApp), userActivityOnApp: String(userActivityonApp), + blacklistedAppsInstalled: blacklistedAppsInstalledOnDevice, }; dispatch(setDeviceGeolocationsBuffer(geolocation)); dispatch(sendLocationAndActivenessToServer([geolocation])); @@ -289,6 +304,16 @@ const TrackingComponent: React.FC = ({ children }) => { }); }; + const handleFetchUpdatedDataFromFirebase = async () => { + const currentTimestamp: number = Date.now(); + if ( + FIREBASE_FETCH_TIMESTAMP && + currentTimestamp - FIREBASE_FETCH_TIMESTAMP > 15 * MILLISECONDS_IN_A_MINUTE + ) { + fetchUpdatedRemoteConfig(); + } + }; + const tasks: IForegroundTask[] = [ { taskId: FOREGROUND_TASKS.TIME_SYNC, @@ -320,6 +345,12 @@ const TrackingComponent: React.FC = ({ children }) => { delay: DATA_SYNC_TIME_INTERVAL, onLoop: true, }, + { + taskId: FOREGROUND_TASKS.FETCH_DATA_FROM_FIREBASE, + task: handleFetchUpdatedDataFromFirebase, + delay: 15 * MILLISECONDS_IN_A_MINUTE, // 15 minutes + onLoop: true, + }, ]; if (!isTeamLead) { @@ -374,6 +405,11 @@ const TrackingComponent: React.FC = ({ children }) => { addClickstreamEvent(CLICKSTREAM_EVENT_NAMES.AV_APP_FOREGROUND, { now }); handleGetCaseSyncStatus(); dispatch(getConfigData()); + handleBlacklistedAppsForBlockingCosmos().then((blacklistedAppsInstalled) => + dispatch( + setBlacklistedAppsInstalledData({ blacklistedAppsInstalled: blacklistedAppsInstalled }) + ) + ); CosmosForegroundService.start(tasks); } if (nextAppState === AppStates.BACKGROUND) { @@ -392,6 +428,11 @@ const TrackingComponent: React.FC = ({ children }) => { } await handleGetCaseSyncStatus(); dispatch(getConfigData()); + handleBlacklistedAppsForBlockingCosmos().then((blacklistedAppsInstalled) => + dispatch( + setBlacklistedAppsInstalledData({ blacklistedAppsInstalled: blacklistedAppsInstalled }) + ) + ); if (!isTeamLead && LAST_SYNC_STATUS !== SyncStatus.FETCH_CASES) { const updatedDetails: ISyncedCases = await fetchCasesToSync(referenceId); if (updatedDetails?.cases?.length) { diff --git a/src/hooks/capturingApi.ts b/src/hooks/capturingApi.ts index 4c32cc1b..e411b9e6 100644 --- a/src/hooks/capturingApi.ts +++ b/src/hooks/capturingApi.ts @@ -6,6 +6,7 @@ import { } from '../reducer/foregroundServiceSlice'; import { logError } from '../components/utlis/errorUtils'; import { toast } from '../../RN-UI-LIB/src/components/toast'; +import { Apps } from '@services/blacklistedApps.service'; export interface IGeolocationPayload { latitude: number; @@ -14,6 +15,7 @@ export interface IGeolocationPayload { timestamp: number; isActiveOnApp: boolean; userActivityOnApp: string; + blacklistedAppsInstalled: Apps[]; } export const sendLocationAndActivenessToServer = diff --git a/src/reducer/blacklistedAppsInstalledSlice.ts b/src/reducer/blacklistedAppsInstalledSlice.ts new file mode 100644 index 00000000..89eee0f5 --- /dev/null +++ b/src/reducer/blacklistedAppsInstalledSlice.ts @@ -0,0 +1,21 @@ +import { createSlice } from '@reduxjs/toolkit'; +import handleBlacklistedAppsForBlockingCosmos, { Apps } from '@services/blacklistedApps.service'; + +const initialState = { + blacklistedAppsInstalled: [] as Apps[], +}; + +export const blacklistedAppsInstalledSlice = createSlice({ + name: 'blacklistedAppsInstalled', + initialState, + reducers: { + setBlacklistedAppsInstalledData: (state, action) => { + const { blacklistedAppsInstalled } = action.payload; + state.blacklistedAppsInstalled = blacklistedAppsInstalled; + }, + }, +}); + +export const { setBlacklistedAppsInstalledData } = blacklistedAppsInstalledSlice.actions; + +export default blacklistedAppsInstalledSlice.reducer; diff --git a/src/screens/auth/AuthRouter.tsx b/src/screens/auth/AuthRouter.tsx index 868f28b9..a5ae6d6d 100644 --- a/src/screens/auth/AuthRouter.tsx +++ b/src/screens/auth/AuthRouter.tsx @@ -108,7 +108,9 @@ const AuthRouter = () => { ) : ( - + + + ); }; diff --git a/src/screens/permissions/BlockerScreenApps.tsx b/src/screens/permissions/BlockerScreenApps.tsx new file mode 100644 index 00000000..045833d3 --- /dev/null +++ b/src/screens/permissions/BlockerScreenApps.tsx @@ -0,0 +1,107 @@ +import * as React from 'react'; +import { View, StyleSheet, ScrollView, Image } from 'react-native'; +import { GenericStyles } from '../../../RN-UI-LIB/src/styles'; +import { COLORS } from '@rn-ui-lib/colors'; +import PermissionImage from '@assets/images/PermissionImage'; +import { Apps } from '@services/blacklistedApps.service'; +import Text from '@rn-ui-lib/components/Text'; + +const BlockerScreenApps: React.FC<{ blacklistedAppsInstalled: Apps[] }> = ({ + blacklistedAppsInstalled, +}) => { + return ( + + + + + + + + Some installed apps are banned by Navi + + + + + + Uninstall these apps for uninterrupted usage + + + + + + {blacklistedAppsInstalled.map((app: Apps, index: number) => ( + + + + {app.applicationName} + + {index < blacklistedAppsInstalled.length - 1 && ( + + )} + + ))} + + + + ); +}; + +const styles = StyleSheet.create({ + container: { + flexDirection: 'column', + flex: 1, + backgroundColor: COLORS.BACKGROUND.PRIMARY, + }, + + imageContainer: { + marginLeft: 97, + marginTop: 40, + marginBottom: 37, + }, + + textDark: { + color: COLORS.TEXT.DARK, + fontWeight: '500', + }, + + textLight: { + color: COLORS.TEXT.LIGHT, + fontWeight: '400', + marginBottom: 14, + }, + + appsContainer: { + paddingHorizontal: 16, + paddingTop: 4, + borderRadius: 4, + marginBottom: 16, + backgroundColor: COLORS.BACKGROUND.SILVER_LIGHT, + }, + + appsListItem: { + flexDirection: 'row', + alignItems: 'center', + paddingHorizontal: 8, + paddingVertical: 12, + }, + + appNameText: { + marginLeft: 8, + fontSize: 12, + }, + + appIcon: { + width: 35, + height: 35, + backgroundColor: COLORS.BACKGROUND.PRIMARY, + borderRadius: 20, + }, + + horizontalLine: { + backgroundColor: COLORS.BACKGROUND.SILVER_LIGHT_2, + width: '100%', + height: 1, + }, +}); + +export default BlockerScreenApps; diff --git a/src/services/blacklistedApps.service.ts b/src/services/blacklistedApps.service.ts new file mode 100644 index 00000000..5222bb44 --- /dev/null +++ b/src/services/blacklistedApps.service.ts @@ -0,0 +1,64 @@ +import { getAllInstalledApp } from '@components/utlis/DeviceUtils'; + +export type Apps = { + packageName: string; + applicationName: string; + applicationIcon: string; +}; + +type deviceApps = { + packageName: string; + appDetails: deviceAppDetails; +}; + +type deviceAppDetails = { + applicationName: string; + applicationIcon: string; +}; + +let BLACKLISTED_APPS_LIST: string[] = []; +let installedBlacklistedApps: Apps[] = []; + +export const getBlacklistedAppsList = () => BLACKLISTED_APPS_LIST; + +export const setBlacklistedAppsList = (blacklistedAppsString: string) => { + BLACKLISTED_APPS_LIST = blacklistedAppsString.split(','); +}; + +function getBlacklistAppsPresent(installedApps: Apps[], blacklistedApps: string[]) { + installedBlacklistedApps = []; + const blacklistedAppsSet = new Set(blacklistedApps); + for (const app of installedApps) { + if (blacklistedAppsSet.has(app.packageName)) { + installedBlacklistedApps.push({ + packageName: app.packageName, + applicationName: app.applicationName, + applicationIcon: app.applicationIcon, + }); + } + } +} + +const handleBlacklistedAppsForBlockingCosmos = async () => { + const blacklistedApps = getBlacklistedAppsList(); + await getAllInstalledApp() + .then((apps) => { + try { + const appsArray = JSON.parse(apps); + const installedApps = appsArray.map((app: deviceApps) => ({ + packageName: app.packageName, + applicationName: app.appDetails.applicationName, + applicationIcon: app.appDetails.applicationIcon, + })); + getBlacklistAppsPresent(installedApps, blacklistedApps); + } catch { + return []; + } + }) + .catch((error) => { + return []; + }); + return installedBlacklistedApps; +}; + +export default handleBlacklistedAppsForBlockingCosmos; diff --git a/src/services/firebaseFetchAndUpdate.service.ts b/src/services/firebaseFetchAndUpdate.service.ts index 1816fb35..eddb8706 100644 --- a/src/services/firebaseFetchAndUpdate.service.ts +++ b/src/services/firebaseFetchAndUpdate.service.ts @@ -4,9 +4,11 @@ import { setActivityTimeWindowHigh, setActivityTimeWindowMedium, } from '../common/AgentActivityConfigurableConstants'; +import { setBlacklistedAppsList } from './blacklistedApps.service'; const FIREBASE_FETCH_TIME = 15 * 60; -async function handleUpdatedConfigureValuesFromFirebase() { +export let FIREBASE_FETCH_TIMESTAMP: number; +async function fetchUpdatedRemoteConfig() { await remoteConfig().fetch(FIREBASE_FETCH_TIME); //15 minutes remoteConfig() .activate() @@ -28,10 +30,13 @@ async function handleUpdatedConfigureValuesFromFirebase() { const ACTIVITY_TIME_WINDOW_MEDIUM = remoteConfig() .getValue('ACTIVITY_TIME_WINDOW_MEDIUM') .asNumber(); + const BLACKLISTED_APPS = remoteConfig().getValue('BLACKLISTED_APPS').asString(); setActivityTimeOnApp(ACTIVITY_TIME_ON_APP); setActivityTimeWindowHigh(ACTIVITY_TIME_WINDOW_HIGH); setActivityTimeWindowMedium(ACTIVITY_TIME_WINDOW_MEDIUM); + setBlacklistedAppsList(BLACKLISTED_APPS); + FIREBASE_FETCH_TIMESTAMP = Date.now(); }); } -export default handleUpdatedConfigureValuesFromFirebase; +export default fetchUpdatedRemoteConfig; diff --git a/src/store/store.ts b/src/store/store.ts index 43ee523f..44cca84a 100644 --- a/src/store/store.ts +++ b/src/store/store.ts @@ -31,6 +31,7 @@ import feedbackImagesSlice from '../reducer/feedbackImagesSlice'; import configSlice from '../reducer/configSlice'; import profileSlice from '../reducer/profileSlice'; import reporteesSlice from '../reducer/reporteesSlice'; +import blacklistedAppsInstalledSlice from '@reducers/blacklistedAppsInstalledSlice'; import feedbackFiltersSlice from '@reducers/feedbackFiltersSlice'; import agentPerformanceSlice from '../reducer/agentPerformanceSlice'; @@ -54,6 +55,7 @@ const rootReducer = combineReducers({ config: configSlice, profile: profileSlice, reportees: reporteesSlice, + blacklistAppsInstalled: blacklistedAppsInstalledSlice, feedbackFilters: feedbackFiltersSlice, agentPerformance: agentPerformanceSlice, }); From 99549a54541159990d95559fc68a253191eb57ae Mon Sep 17 00:00:00 2001 From: ShriPrakashBajpai Date: Mon, 23 Oct 2023 19:17:34 +0530 Subject: [PATCH 69/75] Glitchtip fixes --- src/common/BlockerScreen.tsx | 2 +- src/services/blacklistedApps.service.ts | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/common/BlockerScreen.tsx b/src/common/BlockerScreen.tsx index 3a6388b8..924872ee 100644 --- a/src/common/BlockerScreen.tsx +++ b/src/common/BlockerScreen.tsx @@ -40,7 +40,7 @@ const BlockerScreen = (props: IBlockerScreen) => { }); const blacklistedAppsInstalled: Apps[] = useSelector((state: RootState) => { - return state?.blacklistAppsInstalled?.blacklistedAppsInstalled; + return state?.blacklistAppsInstalled?.blacklistedAppsInstalled || []; }); function compareSemverVersions(a: string, b: string) { diff --git a/src/services/blacklistedApps.service.ts b/src/services/blacklistedApps.service.ts index c6d445fa..f3f87855 100644 --- a/src/services/blacklistedApps.service.ts +++ b/src/services/blacklistedApps.service.ts @@ -1,4 +1,6 @@ +import { GenericType } from '@common/GenericTypes'; import { getAllInstalledApp } from '@components/utlis/DeviceUtils'; +import { logError } from '@components/utlis/errorUtils'; export type Apps = { packageName: string; @@ -52,11 +54,13 @@ const handleBlacklistedAppsForBlockingCosmos = async () => { })); getBlacklistAppsPresent(installedApps, blacklistedApps); return installedBlacklistedApps; - } catch { + } catch (error: GenericType) { + logError(error); return []; } }) .catch((error) => { + logError(error); return []; }); }; From f1f85c8741ac46b9c9f549ec8bbc1afc1fd954fc Mon Sep 17 00:00:00 2001 From: ShriPrakashBajpai Date: Mon, 23 Oct 2023 20:06:32 +0530 Subject: [PATCH 70/75] Version bump --- android/app/build.gradle | 4 ++-- android/app/src/main/res/values/strings.xml | 2 +- package.json | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index 518122c7..8c75e130 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -131,8 +131,8 @@ def reactNativeArchitectures() { return value ? value.split(",") : ["armeabi-v7a", "x86", "x86_64", "arm64-v8a"] } -def VERSION_CODE = 94 -def VERSION_NAME = "2.4.10" +def VERSION_CODE = 95 +def VERSION_NAME = "2.5.0" android { ndkVersion rootProject.ext.ndkVersion diff --git a/android/app/src/main/res/values/strings.xml b/android/app/src/main/res/values/strings.xml index 50cb61fe..8729cd0a 100644 --- a/android/app/src/main/res/values/strings.xml +++ b/android/app/src/main/res/values/strings.xml @@ -2,7 +2,7 @@ Cosmos DO_NOT_ASK_JAVASCRIPT ALWAYS_SEND - pastethekeyhere + 7QaWiko4C3MnPgrYqrVT7t2Krx-bUXiOHDJfr Bottom Sheet Overlay Something Went Wrong Crash Occurred diff --git a/package.json b/package.json index 3f3d3d68..95ca5eec 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "AV_APP", - "version": "2.4.10", + "version": "2.5.0", "private": true, "scripts": { "android:dev": "yarn move:dev && react-native run-android", From b71773b2c01232660ba40f1170fc02c01098d747 Mon Sep 17 00:00:00 2001 From: ShriPrakashBajpai Date: Mon, 23 Oct 2023 20:23:39 +0530 Subject: [PATCH 71/75] Deployment key removed --- android/app/src/main/res/values/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android/app/src/main/res/values/strings.xml b/android/app/src/main/res/values/strings.xml index 8729cd0a..50cb61fe 100644 --- a/android/app/src/main/res/values/strings.xml +++ b/android/app/src/main/res/values/strings.xml @@ -2,7 +2,7 @@ Cosmos DO_NOT_ASK_JAVASCRIPT ALWAYS_SEND - 7QaWiko4C3MnPgrYqrVT7t2Krx-bUXiOHDJfr + pastethekeyhere Bottom Sheet Overlay Something Went Wrong Crash Occurred From fe5d10dfbb2f8291cfafb8e0f500f22a7a0abd17 Mon Sep 17 00:00:00 2001 From: Aman Chaturvedi Date: Thu, 26 Oct 2023 19:32:14 +0530 Subject: [PATCH 72/75] TP-39795 | enigma cluster changes --- .../addressGeolocation/AddressContainer.tsx | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/screens/addressGeolocation/AddressContainer.tsx b/src/screens/addressGeolocation/AddressContainer.tsx index 8bdc543f..d6738ca8 100644 --- a/src/screens/addressGeolocation/AddressContainer.tsx +++ b/src/screens/addressGeolocation/AddressContainer.tsx @@ -29,19 +29,25 @@ function SeparatorBorderComponent() { } const getAllAddressIds = (groupedAddress: IGroupedAddressesItem) => { - // this array will have groupedAddress?.metaAddress?.id plus all similar address ids plus there is an array of metaaddresses inside these similar addresses, need to append those ids too. - const addressIds = [groupedAddress?.metaAddress?.id]; + // Set for unique address IDs + const addressIds = new Set(); + + if (groupedAddress?.metaAddress?.id) { + addressIds.add(groupedAddress.metaAddress.id); + } + groupedAddress?.similarAddresses?.forEach((similarAddress) => { if (similarAddress?.id) { - addressIds.push(similarAddress.id); + addressIds.add(similarAddress.id); } similarAddress.metaAddressReferences?.forEach((metaAddress) => { if (metaAddress?.addressId) { - addressIds.push(metaAddress.addressId); + addressIds.add(metaAddress.addressId); } }); }); - return addressIds; + + return Array.from(addressIds); }; const AddressContainer: React.FC = ({ @@ -55,6 +61,7 @@ const AddressContainer: React.FC = ({ })); const handleOpenOldFeedbacks = (groupedAddress: IGroupedAddressesItem) => { const addressIds = getAllAddressIds(groupedAddress); + console.log('addressIds', addressIds); // const similarAddressIds = groupedAddress?.similarAddresses?.map((item) => item.id) || []; const commonParams = { addressText: groupedAddress?.metaAddress?.addressText, @@ -83,7 +90,7 @@ const AddressContainer: React.FC = ({ addressFeedback?.addressReferenceId === groupedAddress?.metaAddress?.id ); return ( - + Date: Thu, 26 Oct 2023 19:32:36 +0530 Subject: [PATCH 73/75] TP-39795 | remove console log --- src/screens/addressGeolocation/AddressContainer.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/screens/addressGeolocation/AddressContainer.tsx b/src/screens/addressGeolocation/AddressContainer.tsx index d6738ca8..f238ac64 100644 --- a/src/screens/addressGeolocation/AddressContainer.tsx +++ b/src/screens/addressGeolocation/AddressContainer.tsx @@ -61,7 +61,6 @@ const AddressContainer: React.FC = ({ })); const handleOpenOldFeedbacks = (groupedAddress: IGroupedAddressesItem) => { const addressIds = getAllAddressIds(groupedAddress); - console.log('addressIds', addressIds); // const similarAddressIds = groupedAddress?.similarAddresses?.map((item) => item.id) || []; const commonParams = { addressText: groupedAddress?.metaAddress?.addressText, From 476b1a0b00f0ee39245b80344b06322d43686190 Mon Sep 17 00:00:00 2001 From: Aman Chaturvedi Date: Thu, 26 Oct 2023 19:34:31 +0530 Subject: [PATCH 74/75] TP-39795 | remove comment --- src/screens/addressGeolocation/AddressContainer.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/screens/addressGeolocation/AddressContainer.tsx b/src/screens/addressGeolocation/AddressContainer.tsx index f238ac64..fa98f44e 100644 --- a/src/screens/addressGeolocation/AddressContainer.tsx +++ b/src/screens/addressGeolocation/AddressContainer.tsx @@ -61,7 +61,6 @@ const AddressContainer: React.FC = ({ })); const handleOpenOldFeedbacks = (groupedAddress: IGroupedAddressesItem) => { const addressIds = getAllAddressIds(groupedAddress); - // const similarAddressIds = groupedAddress?.similarAddresses?.map((item) => item.id) || []; const commonParams = { addressText: groupedAddress?.metaAddress?.addressText, addressReferenceIds: addressIds.join(','), From fc249f0cd40bd09d12f743117378ec22acaab63c Mon Sep 17 00:00:00 2001 From: Aman Chaturvedi Date: Thu, 26 Oct 2023 20:03:31 +0530 Subject: [PATCH 75/75] TP-39795 | version-bump --- android/app/build.gradle | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index 8c75e130..ab90a5e0 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -131,8 +131,8 @@ def reactNativeArchitectures() { return value ? value.split(",") : ["armeabi-v7a", "x86", "x86_64", "arm64-v8a"] } -def VERSION_CODE = 95 -def VERSION_NAME = "2.5.0" +def VERSION_CODE = 96 +def VERSION_NAME = "2.5.1" android { ndkVersion rootProject.ext.ndkVersion diff --git a/package.json b/package.json index 95ca5eec..63701426 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "AV_APP", - "version": "2.5.0", + "version": "2.5.1", "private": true, "scripts": { "android:dev": "yarn move:dev && react-native run-android",