From 0d04d4583af468e5268f1bc236a50bcb39e1df3e Mon Sep 17 00:00:00 2001 From: ShriPrakashBajpai Date: Mon, 9 Oct 2023 23:39:18 +0530 Subject: [PATCH 01/32] Whatsapp Business share implemented --- src/screens/caseDetails/feedback/FeedbackDetailItem.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/screens/caseDetails/feedback/FeedbackDetailItem.tsx b/src/screens/caseDetails/feedback/FeedbackDetailItem.tsx index 1846d506..6d63f3d4 100644 --- a/src/screens/caseDetails/feedback/FeedbackDetailItem.tsx +++ b/src/screens/caseDetails/feedback/FeedbackDetailItem.tsx @@ -114,7 +114,7 @@ const FeedbackDetailItem = ({ feedbackItem, isExpanded, caseId }: IFeedbackDetai agentId: agentId, }); - var message = `*Visit Feedback* for ${sanitizeString(caseDetails?.customerName)} + let message = `*Visit Feedback* for ${sanitizeString(caseDetails?.customerName)} _${sanitizeString(dateFormat(new Date(feedbackItem?.createdAt), 'DD MMM, YYYY | HH:mm a.'))}_\n *LAN*: ${sanitizeString(caseDetails?.loanAccountNumber)} *DPD Bucket*: ${sanitizeString(caseDetails?.dpdBucket)} @@ -162,10 +162,10 @@ _${sanitizeString(dateFormat(new Date(feedbackItem?.createdAt), 'DD MMM, YYYY | const imagesList = feedbackItem?.answerViews.filter( (answer) => answer.questionTag === OPTION_TAG.IMAGE_UPLOAD ); - var imageUrl = ''; + let imageUrl = ''; const mimeType = 'image/*'; if (imagesList.length > 0) { - var imageUri = ''; + let imageUri = ''; imageUri = imagesList[0]?.inputText ? imagesList[0].inputText : ''; let imagePath = ''; ReactNativeBlobUtil.config({ From 5d061629f083a779e7d56b2723dbb14c84c0b5f7 Mon Sep 17 00:00:00 2001 From: Varnit Goyal Date: Tue, 10 Oct 2023 14:42:45 +0530 Subject: [PATCH 02/32] TP-00000 | merged to master --- RN-UI-LIB | 2 +- src/screens/caseDetails/feedback/FeedbackDetailItem.tsx | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/RN-UI-LIB b/RN-UI-LIB index 4c7f4f68..b10108d9 160000 --- a/RN-UI-LIB +++ b/RN-UI-LIB @@ -1 +1 @@ -Subproject commit 4c7f4f6880d96bffa856e04d7b2b4d383e42c5cf +Subproject commit b10108d97c70125e17d9781654f7a4cf01b3f2da diff --git a/src/screens/caseDetails/feedback/FeedbackDetailItem.tsx b/src/screens/caseDetails/feedback/FeedbackDetailItem.tsx index d72207b1..967f4a51 100644 --- a/src/screens/caseDetails/feedback/FeedbackDetailItem.tsx +++ b/src/screens/caseDetails/feedback/FeedbackDetailItem.tsx @@ -20,7 +20,6 @@ import { IFeedback, OPTION_TAG, } from '../../../types/feedback.types'; -import { CaseDetail, Address as IAddress } from '../interface'; import MapIcon from '../../../../RN-UI-LIB/src/Icons/MapIcon'; import { FEEDBACK_TYPE } from '../../../types/feedback.types'; import CallIcon from '../../../../RN-UI-LIB/src/Icons/CallIcon'; From aed9b6902f832e77d5e9647dc2168c1d2888f705 Mon Sep 17 00:00:00 2001 From: "aman.singh" Date: Tue, 10 Oct 2023 17:42:43 +0530 Subject: [PATCH 03/32] alfred bottomsheet | Aman singh --- android/app/build.gradle | 7 ++- .../java/com/avapp/DeviceUtilsModule.java | 39 ++++++++++--- .../app/src/main/java/com/avapp/ViewShot.java | 58 +++++++++++++++++++ src/common/BottomSheetWrapper.tsx | 20 ++++--- src/common/DropDownWrapper.tsx | 25 +++++--- src/components/utlis/DeviceUtils.ts | 4 ++ 6 files changed, 127 insertions(+), 26 deletions(-) create mode 100644 android/app/src/main/java/com/avapp/ViewShot.java diff --git a/android/app/build.gradle b/android/app/build.gradle index 8e37dd18..c867af28 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -131,8 +131,9 @@ def reactNativeArchitectures() { return value ? value.split(",") : ["armeabi-v7a", "x86", "x86_64", "arm64-v8a"] } -def VERSION_CODE = 89 -def VERSION_NAME = "2.4.5" + +def VERSION_CODE = 92 +def VERSION_NAME = "2.4.10" android { ndkVersion rootProject.ext.ndkVersion @@ -313,7 +314,7 @@ dependencies { implementation "com.github.anrwatchdog:anrwatchdog:1.4.0" - implementation 'com.navi.medici:alfred:v1.0.1' + implementation 'com.navi.medici:alfred:v1.0.1-20231009.124735-1' //noinspection GradleDynamicVersion implementation "com.facebook.react:react-native:+" // From node_modules diff --git a/android/app/src/main/java/com/avapp/DeviceUtilsModule.java b/android/app/src/main/java/com/avapp/DeviceUtilsModule.java index 81183c60..e3656a9d 100644 --- a/android/app/src/main/java/com/avapp/DeviceUtilsModule.java +++ b/android/app/src/main/java/com/avapp/DeviceUtilsModule.java @@ -21,6 +21,9 @@ import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.bridge.ReactContextBaseJavaModule; import com.facebook.react.bridge.ReactMethod; import com.facebook.react.bridge.ReadableMap; +import com.facebook.react.uimanager.NativeViewHierarchyManager; +import com.facebook.react.uimanager.UIBlock; +import com.facebook.react.uimanager.UIManagerModule; import com.navi.alfred.AlfredManager; import android.content.pm.PackageInfo; @@ -153,17 +156,37 @@ public class DeviceUtilsModule extends ReactContextBaseJavaModule { } } + + @ReactMethod + public void setBottomSheetView(Integer refID) { + if (refID != null) { + UIManagerModule uiManagerModule = RNContext.getNativeModule(UIManagerModule.class); + if (uiManagerModule != null) { + uiManagerModule.addUIBlock(nativeViewHierarchyManager -> { + Log.d("Alfred", "setBottomSheetView nativeViewHierarchyManager:" + nativeViewHierarchyManager); + View view = nativeViewHierarchyManager.resolveView(refID); + Log.d("Alfred", "setBottomSheetView view:" + view); + AlfredManager.INSTANCE.setBottomSheetView(view); + }); + } +// UIManagerModule uiManager = RNContext.getNativeModule(UIManagerModule.class); +// Executor executor = Executors.newCachedThreadPool(); +// uiManager.addUIBlock(new ViewShot(refID, RNContext, executor)); + } + // AlfredManager.INSTANCE.clearBottomSheetView(); + } + + + @ReactMethod + public void clearBottomSheet() { + AlfredManager.INSTANCE.clearBottomSheetView(); + } + @ReactMethod public void sendBottomSheetOpenSignal(Boolean isBottomSheetOpen) { - if (isBottomSheetOpen) { - View bottomSheetScreen = LayoutInflater.from(RNContext).inflate(R.layout.bottom_sheet_screen, null); - AlfredManager.INSTANCE.measureInflatedView(bottomSheetScreen, 1080, 540); - AlfredManager.INSTANCE.setCosmosBottomSheet(bottomSheetScreen); - } else { - AlfredManager.INSTANCE.setCosmosBottomSheet(null); - } - return; } + + private static File convertBase64ToFile(Context context,String base64Data) { try { byte[] decodedBytes = Base64.decode(base64Data, Base64.DEFAULT); diff --git a/android/app/src/main/java/com/avapp/ViewShot.java b/android/app/src/main/java/com/avapp/ViewShot.java new file mode 100644 index 00000000..63c16119 --- /dev/null +++ b/android/app/src/main/java/com/avapp/ViewShot.java @@ -0,0 +1,58 @@ +package com.avapp; + +import android.app.Activity; + +import android.util.Log; +import android.view.View; + +import com.facebook.react.bridge.Promise; +import com.facebook.react.bridge.ReactApplicationContext; +import com.facebook.react.uimanager.NativeViewHierarchyManager; +import com.facebook.react.uimanager.UIBlock; + +import java.util.concurrent.Executor; + +/** + * Snapshot utility class allow to screenshot a view. + */ +public class ViewShot implements UIBlock { + + private final int tag; + @SuppressWarnings({"unused", "FieldCanBeLocal"}) + private final ReactApplicationContext reactContext; + private final Executor executor; + + //region Constructors + @SuppressWarnings("WeakerAccess") + public ViewShot( + final int tag, + final ReactApplicationContext reactContext, + final Executor executor) { + this.tag = tag; + this.reactContext = reactContext; + this.executor = executor; + } + + @Override + public void execute(final NativeViewHierarchyManager nativeViewHierarchyManager) { + Log.d("Alfred", "ViewShot execute NativeViewHierarchyManager:" + nativeViewHierarchyManager + executor); + + executor.execute(new Runnable() { + @Override + public void run() { + try { + final View view; + view = nativeViewHierarchyManager.resolveView(tag); + + Log.d("Alfred", "Bottomsheet view: " + view); +// if (tag == -1) { +// view = currentActivity.getWindow().getDecorView().findViewById(android.R.id.content); +// } else { +// view = nativeViewHierarchyManager.resolveView(tag); +// } + } catch (final Throwable ex) { + } + } + }); + } +} \ No newline at end of file diff --git a/src/common/BottomSheetWrapper.tsx b/src/common/BottomSheetWrapper.tsx index 01d9561d..1d71f2bf 100644 --- a/src/common/BottomSheetWrapper.tsx +++ b/src/common/BottomSheetWrapper.tsx @@ -2,24 +2,30 @@ import React from 'react'; import BottomSheet, { BottomSheetProps, } from '../../RN-UI-LIB/src/components/bottom_sheet/BottomSheet'; -import { sendBottomSheetOpenSignal } from '../components/utlis/DeviceUtils'; -import { NativeSyntheticEvent } from 'react-native'; +import { clearBottomSheet, setBottomSheetView } from '../components/utlis/DeviceUtils'; interface IBottomSheetWrapperProps extends BottomSheetProps {} const BottomSheetWrapper: React.FC = (props) => { const { children, onShow, onSwipeDownClose, onClose, ...restProps } = props; const onCloseHandler = () => { - sendBottomSheetOpenSignal(false); + clearBottomSheet(); + console.log('bottomSheet closed'); if (typeof onClose === 'function') onClose(); }; - const onShowHandler = (event: NativeSyntheticEvent) => { - sendBottomSheetOpenSignal(true); - if (typeof onShow === 'function') onShow(event); + const onAnimationEndHandler = (id: number | null) => { + if (!id) return; + console.log('bottomSheet closed'); + setBottomSheetView(id); }; return ( - + {children} ); diff --git a/src/common/DropDownWrapper.tsx b/src/common/DropDownWrapper.tsx index e3ba6f4b..4749d4a3 100644 --- a/src/common/DropDownWrapper.tsx +++ b/src/common/DropDownWrapper.tsx @@ -1,19 +1,28 @@ import React from 'react'; import Dropdown, { IDropdown } from '../../RN-UI-LIB/src/components/dropdown/Dropdown'; -import { sendBottomSheetOpenSignal } from '../components/utlis/DeviceUtils'; +import { + clearBottomSheet, + sendBottomSheetOpenSignal, + setBottomSheetView, +} from '../components/utlis/DeviceUtils'; const DropDownWrapper: React.FC = (props) => { - const { onShow, onClose, children, ...remainingProps } = props; - const onShowHandler = () => { - if (typeof onShow === 'function') onShow(); - sendBottomSheetOpenSignal(true); - }; + const { onShow, onClose, onAnimationEnd, children, ...remainingProps } = props; + const onCloseHandler = () => { if (typeof onClose === 'function') onClose(); - sendBottomSheetOpenSignal(false); + console.log('dropdown closed'); + clearBottomSheet(); }; + + const onAnimationEndHandler = (id: number | null) => { + if (!id) return; + console.log('dropdown opened', id); + setBottomSheetView(id); + }; + return ( - + {children} ); diff --git a/src/components/utlis/DeviceUtils.ts b/src/components/utlis/DeviceUtils.ts index 28ad745d..dacfb45a 100644 --- a/src/components/utlis/DeviceUtils.ts +++ b/src/components/utlis/DeviceUtils.ts @@ -29,6 +29,10 @@ export const alfredSetUserId = (userId: string) => DeviceUtilsModule.setUserId(u export const sendBottomSheetOpenSignal = (e: boolean) => DeviceUtilsModule.sendBottomSheetOpenSignal(e); +export const setBottomSheetView = (id: number | null) => DeviceUtilsModule.setBottomSheetView(id); + +export const clearBottomSheet = () => DeviceUtilsModule.clearBottomSheet(); + export const alfredSetEmailId = (emailId: string) => DeviceUtilsModule.setEmailId(emailId); // sends feedback data to whatsapp. From 2fb380040fddb6131fb9af792f97dec0ee8485ff Mon Sep 17 00:00:00 2001 From: "aman.singh" Date: Tue, 10 Oct 2023 17:44:34 +0530 Subject: [PATCH 04/32] alfred bottomsheet submodule update | Aman singh --- RN-UI-LIB | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RN-UI-LIB b/RN-UI-LIB index 89dff942..6f4a8cca 160000 --- a/RN-UI-LIB +++ b/RN-UI-LIB @@ -1 +1 @@ -Subproject commit 89dff942f5689b3f8c43be1f9f6d6d26c2001b85 +Subproject commit 6f4a8ccac185ed99e2f6f4c2c31521ac3c2c9800 From 20f989e51edefd539d41d23ecf4cf9e30b7514a0 Mon Sep 17 00:00:00 2001 From: ShriPrakashBajpai Date: Tue, 10 Oct 2023 18:25:14 +0530 Subject: [PATCH 05/32] Whatsapp business implemented with EMI amount --- android/app/src/main/AndroidManifest.xml | 1 + .../java/com/avapp/DeviceUtilsModule.java | 95 +++++++++++++------ src/components/utlis/commonFunctions.ts | 7 -- 3 files changed, 68 insertions(+), 35 deletions(-) diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index b6c2906d..463e9f52 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -35,6 +35,7 @@ + isWhatsAppInstalled() { PackageManager packageManager = RNContext.getPackageManager(); List packages = packageManager.getInstalledPackages(PackageManager.GET_META_DATA); + ArrayList appsInstalled = new ArrayList(); for (PackageInfo packageInfo : packages) { String packageName = packageInfo.packageName; - if(packageName.equals("com.whatsapp")){ - return true; + if(packageName.equals("com.whatsapp") || packageName.equals("com.whatsapp.w4b")){ + appsInstalled.add(packageName); } } - return false; + return appsInstalled; + } + + public Intent getWhatsappShareIntent(String message, String imageUrl, String mimeType, String packageName) { + Intent sendIntent = new Intent(); + sendIntent.setAction(Intent.ACTION_SEND); + sendIntent.putExtra(Intent.EXTRA_TEXT, message); + + if (imageUrl.equals("")) { + sendIntent.setType("text/plain"); + sendIntent.setPackage(packageName); + } else { + sendIntent.setType(mimeType); + sendIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + imageFile = convertBase64ToFile(getReactApplicationContext(), imageUrl); + Uri fileUri = FileProvider.getUriForFile(getReactApplicationContext(), BuildConfig.APPLICATION_ID + ".provider", new File( + Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), + imageFile.getName() + ) + ); + sendIntent.putExtra(Intent.EXTRA_STREAM, fileUri); + sendIntent.setPackage(packageName); + } + + return sendIntent; } @ReactMethod public void sendFeedbackToWhatsapp(String message, String imageUrl, String mimeType, Promise promise) { try{ - if(!isWhatsAppInstalled()){ + ArrayList appsInstalled = isWhatsAppInstalled(); + int numberOfAppsInstalled = appsInstalled.size(); + + if(numberOfAppsInstalled == 0){ promise.reject("errorCode", "1"); return; } - Intent sendIntent = new Intent(); - sendIntent.setAction(Intent.ACTION_SEND); - sendIntent.putExtra(Intent.EXTRA_TEXT, message); - - if(imageUrl.equals("")) { - sendIntent.setType("text/plain"); - sendIntent.setPackage("com.whatsapp"); - getCurrentActivity().startActivity(sendIntent); - } else { - sendIntent.setType(mimeType); - sendIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); - imageFile = convertBase64ToFile(getReactApplicationContext(), imageUrl); - Uri fileUri = FileProvider.getUriForFile(getReactApplicationContext(), BuildConfig.APPLICATION_ID + ".provider", new File( - Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), - imageFile.getName() - ) - ); - sendIntent.putExtra(Intent.EXTRA_STREAM, fileUri); - sendIntent.setPackage("com.whatsapp"); - getCurrentActivity().startActivityForResult(sendIntent, WHATSAPP_SHARE_REQUEST_CODE); + else if(numberOfAppsInstalled == 1) { + String packageName = appsInstalled.get(0); + Intent sendIntent = getWhatsappShareIntent(message, imageUrl, mimeType, packageName); + if(getCurrentActivity()!=null) { + getCurrentActivity().startActivityForResult(sendIntent, WHATSAPP_SHARE_REQUEST_CODE); + } + promise.resolve(true); + return; + } + + else { + String packageName1 = appsInstalled.get(0); + String packageName2 = appsInstalled.get(1); + //Firing two intents, one for WhatsApp, another for WhatsApp business + Intent sendIntent1 = getWhatsappShareIntent(message, imageUrl, mimeType, packageName1); + Intent sendIntent2 = getWhatsappShareIntent(message, imageUrl, mimeType, packageName2); + ArrayList appIntents = new ArrayList<>(); + appIntents.add(sendIntent1); + appIntents.add(sendIntent2); + + Intent defaultIntent = new Intent(android.content.Intent.ACTION_SEND); + defaultIntent.setType("text/plain"); + defaultIntent.putExtra(android.content.Intent.EXTRA_TEXT, "Sharing to WhatsApp"); + + Intent chooserIntent = Intent.createChooser(defaultIntent, "Share via"); + chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, appIntents.toArray(new Parcelable[appIntents.size()])); + if (getCurrentActivity() != null) { + getCurrentActivity().startActivityForResult(chooserIntent, WHATSAPP_SHARE_REQUEST_CODE); + } + promise.resolve(true); + return; } - promise.resolve(true); - return; } catch (Error e){ promise.reject("errorCode","2"); diff --git a/src/components/utlis/commonFunctions.ts b/src/components/utlis/commonFunctions.ts index 993f96cd..caf22894 100644 --- a/src/components/utlis/commonFunctions.ts +++ b/src/components/utlis/commonFunctions.ts @@ -368,10 +368,3 @@ export function getDistanceFromLatLonInKm( const distance = 2 * Math.atan2(Math.sqrt(intermediateResult), Math.sqrt(1 - intermediateResult)); return EARTH_RADIUS * distance; } - -export function insertCommasinAmount(amount: number | undefined) { - const reversedAmount = amount?.toString().split('').reverse().join(''); - const groups = reversedAmount?.match(/.{1,3}/g); - const result = groups?.join(',').split('').reverse().join(''); - return result; -} From 29527eb8f8ba0f8800f7d63f7627d720f961b059 Mon Sep 17 00:00:00 2001 From: "aman.singh" Date: Wed, 11 Oct 2023 14:34:24 +0530 Subject: [PATCH 06/32] modal for alfred to record| Aman singh --- src/common/ModalWrapperForAlfredV2.tsx | 46 ++++++++++++++++++++++++++ src/screens/allCases/CasesList.tsx | 5 +-- 2 files changed, 49 insertions(+), 2 deletions(-) create mode 100644 src/common/ModalWrapperForAlfredV2.tsx diff --git a/src/common/ModalWrapperForAlfredV2.tsx b/src/common/ModalWrapperForAlfredV2.tsx new file mode 100644 index 00000000..d1dbb46b --- /dev/null +++ b/src/common/ModalWrapperForAlfredV2.tsx @@ -0,0 +1,46 @@ +import React, { useEffect } from 'react'; +import { Modal, NativeSyntheticEvent, View, findNodeHandle } from 'react-native'; +import { IModalWrapper } from '../../RN-UI-LIB/src/components/modalWrapper/ModalWrapper'; +import { + clearBottomSheet, + sendBottomSheetOpenSignal, + setBottomSheetView, +} from '../components/utlis/DeviceUtils'; +import { GenericStyles } from '@rn-ui-lib/styles'; + +const ModalWrapperForAlfredV2: React.FC = ({ children, ...props }) => { + const { onRequestClose, onShow, visible } = props; + const modalRef = React.useRef(null); + const lastSent = React.useRef(visible); + const onRequestCloseHandler = (event: NativeSyntheticEvent) => { + if (typeof onRequestClose === 'function') onRequestClose(event); + clearBottomSheet(); + }; + const onShowHandler = (event: NativeSyntheticEvent) => { + if (typeof onShow === 'function') onShow(event); + const nodeId = findNodeHandle(modalRef.current); + console.log('nodeId from modal', nodeId); + lastSent.current = true; + setBottomSheetView(nodeId); + }; + + return ( + + + {children} + + + ); +}; + +export default ModalWrapperForAlfredV2; diff --git a/src/screens/allCases/CasesList.tsx b/src/screens/allCases/CasesList.tsx index 6d8ce2fd..4b50936b 100644 --- a/src/screens/allCases/CasesList.tsx +++ b/src/screens/allCases/CasesList.tsx @@ -56,6 +56,7 @@ import BottomSheetWrapper from '../../common/BottomSheetWrapper'; import { toast } from '../../../RN-UI-LIB/src/components/toast'; import { setFilteredListToast } from '../../reducer/allCasesSlice'; import { getFilterCount, getSelectedFilters } from '../Dashboard/utils'; +import ModalWrapperForAlfredV2 from '@common/ModalWrapperForAlfredV2'; export const getItem = (item: Array, index: number) => item[index]; export const ESTIMATED_ITEM_SIZE = 250; // Average height of List item @@ -354,7 +355,7 @@ const CasesList: React.FC = ({ {listEmptyComponent} )} - { @@ -370,7 +371,7 @@ const CasesList: React.FC = ({ isVisitPlan={isVisitPlan} isAgentDashboard={isAgentDashboard} /> - + ( From 941c8bc7c91585c81bf7664143c033c7ed620264 Mon Sep 17 00:00:00 2001 From: Girish Suragani Date: Wed, 11 Oct 2023 15:33:56 +0530 Subject: [PATCH 07/32] Updated bottomsheet version --- android/app/build.gradle | 2 +- .../java/com/avapp/DeviceUtilsModule.java | 27 ++++----- .../app/src/main/java/com/avapp/ViewShot.java | 58 ------------------- 3 files changed, 11 insertions(+), 76 deletions(-) delete mode 100644 android/app/src/main/java/com/avapp/ViewShot.java diff --git a/android/app/build.gradle b/android/app/build.gradle index c867af28..900a35af 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -314,7 +314,7 @@ dependencies { implementation "com.github.anrwatchdog:anrwatchdog:1.4.0" - implementation 'com.navi.medici:alfred:v1.0.1-20231009.124735-1' + implementation 'com.navi.medici:alfred:v1.0.2' //noinspection GradleDynamicVersion implementation "com.facebook.react:react-native:+" // From node_modules diff --git a/android/app/src/main/java/com/avapp/DeviceUtilsModule.java b/android/app/src/main/java/com/avapp/DeviceUtilsModule.java index e3656a9d..716897d7 100644 --- a/android/app/src/main/java/com/avapp/DeviceUtilsModule.java +++ b/android/app/src/main/java/com/avapp/DeviceUtilsModule.java @@ -156,37 +156,30 @@ public class DeviceUtilsModule extends ReactContextBaseJavaModule { } } - @ReactMethod public void setBottomSheetView(Integer refID) { if (refID != null) { UIManagerModule uiManagerModule = RNContext.getNativeModule(UIManagerModule.class); if (uiManagerModule != null) { - uiManagerModule.addUIBlock(nativeViewHierarchyManager -> { - Log.d("Alfred", "setBottomSheetView nativeViewHierarchyManager:" + nativeViewHierarchyManager); - View view = nativeViewHierarchyManager.resolveView(refID); - Log.d("Alfred", "setBottomSheetView view:" + view); - AlfredManager.INSTANCE.setBottomSheetView(view); - }); + try { + uiManagerModule.addUIBlock(nativeViewHierarchyManager -> { + Log.d("Alfred", "setBottomSheetView nativeViewHierarchyManager:" + nativeViewHierarchyManager); + View view = nativeViewHierarchyManager.resolveView(refID); + Log.d("Alfred", "setBottomSheetView view:" + view); + AlfredManager.INSTANCE.setBottomSheetView(view); + }); + } catch (Exception error) { + Log.d("Alfred", "setBottomSheetView error:" + error); + } } -// UIManagerModule uiManager = RNContext.getNativeModule(UIManagerModule.class); -// Executor executor = Executors.newCachedThreadPool(); -// uiManager.addUIBlock(new ViewShot(refID, RNContext, executor)); } - // AlfredManager.INSTANCE.clearBottomSheetView(); } - @ReactMethod public void clearBottomSheet() { AlfredManager.INSTANCE.clearBottomSheetView(); } - @ReactMethod - public void sendBottomSheetOpenSignal(Boolean isBottomSheetOpen) { - } - - private static File convertBase64ToFile(Context context,String base64Data) { try { byte[] decodedBytes = Base64.decode(base64Data, Base64.DEFAULT); diff --git a/android/app/src/main/java/com/avapp/ViewShot.java b/android/app/src/main/java/com/avapp/ViewShot.java deleted file mode 100644 index 63c16119..00000000 --- a/android/app/src/main/java/com/avapp/ViewShot.java +++ /dev/null @@ -1,58 +0,0 @@ -package com.avapp; - -import android.app.Activity; - -import android.util.Log; -import android.view.View; - -import com.facebook.react.bridge.Promise; -import com.facebook.react.bridge.ReactApplicationContext; -import com.facebook.react.uimanager.NativeViewHierarchyManager; -import com.facebook.react.uimanager.UIBlock; - -import java.util.concurrent.Executor; - -/** - * Snapshot utility class allow to screenshot a view. - */ -public class ViewShot implements UIBlock { - - private final int tag; - @SuppressWarnings({"unused", "FieldCanBeLocal"}) - private final ReactApplicationContext reactContext; - private final Executor executor; - - //region Constructors - @SuppressWarnings("WeakerAccess") - public ViewShot( - final int tag, - final ReactApplicationContext reactContext, - final Executor executor) { - this.tag = tag; - this.reactContext = reactContext; - this.executor = executor; - } - - @Override - public void execute(final NativeViewHierarchyManager nativeViewHierarchyManager) { - Log.d("Alfred", "ViewShot execute NativeViewHierarchyManager:" + nativeViewHierarchyManager + executor); - - executor.execute(new Runnable() { - @Override - public void run() { - try { - final View view; - view = nativeViewHierarchyManager.resolveView(tag); - - Log.d("Alfred", "Bottomsheet view: " + view); -// if (tag == -1) { -// view = currentActivity.getWindow().getDecorView().findViewById(android.R.id.content); -// } else { -// view = nativeViewHierarchyManager.resolveView(tag); -// } - } catch (final Throwable ex) { - } - } - }); - } -} \ No newline at end of file From 6e1a3bf5990b95cf61701f83e3b40578755b16a7 Mon Sep 17 00:00:00 2001 From: yashmantri Date: Wed, 11 Oct 2023 17:56:44 +0530 Subject: [PATCH 08/32] 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 09/32] 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 4e0059ec61c1b7dfdad8c33383e86d06aa8374b4 Mon Sep 17 00:00:00 2001 From: yashmantri Date: Thu, 12 Oct 2023 02:37:50 +0530 Subject: [PATCH 10/32] 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 11/32] 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 0be5350b001c1463d208534dfb0e9b524c35f076 Mon Sep 17 00:00:00 2001 From: yashmantri Date: Thu, 12 Oct 2023 15:40:17 +0530 Subject: [PATCH 12/32] 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 13/32] 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 83dc4a1c38b0969246ea64c5c5f78134f1c8060a Mon Sep 17 00:00:00 2001 From: Aman Chaturvedi Date: Thu, 12 Oct 2023 19:55:24 +0530 Subject: [PATCH 14/32] TP-0 | fix --- src/screens/caseDetails/feedback/FeedbackDetailItem.tsx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/screens/caseDetails/feedback/FeedbackDetailItem.tsx b/src/screens/caseDetails/feedback/FeedbackDetailItem.tsx index 967f4a51..033dd6e6 100644 --- a/src/screens/caseDetails/feedback/FeedbackDetailItem.tsx +++ b/src/screens/caseDetails/feedback/FeedbackDetailItem.tsx @@ -72,7 +72,12 @@ function getLocationLink(latitude: string, longitude: string): string { return link; } -const FeedbackDetailItem = ({ feedbackItem, isExpanded, caseId }: IFeedbackDetailItem) => { +const FeedbackDetailItem = ({ + feedbackItem, + isExpanded, + caseId, + hideAddress, +}: IFeedbackDetailItem) => { const caseDetails = useAppSelector((state) => state.allCases.caseDetails[caseId]); const { agentId } = useAppSelector((state) => ({ agentId: state.user.user?.referenceId!! })); const [isWhastappSendLoading, setIsWhatsappSendLoading] = useState(false); From 165aae292809d87ff61c302912059b0bdfff194a Mon Sep 17 00:00:00 2001 From: "aman.singh" Date: Thu, 12 Oct 2023 20:12:22 +0530 Subject: [PATCH 15/32] removed console and version bump| Aman singh --- android/app/build.gradle | 4 ++-- src/common/BottomSheetWrapper.tsx | 2 -- src/common/DropDownWrapper.tsx | 1 - src/common/ModalWrapperForAlfredV2.tsx | 1 - 4 files changed, 2 insertions(+), 6 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index c867af28..67a95caf 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -132,8 +132,8 @@ def reactNativeArchitectures() { } -def VERSION_CODE = 92 -def VERSION_NAME = "2.4.10" +def VERSION_CODE = 89 +def VERSION_NAME = "2.4.5" android { ndkVersion rootProject.ext.ndkVersion diff --git a/src/common/BottomSheetWrapper.tsx b/src/common/BottomSheetWrapper.tsx index 1d71f2bf..15ecb14c 100644 --- a/src/common/BottomSheetWrapper.tsx +++ b/src/common/BottomSheetWrapper.tsx @@ -10,13 +10,11 @@ const BottomSheetWrapper: React.FC = (props) => { const { children, onShow, onSwipeDownClose, onClose, ...restProps } = props; const onCloseHandler = () => { clearBottomSheet(); - console.log('bottomSheet closed'); if (typeof onClose === 'function') onClose(); }; const onAnimationEndHandler = (id: number | null) => { if (!id) return; - console.log('bottomSheet closed'); setBottomSheetView(id); }; return ( diff --git a/src/common/DropDownWrapper.tsx b/src/common/DropDownWrapper.tsx index 4749d4a3..97f20582 100644 --- a/src/common/DropDownWrapper.tsx +++ b/src/common/DropDownWrapper.tsx @@ -11,7 +11,6 @@ const DropDownWrapper: React.FC = (props) => { const onCloseHandler = () => { if (typeof onClose === 'function') onClose(); - console.log('dropdown closed'); clearBottomSheet(); }; diff --git a/src/common/ModalWrapperForAlfredV2.tsx b/src/common/ModalWrapperForAlfredV2.tsx index d1dbb46b..4577809f 100644 --- a/src/common/ModalWrapperForAlfredV2.tsx +++ b/src/common/ModalWrapperForAlfredV2.tsx @@ -19,7 +19,6 @@ const ModalWrapperForAlfredV2: React.FC = ({ children, ...props } const onShowHandler = (event: NativeSyntheticEvent) => { if (typeof onShow === 'function') onShow(event); const nodeId = findNodeHandle(modalRef.current); - console.log('nodeId from modal', nodeId); lastSent.current = true; setBottomSheetView(nodeId); }; From 982eb0c841a22a829ac70b7dcd3314f977008578 Mon Sep 17 00:00:00 2001 From: "aman.singh" Date: Thu, 12 Oct 2023 20:19:37 +0530 Subject: [PATCH 16/32] submodule update| Aman singh --- RN-UI-LIB | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RN-UI-LIB b/RN-UI-LIB index 6f4a8cca..9f4a3ae2 160000 --- a/RN-UI-LIB +++ b/RN-UI-LIB @@ -1 +1 @@ -Subproject commit 6f4a8ccac185ed99e2f6f4c2c31521ac3c2c9800 +Subproject commit 9f4a3ae2675e913bbbbe3326d49c52ab987b3339 From 5cd3b815c32d4c2c7291d65cebf7547260e5f42c Mon Sep 17 00:00:00 2001 From: "aman.singh" Date: Fri, 13 Oct 2023 12:43:21 +0530 Subject: [PATCH 17/32] device utlis| Aman singh --- android/app/src/main/java/com/avapp/DeviceUtilsModule.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/android/app/src/main/java/com/avapp/DeviceUtilsModule.java b/android/app/src/main/java/com/avapp/DeviceUtilsModule.java index ad4fd9fe..478a84f3 100644 --- a/android/app/src/main/java/com/avapp/DeviceUtilsModule.java +++ b/android/app/src/main/java/com/avapp/DeviceUtilsModule.java @@ -122,6 +122,10 @@ public class DeviceUtilsModule extends ReactContextBaseJavaModule { promise.reject(err); } } + + @ReactMethod + public void sendBottomSheetOpenSignal(Boolean isBottomSheetOpen) { + } @ReactMethod public void setUserId(String userId) { From d90c96fb1fe0692fb638cc5552dd2157958243ee Mon Sep 17 00:00:00 2001 From: Ashish Deo Date: Fri, 13 Oct 2023 19:18:27 +0530 Subject: [PATCH 18/32] Removed labelling (Common,Collection) of filters and limited Search Bar to selective filters only --- .../allCasesFilters/FiltersContainer.tsx | 50 +++++++++++-------- .../allCases/allCasesFilters/Interface.ts | 1 + src/screens/allCases/interface.ts | 1 + 3 files changed, 30 insertions(+), 22 deletions(-) diff --git a/src/components/screens/allCases/allCasesFilters/FiltersContainer.tsx b/src/components/screens/allCases/allCasesFilters/FiltersContainer.tsx index f2ad18f6..61144063 100644 --- a/src/components/screens/allCases/allCasesFilters/FiltersContainer.tsx +++ b/src/components/screens/allCases/allCasesFilters/FiltersContainer.tsx @@ -43,6 +43,7 @@ const FiltersContainer: React.FC = (props) => { filterKeys && filterKeys[filterGroupKeys[0]][0]) || '', + isSearchable: false, }); const [filterSearchString, setFilterSearchString] = React.useState(''); const dispatch = useAppDispatch(); @@ -133,19 +134,21 @@ const FiltersContainer: React.FC = (props) => { {filterGroupKeys.map((filterGroupKey) => ( <> - - - {filters[filterGroupKey].headerText} - - + {filterGroupKeys.length > 1 && ( + + + {filters[filterGroupKey].headerText} + + + )} {filterKeys[filterGroupKey].map((filterKey) => filters[filterGroupKey].filters[filterKey]?.visible !== false ? ( @@ -163,6 +166,7 @@ const FiltersContainer: React.FC = (props) => { setSelectedFilterKey({ filterGroup: filterGroupKey, filterKey, + isSearchable: filters[filterGroupKey].filters[filterKey]?.searchEnabled, }); setFilterSearchString(''); addClickstreamEvent(CLICKSTREAM_EVENT_NAMES.AV_FILTERS_TAB_CLICKED, { @@ -210,15 +214,17 @@ const FiltersContainer: React.FC = (props) => { {selectedFilterKey && ( <> - - } - placeholder="Search..." - defaultValue={filterSearchString} - onChangeText={handleOptionFilterChange} - testID="test_search" - /> - + {selectedFilterKey.isSearchable && ( + + } + placeholder="Search..." + defaultValue={filterSearchString} + onChangeText={handleOptionFilterChange} + testID="test_search" + /> + + )} Date: Mon, 16 Oct 2023 14:56:00 +0530 Subject: [PATCH 19/32] 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 20/32] 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 21/32] 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 22/32] 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 23/32] 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 8df3da24c08e3ae84f056a784e305843a15b957c Mon Sep 17 00:00:00 2001 From: Ashish Deo Date: Mon, 16 Oct 2023 19:24:13 +0530 Subject: [PATCH 24/32] Fixed default filter screen view --- .../screens/allCases/allCasesFilters/FiltersContainer.tsx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/components/screens/allCases/allCasesFilters/FiltersContainer.tsx b/src/components/screens/allCases/allCasesFilters/FiltersContainer.tsx index 61144063..7c493396 100644 --- a/src/components/screens/allCases/allCasesFilters/FiltersContainer.tsx +++ b/src/components/screens/allCases/allCasesFilters/FiltersContainer.tsx @@ -32,9 +32,14 @@ const FiltersContainer: React.FC = (props) => { React.useState>(selectedFilters); const filterGroupKeys = Object.keys(filters); const filterKeys: Record = {}; + filterGroupKeys.forEach((filterGroupKey) => { - filterKeys[filterGroupKey] = Object.keys(filters[filterGroupKey].filters); + const visibleFilters = Object.keys(filters[filterGroupKey].filters).filter((key) => { + if (filters[filterGroupKey].filters[key].visible) return key; + }); + filterKeys[filterGroupKey] = visibleFilters; }); + const [selectedFilterKey, setSelectedFilterKey] = React.useState({ filterGroup: (filterGroupKeys && filterGroupKeys.length > 0 && filterGroupKeys[0]) || '', filterKey: From 37611bc4f887650e214000924e12b30c6e76353f Mon Sep 17 00:00:00 2001 From: Ashish Deo Date: Tue, 17 Oct 2023 14:13:09 +0530 Subject: [PATCH 25/32] used optional chaining --- .../screens/allCases/allCasesFilters/FiltersContainer.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/screens/allCases/allCasesFilters/FiltersContainer.tsx b/src/components/screens/allCases/allCasesFilters/FiltersContainer.tsx index 7c493396..59f051a8 100644 --- a/src/components/screens/allCases/allCasesFilters/FiltersContainer.tsx +++ b/src/components/screens/allCases/allCasesFilters/FiltersContainer.tsx @@ -34,8 +34,8 @@ const FiltersContainer: React.FC = (props) => { const filterKeys: Record = {}; filterGroupKeys.forEach((filterGroupKey) => { - const visibleFilters = Object.keys(filters[filterGroupKey].filters).filter((key) => { - if (filters[filterGroupKey].filters[key].visible) return key; + const visibleFilters = Object.keys(filters?.[filterGroupKey]?.filters || {}).filter((key) => { + if (filters?.[filterGroupKey]?.filters?.[key]?.visible) return key; }); filterKeys[filterGroupKey] = visibleFilters; }); From 578528bd753126e5816c5e19cb0d9770ec4d2fde Mon Sep 17 00:00:00 2001 From: Ashish Deo Date: Tue, 17 Oct 2023 15:46:41 +0530 Subject: [PATCH 26/32] 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 27/32] 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 28/32] 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 29/32] 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 30/32] 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 31/32] 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 32/32] 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 ? (