Merge pull request #581 from navi-medici/feature/alfred_integration

Feature/alfred integration
This commit is contained in:
Mantri Ramkishor
2023-10-09 19:44:17 +05:30
committed by GitHub
37 changed files with 599 additions and 53 deletions

View File

@@ -146,6 +146,10 @@ android {
versionCode VERSION_CODE
versionName VERSION_NAME
buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString()
buildConfigField "string", "FLAVOR", '"'
buildConfigField "string", "BUILD_FLAVOR", '"'
buildConfigField "string", "APP_NAME", '"'
buildConfigField "string", "API_KEY", '"'
if (isNewArchitectureEnabled()) {
// We configure the CMake build only if you decide to opt-in for the New Architecture.
@@ -267,11 +271,49 @@ android {
}
}
flavorDimensions "env"
productFlavors {
fieldAgentsQA {
applicationId "com.avapp"
versionName VERSION_NAME
buildConfigField 'String', 'FLAVOR', '"fieldAgentsQa"'
buildConfigField 'String', 'BUILD_FLAVOR', '"qa"'
buildConfigField 'String', 'APP_NAME', '"COSMOS"'
buildConfigField 'String', 'API_KEY', '"Egsn144zdk4CZBZuhmDBMc4ytV7sLQ1C"'
}
fieldAgentsProd {
applicationId "com.avapp"
versionName VERSION_NAME
buildConfigField 'String', 'FLAVOR', '"fieldAgentsProd"'
buildConfigField 'String', 'BUILD_FLAVOR', '"prod"'
buildConfigField 'String', 'APP_NAME', '"COSMOS"'
buildConfigField 'String', 'API_KEY', '"tOScvaFFqRd0tKF2d8jnJu6oY6eSwtLA"'
}
callingAgentsQA {
applicationId "com.avapp"
versionName VERSION_NAME
buildConfigField 'String', 'FLAVOR', '"callingAgentsQA"'
buildConfigField 'String', 'BUILD_FLAVOR', '"qa"'
buildConfigField 'String', 'APP_NAME', '"COSMOS"'
buildConfigField 'String', 'API_KEY', '"Egsn144zdk4CZBZuhmDBMc4ytV7sLQ1C"'
}
callingAgentsProd {
applicationId "com.avapp"
versionName VERSION_NAME
buildConfigField 'String', 'FLAVOR', '"callingAgentsProd"'
buildConfigField 'String', 'BUILD_FLAVOR', '"prod"'
buildConfigField 'String', 'APP_NAME', '"COSMOS"'
buildConfigField 'String', 'API_KEY', '"tOScvaFFqRd0tKF2d8jnJu6oY6eSwtLA"'
}
}
}
dependencies {
implementation fileTree(dir: "libs", include: ["*.jar"])
implementation "com.github.anrwatchdog:anrwatchdog:1.4.0"
implementation 'com.navi.medici:alfred:v1.0.1'
//noinspection GradleDynamicVersion
implementation "com.facebook.react:react-native:+" // From node_modules
@@ -335,3 +377,4 @@ def isNewArchitectureEnabled() {
}
apply plugin: 'com.google.gms.google-services'

View File

@@ -8,4 +8,10 @@
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
-keep public class com.horcrux.svg.** {*;}
-keep public class com.horcrux.svg.** {*;}
#Alfred specific classes
-keep class com.navi.alfred.model.** { *; }
-keep class com.navi.alfred.network.model.** { *; }
-keep class com.navi.alfred.db.** { *; }
-keep class com.navi.alfred.AlfredConfig { *; }

View File

@@ -23,13 +23,13 @@
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" /> -> 10+
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<uses-permission android:name="android.permission.RECEIVE_WAP_PUSH" />
<uses-permission android:name="android.permission.POST_NOTIFICATION" />
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/> ->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />

View File

@@ -20,6 +20,9 @@ import com.facebook.react.bridge.Promise;
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.navi.alfred.AlfredManager;
import android.content.pm.PackageInfo;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
@@ -27,11 +30,16 @@ import android.os.Environment;
import android.os.Handler;
import android.util.Base64;
import android.os.Looper;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.HashMap;
import java.util.List;
import android.net.Uri;
@@ -77,7 +85,7 @@ public class DeviceUtilsModule extends ReactContextBaseJavaModule {
@ReactMethod
public void isLocationEnabled (Promise promise) {
public void isLocationEnabled(Promise promise) {
try {
LocationManager locationManager = (LocationManager) RNContext.getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
Boolean isEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
@@ -88,7 +96,7 @@ public class DeviceUtilsModule extends ReactContextBaseJavaModule {
}
@ReactMethod
public void getAllInstalledApp (Promise promise) {
public void getAllInstalledApp(Promise promise) {
try {
PackageManager packageManager = RNContext.getPackageManager();
List<PackageInfo> installedPackages = packageManager.getInstalledPackages(0);
@@ -97,18 +105,65 @@ public class DeviceUtilsModule extends ReactContextBaseJavaModule {
for (PackageInfo packageInfo : installedPackages) {
JSONObject mainObject = new JSONObject();
JSONObject appObject = new JSONObject();
appObject.put("appName",packageInfo.applicationInfo.processName);
appObject.put("appName", packageInfo.applicationInfo.processName);
appObject.put("firstInstallTime", packageInfo.firstInstallTime);
appObject.put("lastUpdateTime", packageInfo.lastUpdateTime);
mainObject.put("packageName", packageInfo.packageName);
mainObject.put("packageName", packageInfo.packageName);
mainObject.put("appDetails", appObject);
jsonArray.put(mainObject);
}
promise.resolve( jsonArray.toString());
}catch (Exception err){
promise.reject( err);
promise.resolve(jsonArray.toString());
} catch (Exception err) {
promise.reject(err);
}
}
@ReactMethod
public void setUserId(String userId) {
AlfredManager.config.setUserId(userId);
}
@ReactMethod
public void handleSWWEvent(String message, String stack, String name) { //<String, Object>
HashMap<String, String> properties = new HashMap<>();
properties.put("message", message);
properties.put("stack", stack);
properties.put("name", name);
AlfredManager.INSTANCE.handleSWWEvent("Cosmos", properties);
}
@ReactMethod
public void setCodePushVersion(String codePushVersion) {
if (codePushVersion != null) {
AlfredManager.config.setCodePushVersion(codePushVersion);
}
}
@ReactMethod
public void setPhoneNumber(String phoneNumber) {
if (phoneNumber != null) {
AlfredManager.config.setPhoneNumber(phoneNumber);
}
}
@ReactMethod
public void setEmailId(String emailId) {
if (emailId != null) {
AlfredManager.config.setAgentEmailId(emailId);
}
}
@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);

View File

@@ -3,12 +3,21 @@ package com.avapp;
import com.facebook.react.ReactActivity;
import com.facebook.react.ReactActivityDelegate;
import com.facebook.react.ReactRootView;
import com.navi.alfred.AlfredManager;
import com.navi.alfred.utils.UtilsKt;
import android.content.IntentFilter;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
public class MainActivity extends ReactActivity {
private static int appInForegroundCounter = 0;
private boolean cruiseApiCalled = false;
/**
* Returns the name of the main component registered from JavaScript. This is used to schedule
* rendering of the component.
@@ -53,4 +62,61 @@ public class MainActivity extends ReactActivity {
return BuildConfig.IS_NEW_ARCHITECTURE_ENABLED;
}
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
AlfredManager.INSTANCE.handleTouchEvent(ev, BuildConfig.APP_NAME, BuildConfig.APP_NAME);
return super.dispatchTouchEvent(ev);
}
@Override
protected void onStart() {
super.onStart();
appInForegroundCounter++;
}
@Override
protected void onResume() {
super.onResume();
if(!cruiseApiCalled) {
AlfredManager.INSTANCE.getAlfredCruiseInfo(() -> {
cruiseApiCalled = true;
if (AlfredManager.config != null && AlfredManager.config.getAlfredStatus() && AlfredManager.config.getEnableRecordingStatus()) {
try {
AlfredManager.INSTANCE.startRecording(this, this.getWindow().getDecorView().getRootView(), BuildConfig.APP_NAME, BuildConfig.APP_NAME, null);
} catch (Exception e) {
UtilsKt.log(e);
}
}
return null;
});
}
else {
if (AlfredManager.config != null && AlfredManager.config.getAlfredStatus() && AlfredManager.config.getEnableRecordingStatus()) {
try {
AlfredManager.INSTANCE.startRecording(this, this.getWindow().getDecorView().getRootView(), BuildConfig.APP_NAME, BuildConfig.APP_NAME, null);
} catch (Exception e) {
UtilsKt.log(e);
}
}
}
}
@Override
protected void onStop() {
super.onStop();
appInForegroundCounter--;
if (appInForegroundCounter == 0) {
if (AlfredManager.config != null && AlfredManager.config.getAlfredStatus() && AlfredManager.config.getEnableRecordingStatus()) {
View appBackgroundView = LayoutInflater.from(this).inflate(R.layout.app_background_screen, null);
AlfredManager.INSTANCE.measureInflatedView(appBackgroundView);
AlfredManager.INSTANCE.stopRecording(appBackgroundView);
}
}
}
public static Boolean isAppInForeground() {
return appInForegroundCounter >= 1;
}
}

View File

@@ -1,6 +1,10 @@
package com.avapp;
import static com.avapp.utils.Constants.APP_IN_FOREGROUND;
import static com.avapp.utils.Constants.LINE_NUMBER;
import static com.avapp.utils.Constants.METHOD_NAME;
import static com.avapp.utils.Constants.STACK_TRACE;
import static com.google.firebase.analytics.FirebaseAnalytics.Param.SCREEN_NAME;
import android.app.Application;
import android.content.Context;
@@ -13,12 +17,18 @@ import com.facebook.react.config.ReactFeatureFlags;
import com.facebook.soloader.SoLoader;
import com.avapp.newarchitecture.MainApplicationReactNativeHost;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.List;
import com.github.anrwatchdog.ANRWatchDog;
import com.microsoft.codepush.react.CodePush;
import com.navi.alfred.AlfredConfig;
import com.navi.alfred.AlfredManager;
import android.database.CursorWindow;
import android.view.LayoutInflater;
import android.view.View;
import java.lang.reflect.Field;
import java.util.Map;
public class MainApplication extends Application implements ReactApplication {
@@ -71,8 +81,59 @@ public class MainApplication extends Application implements ReactApplication {
SoLoader.init(this, /* native exopackage */ false);
initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
AlfredConfig alfredConfig = new AlfredConfig(BuildConfig.APP_NAME, String.valueOf(BuildConfig.VERSION_CODE), BuildConfig.VERSION_NAME, BuildConfig.BUILD_FLAVOR, BuildConfig.API_KEY);
AlfredManager.INSTANCE.init(alfredConfig, getApplicationContext());
new ANRWatchDog().setIgnoreDebugger(true).setReportMainThreadOnly().setANRListener(error -> {
if (error.getCause().getStackTrace().length == 0) {
return;
}
Map<String, String> anrEventProperties = new HashMap<>();
anrEventProperties.put(SCREEN_NAME, BuildConfig.APP_NAME);
anrEventProperties.put(METHOD_NAME, error.getCause().getStackTrace()[0].getMethodName());
anrEventProperties.put(LINE_NUMBER, String.valueOf(error.getCause().getStackTrace()[0].getLineNumber()));
anrEventProperties.put(APP_IN_FOREGROUND, MainActivity.isAppInForeground().toString());
if (AlfredManager.config.getAlfredStatus() && AlfredManager.config.getAnrEnableStatus()) {
anrEventProperties.put(STACK_TRACE, error.getCause().getStackTrace()[0].toString());
View anrView = LayoutInflater.from(getApplicationContext()).inflate(R.layout.anr_screen, null);
AlfredManager.INSTANCE.measureInflatedView(anrView);
AlfredManager.INSTANCE.handleAnrEvent(anrEventProperties, anrView, SCREEN_NAME);
}
}).start();
// Crash Reporting to backend
Thread.UncaughtExceptionHandler defaultHandler = Thread.getDefaultUncaughtExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler((thread, exception) -> {
if ((exception.getStackTrace() == null) || (exception.getStackTrace().length == 0)) {
if (defaultHandler != null) {
defaultHandler.uncaughtException(thread, exception);
}
return;
}
try {
Map<String, String> crashEventProperties = new HashMap<>();
crashEventProperties.put(SCREEN_NAME, BuildConfig.APP_NAME);
crashEventProperties.put(METHOD_NAME, exception.getStackTrace()[0].getMethodName());
crashEventProperties.put(LINE_NUMBER, String.valueOf(exception.getStackTrace()[0].getLineNumber()));
crashEventProperties.put(APP_IN_FOREGROUND, MainActivity.isAppInForeground().toString());
if ((AlfredManager.config.getAlfredStatus() && AlfredManager.config.getCrashEnableStatus())) {
StackTraceElement stackTraceElement = exception.getStackTrace()[0];
if (stackTraceElement != null) {
crashEventProperties.put(STACK_TRACE, stackTraceElement.toString());
}
View crashView = LayoutInflater.from(getApplicationContext()).inflate(R.layout.crash_screen, null);
AlfredManager.INSTANCE.measureInflatedView(crashView);
AlfredManager.INSTANCE.handleCrashEvent(crashEventProperties, crashView.getRootView(), BuildConfig.APP_NAME);
}
} finally {
if (defaultHandler != null) {
defaultHandler.uncaughtException(thread, exception);
}
}
});
// https://github.com/rt2zz/redux-persist/issues/284#issuecomment-1011214066
try {

View File

@@ -0,0 +1,9 @@
package com.avapp.utils;
public class Constants {
public static final String SCREEN_NAME = "screen_name";
public static final String METHOD_NAME = "method_name";
public static final String LINE_NUMBER = "line_number";
public static final String APP_IN_FOREGROUND = "app_in_foreground";
public static final String STACK_TRACE = "STACK_TRACE";
}

View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white"
xmlns:app="http://schemas.android.com/apk/res-auto">
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/tv_anr"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/anr_occurred"
android:textColor="@color/black"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white"
xmlns:app="http://schemas.android.com/apk/res-auto">
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/tv_app_background"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/app_in_background"
android:textColor="@color/black"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white">
<View
android:layout_width="match_parent"
android:layout_height="5dp"
android:background="@color/black"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/tv_bottom_sheet"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/bottom_sheet_overlay"
android:textColor="@color/black"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white"
xmlns:app="http://schemas.android.com/apk/res-auto">
<TextView
android:id="@+id/tv_crash"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/crash_occurred"
android:textColor="@color/black"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -3,4 +3,9 @@
<string name="appCenterCrashes_whenToSendCrashes" moduleConfig="true" translatable="false">DO_NOT_ASK_JAVASCRIPT</string>
<string name="appCenterAnalytics_whenToEnableAnalytics" moduleConfig="true" translatable="false">ALWAYS_SEND</string>
<string moduleConfig="true" name="CodePushDeploymentKey">pastethekeyhere</string>
<string name="bottom_sheet_overlay">Bottom Sheet Overlay</string>
<string name="something_went_wrong">Something Went Wrong</string>
<string name="crash_occurred">Crash Occurred</string>
<string name="app_in_background">App In Background</string>
<string name="anr_occurred">Anr Occurred</string>
</resources>

View File

@@ -42,6 +42,20 @@ allprojects {
// Android JSC is installed from npm
url("$rootDir/../node_modules/jsc-android/dist")
}
maven {
url 'https://nexus.cmd.navi-tech.in/repository/maven-snapshots'
credentials {
username 'nexus-user'
password 'nexus-user'
}
}
maven {
url 'https://nexus.cmd.navi-tech.in/repository/maven-releases'
credentials {
username 'nexus-user'
password 'nexus-user'
}
}
mavenCentral {
// We don't want to fetch react-native from Maven Central as there are
// older versions over there.

View File

@@ -6,6 +6,18 @@
"android:dev": "yarn move:dev && react-native run-android",
"android:qa": "yarn move:qa && react-native run-android",
"android:prod": "yarn move:prod && react-native run-android",
"android-field:dev": "yarn move:dev && react-native run-android --variant=fieldAgentsQADebug",
"android-field:qa": "yarn move:qa && react-native run-android --variant=fieldAgentsQADebug",
"android-field:prod": "yarn move:prod && react-native run-android --variant=fieldAgentsQADebug",
"release-field:dev": "yarn move:dev && react-native run-android --variant=fieldAgentsQARelease && cd android && ./gradlew assemblefieldAgentsQARelease",
"release-field:qa": "yarn move:qa && react-native run-android --variant=fieldAgentsQARelease && cd android && ./gradlew assemblefieldAgentsQARelease",
"release-field:prod": "yarn move:prod && react-native run-android --variant=fieldAgentsProdRelease && cd android && ./gradlew assemblefieldAgentsProdRelease",
"android-calling:dev": "yarn move:dev && react-native run-android --variant=callingAgentsQADebug",
"android-calling:qa": "yarn move:qa && react-native run-android --variant=callingAgentsQADebug",
"android-calling:prod": "yarn move:prod && react-native run-android --variant=callingAgentsQADebug",
"release-calling:dev": "yarn move:dev && react-native run-android --variant=callingAgentsQARelease && cd android && ./gradlew assemblecallingAgentsQARelease",
"release-calling:qa": "yarn move:qa && react-native run-android --variant=callingAgentsQARelease && cd android && ./gradlew assemblecallingAgentsQARelease",
"release-calling:prod": "yarn move:dev && react-native run-android --variant=callingAgentsProdRelease && cd android && ./gradlew assemblecallingAgentsProdRelease",
"ios": "react-native run-ios",
"start": "react-native start",
"test": "jest",

View File

@@ -0,0 +1,28 @@
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';
interface IBottomSheetWrapperProps extends BottomSheetProps {}
const BottomSheetWrapper: React.FC<IBottomSheetWrapperProps> = (props) => {
const { children, onShow, onSwipeDownClose, onClose, ...restProps } = props;
const onCloseHandler = () => {
sendBottomSheetOpenSignal(false);
if (typeof onClose === 'function') onClose();
};
const onShowHandler = (event: NativeSyntheticEvent<any>) => {
sendBottomSheetOpenSignal(true);
if (typeof onShow === 'function') onShow(event);
};
return (
<BottomSheet onShow={onShowHandler} onClose={onCloseHandler} {...restProps}>
{children}
</BottomSheet>
);
};
export default BottomSheetWrapper;

View File

@@ -0,0 +1,22 @@
import React from 'react';
import Dropdown, { IDropdown } from '../../RN-UI-LIB/src/components/dropdown/Dropdown';
import { sendBottomSheetOpenSignal } from '../components/utlis/DeviceUtils';
const DropDownWrapper: React.FC<IDropdown> = (props) => {
const { onShow, onClose, children, ...remainingProps } = props;
const onShowHandler = () => {
if (typeof onShow === 'function') onShow();
sendBottomSheetOpenSignal(true);
};
const onCloseHandler = () => {
if (typeof onClose === 'function') onClose();
sendBottomSheetOpenSignal(false);
};
return (
<Dropdown onShow={onShowHandler} onClose={onCloseHandler} {...remainingProps}>
{children}
</Dropdown>
);
};
export default DropDownWrapper;

View File

@@ -9,6 +9,7 @@ import VersionNumber from 'react-native-version-number';
import Text from '../../RN-UI-LIB/src/components/Text';
import { getAppVersion } from '../components/utlis/commonFunctions';
import { COLORS } from '../../RN-UI-LIB/src/styles/colors';
import { alfredHandleSWWEvent } from '../components/utlis/DeviceUtils';
interface IErrorBoundary {
children?: ReactNode;
@@ -30,6 +31,7 @@ class ErrorBoundary extends Component<IErrorBoundary, IErrorBoundaryState> {
});
addClickstreamEvent(CLICKSTREAM_EVENT_NAMES.AV_ERROR_PAGE_LOADED, { error });
logError(error);
alfredHandleSWWEvent(error);
}
render() {

View File

@@ -0,0 +1,26 @@
import React, { useEffect } from 'react';
import FullScreenLoader, {
IFullScreenLoader,
} from '../../RN-UI-LIB/src/components/FullScreenLoader';
import { sendBottomSheetOpenSignal } from '../components/utlis/DeviceUtils';
const FullScreenLoaderWrapper: React.FC<IFullScreenLoader> = (props) => {
const { loading, onShow, isTranslucent = true } = props;
useEffect(() => {
if (loading) sendBottomSheetOpenSignal(true);
if (!loading) sendBottomSheetOpenSignal(false);
return () => {
sendBottomSheetOpenSignal(false);
};
}, [loading]);
const onShowHandler = () => {
sendBottomSheetOpenSignal(true);
if (typeof onShow === 'function') onShow();
};
return <FullScreenLoader onShow={onShow} loading={loading} isTranslucent={isTranslucent} />;
};
export default FullScreenLoaderWrapper;

View File

@@ -0,0 +1,32 @@
import React, { useEffect } from 'react';
import { NativeSyntheticEvent } from 'react-native';
import ModalWrapper, {
IModalWrapper,
} from '../../RN-UI-LIB/src/components/modalWrapper/ModalWrapper';
import { sendBottomSheetOpenSignal } from '../components/utlis/DeviceUtils';
const ModalWrapperForAlfred: React.FC<IModalWrapper> = ({ children, ...props }) => {
const { onRequestClose, onShow, visible } = props;
const lastSent = React.useRef(visible);
const onRequestCloseHandler = (event: NativeSyntheticEvent<any>) => {
if (typeof onRequestClose === 'function') onRequestClose(event);
sendBottomSheetOpenSignal(false);
};
const onShowHandler = (event: NativeSyntheticEvent<any>) => {
if (typeof onShow === 'function') onShow(event);
lastSent.current = true;
sendBottomSheetOpenSignal(true);
};
useEffect(() => {
if (lastSent.current === visible) return;
if (typeof visible === 'boolean') sendBottomSheetOpenSignal(visible);
}, [visible]);
return (
<ModalWrapper onShow={onShowHandler} onRequestClose={onRequestCloseHandler} {...props}>
{children}
</ModalWrapper>
);
};
export default ModalWrapperForAlfred;

View File

@@ -11,6 +11,7 @@ import Button from '../../../RN-UI-LIB/src/components/Button';
import { addClickstreamEvent } from '../../services/clickstreamEventService';
import { CLICKSTREAM_EVENT_NAMES } from '../../common/Constants';
import WarningIcon from '../../../RN-UI-LIB/src/Icons/WarningIcon';
import BottomSheetWrapper from '../../common/BottomSheetWrapper';
interface INudgeSuspiciousFeedbackBottomSheet {
caseId: string;
@@ -43,7 +44,7 @@ const NudgeSuspiciousFeedbackBottomSheet: React.FC<INudgeSuspiciousFeedbackBotto
};
return (
<BottomSheet
<BottomSheetWrapper
heightPercentage={height(4.5)}
visible={openBottomSheet}
HeaderNode={() => (
@@ -75,7 +76,7 @@ const NudgeSuspiciousFeedbackBottomSheet: React.FC<INudgeSuspiciousFeedbackBotto
testID={'test_submit_anyway_btn'}
/>
</View>
</BottomSheet>
</BottomSheetWrapper>
);
};

View File

@@ -16,6 +16,7 @@ import { CLICKSTREAM_EVENT_NAMES } from '../../../common/Constants';
import { isQuestionMandatory, validateInput } from '../services/validation.service';
import { CaseAllocationType } from '../../../screens/allCases/interface';
import { getDynamicBottomSheetHeightPercentageFn } from '../../utlis/commonFunctions';
import DropDownWrapper from '../../../common/DropDownWrapper';
interface IDropDown {
questionType: string;
@@ -92,7 +93,7 @@ const DropDown: React.FC<IDropDown> = (props) => {
control={props.control}
rules={{ validate: (data) => validateInput(data, question.metadata.validators) }}
render={({ field: { onChange, value } }) => (
<RNDropDown
<DropDownWrapper
header={question.metadata?.placeholder}
bottomSheetHeight={getBottomSheetHeight(question.options.length)}
onValueChange={(change) => handleChange(change, onChange)}
@@ -103,7 +104,7 @@ const DropDown: React.FC<IDropDown> = (props) => {
{question.options.map((option: keyof typeof options) => {
return <RNOptions id={option as string} label={options[option]?.text} />;
})}
</RNDropDown>
</DropDownWrapper>
)}
name={`widgetContext.${widgetId}.sectionContext.${props.sectionId}.questionContext.${questionId}`}
/>

View File

@@ -8,6 +8,29 @@ export const locationEnabled = (): Promise<boolean> => DeviceUtilsModule.isLocat
// returns array of all the installed packages.
export const getAllInstalledApp = (): Promise<string> => DeviceUtilsModule.getAllInstalledApp();
export const alfredHandleSWWEvent = (error: Error) => {
const { message = '', stack = '', name = '' } = error;
DeviceUtilsModule.handleSWWEvent(message, stack, name);
};
export const handleCrash = () => DeviceUtilsModule.handleCrash();
export const handleANR = () => DeviceUtilsModule.handleANR();
export const alfredSetPhoneNumber = (phoneNumber: string) =>
DeviceUtilsModule.setPhoneNumber(phoneNumber);
export const alfredSetCodePushVersion = (codePushVersion: string) =>
DeviceUtilsModule.setCodePushVersion(codePushVersion);
export const alfredSetUserId = (userId: string) => DeviceUtilsModule.setUserId(userId);
export const sendBottomSheetOpenSignal = (e: boolean) =>
DeviceUtilsModule.sendBottomSheetOpenSignal(e);
export const alfredSetEmailId = (emailId: string) => DeviceUtilsModule.setEmailId(emailId);
// sends feedback data to whatsapp.
export const sendFeedbackToWhatsapp = (
message: string,

View File

@@ -15,6 +15,7 @@ import {
REQUEST_TYPE_TO_BLOCK_FOR_IMPERSONATION,
} from '../../common/Constants';
import { ToastMessages } from '../../screens/allCases/constants';
import { alfredHandleSWWEvent } from './DeviceUtils';
export enum ApiKeys {
GENERATE_OTP = 'GENERATE_OTP',
@@ -215,6 +216,7 @@ axiosInstance.interceptors.response.use(
});
}
const { config, response } = error;
alfredHandleSWWEvent(new Error(JSON.stringify(response ?? '{}')));
logError(error as Error, config?.baseURL + config?.url);
const start = response.config.headers['request-start-time'];
const end = Date.now();

View File

@@ -10,6 +10,7 @@ import { COLORS } from '../../../RN-UI-LIB/src/styles/colors';
import ReviewIDImage from './ReviewIDImage';
import { useAppDispatch, useAppSelector } from '../../hooks';
import { setImageUri, setShowReviewImageModal } from '../../reducer/profileSlice';
import ModalWrapperForAlfred from '../../common/ModalWrapperForAlfred';
const IDCardImageCapture = () => {
const { imageUri, showReviewImageModal } = useAppSelector((state) => state.profile);
@@ -82,13 +83,13 @@ const IDCardImageCapture = () => {
</View>
</View>
</TouchableOpacity>
<Modal visible={showReviewImageModal} onRequestClose={toggleReviewImageModal}>
<ModalWrapperForAlfred visible={showReviewImageModal} onRequestClose={toggleReviewImageModal}>
<ReviewIDImage
closeModal={handleCloseModal}
imageUri={imageUri}
retakeImage={handleImageCapture}
/>
</Modal>
</ModalWrapperForAlfred>
</View>
);
};

View File

@@ -14,6 +14,7 @@ import DropdownItem from '../registerPayements/DropdownItem';
import { getDynamicBottomSheetHeightPercentageFn } from '../../components/utlis/commonFunctions';
import { addNewNumberApi } from './apiHelper';
import { useAppSelector } from '../../hooks';
import DropDownWrapper from '../../common/DropDownWrapper';
interface IAddNewNumber {
number: string;
@@ -130,7 +131,7 @@ const AddNewNumber: React.FC<IAddNewNumber> = (props) => {
<Controller
control={control}
render={({ field: { onChange, onBlur, value } }) => (
<Dropdown
<DropDownWrapper
placeholder="Select"
onValueChange={(number) => {
onChange(number);
@@ -141,7 +142,7 @@ const AddNewNumber: React.FC<IAddNewNumber> = (props) => {
value={value ?? ''}
>
{SourceChildComponents}
</Dropdown>
</DropDownWrapper>
)}
name="source"
rules={{ required: true }}
@@ -154,7 +155,7 @@ const AddNewNumber: React.FC<IAddNewNumber> = (props) => {
<Controller
control={control}
render={({ field: { onChange, onBlur, value } }) => (
<Dropdown
<DropDownWrapper
placeholder="Select"
onValueChange={(number) => {
onChange(number);
@@ -165,7 +166,7 @@ const AddNewNumber: React.FC<IAddNewNumber> = (props) => {
value={value ?? ''}
>
{TagChildComponents}
</Dropdown>
</DropDownWrapper>
)}
name="tag"
rules={{ required: true }}

View File

@@ -8,6 +8,7 @@ import {
Pressable,
StyleSheet,
View,
findNodeHandle,
} from 'react-native';
import { GenericStyles, SCREEN_HEIGHT, SCREEN_WIDTH } from '../../../RN-UI-LIB/src/styles';
import { COLORS } from '../../../RN-UI-LIB/src/styles/colors';
@@ -43,6 +44,7 @@ import { FlashList } from '@shopify/flash-list';
import { VisitPlanStatus } from '../../reducer/userSlice';
import { getAttemptedList, getNonAttemptedList } from './utils';
import { GenericType } from '../../common/GenericTypes';
import ModalWrapperForAlfred from '../../common/ModalWrapperForAlfred';
import Text from '../../../RN-UI-LIB/src/components/Text';
import BottomSheet from '../../../RN-UI-LIB/src/components/bottom_sheet/BottomSheet';
import Heading from '../../../RN-UI-LIB/src/components/Heading';
@@ -50,6 +52,7 @@ import { row } from '../emiSchedule/constants';
import CloseIcon from '../../../RN-UI-LIB/src/Icons/CloseIcon';
import AgentsListContainer from './AgentsListContainer';
import { setShowAgentSelectionBottomSheet } from '../../reducer/reporteesSlice';
import BottomSheetWrapper from '../../common/BottomSheetWrapper';
export const getItem = (item: Array<ICaseItem>, index: number) => item[index];
export const ESTIMATED_ITEM_SIZE = 250; // Average height of List item
@@ -94,7 +97,6 @@ const CasesList: React.FC<ICasesList> = ({ casesList = [], isVisitPlan, allCases
const [showFilterModal, setShowFilterModal] = React.useState<boolean>(false);
const flashListRef = useRef<GenericType>(null);
const scrollAnimation = useRef(new Animated.Value(0)).current;
const firePageLoadEvent = () => {
@@ -322,7 +324,7 @@ const CasesList: React.FC<ICasesList> = ({ casesList = [], isVisitPlan, allCases
<View style={GenericStyles.ph12}>{listEmptyComponent}</View>
)}
</View>
<Modal
<ModalWrapperForAlfred
animationType="slide"
animated
onRequestClose={() => {
@@ -337,8 +339,8 @@ const CasesList: React.FC<ICasesList> = ({ casesList = [], isVisitPlan, allCases
}}
isVisitPlan={isVisitPlan}
/>
</Modal>
<BottomSheet
</ModalWrapperForAlfred>
<BottomSheetWrapper
HeaderNode={() => (
<View style={[...row, GenericStyles.ph16]}>
<Heading dark type="h4">
@@ -357,7 +359,7 @@ const CasesList: React.FC<ICasesList> = ({ casesList = [], isVisitPlan, allCases
<View style={[GenericStyles.mt16, GenericStyles.fill]}>
<AgentsListContainer showAgentSelectionBottomSheet={showAgentSelectionBottomSheet} />
</View>
</BottomSheet>
</BottomSheetWrapper>
</View>
);
};

View File

@@ -4,6 +4,7 @@ import { SafeAreaView } from 'react-native-safe-area-context';
import Text from '../../../RN-UI-LIB/src/components/Text';
import { COLORS } from '../../../RN-UI-LIB/src/styles/colors';
import OnboardingModal from './OnboardingModal';
import ModalWrapperForAlfred from '../../common/ModalWrapperForAlfred';
const LearnTodoBanner = () => {
const [showOnboarding, setShowOnboarding] = useState(false);
@@ -20,9 +21,9 @@ const LearnTodoBanner = () => {
Watch video
</Text>
</Text>
<Modal visible={showOnboarding} onRequestClose={toggleOnboarding}>
<ModalWrapperForAlfred visible={showOnboarding} onRequestClose={toggleOnboarding}>
<OnboardingModal closeModal={toggleOnboarding} />
</Modal>
</ModalWrapperForAlfred>
</>
);
};

View File

@@ -22,6 +22,7 @@ import { addClickstreamEvent } from '@services/clickstreamEventService';
import { CLICKSTREAM_EVENT_NAMES } from '@common/Constants';
import { BOTTOM_TAB_ROUTES } from './constants';
import { getSelfieDocument } from '@actions/profileActions';
import FullScreenLoaderWrapper from '@common/FullScreenLoaderWrapper';
const AllCasesMain = () => {
const { pendingList, pinnedList, completedList, loading } = useAppSelector(
@@ -76,7 +77,7 @@ const AllCasesMain = () => {
return (
<Layout>
<FullScreenLoader loading={loading} />
<FullScreenLoaderWrapper loading={loading} />
<BottomNavigator
screens={HOME_SCREENS}
initialRoute={isTeamLead ? BOTTOM_TAB_ROUTES.Cases : BOTTOM_TAB_ROUTES.VisitPlan}

View File

@@ -1,4 +1,4 @@
import { Linking, StyleSheet } from 'react-native';
import { AppState, Linking, StyleSheet } from 'react-native';
import React, { useEffect } from 'react';
import { useAppDispatch } from '../../hooks';
import { useSelector } from 'react-redux';
@@ -15,6 +15,14 @@ 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 {
alfredSetCodePushVersion,
alfredSetEmailId,
alfredSetPhoneNumber,
alfredSetUserId,
} from '../../components/utlis/DeviceUtils';
import { getAppVersion, getPhoneNumberString } from '../../components/utlis/commonFunctions';
import AnswerRender from '../../components/form/AnswerRender';
import useScreenshotTracking from '../../hooks/useScreenshotTracking';
const AuthRouter = () => {
@@ -30,6 +38,35 @@ const AuthRouter = () => {
}
}, []);
useEffect(() => {
const appStateChange = AppState.addEventListener('change', async (change) => {
if (change !== 'active') return;
if (isLoggedIn && user.user && user.user.referenceId) {
alfredSetUserId(user.user?.referenceId);
alfredSetPhoneNumber(user?.user?.phoneNumber);
// user.user.emailId
alfredSetEmailId(user.user?.emailId ?? '');
} else {
alfredSetUserId(deviceId);
}
alfredSetCodePushVersion(getAppVersion());
});
return () => {
appStateChange.remove();
};
}, [user]);
useEffect(() => {
if (isLoggedIn && user.user && user.user.referenceId) {
alfredSetUserId(user.user?.referenceId);
alfredSetPhoneNumber(user?.user?.phoneNumber);
alfredSetEmailId(user?.user?.emailId ?? '');
} else {
alfredSetUserId(deviceId);
}
alfredSetCodePushVersion(getAppVersion());
}, []);
// for setting user token in global.ts for api calling's
setGlobalUserData({
token: sessionDetails?.sessionToken,

View File

@@ -8,6 +8,7 @@ import { IAnswerView } from '../../../types/feedback.types';
import { COLORS } from '../../../../RN-UI-LIB/src/styles/colors';
import { getQuestionText } from './FeedbackDetailAnswerContainer';
import ExpandableImage from '../../../components/expandableImage/ExpandableImage';
import ModalWrapperForAlfred from '../../../common/ModalWrapperForAlfred';
interface IFeedbackDetailImageItem {
image: IAnswerView;
@@ -47,7 +48,7 @@ const FeedbackDetailImageItem: React.FC<IFeedbackDetailImageItem> = ({ image })
onPress={handleExpandImage}
/>
</TouchableOpacity>
<Modal
<ModalWrapperForAlfred
visible={isImageExpanded}
transparent
onRequestClose={handleExpandedImageClose}
@@ -59,7 +60,7 @@ const FeedbackDetailImageItem: React.FC<IFeedbackDetailImageItem> = ({ image })
title={questionText}
close={handleExpandedImageClose}
/>
</Modal>
</ModalWrapperForAlfred>
</View>
);
};

View File

@@ -11,6 +11,7 @@ import React, { useEffect } from 'react';
import { addClickstreamEvent } from '../../../services/clickstreamEventService';
import { CLICKSTREAM_EVENT_NAMES, WhatsAppText } from '../../../common/Constants';
import BackArrowIcon from '../../../../RN-UI-LIB/src/Icons/BackArrowIcon';
import BottomSheetWrapper from '../../../common/BottomSheetWrapper';
interface CallingBottomSheetProps {
selectedPhoneNumber: string;
@@ -63,7 +64,7 @@ const CallingBottomSheet: React.FC<CallingBottomSheetProps> = (props) => {
};
return (
<BottomSheet
<BottomSheetWrapper
heightPercentage={30}
visible={showCallingBottomSheet}
HeaderNode={() => (
@@ -76,7 +77,7 @@ const CallingBottomSheet: React.FC<CallingBottomSheetProps> = (props) => {
]}
>
<View style={[GenericStyles.row, GenericStyles.alignCenter]}>
{setShowPhoneBottomSheet && (
{/* {setShowPhoneBottomSheet && (
<TouchableOpacity
activeOpacity={0.7}
style={GenericStyles.mr16}
@@ -84,7 +85,7 @@ const CallingBottomSheet: React.FC<CallingBottomSheetProps> = (props) => {
>
<BackArrowIcon />
</TouchableOpacity>
)}
)} */}
<Heading dark type="h4">
Call {selectedPhoneNumber} Via
@@ -119,7 +120,7 @@ const CallingBottomSheet: React.FC<CallingBottomSheetProps> = (props) => {
<IconLabel text="Whats App" icon={<WhatsAppIcon />} />
</TouchableOpacity>
</View>
</BottomSheet>
</BottomSheetWrapper>
);
};

View File

@@ -16,6 +16,7 @@ import {
import Button from '../../../../RN-UI-LIB/src/components/Button';
import RenderIcons from './RenderIcon';
import { toastConfigs, ToastContainer } from '../../../../RN-UI-LIB/src/components/toast';
import BottomSheetWrapper from '../../../common/BottomSheetWrapper';
interface PhoneNumberSelectionBottomSheetProps {
showPhoneNumberBottomSheet: boolean;
@@ -35,7 +36,7 @@ const PhoneNumberSelectionBottomSheet: React.FC<PhoneNumberSelectionBottomSheetP
const getBottomSheetHeight = getDynamicBottomSheetHeightPercentageFn(100, 70);
return (
<BottomSheet
<BottomSheetWrapper
heightPercentage={getBottomSheetHeight(mobileNumbers?.length)}
visible={showPhoneNumberBottomSheet}
HeaderNode={() => (
@@ -75,7 +76,7 @@ const PhoneNumberSelectionBottomSheet: React.FC<PhoneNumberSelectionBottomSheetP
})}
</ScrollView>
<ToastContainer config={toastConfigs} position="top" />
</BottomSheet>
</BottomSheetWrapper>
);
};

View File

@@ -11,6 +11,7 @@ import { IEmiItem } from './EmiScheduleItem';
import { formatAmount } from '../../../RN-UI-LIB/src/utlis/amount';
import { getNumberWithRankSuffix } from '../../../RN-UI-LIB/src/utlis/common';
import { getDynamicBottomSheetHeightPercentageFn } from '../../components/utlis/commonFunctions';
import BottomSheetWrapper from '../../common/BottomSheetWrapper';
interface IEmiBreakupBottomSheet {
openBottomSheet: boolean;
@@ -31,7 +32,7 @@ const EmiBreakupBottomSheet: React.FC<IEmiBreakupBottomSheet> = (props) => {
} = props;
const height = getDynamicBottomSheetHeightPercentageFn();
return (
<BottomSheet
<BottomSheetWrapper
heightPercentage={height(3)}
visible={openBottomSheet}
HeaderNode={() => (
@@ -41,9 +42,9 @@ const EmiBreakupBottomSheet: React.FC<IEmiBreakupBottomSheet> = (props) => {
? `${getNumberWithRankSuffix(listNumber)} EMI breakup`
: 'Total due breakup'}
</Heading>
<TouchableOpacity activeOpacity={0.7} onPress={() => setOpenBottomSheet((prev) => !prev)}>
{/* <TouchableOpacity activeOpacity={0.7} onPress={() => setOpenBottomSheet((prev) => !prev)}>
<CloseIcon color={COLORS.TEXT.LIGHT} />
</TouchableOpacity>
</TouchableOpacity> */}
</View>
)}
setVisible={() => setOpenBottomSheet((prev) => !prev)}
@@ -67,7 +68,7 @@ const EmiBreakupBottomSheet: React.FC<IEmiBreakupBottomSheet> = (props) => {
<Text style={{ color: COLORS.TEXT.RED }}>{formatAmount(totalOverDueAmount)}</Text>
</View>
</View>
</BottomSheet>
</BottomSheetWrapper>
);
};

View File

@@ -32,6 +32,7 @@ import Chevron from '../../../RN-UI-LIB/src/Icons/Chevron';
import FloatingInfoText from '../../components/floatingInfoText';
import ForeclosureBottomSheet from './ForeclosureBottomSheet';
import ForeclosureBreakupAccordion, { IForeclosureBreakup } from './ForeclosureBreakupAccordion';
import DropDownWrapper from '../../common/DropDownWrapper';
interface IForeclosure {
caseId: string;
@@ -183,7 +184,7 @@ const Foreclosure: React.FC<IForeclosure> = ({ caseId, numbers, primaryPhoneNumb
<Controller
control={control}
render={({ field: { value } }) => (
<Dropdown
<DropDownWrapper
placeholder="Select phone number"
onValueChange={(number) => {
addClickstreamEvent(CLICKSTREAM_EVENT_NAMES.FA_COLLECT_MONEY_NUMBER_CHANGED, {
@@ -199,7 +200,7 @@ const Foreclosure: React.FC<IForeclosure> = ({ caseId, numbers, primaryPhoneNumb
value={value}
>
{ChildComponents}
</Dropdown>
</DropDownWrapper>
)}
name="selectedPhoneNumber"
rules={{ required: true }}

View File

@@ -12,6 +12,7 @@ import { getForeclosureAmount } from '../../action/paymentActions';
import { DEFAULT_FORECLOSURE_BREAKUP } from './Foreclosure';
import { BUSINESS_DATE_FORMAT, ISO_DATE_FORMAT } from '../../../RN-UI-LIB/src/utlis/dates';
import WebBasedDatePicker from '../../../RN-UI-LIB/src/components/WebBasedDatePicker';
import BottomSheetWrapper from '../../common/BottomSheetWrapper';
interface IForeclosureBottomSheet {
showForeclosureBottomSheet: boolean;
@@ -37,15 +38,15 @@ const ForeclosureBottomSheet: React.FC<IForeclosureBottomSheet> = ({
setForeclosureBreakup(foreclosureAmount);
};
return (
<BottomSheet
<BottomSheetWrapper
HeaderNode={() => (
<View style={[...row, GenericStyles.p16]}>
<Heading dark type="h3">
Foreclosure amount by selected date
</Heading>
<TouchableOpacity activeOpacity={0.7} onPress={toggleForeclosureBottomSheet}>
{/* <TouchableOpacity activeOpacity={0.7} onPress={toggleForeclosureBottomSheet}>
<CloseIcon color={COLORS.TEXT.LIGHT} />
</TouchableOpacity>
</TouchableOpacity> */}
</View>
)}
heightPercentage={60}
@@ -63,7 +64,7 @@ const ForeclosureBottomSheet: React.FC<IForeclosureBottomSheet> = ({
/>
<ForeclosureBreakupAccordion foreclosureBreakup={foreclosureBreakup} defaultExpanded />
</View>
</BottomSheet>
</BottomSheetWrapper>
);
};

View File

@@ -25,6 +25,7 @@ import ModalWrapper from '../../../RN-UI-LIB/src/components/modalWrapper/ModalWr
import QrCodeModal from './QrCodeModal';
import { toast } from '../../../RN-UI-LIB/src/components/toast';
import { ToastMessages } from '../allCases/constants';
import DropDownWrapper from '../../common/DropDownWrapper';
interface IOnlinePayment {
caseId: string;
@@ -171,7 +172,7 @@ const OnlinePayment: React.FC<IOnlinePayment> = ({
<Controller
control={control}
render={({ field: { value } }) => (
<Dropdown
<DropDownWrapper
placeholder="Select phone number"
onValueChange={(number) => {
addClickstreamEvent(CLICKSTREAM_EVENT_NAMES.FA_COLLECT_MONEY_NUMBER_CHANGED, {
@@ -187,7 +188,7 @@ const OnlinePayment: React.FC<IOnlinePayment> = ({
value={value}
>
{ChildComponents}
</Dropdown>
</DropDownWrapper>
)}
name="selectedPhoneNumber"
rules={{ required: true }}