TP-53637 | Spotless | AP + VKYC + COMMON + WIDGETS (#9997)

This commit is contained in:
Shivam Goyal
2024-03-02 22:15:55 +05:30
committed by GitHub
parent 98a93e5745
commit c6b402f18a
1657 changed files with 29826 additions and 27492 deletions

View File

@@ -1,3 +1,10 @@
/*
*
* * Copyright © 2024 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import com.google.accompanist.systemuicontroller.rememberSystemUiController
@@ -5,13 +12,11 @@ import com.navi.ap.common.viewmodel.ApplicationPlatformVM
import com.navi.common.uitron.model.action.SystemUiAction
import kotlinx.coroutines.flow.distinctUntilChanged
@Composable
fun SystemUiActionHandler(viewModel: ApplicationPlatformVM) {
val systemUiController = rememberSystemUiController()
fun setSystemUiColors(systemUiAction: SystemUiAction) {
systemUiController.isStatusBarVisible = systemUiAction.isStatusBarVisible.orTrue()
systemUiController.isNavigationBarVisible = systemUiAction.isNavigationBarVisible.orTrue()
@@ -32,4 +37,4 @@ fun SystemUiActionHandler(viewModel: ApplicationPlatformVM) {
}
}
}
}
}

View File

@@ -1,3 +1,10 @@
/*
*
* * Copyright © 2024 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.navi.ap.common.deserializer
import com.google.gson.JsonDeserializationContext
@@ -9,7 +16,7 @@ import com.navi.common.uitron.util.ApActionType
import com.navi.uitron.model.data.UiTronAction
import java.lang.reflect.Type
/** AP specific actions which cannot be placed in common module should be added here **/
/** AP specific actions which cannot be placed in common module should be added here * */
class ApUiTronActionDeserializer : UiTronActionDeserializer() {
override fun deserialize(
json: JsonElement?,
@@ -22,13 +29,11 @@ class ApUiTronActionDeserializer : UiTronActionDeserializer() {
return when (type.asString) {
ApActionType.UpdateDataViaHandleAction.name ->
context?.deserialize(jsonObject, UpdateDataViaHandleAction::class.java)
ApActionType.InitiateVKYCAgentPollingAction.name ->
context?.deserialize(jsonObject, InitiateVKYCAgentPollingAction::class.java)
else -> super.deserialize(json, typeOfT, context)
}
}
return null
}
}
}

View File

@@ -36,37 +36,27 @@ class CustomUiTronDataDeserializer : UiTronDataDeserializer() {
return when (jsonObject["viewType"].asString) {
CustomWidgets.COLLAPSABLE_ITEMS_WITH_TITLE_WIDGET.name ->
context?.deserialize(json, CollapsableItemsWithTitleWidgetData::class.java)
CustomWidgets.DYNAMIC_GRID_WIDGET.name ->
context?.deserialize(json, DynamicGridWidgetData::class.java)
CustomWidgets.DYNAMIC_COLUMN_WIDGET.name ->
context?.deserialize(json, DynamicColumnWidgetData::class.java)
CustomWidgets.DYNAMIC_ROW_WIDGET.name ->
context?.deserialize(json, DynamicRowWidgetData::class.java)
CustomWidgets.CARD_WITH_HEADER_FOOTER_AND_LAZY_COLUMN_WIDGET.name ->
context?.deserialize(
json,
CardWithHeaderFooterAndLazyColumnWidgetData::class.java
)
CustomWidgets.STEP_TRACKER_WIDGET.name ->
context?.deserialize(json, StepTrackerWidgetData::class.java)
CustomWidgets.MAPPED_RADIO_WIDGET.name ->
context?.deserialize(json, MappedRadioListWidgetData::class.java)
CustomWidgets.DYNAMIC_RADIO_GROUP_WITH_SECTIONS_WIDGET.name ->
context?.deserialize(json, DynamicRadioGroupWithSectionsWidgetData::class.java)
CustomWidgets.CAMERA.name ->
context?.deserialize(json, CameraWidgetData::class.java)
CustomWidgets.CALENDAR_WIDGET.name ->
context?.deserialize(json, CalendarWidgetData::class.java)
else -> super.deserialize(json, typeOfT, context)
}
}

View File

@@ -1,3 +1,10 @@
/*
*
* * Copyright © 2024 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.navi.ap.common.deserializer
import com.google.gson.JsonDeserializationContext
@@ -26,34 +33,18 @@ class KYCSDKSettingsDataDeserializer : JsonDeserializer<KYCSdkSettingData> {
val jsonObject = it.asJsonObject
val type = jsonObject["name"] ?: return null
return when (type.asString) {
SELFIE_HYPERVERGE.name -> context?.deserialize(
jsonObject,
HyperVergeSelfieSettingData::class.java
)
AADHAR_DIGITAP.name -> context?.deserialize(
jsonObject,
DigiTapAadhaarSettingData::class.java
)
DIGILOCKER_DIGIO.name -> context?.deserialize(
jsonObject,
DigiLockerSdkSettingData::class.java
)
PAN_DOCUMENT_HYPERVERGE.name -> context?.deserialize(
jsonObject,
HyperVergePANSettingData::class.java
)
VKYC_NAVI.name -> context?.deserialize(
jsonObject,
VKYCSettingsData::class.java
)
SELFIE_HYPERVERGE.name ->
context?.deserialize(jsonObject, HyperVergeSelfieSettingData::class.java)
AADHAR_DIGITAP.name ->
context?.deserialize(jsonObject, DigiTapAadhaarSettingData::class.java)
DIGILOCKER_DIGIO.name ->
context?.deserialize(jsonObject, DigiLockerSdkSettingData::class.java)
PAN_DOCUMENT_HYPERVERGE.name ->
context?.deserialize(jsonObject, HyperVergePANSettingData::class.java)
VKYC_NAVI.name -> context?.deserialize(jsonObject, VKYCSettingsData::class.java)
else -> null
}
}
return null
}
}
}

View File

@@ -55,13 +55,16 @@ fun HandleApiAction(viewModel: ApplicationPlatformVM, activity: ApplicationPlatf
is FillApiAction -> {
var screenRequest: ScreenRequest? = null
if (action.isPartialFillCall.orFalse().not()) {
screenRequest = ScreenRequest(
action = ApNavigationActions.NEXT.name,
isScreenDefinitionRequired = true,
fromScreen = queryMap[APP_PLATFORM_SCREEN_ID].orEmpty(),
fromScreenStateId = queryMap[APP_PLATFORM_SCREEN_STATE_ID].orElse(
DEFAULT_SCREEN_STATE_ID),
)
screenRequest =
ScreenRequest(
action = ApNavigationActions.NEXT.name,
isScreenDefinitionRequired = true,
fromScreen = queryMap[APP_PLATFORM_SCREEN_ID].orEmpty(),
fromScreenStateId =
queryMap[APP_PLATFORM_SCREEN_STATE_ID].orElse(
DEFAULT_SCREEN_STATE_ID
),
)
}
fillApplication(
fields = action.fields,
@@ -72,35 +75,36 @@ fun HandleApiAction(viewModel: ApplicationPlatformVM, activity: ApplicationPlatf
apiAction = action,
)
}
is GetNextScreenApiAction -> {
viewModel.getCta(
applicationId = queryMap[APP_PLATFORM_APPLICATION_ID].orEmpty(),
applicationType = queryMap[APP_PLATFORM_APPLICATION_TYPE].orEmpty(),
verticalType = queryMap[APP_PLATFORM_VERTICAL_TYPE]
?: queryMap[APP_PLATFORM_APPLICATION_TYPE].orEmpty(),
verticalType =
queryMap[APP_PLATFORM_VERTICAL_TYPE]
?: queryMap[APP_PLATFORM_APPLICATION_TYPE].orEmpty(),
action = ApNavigationActions.NEXT.name,
isScreenDefinitionRequired = true,
apiAction = action
)
}
is GetScreenDefinitionApiAction -> {
viewModel.fetchScreenDefinition(
applicationId = queryMap[APP_PLATFORM_APPLICATION_ID].orEmpty(),
applicationType = queryMap[APP_PLATFORM_APPLICATION_TYPE].orEmpty(),
verticalType = queryMap[APP_PLATFORM_VERTICAL_TYPE]
?: queryMap[APP_PLATFORM_APPLICATION_TYPE].orEmpty(),
verticalType =
queryMap[APP_PLATFORM_VERTICAL_TYPE]
?: queryMap[APP_PLATFORM_APPLICATION_TYPE].orEmpty(),
screenId = queryMap[APP_PLATFORM_SCREEN_ID].orEmpty(),
screenStateId = queryMap[APP_PLATFORM_SCREEN_STATE_ID].orElse(DEFAULT_SCREEN_STATE_ID),
screenStateId =
queryMap[APP_PLATFORM_SCREEN_STATE_ID].orElse(DEFAULT_SCREEN_STATE_ID),
action = queryMap[APP_ACTION].orElse(ApNavigationActions.PRE_DEFINED.name),
configVersion = queryMap[APP_CONFIG_VERSION].orEmpty()
)
}
is PartialFillCallAction -> {
if (action.isPartialFillCallExecuted.not() &&
action.areFieldsNotNullAndNotEmpty(viewModel.handle)
if (
action.isPartialFillCallExecuted.not() &&
action.areFieldsNotNullAndNotEmpty(viewModel.handle)
) {
fillApplication(
fields = action.fields,
@@ -115,27 +119,25 @@ fun HandleApiAction(viewModel: ApplicationPlatformVM, activity: ApplicationPlatf
}
}
}
is GetApplicationIdApiAction -> {
val applicationType = queryMap[APP_PLATFORM_APPLICATION_TYPE]
viewModel.createApplicationAndGetCta(
applicationType = applicationType.orEmpty(),
verticalType = queryMap[APP_PLATFORM_VERTICAL_TYPE]
?: applicationType.orEmpty(),
applicationRequestBody = ApplicationRequestBody(
applicantType = queryMap[APP_PLATFORM_APPLICANT_TYPE],
applicationType = applicationType,
isScreenCtaRequired = true,
isScreenDefinitionRequired = true
),
verticalType =
queryMap[APP_PLATFORM_VERTICAL_TYPE] ?: applicationType.orEmpty(),
applicationRequestBody =
ApplicationRequestBody(
applicantType = queryMap[APP_PLATFORM_APPLICANT_TYPE],
applicationType = applicationType,
isScreenCtaRequired = true,
isScreenDefinitionRequired = true
),
apiAction = action
)
}
is LambdaApiAction -> {
lambdaApiActionHandler(viewModel = viewModel, lambdaApiAction = action)
}
else -> {}
}
}
@@ -150,19 +152,21 @@ private fun fillApplication(
activity: ApplicationPlatformActivity,
apiAction: TriggerApiAction
) {
val fillApplicationRequestBody = getFillApplicationRequestBody(
fields = fields,
viewModel = viewModel,
applicationType = viewModel.getQueryMap()[APP_PLATFORM_APPLICATION_TYPE],
screenRequest = screenRequest,
activity = activity
)
val fillApplicationRequestBody =
getFillApplicationRequestBody(
fields = fields,
viewModel = viewModel,
applicationType = viewModel.getQueryMap()[APP_PLATFORM_APPLICATION_TYPE],
screenRequest = screenRequest,
activity = activity
)
viewModel.fillApplication(
applicationId = viewModel.getQueryMap()[APP_PLATFORM_APPLICATION_ID].orEmpty(),
fillApplicationRequestBody = fillApplicationRequestBody,
applicationType = viewModel.getQueryMap()[APP_PLATFORM_APPLICATION_TYPE].orEmpty(),
verticalType = viewModel.getQueryMap()[APP_PLATFORM_VERTICAL_TYPE]
?: viewModel.getQueryMap()[APP_PLATFORM_APPLICATION_TYPE].orEmpty(),
verticalType =
viewModel.getQueryMap()[APP_PLATFORM_VERTICAL_TYPE]
?: viewModel.getQueryMap()[APP_PLATFORM_APPLICATION_TYPE].orEmpty(),
isPartialFillCall = isPartialFillCall,
apiAction = apiAction
)
@@ -175,57 +179,54 @@ fun getFillApplicationRequestBody(
screenRequest: ScreenRequest?,
activity: ApplicationPlatformActivity
): FillApplicationRequestBody {
val list = fields?.filter { it.name.isNotNull() }?.map { item ->
when (item.source) {
SourceType.WIDGET_OUTPUT.name -> {
val layoutId: String? = viewModel.handle[item.name.orEmpty()]
val output: String? = viewModel.handle[layoutId.getInputId()]
Field(item.name.orEmpty(), output?.trim())
val list =
fields
?.filter { it.name.isNotNull() }
?.map { item ->
when (item.source) {
SourceType.WIDGET_OUTPUT.name -> {
val layoutId: String? = viewModel.handle[item.name.orEmpty()]
val output: String? = viewModel.handle[layoutId.getInputId()]
Field(item.name.orEmpty(), output?.trim())
}
SourceType.CURRENT_TIMESTAMP.name -> {
Field(item.name.orEmpty(), Timestamp(System.currentTimeMillis()).toString())
}
SourceType.ZERO_TIMESTAMP.name -> {
Field(item.name.orEmpty(), Timestamp(0).toString())
}
SourceType.SDK_OUTPUT.name -> {
val output: String? = viewModel.handle[item.sourceProperty.orEmpty()]
output?.let { Field(item.name.orEmpty(), output) }
?: run { Field(item.name.orEmpty(), item.value) }
}
SourceType.DEVICE_PROPERTY.name -> {
val value =
getDeviceData(
sourceProperty = item.sourceProperty.orEmpty(),
context = activity.applicationContext,
additionalValues = item.additionalParameters
)
Field(item.name.orEmpty(), value)
}
SourceType.PRE_DEFINED.name -> {
Field(item.name.orEmpty(), item.value)
}
SourceType.HANDLE.name -> {
Field(item.name.orEmpty(), viewModel.handle[item.name.orEmpty()])
}
SourceType.HANDLE_OBJECT.name -> {
val obj: Any? = viewModel.handle[item.sourceProperty.orEmpty()]
val output = readJsonPath(obj.toJson(), item.jsonPath.orEmpty())
Field(item.name.orEmpty(), output)
}
SourceType.USER_LOCATION.name -> {
val value = getUserLocation(item.sourceProperty.orEmpty())
Field(item.name.orEmpty(), value)
}
else -> null
}
}
SourceType.CURRENT_TIMESTAMP.name -> {
Field(item.name.orEmpty(), Timestamp(System.currentTimeMillis()).toString())
}
SourceType.ZERO_TIMESTAMP.name -> {
Field(item.name.orEmpty(), Timestamp(0).toString())
}
SourceType.SDK_OUTPUT.name -> {
val output: String? = viewModel.handle[item.sourceProperty.orEmpty()]
output?.let { Field(item.name.orEmpty(), output) }
?: run { Field(item.name.orEmpty(), item.value) }
}
SourceType.DEVICE_PROPERTY.name -> {
val value = getDeviceData(
sourceProperty = item.sourceProperty.orEmpty(),
context = activity.applicationContext,
additionalValues = item.additionalParameters
)
Field(item.name.orEmpty(), value)
}
SourceType.PRE_DEFINED.name -> {
Field(item.name.orEmpty(), item.value)
}
SourceType.HANDLE.name -> {
Field(item.name.orEmpty(), viewModel.handle[item.name.orEmpty()])
}
SourceType.HANDLE_OBJECT.name -> {
val obj: Any? = viewModel.handle[item.sourceProperty.orEmpty()]
val output = readJsonPath(obj.toJson(), item.jsonPath.orEmpty())
Field(item.name.orEmpty(), output)
}
SourceType.USER_LOCATION.name -> {
val value = getUserLocation(item.sourceProperty.orEmpty())
Field(item.name.orEmpty(), value)
}
else -> null
}
}
val fillRequest = FillRequest(ApplicationFields(list), applicationType)
return FillApplicationRequestBody(fillRequest, screenRequest)
}

View File

@@ -74,8 +74,9 @@ private fun handleCta(
}
else -> {
val screenStructureSuccessState = viewModel.getScreenStructureSuccessState()
val screenId = screenStructureSuccessState?.screenData?.screenStructure?.screenId
?: DEFAULT_SOURCE_SCREEN
val screenId =
screenStructureSuccessState?.screenData?.screenStructure?.screenId
?: DEFAULT_SOURCE_SCREEN
val screenStateId =
screenStructureSuccessState?.screenData?.metaData?.get(APP_PLATFORM_SCREEN_STATE_ID)
?: DEFAULT_SCREEN_STATE_ID

View File

@@ -1,46 +1,51 @@
/*
*
* * Copyright © 2024 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.navi.ap.common.handler
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.rememberCoroutineScope
import com.navi.common.uitron.model.action.DownloadAction
import com.navi.ap.common.ui.ApplicationPlatformActivity
import com.navi.ap.common.viewmodel.ApplicationPlatformVM
import com.navi.ap.utils.downloader.DownloadCallback
import com.navi.common.uitron.model.action.DownloadAction
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.launch
@Composable
fun DownloadActionHandler(viewModel: ApplicationPlatformVM, activity: ApplicationPlatformActivity) {
val coroutineScope = rememberCoroutineScope()
DisposableEffect(Unit) {
val job = coroutineScope.launch(Dispatchers.IO) {
val job =
coroutineScope.launch(Dispatchers.IO) {
viewModel.getActionCallback().distinctUntilChanged().collect { action ->
if (action is DownloadAction) {
viewModel.handleActions(action.downloadAction?.onStart)
viewModel.getActionCallback().distinctUntilChanged().collect { action ->
if (action is DownloadAction) {
viewModel.handleActions(action.downloadAction?.onStart)
activity.taskDownloadManager.startDownload(
downloadAction = action,
downloadCallback =
object : DownloadCallback {
override fun onDownloadSuccess(downloadId: Long) {
viewModel.handleActions(action.downloadAction?.onCompleted)
}
activity.taskDownloadManager.startDownload(
downloadAction = action,
downloadCallback = object : DownloadCallback {
override fun onDownloadSuccess(downloadId: Long) {
viewModel.handleActions(action.downloadAction?.onCompleted)
}
override fun onDownloadFailure(downloadId: Long) {
viewModel.handleActions(action.downloadAction?.onFailed)
}
}
)
override fun onDownloadFailure(downloadId: Long) {
viewModel.handleActions(action.downloadAction?.onFailed)
}
}
)
}
}
}
}
onDispose {
job.cancel()
}
onDispose { job.cancel() }
}
}
}

View File

@@ -71,34 +71,34 @@ private fun handleCtaUrl(
viewModel.fetchBottomSheetDefinition(
applicationId = queryMap?.get(APP_PLATFORM_APPLICATION_ID).orEmpty(),
applicationType = queryMap?.get(APP_PLATFORM_APPLICATION_TYPE).orEmpty(),
verticalType = queryMap?.get(APP_PLATFORM_VERTICAL_TYPE)
?: queryMap?.get(APP_PLATFORM_APPLICATION_TYPE).orEmpty(),
verticalType =
queryMap?.get(APP_PLATFORM_VERTICAL_TYPE)
?: queryMap?.get(APP_PLATFORM_APPLICATION_TYPE).orEmpty(),
screenId = queryMap?.get(APP_PLATFORM_SCREEN_ID).orEmpty(),
screenStateId = queryMap?.get(APP_PLATFORM_SCREEN_STATE_ID).orEmpty(),
action =
queryMap?.get(APP_ACTION).orElse(ApNavigationActions.PRE_DEFINED.name),
queryMap?.get(APP_ACTION).orElse(ApNavigationActions.PRE_DEFINED.name),
configVersion = queryMap?.get(APP_CONFIG_VERSION).orEmpty()
)
}
}
else -> {
ctaResponse?.cta?.let {
val screenStructureSuccessState = viewModel.getScreenStructureSuccessState()
val screenId = screenStructureSuccessState?.screenData?.screenStructure?.screenId
val screenStateId = screenStructureSuccessState?.screenData?.metaData?.get(
APP_PLATFORM_SCREEN_STATE_ID
)
setBackScreenData(
activity,
screenId,
screenStateId
)
val screenStateId =
screenStructureSuccessState
?.screenData
?.metaData
?.get(APP_PLATFORM_SCREEN_STATE_ID)
setBackScreenData(activity, screenId, screenStateId)
val isSameScreen = screenId == queryMap?.get(APP_PLATFORM_SCREEN_ID)
if (isSameScreen) {
viewModel.setScreenDefinitionState(
ApScreenDefinitionState.Success(
ApScreenDefinitionStructure(screenData = screenDefinitionResponse?.screenData)
ApScreenDefinitionStructure(
screenData = screenDefinitionResponse?.screenData
)
)
)
if (screenStateId != queryMap?.get(APP_PLATFORM_SCREEN_STATE_ID)) {
@@ -113,7 +113,9 @@ private fun handleCtaUrl(
screenDefinitionResponse?.let {
activity
.getApplicationPlatformSharedVM()
.setScreenDefinitionStructure(apScreenDefinitionStructure = screenDefinitionResponse)
.setScreenDefinitionStructure(
apScreenDefinitionStructure = screenDefinitionResponse
)
}
viewModel.clearGetCtaState()
activity.navigator.navigate(

View File

@@ -1,3 +1,10 @@
/*
*
* * Copyright © 2024 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.navi.ap.common.handler
import com.navi.ap.common.models.ApplyLoanState
@@ -6,7 +13,6 @@ import com.navi.ap.common.ui.ApplicationPlatformActivity
import com.navi.ap.common.viewmodel.ApplicationPlatformVM
import com.navi.base.deeplink.DeepLinkManager
fun lambdaSuccessHandler(
lambdaResponse: LambdaResponseType,
viewModel: ApplicationPlatformVM,
@@ -17,12 +23,9 @@ fun lambdaSuccessHandler(
// TODO : Need to remove it after Bank details will power through AP
is ApplyLoanState -> {
lambdaResponse.nextCta?.let {
DeepLinkManager.getDeepLinkListener()?.navigateTo(
activity = activity,
ctaData = it,
finish = true
)
DeepLinkManager.getDeepLinkListener()
?.navigateTo(activity = activity, ctaData = it, finish = true)
}
}
}
}
}

View File

@@ -27,7 +27,10 @@ import com.navi.common.uitron.model.action.LaunchIntentAction
import com.navi.common.uitron.model.action.LaunchIntentType
@Composable
fun HandleLaunchIntentAction(viewModel: ApplicationPlatformVM, activity: ApplicationPlatformActivity) {
fun HandleLaunchIntentAction(
viewModel: ApplicationPlatformVM,
activity: ApplicationPlatformActivity
) {
val action = remember { mutableStateOf(LaunchIntentAction()) }
val intentResult = getDefaultResultLauncher(viewModel = viewModel, action = action.value)
LaunchedEffect(Unit) {

View File

@@ -1,5 +1,11 @@
package com.navi.ap.common.handler
/*
*
* * Copyright © 2024 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.navi.ap.common.handler
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
@@ -28,7 +34,6 @@ fun HandlePostLocationAction(
naviLocationManager = activity.getNaviLocationManager()
)
}
else -> Unit
}
}
@@ -46,4 +51,4 @@ private fun handlePostLocationAction(
) {
PreferenceManager.setBooleanPreference(NaviLocationManager.IS_HARD_LOCATION_UPDATE, true)
naviLocationManager.postLocationData(activity = activity)
}
}

View File

@@ -1,3 +1,10 @@
/*
*
* * Copyright © 2024 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.navi.ap.common.handler
import androidx.compose.runtime.Composable
@@ -24,34 +31,34 @@ fun HandlePublishEventAction(
val coroutineScope = rememberCoroutineScope()
DisposableEffect(Unit) {
val job = coroutineScope.launch(Dispatchers.IO) {
viewModel.getActionCallback().distinctUntilChanged().collect { action ->
if (action is PublishEventAction) {
action.events?.filter { it.eventName.isNotNullAndNotEmpty() }
?.forEach { event ->
val eventSubscribers: List<SubscriberEventData>? =
viewModel.handle[event.eventName.plus(BaseProperty.EVENT_SUFFIX)]
eventSubscribers?.forEach { subscriberData ->
handlePropertyUpdate(
stateKey = subscriberData.stateKey ?: event.stateKey,
layoutId = subscriberData.layoutId,
viewModel = viewModel
)
handleDataUpdate(
uiTronData = event.uiTronData,
subscriberData = subscriberData,
viewModel = viewModel,
uiTronDataProviderFactory = uiTronDataProviderFactory
)
val job =
coroutineScope.launch(Dispatchers.IO) {
viewModel.getActionCallback().distinctUntilChanged().collect { action ->
if (action is PublishEventAction) {
action.events
?.filter { it.eventName.isNotNullAndNotEmpty() }
?.forEach { event ->
val eventSubscribers: List<SubscriberEventData>? =
viewModel.handle[
event.eventName.plus(BaseProperty.EVENT_SUFFIX)]
eventSubscribers?.forEach { subscriberData ->
handlePropertyUpdate(
stateKey = subscriberData.stateKey ?: event.stateKey,
layoutId = subscriberData.layoutId,
viewModel = viewModel
)
handleDataUpdate(
uiTronData = event.uiTronData,
subscriberData = subscriberData,
viewModel = viewModel,
uiTronDataProviderFactory = uiTronDataProviderFactory
)
}
}
}
}
}
}
}
onDispose {
job.cancel()
}
onDispose { job.cancel() }
}
}
@@ -60,9 +67,7 @@ private fun handlePropertyUpdate(
layoutId: String?,
viewModel: ApplicationPlatformVM
) {
stateKey?.let {
viewModel.handle[layoutId + BaseProperty.PROPERTY_SUFFIX] = it
}
stateKey?.let { viewModel.handle[layoutId + BaseProperty.PROPERTY_SUFFIX] = it }
}
private fun handleDataUpdate(

View File

@@ -100,8 +100,7 @@ private fun handleThirdPartySdkAction(
SDKType.FINARKEIN.name -> {
(action.value as? FinarkeinSDKAction)?.let {
val finarkeinHelper = FinarkeinHelper(anubhavSDKResult)
(viewModel.handle.get(FINARKEIN_CONSENT_DATA.getInputId())
as? ConsentResponse)
(viewModel.handle.get(FINARKEIN_CONSENT_DATA.getInputId()) as? ConsentResponse)
?.let { finarkeinHelper.openFinarkein(it) }
}
}
@@ -140,8 +139,12 @@ private fun handleThirdPartySdkAction(
}
}
SDKType.HYPERVERGE_SELFIE.name -> {
(action.value as? HyperVergeSelfieSDKAction)?.let { actionData ->
handleHyperVergeSelfieSdk(viewModel, activity, hyperVergeSelfieSDKAction = actionData)
(action.value as? HyperVergeSelfieSDKAction)?.let { actionData ->
handleHyperVergeSelfieSdk(
viewModel,
activity,
hyperVergeSelfieSDKAction = actionData
)
}
}
SDKType.DIGI_TAP_AADHAAR.name -> {
@@ -159,7 +162,6 @@ private fun handleThirdPartySdkAction(
handleKycDigiLockerSdk(viewModel, activity, kycDigiLockerSDKAction = actionData)
}
}
else -> {}
}
}
@@ -169,7 +171,8 @@ private fun handleHyperVergeSelfieSdk(
activity: ApplicationPlatformActivity,
hyperVergeSelfieSDKAction: HyperVergeSelfieSDKAction
) {
val selfieSettingData = viewModel.handle.get<HyperVergeSelfieSettingData>(HYPER_VERGE_SELFIE_SETTING_DATA)
val selfieSettingData =
viewModel.handle.get<HyperVergeSelfieSettingData>(HYPER_VERGE_SELFIE_SETTING_DATA)
viewModel.handle[HYPER_VERGE_SELFIE_ON_SUCCESS_ACTION] = hyperVergeSelfieSDKAction.onSuccess
viewModel.handle[HYPER_VERGE_SELFIE_ON_FAILURE_ACTION] = hyperVergeSelfieSDKAction.onFailure
activity.sdkHelper.hyperVergeSelfieCaptureHelper.startFaceCapture(
@@ -190,7 +193,8 @@ private fun handleHyperVergePanSdk(
activity: ApplicationPlatformActivity,
hyperVergePanSDKAction: HyperVergePanSDKAction
) {
val panSettingData = viewModel.handle.get<HyperVergePANSettingData>(HYPER_VERGE_PAN_SETTING_DATA)
val panSettingData =
viewModel.handle.get<HyperVergePANSettingData>(HYPER_VERGE_PAN_SETTING_DATA)
viewModel.handle[HYPER_VERGE_PAN_ON_SUCCESS_ACTION] = hyperVergePanSDKAction.onSuccess
viewModel.handle[HYPER_VERGE_PAN_ON_FAILURE_ACTION] = hyperVergePanSDKAction.onFailure
activity.sdkHelper.hyperVergePanCaptureHelper.startPanCapture(
@@ -231,11 +235,12 @@ private fun handleKycDigiLockerSdk(
viewModel: ApplicationPlatformVM,
activity: ApplicationPlatformActivity,
kycDigiLockerSDKAction: KycDigiLockerSDKAction
){
val kycDigiLockerSettingData = viewModel.handle.get<DigiLockerSdkSettingData>(KYC_DIGI_LOCKER_SDK_SETTING_DATA)
) {
val kycDigiLockerSettingData =
viewModel.handle.get<DigiLockerSdkSettingData>(KYC_DIGI_LOCKER_SDK_SETTING_DATA)
viewModel.handle[KYC_DIGI_LOCKER_SDK_ON_SUCCESS_ACTION] = kycDigiLockerSDKAction.onSuccess
viewModel.handle[KYC_DIGI_LOCKER_SDK_ON_FAILURE_ACTION] = kycDigiLockerSDKAction.onFailure
activity.sdkHelper.kycDigiLockerSdkHelper.start(kycDigiLockerSettingData,activity)
activity.sdkHelper.kycDigiLockerSdkHelper.start(kycDigiLockerSettingData, activity)
activity.setKycDigiLockerStrategy(
KycDigiLockerListenerStrategy(
applicationPlatformVM = viewModel,
@@ -264,9 +269,9 @@ private fun GetAnubhavResultLauncher(
}
}
fun List<String?>.getIncomeVerificationAvailableSDK(): String?{
fun List<String?>.getIncomeVerificationAvailableSDK(): String? {
forEach {
when(it){
when (it) {
SDKType.FINARKEIN.name -> return it
}
}

View File

@@ -66,9 +66,7 @@ fun HandleUploadDataAction(
.orFalse()
) {
analyticsTracker.onUploadToS3Failed(
userDataUploadCallbackResponse.ingestionStatusList
?.ingestionStatusList
.toString()
userDataUploadCallbackResponse.ingestionStatusList?.ingestionStatusList.toString()
)
viewModel.handleActions(uiTronAction.onFailure)
} else {
@@ -81,13 +79,14 @@ fun HandleUploadDataAction(
viewModel.getActionCallback().distinctUntilChanged().collect { uiTronAction ->
if (uiTronAction is UploadDataAction) {
action.value = uiTronAction
val eventMap = mapOf(
Pair("worker_type", uiTronAction.verticalType.orEmpty()),
Pair(
"screen_name",
viewModel.handle.get<String>("APP_PLATFORM_SCREEN_ID").orEmpty()
val eventMap =
mapOf(
Pair("worker_type", uiTronAction.verticalType.orEmpty()),
Pair(
"screen_name",
viewModel.handle.get<String>("APP_PLATFORM_SCREEN_ID").orEmpty()
)
)
)
(uiTronAction.data)?.let { data ->
val uploadSmsToS3: Boolean =
@@ -161,14 +160,17 @@ fun HandleUploadDataAction(
businessVertical.orEmpty(),
numberOfRetriesLeft,
) { _, userDataUploadCallbackResponse ->
val needIngestionPolling = FirebaseRemoteConfigHelper.getBoolean(
FirebaseRemoteConfigHelper.UW_INGESTION_POLLING,
true
)
val needIngestionPolling =
FirebaseRemoteConfigHelper.getBoolean(
FirebaseRemoteConfigHelper.UW_INGESTION_POLLING,
true
)
analyticsTracker.onPostDataInjestion(needIngestionPolling)
if (needIngestionPolling.orFalse() &&
userDataUploadCallbackResponse.uploadDataAsyncResponse != null
if (
needIngestionPolling.orFalse() &&
userDataUploadCallbackResponse.uploadDataAsyncResponse !=
null
) {
pollingUtil.handleUploadDataResponse(
userDataUploadCallbackResponse

View File

@@ -1,3 +1,10 @@
/*
*
* * Copyright © 2024 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.navi.ap.common.lambda
import com.navi.ap.common.lambda.definition.Lambda
@@ -7,10 +14,7 @@ import com.navi.ap.common.lambda.verticals.coins.CoinsLambdaHandler
import com.navi.ap.common.lambda.verticals.personalloan.PLLambdaHandlerFactory
import com.navi.ap.utils.constants.ApplicationType
class LambdaFactory(
private val bridge: LambdaBridge
) {
class LambdaFactory(private val bridge: LambdaBridge) {
internal fun get(applicationType: String, screenName: String? = null): Lambda {
return getLambdaHandler(
@@ -26,14 +30,13 @@ class LambdaFactory(
screenName: String?
): Lambda {
return when (applicationType) {
ApplicationType.PL.name, ApplicationType.PL_REFILL.name, ApplicationType.PL_REPEAT.name, ApplicationType.PL_TOP_UP.name -> PLLambdaHandlerFactory(
bridge
).getLambdaHandler(
screenName
)
ApplicationType.PL.name,
ApplicationType.PL_REFILL.name,
ApplicationType.PL_REPEAT.name,
ApplicationType.PL_TOP_UP.name ->
PLLambdaHandlerFactory(bridge).getLambdaHandler(screenName)
ApplicationType.COINS.name -> CoinsLambdaHandler(bridge)
else -> DefaultLambdaHandler(bridge)
}
}
}
}

View File

@@ -1,11 +1,17 @@
/*
*
* * Copyright © 2024 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.navi.ap.common.lambda.definition
import com.navi.ap.common.models.lambdamodels.LambdaData
import com.navi.common.uitron.model.action.LambdaApiAction
interface Lambda {
fun execute(lambdaApiAction: LambdaApiAction, lambadaData: LambdaData)
fun executeVKYCLambda() {}
}
}

View File

@@ -1,3 +1,10 @@
/*
*
* * Copyright © 2024 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.navi.ap.common.lambda.definition
import androidx.lifecycle.SavedStateHandle
@@ -31,11 +38,10 @@ interface LambdaBridge {
fun getQueryMap(): MutableMap<String, String?>
fun setLambdaState(state : LambdaState)
fun setLambdaState(state: LambdaState)
}
interface VKYCBridge: LambdaBridge {
interface VKYCBridge : LambdaBridge {
fun fetchVKYCSettings(resolvedValues: MutableMap<String, Any?>) {}
fun cancelVKYCCall(lambdaApiAction: LambdaApiAction? = null) {}

View File

@@ -1,8 +1,14 @@
/*
*
* * Copyright © 2024 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.navi.ap.common.lambda.handler
import com.navi.ap.common.lambda.definition.LambdaBridge
internal class DefaultLambdaHandler(
override val bridge: LambdaBridge,
) : LambdaHandler(bridge = bridge)
) : LambdaHandler(bridge = bridge)

View File

@@ -1,3 +1,10 @@
/*
*
* * Copyright © 2024 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.navi.ap.common.lambda.handler
import com.navi.ap.common.lambda.definition.Lambda
@@ -8,17 +15,14 @@ import com.navi.common.uitron.model.action.LambdaApiAction
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.update
abstract class LambdaHandler(
open val bridge: LambdaBridge,
open val bridge: LambdaBridge,
) : Lambda {
private val clonedScreenDefinitionState = MutableStateFlow<ApScreenDefinitionStructure?>(null)
fun setClonedScreenDefinitionState(screenDefinitionState: ApScreenDefinitionStructure?) {
clonedScreenDefinitionState.update {
screenDefinitionState
}
clonedScreenDefinitionState.update { screenDefinitionState }
}
fun getClonedScreenDefinitionState() = clonedScreenDefinitionState.value
@@ -26,4 +30,4 @@ abstract class LambdaHandler(
override fun execute(lambdaApiAction: LambdaApiAction, lambadaData: LambdaData) {
// TODO : Put Common lambda here
}
}
}

View File

@@ -1,3 +1,10 @@
/*
*
* * Copyright © 2024 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.navi.ap.common.lambda.verticals.coins
import com.navi.ap.common.lambda.handler.LambdaHandler
@@ -14,13 +21,11 @@ import com.navi.common.uitron.model.action.LambdaApiAction
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
internal class CoinLambdaImpl(private val lambdaHandler: LambdaHandler) {
internal class CoinLambdaImpl(
private val lambdaHandler: LambdaHandler
) {
private val repository: CoinLambdaRepository = CoinsLambdaRepositoryProvider()
.getRepository(CommonLibManager.application.applicationContext)
private val repository: CoinLambdaRepository =
CoinsLambdaRepositoryProvider()
.getRepository(CommonLibManager.application.applicationContext)
fun validateCoinsUPIId(
lambdaApiAction: LambdaApiAction,
@@ -39,7 +44,6 @@ internal class CoinLambdaImpl(
}
LambdaState.Success(LambdaResponseType())
}
lambdaResponse.errorBottomSheetStructure.isNotNull() -> {
lambdaHandler.bridge.executeActions(lambdaApiAction.onFailure)
LambdaState.Error(
@@ -48,19 +52,17 @@ internal class CoinLambdaImpl(
lambdaResponse.genericErrorBottomSheetFields
)
}
lambdaResponse.data.isNull() -> {
val errorBottomSheetFields = BottomSheetHelper.getLambdaErrorBottomSheet(
ApiType.LambdaApiAction.name
)
val errorBottomSheetFields =
BottomSheetHelper.getLambdaErrorBottomSheet(
ApiType.LambdaApiAction.name
)
LambdaState.Error(
lambdaResponse.statusCode,
getBottomSheetStructure(errorBottomSheetFields),
errorBottomSheetFields
)
}
else -> {
LambdaState.Nothing
}
@@ -68,5 +70,4 @@ internal class CoinLambdaImpl(
)
}
}
}

View File

@@ -1,3 +1,10 @@
/*
*
* * Copyright © 2024 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.navi.ap.common.lambda.verticals.coins
import com.navi.ap.common.models.lambdamodels.ValidateCoinsUPIIdResponse
@@ -11,15 +18,13 @@ import com.navi.ap.utils.logApEvent
import com.navi.common.uitron.model.action.ApiType
import javax.inject.Inject
class CoinLambdaRepository @Inject constructor(private val retrofitService: APRetrofitService) :
ApplicationPlatformRepositoryImp(retrofitService) {
suspend fun validateCoinsUPIId(
upiId: String,
): ApRepoResult<ValidateCoinsUPIIdResponse> {
val response =
retrofitService.validateCoinsUPIID(upiId = upiId)
val response = retrofitService.validateCoinsUPIID(upiId = upiId)
logApEvent(
Pair(
RESULT,

View File

@@ -1,3 +1,10 @@
/*
*
* * Copyright © 2024 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.navi.ap.common.lambda.verticals.coins
import com.navi.ap.common.lambda.definition.LambdaBridge
@@ -6,18 +13,12 @@ import com.navi.ap.common.models.lambdamodels.LambdaData
import com.navi.ap.utils.constants.LambdaType
import com.navi.common.uitron.model.action.LambdaApiAction
// TODO("Inject dependency using hilt")
internal class CoinsLambdaHandler(
override val bridge: LambdaBridge,
) : LambdaHandler(bridge = bridge) {
private val lambdaImpl by lazy {
CoinLambdaImpl(
lambdaHandler = this@CoinsLambdaHandler
)
}
private val lambdaImpl by lazy { CoinLambdaImpl(lambdaHandler = this@CoinsLambdaHandler) }
override fun execute(lambdaApiAction: LambdaApiAction, lambadaData: LambdaData) {
@@ -28,11 +29,9 @@ internal class CoinsLambdaHandler(
resolvedValues = lambadaData.resolvedValue.toMutableMap()
)
}
else -> {
super.execute(lambdaApiAction, lambadaData)
}
}
}
}
}

View File

@@ -1,17 +1,24 @@
/*
*
* * Copyright © 2024 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.navi.ap.common.lambda.verticals.coins
import android.content.Context
import com.navi.ap.di.EntryPoints
import dagger.hilt.android.EntryPointAccessors
internal class CoinsLambdaRepositoryProvider {
fun getRepository(context: Context): CoinLambdaRepository {
val hiltEntryPoint = EntryPointAccessors.fromApplication(
context,
EntryPoints.CoinLambdaRepositoryEntryPoint::class.java
)
val hiltEntryPoint =
EntryPointAccessors.fromApplication(
context,
EntryPoints.CoinLambdaRepositoryEntryPoint::class.java
)
return hiltEntryPoint.getCoinLambdaRepository()
}
}
}

View File

@@ -1,5 +1,11 @@
package com.navi.ap.common.lambda.verticals.personalloan
/*
*
* * Copyright © 2024 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.navi.ap.common.lambda.verticals.personalloan
import com.navi.ap.common.lambda.definition.LambdaBridge
import com.navi.ap.common.lambda.handler.LambdaHandler
@@ -19,51 +25,39 @@ import com.navi.common.awsupload.model.AWSPresignedUrlRequest
import com.navi.common.uitron.model.action.LambdaApiAction
import com.navi.uitron.model.data.UiTronActionData
// TODO("Inject dependency using hilt")
open class PLLambdaHandler(
override val bridge: LambdaBridge,
) : LambdaHandler(bridge = bridge) {
private val lambdaImpl by lazy {
PLLambdaImpl(
lambdaHandler = this@PLLambdaHandler
)
}
private val lambdaImpl by lazy { PLLambdaImpl(lambdaHandler = this@PLLambdaHandler) }
override fun execute(lambdaApiAction: LambdaApiAction, lambadaData: LambdaData) {
when (lambdaApiAction.lambdaType) {
LambdaType.TELCO_RESEND_OTP.name -> {
lambdaImpl.resendTelcoOtp(lambdaApiAction = lambdaApiAction)
}
LambdaType.LOAN_OFFER_DETAILS.name -> {
lambdaImpl.fetchOfferDetails(
lambdaApiAction,
lambadaData.resolvedValue.toMutableMap()
)
}
LambdaType.REFILL_LOAN_DETAILS.name -> {
lambdaImpl.fetchRefillOfferDetails(
lambadaData.resolvedValue.toMutableMap(),
lambdaApiAction
)
}
LambdaType.APPLY_LOAN.name -> {
lambdaImpl.applyLoan(lambadaData.resolvedValue.toMutableMap())
}
LambdaType.FETCH_CONSENT_DATA.name -> {
lambdaImpl.fetchConsentData(lambdaApiAction)
}
LambdaType.FETCH_BANKS.name -> {
lambdaImpl.fetchAllBanks(lambdaApiAction, lambadaData.resolvedValue.toMutableMap())
}
LambdaType.FETCH_RPD_TOKEN.name -> {
lambdaImpl.fetchRpdToken(
lambadaData.resolvedValue.toMutableMap(),
@@ -71,14 +65,12 @@ open class PLLambdaHandler(
lambdaApiAction
)
}
LambdaType.FETCH_RPD_PAYMENT_METHOD_DETAILS.name -> {
lambdaImpl.fetchRpdPaymentMethodDetails(
bridge.getSaveStateHandle(),
lambdaApiAction
)
}
LambdaType.VALIDATE_IFSC.name -> {
lambdaImpl.validateIFSC(
bridge.getSaveStateHandle(),
@@ -86,81 +78,68 @@ open class PLLambdaHandler(
lambadaData.resolvedValue.toMutableMap()
)
}
LambdaType.FETCH_BANK_BRANCHES.name -> {
lambdaImpl.fetchBranchList(
lambadaData.resolvedValue.toMutableMap(),
lambdaApiAction
)
}
LambdaType.FETCH_BANK_DETAILS_BY_BANK_NAME.name -> {
lambdaImpl.fetchBankDetailsByBankName(
lambadaData.resolvedValue.toMutableMap(),
lambdaApiAction
)
}
LambdaType.FETCH_ALL_SUPPORTED_BANKS.name -> {
lambdaImpl.fetchAllSupportedBanks(
lambdaApiAction,
lambadaData.resolvedValue.toMutableMap()
)
}
LambdaType.FETCH_PG_TOKEN.name -> {
lambdaImpl.fetchPGToken(lambadaData.resolvedValue.toMutableMap(), lambdaApiAction)
}
LambdaType.GET_PAYMENT_METHODS.name -> {
lambdaImpl.getPaymentMethods(lambdaApiAction)
}
LambdaType.POST_MANDATE_STATUS.name -> {
lambdaImpl.postMandateStatus(
lambadaData.resolvedValue.toMutableMap(),
lambdaApiAction
)
}
LambdaType.FETCH_MANDATE_OPTIONS.name -> {
lambdaImpl.fetchMandateMethods(
lambadaData.resolvedValue.toMutableMap(),
lambdaApiAction
)
}
LambdaType.POST_PAYMENT_METHOD_STATUS.name -> {
lambdaImpl.postPaymentMethodStatus(bridge.getSaveStateHandle(), lambdaApiAction)
}
LambdaType.FETCH_EMI_CALENDER_DETAILS.name -> {
lambdaImpl.fetchEmiInstallments(
lambdaApiAction,
lambadaData.resolvedValue.toMutableMap()
)
}
LambdaType.DOWNLOAD_LOAN_AGREEMENT_AND_SANCTION_LETTER.name -> {
lambdaImpl.initiateAgreementAndSanctionLetterDownload(
lambadaData.resolvedValue.toMutableMap(),
lambdaApiAction
)
}
LambdaType.KYC_TRACKER_ITEMS_LIST.name -> {
lambdaImpl.fetchKYCItemsList(
resolvedValues = lambadaData.resolvedValue.toMutableMap()
)
}
LambdaType.KYC_SDK_SETTING.name -> {
lambdaImpl.fetchKYCSDKSettings(
lambdaApiAction = lambdaApiAction,
resolvedValues = lambadaData.resolvedValue.toMutableMap()
)
}
LambdaType.POST_KYC_SDK_VERIFICATION.name -> {
lambdaImpl.postKYCSdkVerification(
handle = bridge.getSaveStateHandle(),
@@ -168,15 +147,12 @@ open class PLLambdaHandler(
resolvedValues = lambadaData.resolvedValue.toMutableMap()
)
}
LambdaType.FETCH_VKYC_CARD_DETAILS.name -> {
lambdaImpl.fetchVKYCLottieCardData()
}
LambdaType.SUBMIT_PERMISSION.name -> {
lambdaImpl.submitVKYCRequiredPermissionList(lambdaApiAction = lambdaApiAction)
}
LambdaType.UPLOAD_SELFIE_IMAGE_TO_AWS.name -> {
val handle = bridge.getSaveStateHandle()
val onSuccessAction =
@@ -185,16 +161,16 @@ open class PLLambdaHandler(
handle.get<UiTronActionData>(HYPER_VERGE_SELFIE_ON_FAILURE_ACTION)
lambdaImpl.uploadLocalImageUriToAWSAndGetS3Url(
localImageUri = lambadaData.resolvedValue[IMAGE_URI].toString(),
awsPreSignedUrlRequest = AWSPresignedUrlRequest(
fileType = FILE_TYPE,
flowId = HYPERVERGE_SELFIE_FLOW_ID
),
awsPreSignedUrlRequest =
AWSPresignedUrlRequest(
fileType = FILE_TYPE,
flowId = HYPERVERGE_SELFIE_FLOW_ID
),
onSuccessAction = onSuccessAction,
onErrorAction = onFailureAction,
imageSavedFileName = HYPERVERGE_SELFIE_SAVED_FILE_NAME
)
}
LambdaType.UPLOAD_PAN_IMAGE_TO_AWS.name -> {
val handle = bridge.getSaveStateHandle()
val onSuccessAction =
@@ -203,42 +179,34 @@ open class PLLambdaHandler(
handle.get<UiTronActionData>(HYPER_VERGE_PAN_ON_FAILURE_ACTION)
lambdaImpl.uploadLocalImageUriToAWSAndGetS3Url(
localImageUri = lambadaData.resolvedValue[IMAGE_URI].toString(),
awsPreSignedUrlRequest = AWSPresignedUrlRequest(
fileType = FILE_TYPE,
flowId = HYPERVERGE_PAN_FLOW_ID
),
awsPreSignedUrlRequest =
AWSPresignedUrlRequest(
fileType = FILE_TYPE,
flowId = HYPERVERGE_PAN_FLOW_ID
),
onSuccessAction = onSuccessAction,
onErrorAction = onFailureAction,
imageSavedFileName = HYPERVERGE_PAN_SAVED_FILE_NAME
)
}
LambdaType.FETCH_PIN_CODE.name -> {
lambdaImpl.getCityAndState(
lambadaData.resolvedValue.toMutableMap(),
lambdaApiAction
)
}
LambdaType.FETCH_ADDRESS_LIST.name -> {
lambdaImpl.getAddressList(lambdaApiAction)
}
LambdaType.UPLOAD_IMAGE_TO_S3_URL.name -> {
lambdaImpl.uploadLocalImageUriToAWSAndGetS3Url(lambdaApiAction = lambdaApiAction)
}
LambdaType.FETCH_CALENDER_DETAILS.name -> {
lambdaImpl.fetchCalendarDetails(
lambadaData.resolvedValue.toMutableMap()
)
lambdaImpl.fetchCalendarDetails(lambadaData.resolvedValue.toMutableMap())
}
else -> {
super.execute(lambdaApiAction, lambadaData)
}
}
}
}

View File

@@ -1,3 +1,10 @@
/*
*
* * Copyright © 2024 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.navi.ap.common.lambda.verticals.personalloan
import com.navi.ap.common.lambda.definition.LambdaBridge
@@ -11,4 +18,4 @@ class PLLambdaHandlerFactory(private val bridge: LambdaBridge) {
else -> PLLambdaHandler(bridge)
}
}
}
}

View File

@@ -1,3 +1,10 @@
/*
*
* * Copyright © 2024 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.navi.ap.common.lambda.verticals.personalloan
import android.content.Context
@@ -5,21 +12,23 @@ import com.navi.ap.common.usecase.UploadImageAWSUseCase
import com.navi.ap.di.EntryPoints
import dagger.hilt.android.EntryPointAccessors
internal class PLLambdaProvider{
internal class PLLambdaProvider {
fun getRepository(context: Context): PLLambdaRepository {
val hiltEntryPoint = EntryPointAccessors.fromApplication(
context,
EntryPoints.PLLambdaRepositoryEntryPoint::class.java
)
val hiltEntryPoint =
EntryPointAccessors.fromApplication(
context,
EntryPoints.PLLambdaRepositoryEntryPoint::class.java
)
return hiltEntryPoint.getPLLambdaRepository()
}
fun getUploadImageAWSUseCase(context: Context): UploadImageAWSUseCase {
val hiltEntryPoint = EntryPointAccessors.fromApplication(
context,
EntryPoints.UploadImageAWSUseCaseEntryPoint::class.java
)
val hiltEntryPoint =
EntryPointAccessors.fromApplication(
context,
EntryPoints.UploadImageAWSUseCaseEntryPoint::class.java
)
return hiltEntryPoint.getUploadImageAWSUseCase()
}
}
}

View File

@@ -1,3 +1,10 @@
/*
*
* * Copyright © 2024 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.navi.ap.common.lambda.verticals.personalloan
import com.navi.ap.common.models.TelcoResendOtpRequest
@@ -392,30 +399,46 @@ class PLLambdaRepository @Inject constructor(private val retrofitService: APRetr
return apiResponseCallback(response = response, apiTag = ApiType.LambdaApiAction.name)
}
suspend fun fetchKYCSDKSettingsData(kycSdkSettingsRequestData: KYCSDKSettingsRequestData): ApRepoResult<KYCSdkSettingData> {
suspend fun fetchKYCSDKSettingsData(
kycSdkSettingsRequestData: KYCSDKSettingsRequestData
): ApRepoResult<KYCSdkSettingData> {
val response =
retrofitService.fetchKYCSDKSettingsData(sdkSettingsRequestData = kycSdkSettingsRequestData)
retrofitService.fetchKYCSDKSettingsData(
sdkSettingsRequestData = kycSdkSettingsRequestData
)
logApiResponseEvents(methodName = ::fetchKYCSDKSettingsData.name, response = response)
return apiResponseCallback(response = response, apiTag = ApiType.LambdaApiAction.name)
}
suspend fun postKYCSdkVerification(sdkPostVerificationRequestData: Any?): ApRepoResult<KycSdkVerificationResponse> {
suspend fun postKYCSdkVerification(
sdkPostVerificationRequestData: Any?
): ApRepoResult<KycSdkVerificationResponse> {
val response =
retrofitService.postKYCSdkVerification(sdkPostVerificationRequestData = sdkPostVerificationRequestData)
retrofitService.postKYCSdkVerification(
sdkPostVerificationRequestData = sdkPostVerificationRequestData
)
logApiResponseEvents(methodName = ::postKYCSdkVerification.name, response = response)
return apiResponseCallback(response = response, apiTag = ApiType.LambdaApiAction.name)
}
suspend fun postAWSPresignedUrl(awsPresignedUrlRequest: AWSPresignedUrlRequest): ApRepoResult<AWSPresignedUrlResponse> {
suspend fun postAWSPresignedUrl(
awsPresignedUrlRequest: AWSPresignedUrlRequest
): ApRepoResult<AWSPresignedUrlResponse> {
val response =
CommonLibManager.commonRetrofitService.postAWSPreSignedUrl(awsPresignedUrlRequest)
logApiResponseEvents(methodName = ::postAWSPresignedUrl.name, response = response)
return apiResponseCallback(response = response, apiTag = ApiType.LambdaApiAction.name)
}
suspend fun fetchKYCItemsList(clientReferenceId: String? = null, isPanOptionScreen: String? = null): ApRepoResult<KYCTrackerItemsListData> {
suspend fun fetchKYCItemsList(
clientReferenceId: String? = null,
isPanOptionScreen: String? = null
): ApRepoResult<KYCTrackerItemsListData> {
val response =
retrofitService.fetchKYCItemsList(clientReferenceId = clientReferenceId.orEmpty(), isPanOptionScreen = isPanOptionScreen)
retrofitService.fetchKYCItemsList(
clientReferenceId = clientReferenceId.orEmpty(),
isPanOptionScreen = isPanOptionScreen
)
logApiResponseEvents(methodName = ::fetchKYCItemsList.name, response = response)
return apiResponseCallback(response = response, apiTag = ApiType.GetScreenDefinition.name)
}
@@ -424,10 +447,11 @@ class PLLambdaRepository @Inject constructor(private val retrofitService: APRetr
clientReferenceId: String?,
loanApplicationId: String?
): ApRepoResult<VKYCAgentAssignedResponse> {
val response = retrofitService.fetchVkycAgentAssignedStatus(
clientReferenceId = clientReferenceId.orEmpty(),
loanApplicationId = loanApplicationId
)
val response =
retrofitService.fetchVkycAgentAssignedStatus(
clientReferenceId = clientReferenceId.orEmpty(),
loanApplicationId = loanApplicationId
)
logApiResponseEvents(methodName = ::fetchVKYCAgentAssignedStatus.name, response = response)
return apiResponseCallback(response = response, apiTag = ApiType.LambdaApiAction.name)
}
@@ -439,11 +463,11 @@ class PLLambdaRepository @Inject constructor(private val retrofitService: APRetr
}
suspend fun submitVKYCRequiredPermissionList(): ApRepoResult<VkycStatus> {
val response = retrofitService.submitVKYCRequiredPermissionList(
updateDevicePermissionsRequest = UpdateDevicePermissionsRequest(
getVKYCPermissionGrantedList()
val response =
retrofitService.submitVKYCRequiredPermissionList(
updateDevicePermissionsRequest =
UpdateDevicePermissionsRequest(getVKYCPermissionGrantedList())
)
)
logApiResponseEvents(
methodName = ::submitVKYCRequiredPermissionList.name,
response = response
@@ -455,16 +479,16 @@ class PLLambdaRepository @Inject constructor(private val retrofitService: APRetr
clientReferenceId: String?,
loanApplicationId: String?
): ApRepoResult<VkycCancelStatus> {
val response = retrofitService.cancelVKYCCall(
clientReferenceId = clientReferenceId.orEmpty(),
loanApplicationId = loanApplicationId,
cancelVKYCRequestData = CancelVKYCRequestData(reason = getCancelVKYCCallReason())
)
val response =
retrofitService.cancelVKYCCall(
clientReferenceId = clientReferenceId.orEmpty(),
loanApplicationId = loanApplicationId,
cancelVKYCRequestData = CancelVKYCRequestData(reason = getCancelVKYCCallReason())
)
logApiResponseEvents(methodName = ::cancelVKYCCall.name, response = response)
return apiResponseCallback(response = response, apiTag = ApiType.LambdaApiAction.name)
}
suspend fun fetchPinCodeData(pinCode: String): ApRepoResult<Any> {
val response = retrofitService.fetchCityAndState(pinCode, target = ModuleName.LE.name)
logApEvent(
@@ -490,5 +514,4 @@ class PLLambdaRepository @Inject constructor(private val retrofitService: APRetr
)
return apiResponseCallback(response = response, apiTag = ApiType.LambdaApiAction.name)
}
}

View File

@@ -15,10 +15,11 @@ import dagger.hilt.android.EntryPointAccessors
internal class UploadImageToAWSUseCaseProvider {
fun getUseCase(context: Context): UploadImageToAWSUseCase {
val hiltEntryPoint = EntryPointAccessors.fromApplication(
context,
EntryPoints.UploadImageToAWSUseCaseEntryPoint::class.java
)
val hiltEntryPoint =
EntryPointAccessors.fromApplication(
context,
EntryPoints.UploadImageToAWSUseCaseEntryPoint::class.java
)
return hiltEntryPoint.getUploadImageToAWSUseCase()
}
}
}

View File

@@ -1,5 +1,11 @@
package com.navi.ap.common.lambda.verticals.vkyc
/*
*
* * Copyright © 2024 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.navi.ap.common.lambda.verticals.vkyc
import com.navi.ap.common.lambda.definition.LambdaBridge
import com.navi.ap.common.lambda.definition.VKYCBridge
@@ -12,22 +18,16 @@ internal class VKYCLambdaHandler(
override val bridge: LambdaBridge,
) : PLLambdaHandler(bridge = bridge) {
private val lambdaImpl by lazy {
VKYCLambdaImpl(
lambdaHandler = this@VKYCLambdaHandler
)
}
private val lambdaImpl by lazy { VKYCLambdaImpl(lambdaHandler = this@VKYCLambdaHandler) }
override fun execute(lambdaApiAction: LambdaApiAction, lambadaData: LambdaData) {
when (lambdaApiAction.lambdaType) {
LambdaType.CANCEL_VKYC.name -> {
(bridge as? VKYCBridge)?.cancelVKYCCall(lambdaApiAction)
}
LambdaType.VKYC_NAVI_100MS_SDK_SETTING.name -> {
(bridge as? VKYCBridge)?.fetchVKYCSettings(lambadaData.resolvedValue.toMutableMap())
}
LambdaType.FETCH_VKYC_CARD_DETAILS.name -> {
lambdaImpl.fetchVKYCLottieCardData()
}

View File

@@ -1,3 +1,10 @@
/*
*
* * Copyright © 2024 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.navi.ap.common.lambda.verticals.vkyc
import com.navi.ap.common.lambda.verticals.personalloan.PLLambdaProvider
@@ -18,53 +25,60 @@ import kotlinx.coroutines.launch
internal class VKYCLambdaImpl(private val lambdaHandler: VKYCLambdaHandler) {
private val repository: PLLambdaRepository = PLLambdaProvider()
.getRepository(CommonLibManager.application.applicationContext)
private val repository: PLLambdaRepository =
PLLambdaProvider().getRepository(CommonLibManager.application.applicationContext)
fun fetchVKYCLottieCardData() {
lambdaHandler.bridge.getViewModelScope().launch(Dispatchers.IO) {
if (lambdaHandler.getClonedScreenDefinitionState() == null) {
lambdaHandler.setClonedScreenDefinitionState(lambdaHandler.bridge.getScreenStructurePreRenderState())
lambdaHandler.setClonedScreenDefinitionState(
lambdaHandler.bridge.getScreenStructurePreRenderState()
)
}
lambdaHandler.bridge.setLambdaState(LambdaState.Loading)
val lambdaResponse = repository.fetchVKYCLottieCardData()
lambdaHandler.bridge.setLambdaState(when {
lambdaResponse.data.isNotNull() && lambdaHandler.getClonedScreenDefinitionState().isNotNull() -> {
val updatedResponse =
BasePathInjector<ApScreenDefinitionStructure, Any?>().injectData(
lambdaHandler.getClonedScreenDefinitionState(), lambdaResponse.data
)
lambdaHandler.bridge.setLambdaState(
when {
lambdaResponse.data.isNotNull() &&
lambdaHandler.getClonedScreenDefinitionState().isNotNull() -> {
val updatedResponse =
BasePathInjector<ApScreenDefinitionStructure, Any?>()
.injectData(
lambdaHandler.getClonedScreenDefinitionState(),
lambdaResponse.data
)
updatedResponse?.let {
lambdaHandler.bridge.setScreenDefinitionState(ApScreenDefinitionState.Success(updatedResponse))
updatedResponse?.let {
lambdaHandler.bridge.setScreenDefinitionState(
ApScreenDefinitionState.Success(updatedResponse)
)
}
LambdaState.Success(LambdaResponseType())
}
lambdaResponse.errorBottomSheetStructure.isNotNull() -> {
LambdaState.Error(
lambdaResponse.statusCode,
lambdaResponse.errorBottomSheetStructure,
lambdaResponse.genericErrorBottomSheetFields
)
}
lambdaResponse.data.isNull() -> {
val errorBottomSheetFields =
BottomSheetHelper.getLambdaErrorBottomSheet(
ApiType.LambdaApiAction.name
)
LambdaState.Error(
lambdaResponse.statusCode,
getBottomSheetStructure(errorBottomSheetFields),
errorBottomSheetFields
)
}
else -> {
LambdaState.Nothing
}
LambdaState.Success(LambdaResponseType())
}
lambdaResponse.errorBottomSheetStructure.isNotNull() -> {
LambdaState.Error(
lambdaResponse.statusCode,
lambdaResponse.errorBottomSheetStructure,
lambdaResponse.genericErrorBottomSheetFields
)
}
lambdaResponse.data.isNull() -> {
val errorBottomSheetFields = BottomSheetHelper.getLambdaErrorBottomSheet(
ApiType.LambdaApiAction.name
)
LambdaState.Error(
lambdaResponse.statusCode,
getBottomSheetStructure(errorBottomSheetFields),
errorBottomSheetFields
)
}
else -> {
LambdaState.Nothing
}
})
)
}
}
}
}

View File

@@ -1,3 +1,10 @@
/*
*
* * Copyright © 2024 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.navi.ap.common.models
data class APBottomSheetStateHolder(

View File

@@ -1,5 +1,11 @@
package com.navi.ap.common.models
/*
*
* * Copyright © 2024 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.navi.ap.common.models
data class ApApiRequest(
val action: String? = null,

View File

@@ -50,7 +50,6 @@ data class WidgetGroup(
val backgroundColor: String? = DEFAULT_BACKGROUND_COLOR
)
data class RenderActions(
val preRenderAction: UiTronActionData? = null,
val postRenderAction: UiTronActionData? = null

View File

@@ -1,3 +1,10 @@
/*
*
* * Copyright © 2024 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.navi.ap.common.models
import android.os.Parcelable
@@ -11,4 +18,4 @@ data class CalendarData(
@SerializedName("isEnabled") val isEnabled: Boolean,
@SerializedName("textInWords") val textInWords: String,
@SerializedName("dateWithSuffix") val dateWithSuffix: String,
) : Parcelable
) : Parcelable

View File

@@ -1,3 +1,10 @@
/*
*
* * Copyright © 2024 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.navi.ap.common.models
import android.os.Parcelable
@@ -11,4 +18,4 @@ data class CalendarDateElementData(
@SerializedName("isEnabled") val isEnabled: Boolean? = null,
@SerializedName("textInWords") val textInWords: String? = null,
@SerializedName("dateWithSuffix") val dateWithSuffix: String? = null,
) : Parcelable
) : Parcelable

View File

@@ -1,3 +1,10 @@
/*
*
* * Copyright © 2024 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.navi.ap.common.models
import android.os.Parcelable
@@ -13,7 +20,6 @@ import kotlinx.parcelize.IgnoredOnParcel
import kotlinx.parcelize.Parcelize
import kotlinx.parcelize.RawValue
@Parcelize
data class CalendarWidgetData(
@SerializedName("selectedDate") var selectedDate: String? = null,
@@ -55,4 +61,4 @@ data class CalendarWidgetData(
@SerializedName("defaultDateTextColor") val defaultDateTextColor: String? = null,
@SerializedName("disabledDateTextColor") val disabledDateTextColor: String? = null,
) : Parcelable
}
}

View File

@@ -17,12 +17,12 @@ data class CameraWidgetData(
val windowPadding: ComposePadding? = null,
val headingTextProperty: TextProperty? = null,
val headingTextData: TextData? = null,
val captureButton : CaptureButton? = null
): UiTronData()
val captureButton: CaptureButton? = null
) : UiTronData()
data class CaptureButton(
val outerCircleSize: Int? = null,
val innerCircleSize: Int? = null,
val circleColor: String? = null,
val captureButtonOnClickAction: UiTronActionData? = null
)
)

View File

@@ -1,3 +1,10 @@
/*
*
* * Copyright © 2024 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.navi.ap.common.models
import com.navi.ap.common.models.lambdamodels.EmiCalendarResponse
@@ -6,23 +13,23 @@ import com.navi.uitron.model.data.UiTronData
import com.navi.uitron.model.ui.BorderStrokeData
data class CardWithHeaderFooterAndLazyColumnWidgetData(
val header : UiTronResponse? = null,
val footer : UiTronResponse? = null,
val header: UiTronResponse? = null,
val footer: UiTronResponse? = null,
val stickyHeaderItem: UiTronResponse? = null,
val titleItem: UiTronResponse? = null,
val containerProperty: ContainerProperty? = null,
val listData: EmiCalendarResponse? = null,
) : UiTronData(){
) : UiTronData() {
data class ContainerProperty(
val verticalOffset : Int? = null,
val verticalOffset: Int? = null,
val backGroundColor: String? = null,
val padding: Int? = null,
val containerHeight : Int? = null,
val containerHeight: Int? = null,
val borderStrokeData: BorderStrokeData? = null
)
}
data class UiTronResponseWithType(
val isSticky:Boolean = false,
val isSticky: Boolean = false,
val uiTronResponse: UiTronResponse?
)
)

View File

@@ -10,7 +10,6 @@ package com.navi.ap.common.models
import com.navi.uitron.model.data.TextData
import com.navi.uitron.model.data.UiTronData
import com.navi.uitron.model.ui.TextProperty
import com.navi.uitron.model.ui.UiTronView
data class CollapsableItemsWithTitleWidgetData(
val reasons: List<DropdownItemData>? = null,
@@ -19,7 +18,7 @@ data class CollapsableItemsWithTitleWidgetData(
val itemTitleData: TextData? = null,
val itemDescriptionProperty: TextProperty? = null,
val itemDescriptionData: TextData? = null,
val backgroundColor: String? =null
val backgroundColor: String? = null
) : UiTronData() {
data class DropdownItemData(val title: String? = null, val description: String? = null)
}

View File

@@ -1,3 +1,10 @@
/*
*
* * Copyright © 2024 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.navi.ap.common.models
import com.navi.uitron.model.data.UiTronData
@@ -8,4 +15,4 @@ data class DynamicColumnWidgetData(
val maxColumnHeight: Int? = null,
val dividerProperty: DividerProperty? = null,
val listData: List<Any>? = null
) : UiTronData()
) : UiTronData()

View File

@@ -1,3 +1,10 @@
/*
*
* * Copyright © 2024 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.navi.ap.common.models
import com.navi.uitron.model.data.UiTronData
@@ -14,4 +21,4 @@ data class DynamicGridWidgetData(
val horizontalArrangementData: ArrangementData,
val verticalArrangementData: ArrangementData,
val listData: List<Any>? = null
) : UiTronData()
) : UiTronData()

View File

@@ -11,15 +11,12 @@ import com.navi.uitron.model.UiTronResponse
import com.navi.uitron.model.data.UiTronActionData
import com.navi.uitron.model.data.UiTronData
data class DynamicRadioGroupWithSectionsWidgetData (
data class DynamicRadioGroupWithSectionsWidgetData(
val sectionDataList: Map<String, List<Any>?>? = null,
val sectionViewList: Map<String, SectionView>? = null
) : UiTronData() {
data class SectionView(
val title: UiTronResponse? = null,
val radioItem: RadioItem? = null
)
data class SectionView(val title: UiTronResponse? = null, val radioItem: RadioItem? = null)
data class RadioItem(
val item: UiTronResponse? = null,
@@ -27,4 +24,4 @@ data class DynamicRadioGroupWithSectionsWidgetData (
val selectedAction: UiTronActionData? = null,
val unSelectedAction: UiTronActionData? = null,
)
}
}

View File

@@ -1,3 +1,10 @@
/*
*
* * Copyright © 2024 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.navi.ap.common.models
import com.navi.uitron.model.data.UiTronData
@@ -6,4 +13,4 @@ import com.navi.uitron.model.ui.DividerProperty
data class DynamicRowWidgetData(
val dividerProperty: DividerProperty? = null,
val listData: List<Any>? = null
) : UiTronData()
) : UiTronData()

View File

@@ -1,9 +1,14 @@
/*
*
* * Copyright © 2024 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.navi.ap.common.models
import com.navi.base.model.CtaData
open class LambdaResponseType
class ApplyLoanState(
val nextCta: CtaData? = null
) : LambdaResponseType()
class ApplyLoanState(val nextCta: CtaData? = null) : LambdaResponseType()

View File

@@ -22,4 +22,4 @@ sealed class LambdaState {
data class Success(val data: LambdaResponseType) : LambdaState()
object Nothing : LambdaState()
}
}

View File

@@ -1,20 +1,26 @@
/*
*
* * Copyright © 2024 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.navi.ap.common.models
import com.navi.uitron.model.UiTronResponse
import com.navi.uitron.model.data.UiTronActionData
import com.navi.uitron.model.data.UiTronData
data class MappedRadioListWidgetData(
val itemMap: Map<String, RadioWidgetResponse>? = null,
) : UiTronData() {
) : UiTronData() {
data class RadioWidgetResponse(
val item: UiTronResponse? = null,
var isSelected : Boolean? = null,
var isDisabled : Boolean? = null,
var isSelected: Boolean? = null,
var isDisabled: Boolean? = null,
var selectedAction: UiTronActionData? = null,
val unSelectedAction: UiTronActionData? = null,
val disableAction : UiTronActionData? = null,
val disableAction: UiTronActionData? = null,
)
}
}

View File

@@ -1,3 +1,10 @@
/*
*
* * Copyright © 2024 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.navi.ap.common.models
import com.navi.common.network.models.GenericErrorBottomSheetFields

View File

@@ -1,3 +1,10 @@
/*
*
* * Copyright © 2024 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.navi.ap.common.models
import com.google.gson.Gson
@@ -8,9 +15,8 @@ import com.navi.uitron.model.ui.ColumnProperty
import com.navi.uitron.model.ui.DividerProperty
import com.navi.uitron.model.ui.UiTronView
data class StepTrackerWidgetData(
val trackerData: Map<String, Map<String, StepTrackerData>>? =null,
val trackerData: Map<String, Map<String, StepTrackerData>>? = null,
val dividerProperty: DividerProperty? = null,
val cardProperty: CardProperty? = null,
val columnProperty: ColumnProperty? = null,
@@ -33,10 +39,7 @@ data class StepTrackerWidgetData(
}
}
data class StepTrackerInfo(
val type: String? = null,
val status: String? = null
)
data class StepTrackerInfo(val type: String? = null, val status: String? = null)
data class StepTrackerData(
val textContent: TextContent? = null,
@@ -70,4 +73,4 @@ data class ImageUrls(
val subSecondImageUrl: String? = null,
val iconUrl: String? = null,
val lottieUrl: String? = null,
)
)

View File

@@ -1,5 +1,12 @@
/*
*
* * Copyright © 2024 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.navi.ap.common.models
enum class VerticalType {
HPC_LOGIN
}
}

View File

@@ -1,3 +1,10 @@
/*
*
* * Copyright © 2024 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.navi.ap.common.models.actions
import android.os.Parcelable
@@ -11,20 +18,21 @@ import com.navi.uitron.model.ui.BaseProperty
import kotlinx.parcelize.Parcelize
@Parcelize
data class UpdateDataViaHandleAction(val dataList: List<FillApiData>? = null, val viewDataList: List<ViewData>? = null) : UiTronAction() {
data class UpdateDataViaHandleAction(
val dataList: List<FillApiData>? = null,
val viewDataList: List<ViewData>? = null
) : UiTronAction() {
override suspend fun manageAction(actionDetails: ActionDetails) {
val action = actionDetails.uiTronAction as UpdateDataViaHandleAction
val map = getResolvedFieldValue(dataList, actionDetails.handle)
action.viewDataList?.forEach {
val updatedUiTronData = BasePathInjector<UiTronData, Map<String, Any?>>().injectData(it.uiTronData, map)
val updatedUiTronData =
BasePathInjector<UiTronData, Map<String, Any?>>().injectData(it.uiTronData, map)
actionDetails.handle[it.layoutId + BaseProperty.DATA_SUFFIX] = updatedUiTronData
}
}
@Parcelize
data class ViewData(
val layoutId: String? = null,
val uiTronData: UiTronData? = null
) : Parcelable
data class ViewData(val layoutId: String? = null, val uiTronData: UiTronData? = null) :
Parcelable
}

View File

@@ -1,10 +1,16 @@
/*
*
* * Copyright © 2024 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.navi.ap.common.models.lambdamodels
import android.os.Parcelable
import com.google.gson.annotations.SerializedName
import kotlinx.parcelize.Parcelize
@Parcelize
data class AgreementLetterDownloadResponse(
@SerializedName("requestId") val requestId: String? = null,
@@ -18,4 +24,4 @@ data class AgreementLetterDownloadResponse(
@SerializedName("uri") val uri: String? = null,
@SerializedName("rawCopyUri") val rawCopyUri: String? = null,
) : Parcelable
}
}

View File

@@ -1,3 +1,10 @@
/*
*
* * Copyright © 2024 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.navi.ap.common.models.lambdamodels
import com.google.gson.annotations.SerializedName
@@ -5,4 +12,4 @@ import com.google.gson.annotations.SerializedName
data class ApplyLoanResponse(
@SerializedName("loanApplicationReferenceId") val loanApplicationReferenceId: String? = null,
@SerializedName("nextCta") val nextCtaUrl: String? = null,
)
)

View File

@@ -22,7 +22,8 @@ data class BankDataResponse(
@SerializedName("suggested") val suggested: Boolean = true,
@SerializedName("title") val title: String? = null,
@SerializedName("iconUrl") val iconUrl: String? = null,
@SerializedName("thirdPartyServiceProviders") val thirdPartyServiceProviders: List<String?>? = null,
@SerializedName("thirdPartyServiceProviders")
val thirdPartyServiceProviders: List<String?>? = null,
@SerializedName("isDisbursementDelayed") val isDisbursementDelayed: Boolean? = null
) : Parcelable
}

View File

@@ -1,10 +1,16 @@
/*
*
* * Copyright © 2024 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.navi.ap.common.models.lambdamodels
import android.os.Parcelable
import com.google.gson.annotations.SerializedName
import kotlinx.parcelize.Parcelize
@Parcelize
data class EmiCalendarResponse(
@SerializedName("dataList") val dataList: List<EmiResponse>? = null,
@@ -29,5 +35,4 @@ data class EmiCalendarResponse(
@SerializedName("date") val date: String? = null,
@SerializedName("amount") val amount: String? = null,
) : Parcelable
}
}

View File

@@ -1,3 +1,10 @@
/*
*
* * Copyright © 2024 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.navi.ap.common.models.lambdamodels
data class EmiModel(

View File

@@ -1,12 +1,19 @@
/*
*
* * Copyright © 2024 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.navi.ap.common.models.lambdamodels
import com.google.gson.annotations.SerializedName
data class FetchPaymentMethodsRequest (
@SerializedName("apApplicationId") val applicationId : String?,
data class FetchPaymentMethodsRequest(
@SerializedName("apApplicationId") val applicationId: String?,
@SerializedName("customerReferenceId") val customerReferenceId: String?,
@SerializedName("loanApplicationId") val loanApplicationId: String?,
@SerializedName("emiAmount") val emiAmount: String?,
@SerializedName("tenureInMonths") val tenureInMonths: String?,
@SerializedName("bankName") val bankName: String?
)
)

View File

@@ -1,3 +1,10 @@
/*
*
* * Copyright © 2024 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.navi.ap.common.models.lambdamodels
import android.os.Parcelable

View File

@@ -1,3 +1,10 @@
/*
*
* * Copyright © 2024 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.navi.ap.common.models.lambdamodels
import android.os.Parcelable

View File

@@ -1,3 +1,10 @@
/*
*
* * Copyright © 2024 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.navi.ap.common.models.lambdamodels
import android.os.Parcelable
@@ -26,4 +33,4 @@ data class SourceList(
@SerializedName("sdkInOrder") val sdkInOrder: List<String>? = null,
@SerializedName("isDisabled") val isDisabled: Boolean? = null,
@SerializedName("isSelected") val isSelected: Boolean? = null,
) : Parcelable
) : Parcelable

View File

@@ -1,3 +1,10 @@
/*
*
* * Copyright © 2024 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.navi.ap.common.models.lambdamodels
import android.os.Parcelable
@@ -6,8 +13,8 @@ import com.navi.ap.common.sdk.digilocker.model.DigilockerPANVerificationData
import com.navi.ap.common.sdk.digitap.model.AadhaarVerificationData
import com.navi.ap.common.sdk.hyperverge.pan.model.HyperVergePanUploadRequestData
import com.navi.ap.common.sdk.hyperverge.selfie.model.HyperVergeSelfieUploadRequestData
import kotlinx.parcelize.Parcelize
import java.util.UUID
import kotlinx.parcelize.Parcelize
@Parcelize
data class KycSdkVerificationRequestData(
@@ -19,7 +26,8 @@ data class KycSdkVerificationRequestData(
@Parcelize
data class SelfieVerificationPayload(
@SerializedName("verifyCustomerSelfie") val verifyCustomerSelfie: HyperVergeSelfieUploadRequestData? = null,
@SerializedName("verifyCustomerSelfie")
val verifyCustomerSelfie: HyperVergeSelfieUploadRequestData? = null,
) : Parcelable, PayLoadData()
@Parcelize
@@ -36,17 +44,21 @@ data class AadhaarVerificationPayload(
@SerializedName("digitapParams") val digitapParams: AadhaarVerificationData? = null,
) : Parcelable
constructor(digitapParams: AadhaarVerificationData?) : this(Params(DigiTapParams(digitapParams)))
constructor(
digitapParams: AadhaarVerificationData?
) : this(Params(DigiTapParams(digitapParams)))
}
@Parcelize
data class HyperVergePanVerificationPayload(
@SerializedName("verifyPanDocumentPayload") val verifyPanDocumentPayload: HyperVergePanUploadRequestData? = null,
@SerializedName("verifyPanDocumentPayload")
val verifyPanDocumentPayload: HyperVergePanUploadRequestData? = null,
) : Parcelable, PayLoadData()
@Parcelize
data class DigiLockerPanVerificationPayload(
@SerializedName("verifyDigilockerPayload") val verifyDigilockerPayload: DigilockerPANVerificationData? = null,
@SerializedName("verifyDigilockerPayload")
val verifyDigilockerPayload: DigilockerPANVerificationData? = null,
) : Parcelable, PayLoadData()
@Parcelize
@@ -56,5 +68,4 @@ data class KycMetadata(
@SerializedName("businessUnit") var businessUnit: String? = null,
) : Parcelable
@Parcelize
open class PayLoadData : Parcelable
@Parcelize open class PayLoadData : Parcelable

View File

@@ -1,3 +1,10 @@
/*
*
* * Copyright © 2024 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.navi.ap.common.models.lambdamodels
import android.os.Parcelable

View File

@@ -1,3 +1,10 @@
/*
*
* * Copyright © 2024 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.navi.ap.common.models.lambdamodels
import android.os.Parcelable
@@ -7,4 +14,4 @@ import kotlinx.parcelize.RawValue
@Parcelize
data class LambdaData(
val resolvedValue: @RawValue Map<String, Any?>,
) : Parcelable
) : Parcelable

View File

@@ -1,3 +1,10 @@
/*
*
* * Copyright © 2024 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.navi.ap.common.models.lambdamodels
import android.os.Parcelable
@@ -34,4 +41,4 @@ data class EmiDetails(
data class EmiChange(
@SerializedName("originalAmount") val originalAmount: String? = null,
@SerializedName("changedAmount") val changedAmount: String? = null,
) : Parcelable
) : Parcelable

View File

@@ -1,5 +1,11 @@
package com.navi.ap.common.models.lambdamodels
/*
*
* * Copyright © 2024 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.navi.ap.common.models.lambdamodels
data class OfferDetails(
val loanAmount: LoanAmountDetails,
@@ -15,4 +21,4 @@ data class OfferDetails(
val unit: String,
val value: String,
)
}
}

View File

@@ -16,7 +16,7 @@ data class PGTokenResponse(
)
data class PGTokenRequest(
@SerializedName("apApplicationId") val applicationId : String? = null,
@SerializedName("apApplicationId") val applicationId: String? = null,
@SerializedName("loanApplicationId") val loanApplicationId: String? = null,
@SerializedName("mandateAuthType") val mandateAuthType: String? = null,
@SerializedName("applicationType") val applicationType: String? = null

View File

@@ -23,6 +23,4 @@ data class RPDPaymentMethodDetails(
@SerializedName("methodDetails") val methodDetails: Map<String, String>? = null
)
data class RPDTokenDetails(
@SerializedName("requestId") val requestId: String? = null
)
data class RPDTokenDetails(@SerializedName("requestId") val requestId: String? = null)

View File

@@ -1,10 +1,15 @@
/*
*
* * Copyright © 2024 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.navi.ap.common.models.lambdamodels
import com.google.gson.annotations.SerializedName
data class VKYCLottieCardData(
@SerializedName("numActiveAgents")
val numberOfActiveAgents: Int? = null,
@SerializedName("avgTimeToCall")
val avgTimeToCall: Long? = null
@SerializedName("numActiveAgents") val numberOfActiveAgents: Int? = null,
@SerializedName("avgTimeToCall") val avgTimeToCall: Long? = null
)

View File

@@ -1,3 +1,10 @@
/*
*
* * Copyright © 2024 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.navi.ap.common.models.lambdamodels
import android.os.Parcelable

View File

@@ -1,3 +1,10 @@
/*
*
* * Copyright © 2024 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.navi.ap.common.renderer
import androidx.compose.foundation.background
@@ -58,8 +65,9 @@ class CalendarWidget {
fun Render(viewModel: UiTronViewModel, widget: WidgetModelDefinition<UiTronResponse>) {
val calendarWidgetData: CalendarWidgetData? =
widget.widgetData?.data?.get("$WIDGET_DATA${widget.widgetId}") as? CalendarWidgetData
val updatedSelectedDate = viewModel.handle.get<Int>(SELECTED_RAW_DATE)
?: calendarWidgetData?.selectedDate?.toIntOrNull()
val updatedSelectedDate =
viewModel.handle.get<Int>(SELECTED_RAW_DATE)
?: calendarWidgetData?.selectedDate?.toIntOrNull()
CalendarView(
selectedDateInitial = updatedSelectedDate,
calendarWidgetData = calendarWidgetData ?: CalendarWidgetData(),
@@ -69,8 +77,8 @@ class CalendarWidget {
}
/**
* A calendar view displaying a grid of dates for a specific month with 31 days,
* with the ability to select a date.
* A calendar view displaying a grid of dates for a specific month with 31 days, with the
* ability to select a date.
*/
@Composable
private fun CalendarView(
@@ -90,19 +98,24 @@ class CalendarWidget {
if (selectedDate == null) return@LaunchedEffect
viewModel.handle[calendarWidgetData.layoutId.getInputId()] = selectedDate.toString()
viewModel.handle[SELECTED_RAW_DATE] = selectedDate
calendarWidgetData.emiDate?.firstOrNull { it.rawDate == selectedDate }?.let {
viewModel.handle[SELECTED_FORMATTED_DATE] = it.formattedDate
calendarWidgetData.emiDate
?.firstOrNull { it.rawDate == selectedDate }
?.let {
viewModel.handle[SELECTED_FORMATTED_DATE] = it.formattedDate
val updatedAction = FieldInjector<UiTronActionData, Any>().injectData(
onClickAction, mapOf(
SELECTED_DATE to it.textInWords,
SELECTED_DATE_WITH_SUFFIX to it.dateWithSuffix,
SELECTED_RAW_DATE to selectedDate.toString(),
SELECTED_FORMATTED_DATE to it.formattedDate,
)
)
viewModel.handleActions(updatedAction)
}
val updatedAction =
FieldInjector<UiTronActionData, Any>()
.injectData(
onClickAction,
mapOf(
SELECTED_DATE to it.textInWords,
SELECTED_DATE_WITH_SUFFIX to it.dateWithSuffix,
SELECTED_RAW_DATE to selectedDate.toString(),
SELECTED_FORMATTED_DATE to it.formattedDate,
)
)
viewModel.handleActions(updatedAction)
}
}
CalendarGrid(
disabledDates = disabledDates,
@@ -110,13 +123,10 @@ class CalendarWidget {
selectedDate = selectedDate,
calendarWidgetData = calendarWidgetData,
viewModel = viewModel,
onDateSelected = {
selectedDate = it
},
onDateSelected = { selectedDate = it },
)
}
/**
* A grid layout representing a calendar month.
*
@@ -163,7 +173,6 @@ class CalendarWidget {
* @param isDisabled Whether this date is disabled.
* @param onClick The action to perform when this box is clicked.
*/
@Composable
private fun DateColumn(
day: Int,
@@ -175,23 +184,22 @@ class CalendarWidget {
val backgroundColor =
if (isSelected)
calendarWidgetData.calendarColors?.selectedDateColor?.hexToComposeColor ?: Color(
SELECTED_COLOR
)
calendarWidgetData.calendarColors?.selectedDateColor?.hexToComposeColor
?: Color(SELECTED_COLOR)
else Color.Transparent
val textColor = getDateTextColor(isSelected, isDisabled, calendarWidgetData.calendarColors)
val dateColumnModifier = Modifier
.width(calendarWidgetData.dateBoxSize?.toInt()?.dp ?: 26.dp)
.height(calendarWidgetData.dateBoxSize?.toInt()?.dp ?: 26.dp)
.background(backgroundColor, CircleShape)
.clickable(
enabled = !isDisabled,
indication = null,
interactionSource = remember { MutableInteractionSource() },
onClick = onClick
)
val dateColumnModifier =
Modifier.width(calendarWidgetData.dateBoxSize?.toInt()?.dp ?: 26.dp)
.height(calendarWidgetData.dateBoxSize?.toInt()?.dp ?: 26.dp)
.background(backgroundColor, CircleShape)
.clickable(
enabled = !isDisabled,
indication = null,
interactionSource = remember { MutableInteractionSource() },
onClick = onClick
)
Column(
modifier = dateColumnModifier,
@@ -207,7 +215,6 @@ class CalendarWidget {
color = textColor,
)
}
}
/**
@@ -216,8 +223,9 @@ class CalendarWidget {
* @param T The type of the data being displayed in the grid.
* @param items The list of items to be displayed in the grid.
* @param rows The number of rows in the grid.
* @param itemContent A composable function describing how each item in [items] should be displayed.
* The function signature provides a [BoxScope] receiver scope and the current item as a parameter.
* @param itemContent A composable function describing how each item in [items] should be
* displayed. The function signature provides a [BoxScope] receiver scope and the current item
* as a parameter.
*/
@Composable
private fun <T> Grid(
@@ -228,48 +236,55 @@ class CalendarWidget {
itemContent: @Composable BoxScope.(T) -> Unit
) {
var showErrorState by remember {
mutableStateOf(false)
}
var showErrorState by remember { mutableStateOf(false) }
LaunchedEffect(Unit) {
viewModel.handle.getStateFlow<String?>(
calendarWidgetData.errorLayoutId.toString(), null
).collect {
showErrorState = it == SHOW
}
viewModel.handle
.getStateFlow<String?>(calendarWidgetData.errorLayoutId.toString(), null)
.collect { showErrorState = it == SHOW }
}
Column(
modifier = Modifier
.fillMaxWidth()
.padding(
calendarWidgetData.calendarProperties?.padding?.start?.dp ?: 16.dp,
calendarWidgetData.calendarProperties?.padding?.top?.dp ?: 16.dp,
calendarWidgetData.calendarProperties?.padding?.end?.dp ?: 16.dp,
calendarWidgetData.calendarProperties?.padding?.bottom?.dp ?: 0.dp
)
.border(
width = calendarWidgetData.calendarProperties?.borderStrokeData?.width?.dp
?: 1.dp,
color = when {
showErrorState -> calendarWidgetData.calendarColors?.calendarErrorBorderColor?.hexToComposeColor
?: Color(ERROR_STATE_COLOR)
else -> calendarWidgetData.calendarColors?.calendarBorderColor?.hexToComposeColor
?: Color(BORDER_COLOR)
},
shape = ShapeUtil.getShape(shape = calendarWidgetData.calendarProperties?.borderStrokeData?.shape)
)
.background(
color = calendarWidgetData.calendarProperties?.backgroundColor?.hexToComposeColor
?: Color.White,
)
modifier =
Modifier.fillMaxWidth()
.padding(
calendarWidgetData.calendarProperties?.padding?.start?.dp ?: 16.dp,
calendarWidgetData.calendarProperties?.padding?.top?.dp ?: 16.dp,
calendarWidgetData.calendarProperties?.padding?.end?.dp ?: 16.dp,
calendarWidgetData.calendarProperties?.padding?.bottom?.dp ?: 0.dp
)
.border(
width =
calendarWidgetData.calendarProperties?.borderStrokeData?.width?.dp
?: 1.dp,
color =
when {
showErrorState ->
calendarWidgetData.calendarColors
?.calendarErrorBorderColor
?.hexToComposeColor ?: Color(ERROR_STATE_COLOR)
else ->
calendarWidgetData.calendarColors
?.calendarBorderColor
?.hexToComposeColor ?: Color(BORDER_COLOR)
},
shape =
ShapeUtil.getShape(
shape =
calendarWidgetData.calendarProperties?.borderStrokeData?.shape
)
)
.background(
color =
calendarWidgetData.calendarProperties
?.backgroundColor
?.hexToComposeColor ?: Color.White,
)
) {
Column(
modifier = Modifier
.fillMaxWidth()
.padding(calendarWidgetData.calendarPadding?.toIntOrNull()?.dp ?: 16.dp),
modifier =
Modifier.fillMaxWidth()
.padding(calendarWidgetData.calendarPadding?.toIntOrNull()?.dp ?: 16.dp),
) {
for (i in 0 until rows) {
Row(
@@ -294,9 +309,9 @@ class CalendarWidget {
}
if (i != rows - 1) {
Spacer(
modifier = Modifier
.fillMaxWidth()
.height(calendarWidgetData.calendarRowGap?.toInt()?.dp ?: 10.dp)
modifier =
Modifier.fillMaxWidth()
.height(calendarWidgetData.calendarRowGap?.toInt()?.dp ?: 10.dp)
)
}
}
@@ -305,22 +320,25 @@ class CalendarWidget {
if (showErrorState) {
Row(modifier = Modifier.padding(start = 16.dp, end = 16.dp)) {
calendarWidgetData.errorIconProperty?.let {
ImageRenderer().Render(
property = it,
uiTronData = ImageData(
iconUrl = calendarWidgetData.errorImageUrl,
),
uiTronViewModel = viewModel,
modifier = null
)
ImageRenderer()
.Render(
property = it,
uiTronData =
ImageData(
iconUrl = calendarWidgetData.errorImageUrl,
),
uiTronViewModel = viewModel,
modifier = null
)
}
calendarWidgetData.errorTextProperty?.let {
TextRenderer().Render(
property = it,
uiTronData = calendarWidgetData.errorMessage,
uiTronViewModel = viewModel,
modifier = null
)
TextRenderer()
.Render(
property = it,
uiTronData = calendarWidgetData.errorMessage,
uiTronViewModel = viewModel,
modifier = null
)
}
}
}
@@ -331,16 +349,14 @@ class CalendarWidget {
isDisabled: Boolean,
calendarColors: CalendarWidgetData.CalendarColors?
): Color {
val textColor = if (isSelected) {
calendarColors?.selectedDateTextColor?.hexToComposeColor
?: Color.White
} else if (isDisabled) {
calendarColors?.disabledDateTextColor?.hexToComposeColor
?: Color(DISABLED_COLOR)
} else {
calendarColors?.defaultDateTextColor?.hexToComposeColor
?: Color(DEFAULT_COLOR)
}
val textColor =
if (isSelected) {
calendarColors?.selectedDateTextColor?.hexToComposeColor ?: Color.White
} else if (isDisabled) {
calendarColors?.disabledDateTextColor?.hexToComposeColor ?: Color(DISABLED_COLOR)
} else {
calendarColors?.defaultDateTextColor?.hexToComposeColor ?: Color(DEFAULT_COLOR)
}
return textColor
}
@@ -354,5 +370,4 @@ class CalendarWidget {
private const val DEFAULT_COLUMN_NUM = 7
private const val DEFAULT_COLUMN_MINUS_ONE = 6
}
}
}

View File

@@ -31,10 +31,8 @@ class CameraHelper {
* @param lifecycleOwner Lifecycle owner to manage the camera lifecycle.
* @param previewView The view to render the camera preview.
* @param imageCapture Instance of [ImageCapture] to capture images.
* @param cameraProviderFuture Future to obtain the
* [ProcessCameraProvider].
* @param onError Callback to be invoked when an error occurs during camera
* initialization.
* @param cameraProviderFuture Future to obtain the [ProcessCameraProvider].
* @param onError Callback to be invoked when an error occurs during camera initialization.
* @param onCameraReady Callback to indicate when the camera is ready.
*/
fun initializeCamera(
@@ -45,26 +43,36 @@ class CameraHelper {
onError: (ImageCaptureException) -> Unit,
onCameraReady: (Camera) -> Unit
) {
cameraProviderFuture.addListener({
try {
val cameraProvider: ProcessCameraProvider = cameraProviderFuture.get()
val preview = Preview.Builder().build().also {
it.setSurfaceProvider(previewView.surfaceProvider)
}
val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA
cameraProvider.unbindAll()
val camera = cameraProvider.bindToLifecycle(
lifecycleOwner, cameraSelector, preview, imageCapture
)
onCameraReady(camera)
} catch (exc: Exception) {
onError(
ImageCaptureException(
ImageCapture.ERROR_UNKNOWN, "Failed to bind camera", exc
cameraProviderFuture.addListener(
{
try {
val cameraProvider: ProcessCameraProvider = cameraProviderFuture.get()
val preview =
Preview.Builder().build().also {
it.setSurfaceProvider(previewView.surfaceProvider)
}
val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA
cameraProvider.unbindAll()
val camera =
cameraProvider.bindToLifecycle(
lifecycleOwner,
cameraSelector,
preview,
imageCapture
)
onCameraReady(camera)
} catch (exc: Exception) {
onError(
ImageCaptureException(
ImageCapture.ERROR_UNKNOWN,
"Failed to bind camera",
exc
)
)
)
}
}, ContextCompat.getMainExecutor(previewView.context))
}
},
ContextCompat.getMainExecutor(previewView.context)
)
}
/**
@@ -72,10 +80,8 @@ class CameraHelper {
*
* @param context Context for accessing resources.
* @param imageCapture Instance of [ImageCapture] to capture images.
* @param onImageCaptured Callback to be invoked with the URI of the
* captured image.
* @param onError Callback to be invoked when an error occurs during image
* capture.
* @param onImageCaptured Callback to be invoked with the URI of the captured image.
* @param onError Callback to be invoked when an error occurs during image capture.
*/
fun capturePhoto(
context: Context,
@@ -86,7 +92,8 @@ class CameraHelper {
val photoFile = BaseUtils.createFileWithTimeStamp(context, CAMERA_FILE_DATE_FORMAT)
val outputOptions = buildOutputOptions(photoFile)
imageCapture.takePicture(outputOptions,
imageCapture.takePicture(
outputOptions,
ContextCompat.getMainExecutor(context),
object : ImageCapture.OnImageSavedCallback {
override fun onImageSaved(output: ImageCapture.OutputFileResults) {
@@ -97,7 +104,8 @@ class CameraHelper {
override fun onError(exc: ImageCaptureException) {
onError(exc)
}
})
}
)
}
/**
@@ -109,5 +117,4 @@ class CameraHelper {
private fun buildOutputOptions(photoFile: File): ImageCapture.OutputFileOptions {
return ImageCapture.OutputFileOptions.Builder(photoFile).build()
}
}
}

View File

@@ -64,14 +64,11 @@ class CameraWidget {
private val cameraHelper: CameraHelper = CameraHelper()
/**
* Renders the camera widget based on the provided [widget] model
* definition. It handles camera permissions and displays the camera feed
* or captured photo.
* Renders the camera widget based on the provided [widget] model definition. It handles camera
* permissions and displays the camera feed or captured photo.
*
* @param widget The widget model definition containing the camera widget
* data.
* @param widget The widget model definition containing the camera widget data.
*/
@Composable
fun Render(widget: WidgetModelDefinition<UiTronResponse>, viewModel: ApplicationPlatformVM) {
val context = LocalContext.current
@@ -83,27 +80,25 @@ class CameraWidget {
capturedImageUri.value?.let { uri ->
viewModel.handle[CAPTURED_IMAGE_URI] = uri.toString()
viewModel.handleActions(cameraWidgetData?.captureButton?.captureButtonOnClickAction)
} ?: CameraWidgetContent(capturedImageUri = capturedImageUri.value,
onImageCaptured = { uri ->
capturedImageUri.value = uri
},
onError = { exception ->
showToast(context, "${CAPTURE_ERROR_MEESAGE}${exception.message}")
},
cameraWidgetData = cameraWidgetData,
viewModel = viewModel
)
}
?: CameraWidgetContent(
capturedImageUri = capturedImageUri.value,
onImageCaptured = { uri -> capturedImageUri.value = uri },
onError = { exception ->
showToast(context, "${CAPTURE_ERROR_MEESAGE}${exception.message}")
},
cameraWidgetData = cameraWidgetData,
viewModel = viewModel
)
}
/**
* Composable function that sets up the content of the camera widget. It
* initializes the camera and sets up the UI to capture images.
* Composable function that sets up the content of the camera widget. It initializes the camera
* and sets up the UI to capture images.
*
* @param onImageCaptured Callback function to handle the captured image
* URI.
* @param onImageCaptured Callback function to handle the captured image URI.
* @param onError Callback function to handle any image capture errors.
* @param cameraWidgetData The data model for the camera widget
* configuration.
* @param cameraWidgetData The data model for the camera widget configuration.
*/
@Composable
private fun CameraWidgetContent(
@@ -116,26 +111,25 @@ class CameraWidget {
val lifecycleOwner = LocalLifecycleOwner.current
val imageCapture = getImageCaptureConfig()
if (capturedImageUri.isNotNull()) GenericShimmerLoader()
else CameraInterface(
cameraWidgetData,
imageCapture,
lifecycleOwner,
onImageCaptured,
onError,
viewModel
)
else
CameraInterface(
cameraWidgetData,
imageCapture,
lifecycleOwner,
onImageCaptured,
onError,
viewModel
)
}
/**
* Composable function that defines the camera interface. It includes the
* camera feed preview and the capture button.
* Composable function that defines the camera interface. It includes the camera feed preview
* and the capture button.
*
* @param cameraWidgetData The data model for the camera widget
* configuration.
* @param cameraWidgetData The data model for the camera widget configuration.
* @param imageCapture The [ImageCapture] instance used to take photos.
* @param lifecycleOwner The lifecycle owner for the camera.
* @param onImageCaptured Callback function to handle the captured image
* URI.
* @param onImageCaptured Callback function to handle the captured image URI.
* @param onError Callback function to handle any image capture errors.
*/
@Composable
@@ -150,68 +144,67 @@ class CameraWidget {
val context = LocalContext.current
var isCameraReady by remember { mutableStateOf(false) }
Column(
modifier = Modifier
.fillMaxSize()
.padding(horizontal = cameraWidgetData?.windowPadding?.start?.dp ?: 0.dp)
modifier =
Modifier.fillMaxSize()
.padding(horizontal = cameraWidgetData?.windowPadding?.start?.dp ?: 0.dp)
) {
CameraText(cameraWidgetData,viewModel)
CameraText(cameraWidgetData, viewModel)
CameraFeedPreview(
lifecycleOwner,
imageCapture,
onError,
context,
onCameraReady = { ready -> isCameraReady = ready })
onCameraReady = { ready -> isCameraReady = ready }
)
CaptureButton(cameraWidgetData) {
cameraHelper.capturePhoto(
context, imageCapture, onImageCaptured, onError
)
cameraHelper.capturePhoto(context, imageCapture, onImageCaptured, onError)
}
}
}
/**
* Remembers and provides an [ImageCapture] instance with predefined
* configurations.
* Remembers and provides an [ImageCapture] instance with predefined configurations.
*
* @return Configured [ImageCapture] instance.
*/
@Composable
private fun getImageCaptureConfig(): ImageCapture {
return remember {
ImageCapture.Builder().setCaptureMode(CAPTURE_MODE_MAXIMIZE_QUALITY)
.setFlashMode(FLASH_MODE_AUTO).build()
ImageCapture.Builder()
.setCaptureMode(CAPTURE_MODE_MAXIMIZE_QUALITY)
.setFlashMode(FLASH_MODE_AUTO)
.build()
}
}
/**
* Displays instructional title text for the camera widget.
*
* @param cameraWidgetData Data model containing text properties for the
* widget.
* @param cameraWidgetData Data model containing text properties for the widget.
*/
@Composable
private fun CameraText(cameraWidgetData: CameraWidgetData?,viewModel: UiTronViewModel) {
TextRenderer().Render(
property = cameraWidgetData?.headingTextProperty?: TextProperty(),
uiTronData = cameraWidgetData?.headingTextData.apply {
this?.text = cameraWidgetData?.headingTextData?.text
},
uiTronViewModel = viewModel,
modifier = null
)
private fun CameraText(cameraWidgetData: CameraWidgetData?, viewModel: UiTronViewModel) {
TextRenderer()
.Render(
property = cameraWidgetData?.headingTextProperty ?: TextProperty(),
uiTronData =
cameraWidgetData?.headingTextData.apply {
this?.text = cameraWidgetData?.headingTextData?.text
},
uiTronViewModel = viewModel,
modifier = null
)
}
/**
* Sets up and displays the camera preview in the UI.
*
* This composable function initializes the camera using the provided
* lifecycle owner and image capture configuration. It handles the camera
* lifecycle, ensuring the camera is ready for use when the preview
* is active and released when the view is disposed. Errors during
* camera operation are communicated back through the onError callback.
* This composable function initializes the camera using the provided lifecycle owner and image
* capture configuration. It handles the camera lifecycle, ensuring the camera is ready for use
* when the preview is active and released when the view is disposed. Errors during camera
* operation are communicated back through the onError callback.
*
* @param lifecycleOwner The component responsible for the camera's
* lifecycle.
* @param lifecycleOwner The component responsible for the camera's lifecycle.
* @param imageCapture Configuration for image capture functionality.
* @param onError Callback for handling image capture errors.
* @param context Application context for resource access.
@@ -226,19 +219,17 @@ class CameraWidget {
onCameraReady: (Boolean) -> Unit
) {
val previewView = remember { PreviewView(context) }
val cameraProviderFuture = remember {
ProcessCameraProvider.getInstance(context)
}
val cameraProviderFuture = remember { ProcessCameraProvider.getInstance(context) }
DisposableEffect(key1 = cameraProviderFuture) {
val cameraProvider: ProcessCameraProvider = cameraProviderFuture.get()
cameraHelper.initializeCamera(lifecycleOwner,
cameraHelper.initializeCamera(
lifecycleOwner,
previewView,
imageCapture,
cameraProviderFuture,
onError = { exception ->
onError(exception)
},
onCameraReady = { onCameraReady(true) })
onError = { exception -> onError(exception) },
onCameraReady = { onCameraReady(true) }
)
onDispose {
cameraProvider.unbindAll()
onCameraReady(false)
@@ -246,12 +237,11 @@ class CameraWidget {
}
AndroidView(
factory = { previewView },
modifier = Modifier
.fillMaxWidth()
.fillMaxHeight(IMAGE_PREVIEW_HEIGHT)
.clip(RoundedCornerShape(CORNER_RADIUS))
modifier =
Modifier.fillMaxWidth()
.fillMaxHeight(IMAGE_PREVIEW_HEIGHT)
.clip(RoundedCornerShape(CORNER_RADIUS))
)
}
/**
@@ -266,8 +256,7 @@ class CameraWidget {
) {
val buttonProperties = cameraWidgetData?.captureButton
val outerCircleModifier = remember {
Modifier
.size(buttonProperties?.outerCircleSize?.dp ?: 0.dp)
Modifier.size(buttonProperties?.outerCircleSize?.dp ?: 0.dp)
.clip(CircleShape)
.background(
buttonProperties?.circleColor?.hexToComposeColor ?: Color(DEFAULT_COLOR)
@@ -276,8 +265,7 @@ class CameraWidget {
}
val innerCircleModifier = remember {
Modifier
.size(buttonProperties?.innerCircleSize?.dp ?: 0.dp)
Modifier.size(buttonProperties?.innerCircleSize?.dp ?: 0.dp)
.clip(CircleShape)
.background(
buttonProperties?.circleColor?.hexToComposeColor ?: Color(DEFAULT_COLOR)
@@ -285,9 +273,7 @@ class CameraWidget {
.border(CAPTURE_BUTTON_INNER_BORDER_WIDTH, Color.White, CircleShape)
}
Row(
modifier = Modifier
.fillMaxWidth()
.fillMaxHeight(),
modifier = Modifier.fillMaxWidth().fillMaxHeight(),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Center
) {
@@ -297,7 +283,6 @@ class CameraWidget {
}
}
companion object {
const val IMAGE_PREVIEW_HEIGHT = 0.8f
val CORNER_RADIUS = 4.dp
@@ -305,6 +290,3 @@ class CameraWidget {
val CAPTURE_BUTTON_INNER_BORDER_WIDTH = 2.dp
}
}

View File

@@ -1,3 +1,10 @@
/*
*
* * Copyright © 2024 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.navi.ap.common.renderer
import androidx.compose.foundation.BorderStroke
@@ -21,8 +28,8 @@ import androidx.hilt.navigation.compose.hiltViewModel
import com.navi.ap.common.models.CardWithHeaderFooterAndLazyColumnWidgetData
import com.navi.ap.common.models.UiTronResponseWithType
import com.navi.ap.common.models.WidgetModelDefinition
import com.navi.ap.common.viewmodel.CardWithHeaderFooterAndLazyColumnVM
import com.navi.ap.common.viewmodel.ApplicationPlatformVM
import com.navi.ap.common.viewmodel.CardWithHeaderFooterAndLazyColumnVM
import com.navi.ap.utils.constants.WIDGET_DATA
import com.navi.base.utils.orFalse
import com.navi.uitron.model.UiTronResponse
@@ -31,7 +38,6 @@ import com.navi.uitron.utils.ShapeUtil
import com.navi.uitron.viewmodel.UiTronViewModel
import hexToComposeColor
class CardWithHeaderFooterAndLazyColumnWidget {
@OptIn(ExperimentalFoundationApi::class)
@@ -42,58 +48,61 @@ class CardWithHeaderFooterAndLazyColumnWidget {
viewModel: CardWithHeaderFooterAndLazyColumnVM = hiltViewModel(),
) {
val widgetData = remember {
widget.widgetData?.data?.get("${WIDGET_DATA}${widget.widgetId}") as? CardWithHeaderFooterAndLazyColumnWidgetData
widget.widgetData?.data?.get("${WIDGET_DATA}${widget.widgetId}")
as? CardWithHeaderFooterAndLazyColumnWidgetData
}
val containerProperty = widgetData?.containerProperty
val widgetListState = remember {
mutableStateListOf<UiTronResponseWithType>()
}
val widgetListState = remember { mutableStateListOf<UiTronResponseWithType>() }
LaunchedEffect(Unit) {
viewModel.getLazyColumnWidgetList(
widgetData, widgetData?.listData, widgetListState
)
viewModel.getLazyColumnWidgetList(widgetData, widgetData?.listData, widgetListState)
}
Column(
modifier = Modifier
.background(containerProperty?.backGroundColor?.hexToComposeColor ?: Color.White)
.padding(containerProperty?.padding?.dp ?: 16.dp)
modifier =
Modifier.background(
containerProperty?.backGroundColor?.hexToComposeColor ?: Color.White
)
.padding(containerProperty?.padding?.dp ?: 16.dp)
) {
Column(
modifier = Modifier.border(
border = BorderStroke(
containerProperty?.borderStrokeData?.width?.dp ?: 1.dp,
containerProperty?.borderStrokeData?.color?.hexToComposeColor
?: Color.Gray
),
shape = ShapeUtil.getShape(shape = containerProperty?.borderStrokeData?.shape)
)
modifier =
Modifier.border(
border =
BorderStroke(
containerProperty?.borderStrokeData?.width?.dp ?: 1.dp,
containerProperty?.borderStrokeData?.color?.hexToComposeColor
?: Color.Gray
),
shape =
ShapeUtil.getShape(shape = containerProperty?.borderStrokeData?.shape)
)
) {
UiRenderer(uiTronResponse = widgetData?.header, viewModel = applicationPlatformVM)
LazyColumn(
modifier = Modifier
.heightIn(Dp.Unspecified, 400.dp) //mention max height here
.offset(
y = containerProperty?.verticalOffset?.dp ?: 0.dp
)
modifier =
Modifier.heightIn(Dp.Unspecified, 400.dp) // mention max height here
.offset(y = containerProperty?.verticalOffset?.dp ?: 0.dp)
) {
widgetListState.forEach { widgetViewWithType ->
val widgetView = widgetViewWithType.uiTronResponse
when {
widgetViewWithType.isSticky.orFalse() -> {
stickyHeader {
UiRenderer(uiTronResponse = widgetView, viewModel = applicationPlatformVM)
UiRenderer(
uiTronResponse = widgetView,
viewModel = applicationPlatformVM
)
}
}
else -> {
item {
UiRenderer(uiTronResponse = widgetView, viewModel = applicationPlatformVM)
UiRenderer(
uiTronResponse = widgetView,
viewModel = applicationPlatformVM
)
}
}
}
@@ -108,9 +117,7 @@ class CardWithHeaderFooterAndLazyColumnWidget {
@Composable
private fun UiRenderer(uiTronResponse: UiTronResponse?, viewModel: UiTronViewModel) {
uiTronResponse?.parentComposeView?.let {
UiTronRenderer(
uiTronResponse.data, viewModel
).Render(composeViews = it)
UiTronRenderer(uiTronResponse.data, viewModel).Render(composeViews = it)
}
}
}
}

View File

@@ -72,13 +72,13 @@ class CollapsableItemsWithTitleWidget {
) {
TextRenderer()
.Render(
property = titleDescriptionListWidgetData.itemTitleProperty
property =
titleDescriptionListWidgetData.itemTitleProperty
?: TextProperty(),
uiTronData =
titleDescriptionListWidgetData.itemTitleData?.apply {
text = it.title
}
?: TextData(text = it.title),
} ?: TextData(text = it.title),
uiTronViewModel = viewModel,
modifier = null
)
@@ -96,13 +96,13 @@ class CollapsableItemsWithTitleWidget {
AnimatedVisibility(visible = expand.value) {
TextRenderer()
.Render(
property = titleDescriptionListWidgetData.itemDescriptionProperty
property =
titleDescriptionListWidgetData.itemDescriptionProperty
?: TextProperty(),
uiTronData =
titleDescriptionListWidgetData.itemTitleData?.apply {
text = it.description
}
?: TextData(text = it.description),
} ?: TextData(text = it.description),
uiTronViewModel = viewModel,
modifier = null
)

View File

@@ -1,3 +1,10 @@
/*
*
* * Copyright © 2024 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.navi.ap.common.renderer
import androidx.compose.foundation.layout.heightIn
@@ -35,35 +42,34 @@ class DynamicColumnWidget {
widget: WidgetModelDefinition<UiTronResponse>,
dynamicWidgetVM: DynamicWidgetVM = hiltViewModel(),
) {
val columnWidgetData = widget.widgetData?.data?.get("${WIDGET_DATA}${widget.widgetId}") as? DynamicColumnWidgetData
val listData = viewModel.handle.getStateFlow(
"${COLUMN_DATA}${widget.widgetId}",
columnWidgetData?.listData
).collectAsState()
val columnWidgetData =
widget.widgetData?.data?.get("${WIDGET_DATA}${widget.widgetId}")
as? DynamicColumnWidgetData
val listData =
viewModel.handle
.getStateFlow("${COLUMN_DATA}${widget.widgetId}", columnWidgetData?.listData)
.collectAsState()
val widgetListState = remember {
mutableStateListOf<WidgetModelDefinition<UiTronResponse>>()
}
var job: Job? by remember {
mutableStateOf(null)
}
var job: Job? by remember { mutableStateOf(null) }
LaunchedEffect(listData.value) {
job?.cancel()
job = dynamicWidgetVM.getWidgetList(widget, listData.value, widgetListState)
}
if (listData.value?.isNotEmpty() == true) {
LazyColumn(
modifier = Modifier.heightIn(
columnWidgetData?.minColumnHeight?.dp ?: MIN_SIZE.dp,
columnWidgetData?.maxColumnHeight?.dp ?: MAX_SIZE.dp
),
modifier =
Modifier.heightIn(
columnWidgetData?.minColumnHeight?.dp ?: MIN_SIZE.dp,
columnWidgetData?.maxColumnHeight?.dp ?: MAX_SIZE.dp
),
flingBehavior = maxScrollFlingBehavior()
) {
itemsIndexed(widgetListState) { index, widgetView ->
widgetView.widgetData?.parentComposeView?.let {
UiTronRenderer(
widgetView.widgetData.data,
viewModel
).Render(composeViews = it)
UiTronRenderer(widgetView.widgetData.data, viewModel)
.Render(composeViews = it)
}
columnWidgetData?.dividerProperty?.let {
if (index != widgetListState.size - 1) {
@@ -78,4 +84,4 @@ class DynamicColumnWidget {
companion object {
const val COLUMN_DATA = "column_data_"
}
}
}

View File

@@ -1,3 +1,10 @@
/*
*
* * Copyright © 2024 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.navi.ap.common.renderer
import androidx.compose.foundation.layout.Arrangement
@@ -37,21 +44,33 @@ import setVerticalArrangement
class DynamicGridWidget {
@Composable
fun Render(viewModel: ApplicationPlatformVM, widget: WidgetModelDefinition<UiTronResponse>,dynamicWidgetVM: DynamicWidgetVM = hiltViewModel()) {
val gridWidgetData = widget.widgetData?.data?.get("${WIDGET_DATA}${widget.widgetId}") as? DynamicGridWidgetData
val listData = viewModel.handle.getStateFlow("${GRID_DATA}${widget.widgetId}", gridWidgetData?.listData).collectAsState()
fun Render(
viewModel: ApplicationPlatformVM,
widget: WidgetModelDefinition<UiTronResponse>,
dynamicWidgetVM: DynamicWidgetVM = hiltViewModel()
) {
val gridWidgetData =
widget.widgetData?.data?.get("${WIDGET_DATA}${widget.widgetId}")
as? DynamicGridWidgetData
val listData =
viewModel.handle
.getStateFlow("${GRID_DATA}${widget.widgetId}", gridWidgetData?.listData)
.collectAsState()
val widgetListState = remember {
mutableStateListOf<WidgetModelDefinition<UiTronResponse>>()
}
var job: Job? by remember {
mutableStateOf(null)
}
var job: Job? by remember { mutableStateOf(null) }
LaunchedEffect(listData.value) {
job?.cancel()
job = dynamicWidgetVM.getWidgetList(widget, listData.value, widgetListState)
}
val modifier = Modifier.setPadding(gridWidgetData?.padding).heightIn(gridWidgetData?.minGridSize?.dp ?: MIN_SIZE.dp, gridWidgetData?.maxGridSize?.dp ?: MAX_SIZE.dp)
if(listData.value?.isNotEmpty() == true){
val modifier =
Modifier.setPadding(gridWidgetData?.padding)
.heightIn(
gridWidgetData?.minGridSize?.dp ?: MIN_SIZE.dp,
gridWidgetData?.maxGridSize?.dp ?: MAX_SIZE.dp
)
if (listData.value?.isNotEmpty() == true) {
if (gridWidgetData?.orientation == LazyGridProperty.ORIENTATION_HORIZONTAL) {
LazyHorizontalGrid(
modifier = modifier,
@@ -60,8 +79,14 @@ class DynamicGridWidget {
content = {
getContent(viewModel = viewModel, widgetListState = widgetListState)
},
horizontalArrangement = Arrangement.setHorizontalArrangement(arrangementData = gridWidgetData.horizontalArrangementData),
verticalArrangement = Arrangement.setVerticalArrangement(arrangementData = gridWidgetData.verticalArrangementData)
horizontalArrangement =
Arrangement.setHorizontalArrangement(
arrangementData = gridWidgetData.horizontalArrangementData
),
verticalArrangement =
Arrangement.setVerticalArrangement(
arrangementData = gridWidgetData.verticalArrangementData
)
)
} else {
LazyVerticalGrid(
@@ -71,31 +96,42 @@ class DynamicGridWidget {
content = {
getContent(viewModel = viewModel, widgetListState = widgetListState)
},
horizontalArrangement = Arrangement.setHorizontalArrangement(arrangementData = gridWidgetData?.horizontalArrangementData),
verticalArrangement = Arrangement.setVerticalArrangement(arrangementData = gridWidgetData?.verticalArrangementData)
horizontalArrangement =
Arrangement.setHorizontalArrangement(
arrangementData = gridWidgetData?.horizontalArrangementData
),
verticalArrangement =
Arrangement.setVerticalArrangement(
arrangementData = gridWidgetData?.verticalArrangementData
)
)
}
}
}
@Composable
private fun getGridCells(
gridWidgetData: DynamicGridWidgetData?
) = if (gridWidgetData?.gridCell?.gridType == LazyGridProperty.GRID_TYPE_ADAPTIVE) {
GridCells.Adaptive(
(if ((gridWidgetData.gridCell.minSize ?: MIN_GRID_CELL_SIZE) > 0) {
gridWidgetData.gridCell.minSize ?: MIN_GRID_CELL_SIZE
} else {
MIN_GRID_CELL_SIZE
}).dp
)
} else {
GridCells.Fixed(gridWidgetData?.gridCell?.count ?: MIN_GRID_CELL_COUNT)
}
private fun getGridCells(gridWidgetData: DynamicGridWidgetData?) =
if (gridWidgetData?.gridCell?.gridType == LazyGridProperty.GRID_TYPE_ADAPTIVE) {
GridCells.Adaptive(
(if ((gridWidgetData.gridCell.minSize ?: MIN_GRID_CELL_SIZE) > 0) {
gridWidgetData.gridCell.minSize ?: MIN_GRID_CELL_SIZE
} else {
MIN_GRID_CELL_SIZE
})
.dp
)
} else {
GridCells.Fixed(gridWidgetData?.gridCell?.count ?: MIN_GRID_CELL_COUNT)
}
fun LazyGridScope.getContent(viewModel: ApplicationPlatformVM, widgetListState: SnapshotStateList<WidgetModelDefinition<UiTronResponse>>) {
items(widgetListState){ widgetView ->
widgetView.widgetData?.parentComposeView?.let { UiTronRenderer(widgetView.widgetData.data, viewModel).Render(composeViews = it) }
fun LazyGridScope.getContent(
viewModel: ApplicationPlatformVM,
widgetListState: SnapshotStateList<WidgetModelDefinition<UiTronResponse>>
) {
items(widgetListState) { widgetView ->
widgetView.widgetData?.parentComposeView?.let {
UiTronRenderer(widgetView.widgetData.data, viewModel).Render(composeViews = it)
}
}
}
@@ -104,4 +140,4 @@ class DynamicGridWidget {
const val MIN_GRID_CELL_COUNT = 3
const val GRID_DATA = "grid_data_"
}
}
}

View File

@@ -39,43 +39,47 @@ class DynamicRadioGroupWithSectionsWidget {
dynamicWidgetVM: DynamicWidgetVM = hiltViewModel(),
) {
val dynamicRadioGroupWithSectionsWidgetData =
widget.widgetData?.data?.get("${WIDGET_DATA}${widget.widgetId}") as? DynamicRadioGroupWithSectionsWidgetData
widget.widgetData?.data?.get("${WIDGET_DATA}${widget.widgetId}")
as? DynamicRadioGroupWithSectionsWidgetData
val radioGroupList = remember {
mutableStateMapOf<String, MutableList<DynamicRadioGroupWithSectionsWidgetData.RadioItem?>>()
mutableStateMapOf<
String, MutableList<DynamicRadioGroupWithSectionsWidgetData.RadioItem?>
>()
}
LaunchedEffect(Unit) {
dynamicWidgetVM.getSectionRadioGroupList(
dynamicRadioGroupWithSectionsWidgetData, radioGroupList
dynamicRadioGroupWithSectionsWidgetData,
radioGroupList
)
}
Column {
radioGroupList.forEach { (key, radioItems) ->
if (radioItems.isEmpty()) return@forEach
dynamicRadioGroupWithSectionsWidgetData?.sectionViewList?.get(key)?.title?.let { title ->
UiTronRenderer(
title.data, viewModel
).Render(composeViews = title.parentComposeView.orEmpty())
dynamicRadioGroupWithSectionsWidgetData?.sectionViewList?.get(key)?.title?.let {
title ->
UiTronRenderer(title.data, viewModel)
.Render(composeViews = title.parentComposeView.orEmpty())
}
radioItems.forEachIndexed { index, radioItem ->
Row(
modifier = Modifier
.wrapContentHeight()
.wrapContentWidth()
.clickable(interactionSource = MutableInteractionSource(),
indication = null,
onClick = {
setSelection(
sectionIndex = key,
radioGroupList = radioGroupList,
selectedIndex = index,
viewModel = viewModel
)
})
modifier =
Modifier.wrapContentHeight()
.wrapContentWidth()
.clickable(
interactionSource = MutableInteractionSource(),
indication = null,
onClick = {
setSelection(
sectionIndex = key,
radioGroupList = radioGroupList,
selectedIndex = index,
viewModel = viewModel
)
}
)
) {
UiTronRenderer(
radioItem?.item?.data, viewModel
).Render(composeViews = radioItem?.item?.parentComposeView.orEmpty())
UiTronRenderer(radioItem?.item?.data, viewModel)
.Render(composeViews = radioItem?.item?.parentComposeView.orEmpty())
if (radioItem?.isSelected.toBoolean()) {
viewModel.handleActions(radioItem?.selectedAction)
}
@@ -87,7 +91,10 @@ class DynamicRadioGroupWithSectionsWidget {
private fun setSelection(
sectionIndex: String,
radioGroupList: SnapshotStateMap<String, MutableList<DynamicRadioGroupWithSectionsWidgetData.RadioItem?>>,
radioGroupList:
SnapshotStateMap<
String, MutableList<DynamicRadioGroupWithSectionsWidgetData.RadioItem?>
>,
selectedIndex: Int,
viewModel: ApplicationPlatformVM,
) {
@@ -103,11 +110,11 @@ class DynamicRadioGroupWithSectionsWidget {
}
}
} else {
radioItems.forEachIndexed { _ , radioItem ->
radioItems.forEachIndexed { _, radioItem ->
radioItem?.isSelected = FALSE
viewModel.handleActions(radioItem?.unSelectedAction)
}
}
}
}
}
}

View File

@@ -1,3 +1,10 @@
/*
*
* * Copyright © 2024 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.navi.ap.common.renderer
import androidx.compose.foundation.lazy.LazyRow
@@ -24,23 +31,33 @@ import kotlinx.coroutines.Job
class DynamicRowWidget {
@Composable
fun Render(viewModel: ApplicationPlatformVM, widget: WidgetModelDefinition<UiTronResponse>,dynamicWidgetVM: DynamicWidgetVM = hiltViewModel()) {
val rowWidgetData = widget.widgetData?.data?.get("$WIDGET_DATA${widget.widgetId}") as? DynamicRowWidgetData
val listData = viewModel.handle.getStateFlow("${ROW_DATA}${widget.widgetId}", rowWidgetData?.listData).collectAsState()
fun Render(
viewModel: ApplicationPlatformVM,
widget: WidgetModelDefinition<UiTronResponse>,
dynamicWidgetVM: DynamicWidgetVM = hiltViewModel()
) {
val rowWidgetData =
widget.widgetData?.data?.get("$WIDGET_DATA${widget.widgetId}") as? DynamicRowWidgetData
val listData =
viewModel.handle
.getStateFlow("${ROW_DATA}${widget.widgetId}", rowWidgetData?.listData)
.collectAsState()
val widgetListState = remember {
mutableStateListOf<WidgetModelDefinition<UiTronResponse>>()
}
var job: Job? by remember {
mutableStateOf(null)
}
var job: Job? by remember { mutableStateOf(null) }
LaunchedEffect(listData.value) {
job?.cancel()
job = dynamicWidgetVM.getWidgetList(widget, listData.value, widgetListState)
}
if(listData.value?.isNotEmpty() == true){
if (listData.value?.isNotEmpty() == true) {
LazyRow {
itemsIndexed(widgetListState){ index, widgetView, ->
widgetView.widgetData?.parentComposeView?.let { UiTronRenderer(widgetView.widgetData.data, viewModel).Render(composeViews = it) }
itemsIndexed(widgetListState) { index, widgetView,
->
widgetView.widgetData?.parentComposeView?.let {
UiTronRenderer(widgetView.widgetData.data, viewModel)
.Render(composeViews = it)
}
rowWidgetData?.dividerProperty?.let {
if (index != widgetListState.size - 1) {
DividerRenderer().Render(property = it, null, viewModel, null)
@@ -54,4 +71,4 @@ class DynamicRowWidget {
companion object {
const val ROW_DATA = "row_data_"
}
}
}

View File

@@ -1,3 +1,10 @@
/*
*
* * Copyright © 2024 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.navi.ap.common.renderer
import androidx.compose.foundation.clickable
@@ -37,24 +44,23 @@ import setBorderStroke
import setHeight
import setWidth
class MappedRadioListWidget {
@Composable
fun Render(viewModel: ApplicationPlatformVM, widget: WidgetModelDefinition<UiTronResponse>) {
val widgetData =
widget.widgetData?.data?.get("$WIDGET_DATA${widget.widgetId}") as? MappedRadioListWidgetData
widget.widgetData?.data?.get("$WIDGET_DATA${widget.widgetId}")
as? MappedRadioListWidgetData
val mappedRadioOptionList = remember {
viewModel.handle.get<List<SourceList>>(
"$MAPPED_RADIO_LIST${widget.widgetId}"
)
viewModel.handle.get<List<SourceList>>("$MAPPED_RADIO_LIST${widget.widgetId}")
}
val rootProperty = widget.widgetData?.parentComposeView?.firstOrNull()?.property
val groupItemList =
remember { mutableStateOf<List<MappedRadioListWidgetData.RadioWidgetResponse?>?>(null) }
val groupItemList = remember {
mutableStateOf<List<MappedRadioListWidgetData.RadioWidgetResponse?>?>(null)
}
LaunchedEffect(Unit) {
getUpdatedGroupItemList(
@@ -66,51 +72,53 @@ class MappedRadioListWidget {
}
Column(
modifier = Modifier
.setWidth(rootProperty?.width)
.setHeight(rootProperty?.height)
.layoutId(rootProperty?.layoutId.orEmpty())
.padding(
start = rootProperty?.margin?.start?.dp ?: 0.dp,
end = rootProperty?.margin?.end?.dp ?: 0.dp,
top = rootProperty?.margin?.top?.dp ?: 0.dp,
bottom = rootProperty?.margin?.bottom?.dp ?: 0.dp
)
.setBackground(
rootProperty?.backgroundColor,
rootProperty?.shape,
rootProperty?.backGroundBrushData
)
.padding(
start = rootProperty?.padding?.start?.dp ?: 0.dp,
end = rootProperty?.padding?.end?.dp ?: 0.dp,
top = rootProperty?.padding?.top?.dp ?: 0.dp,
bottom = rootProperty?.padding?.bottom?.dp ?: 0.dp
)
.alpha(rootProperty?.alpha ?: 1.0f)
.setBorderStroke(rootProperty?.borderStrokeData)
modifier =
Modifier.setWidth(rootProperty?.width)
.setHeight(rootProperty?.height)
.layoutId(rootProperty?.layoutId.orEmpty())
.padding(
start = rootProperty?.margin?.start?.dp ?: 0.dp,
end = rootProperty?.margin?.end?.dp ?: 0.dp,
top = rootProperty?.margin?.top?.dp ?: 0.dp,
bottom = rootProperty?.margin?.bottom?.dp ?: 0.dp
)
.setBackground(
rootProperty?.backgroundColor,
rootProperty?.shape,
rootProperty?.backGroundBrushData
)
.padding(
start = rootProperty?.padding?.start?.dp ?: 0.dp,
end = rootProperty?.padding?.end?.dp ?: 0.dp,
top = rootProperty?.padding?.top?.dp ?: 0.dp,
bottom = rootProperty?.padding?.bottom?.dp ?: 0.dp
)
.alpha(rootProperty?.alpha ?: 1.0f)
.setBorderStroke(rootProperty?.borderStrokeData)
) {
groupItemList.value?.mapIndexed { index, itemWidgetResponse ->
Row(modifier = Modifier
.wrapContentHeight()
.wrapContentWidth()
.clickable(interactionSource = MutableInteractionSource(),
indication = null,
onClick = {
if (itemWidgetResponse?.isDisabled.orFalse().not()) {
setSelection(
groupItemList = groupItemList.value,
selectedIndex = index,
viewModel = viewModel
)
}
})
Row(
modifier =
Modifier.wrapContentHeight()
.wrapContentWidth()
.clickable(
interactionSource = MutableInteractionSource(),
indication = null,
onClick = {
if (itemWidgetResponse?.isDisabled.orFalse().not()) {
setSelection(
groupItemList = groupItemList.value,
selectedIndex = index,
viewModel = viewModel
)
}
}
)
) {
UiTronRenderer(
itemWidgetResponse?.item?.data,
viewModel
).Render(composeViews = itemWidgetResponse?.item?.parentComposeView.orEmpty())
UiTronRenderer(itemWidgetResponse?.item?.data, viewModel)
.Render(
composeViews = itemWidgetResponse?.item?.parentComposeView.orEmpty()
)
if (itemWidgetResponse?.isSelected.orFalse()) {
viewModel.handleActions(itemWidgetResponse?.selectedAction)
@@ -153,13 +161,14 @@ class MappedRadioListWidget {
if (index == 0) {
itemWidgetResponse?.isSelected = true
}
itemWidgetResponse?.selectedAction = itemWidgetResponse?.selectedAction?.let {
FieldInjector<UiTronActionData, Any>().injectData(
it, mapOf(
SELECTED_SDK to item.sdkInOrder?.firstOrNull().orEmpty()
)
)
}
itemWidgetResponse?.selectedAction =
itemWidgetResponse?.selectedAction?.let {
FieldInjector<UiTronActionData, Any>()
.injectData(
it,
mapOf(SELECTED_SDK to item.sdkInOrder?.firstOrNull().orEmpty())
)
}
itemList.add(itemWidgetResponse)
}
groupItemList.value = itemList.toList()
@@ -170,5 +179,4 @@ class MappedRadioListWidget {
private const val MAPPED_RADIO_LIST = "mapped_radio_list_"
private const val SELECTED_SDK = "selectedSDK"
}
}
}

View File

@@ -1,3 +1,10 @@
/*
*
* * Copyright © 2024 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.navi.ap.common.renderer
import androidx.compose.foundation.layout.Arrangement
@@ -47,7 +54,9 @@ class StepTrackerWidget {
LaunchedEffect(Unit) {
viewModel.getStepTrackerWidgetsList(
widget, widgetListState, titleDescriptionListWidgetData
widget,
widgetListState,
titleDescriptionListWidgetData
)
}
@@ -56,37 +65,38 @@ class StepTrackerWidget {
if (widgetListState.isNotEmpty()) {
Card(
modifier = Modifier
.setWidth(cardProperty?.width)
.setHeight(cardProperty?.height)
.setPadding(cardProperty?.padding)
.shadow(
elevation = cardProperty?.elevation?.dp ?: 0.dp,
ambientColor = cardProperty?.ambientColor?.hexToComposeColor
?: DefaultShadowColor,
spotColor = cardProperty?.spotColor?.hexToComposeColor
?: DefaultShadowColor,
shape = ShapeUtil.getShape(shape = cardProperty?.shape)
),
modifier =
Modifier.setWidth(cardProperty?.width)
.setHeight(cardProperty?.height)
.setPadding(cardProperty?.padding)
.shadow(
elevation = cardProperty?.elevation?.dp ?: 0.dp,
ambientColor =
cardProperty?.ambientColor?.hexToComposeColor ?: DefaultShadowColor,
spotColor =
cardProperty?.spotColor?.hexToComposeColor ?: DefaultShadowColor,
shape = ShapeUtil.getShape(shape = cardProperty?.shape)
),
backgroundColor = cardProperty?.backgroundColor?.hexToComposeColor ?: Color.White,
elevation = cardProperty?.elevation?.dp ?: 0.dp
) {
Column(
modifier = Modifier
.fillMaxWidth()
.setPadding(titleDescriptionListWidgetData?.columnProperty?.padding),
verticalArrangement = Arrangement.setVerticalArrangement(arrangementData = columnProperty?.arrangementData),
horizontalAlignment = getHorizontalAlignment(horizontalAlignment = columnProperty?.horizontalAlignment),
) {
modifier =
Modifier.fillMaxWidth()
.setPadding(titleDescriptionListWidgetData?.columnProperty?.padding),
verticalArrangement =
Arrangement.setVerticalArrangement(
arrangementData = columnProperty?.arrangementData
),
horizontalAlignment =
getHorizontalAlignment(
horizontalAlignment = columnProperty?.horizontalAlignment
),
) {
widgetListState.forEachIndexed { index, widgetView ->
widgetView.widgetData?.parentComposeView?.let {
UiTronRenderer(
widgetView.widgetData.data, viewModel
).Render(composeViews = it)
UiTronRenderer(widgetView.widgetData.data, viewModel)
.Render(composeViews = it)
}
titleDescriptionListWidgetData?.dividerProperty?.let {
@@ -99,10 +109,8 @@ class StepTrackerWidget {
}
} else {
titleDescriptionListWidgetData?.shimmerView?.let {
UiTronRenderer(
null, viewModel
).Render(composeViews = it)
UiTronRenderer(null, viewModel).Render(composeViews = it)
}
}
}
}
}

View File

@@ -1,5 +1,11 @@
package com.navi.ap.common.sdk.digilocker.helper
/*
*
* * Copyright © 2024 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.navi.ap.common.sdk.digilocker.helper
import android.app.Activity
import androidx.appcompat.app.AppCompatActivity
@@ -19,15 +25,14 @@ import com.navi.base.utils.PROD
import com.navi.common.CommonLibManager
import com.navi.common.utils.getNetworkType
import com.navi.common.utils.log
import com.navi.design.R as DesignR
import `in`.digio.sdk.gateway.enums.DigioEnvironment
import `in`.digio.sdk.gateway.model.DigioConfig
import `in`.digio.sdk.gateway.model.DigioTheme
import `in`.digio.sdk.kyc.DigioWorkflowSession
import javax.inject.Inject
import com.navi.design.R as DesignR
class KycDigiLockerSdkHelper @Inject constructor(){
class KycDigiLockerSdkHelper @Inject constructor() {
private val digioWorkflowSession = DigioWorkflowSession()
@@ -72,7 +77,7 @@ class KycDigiLockerSdkHelper @Inject constructor(){
return config
}
private fun startDigioSession(data: DigiLockerSdkSettingData?, activity: Activity){
private fun startDigioSession(data: DigiLockerSdkSettingData?, activity: Activity) {
try {
digioWorkflowSession.start(
data?.requestId.orEmpty(),
@@ -90,5 +95,4 @@ class KycDigiLockerSdkHelper @Inject constructor(){
e.log()
}
}
}
}

View File

@@ -1,3 +1,10 @@
/*
*
* * Copyright © 2024 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.navi.ap.common.sdk.digilocker.listener
import com.navi.ap.common.sdk.digilocker.model.DigilockerPANVerificationData
@@ -7,4 +14,4 @@ interface KycDigiLockerListener {
fun onKycDigiLockerSuccess(data: DigilockerPANVerificationData?)
fun onKycDigiLockerError(data: DigilockerPANVerificationData?)
}
}

View File

@@ -1,3 +1,10 @@
/*
*
* * Copyright © 2024 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.navi.ap.common.sdk.digilocker.listener
import com.navi.ap.common.viewmodel.ApplicationPlatformVM
@@ -9,11 +16,10 @@ class KycDigiLockerListenerStrategy(
) {
fun getKycDigiLockerSdkListenerImpl(): KycDigiLockerListener? {
return when (applicationType) {
ApplicationType.PL.name, ApplicationType.PL_REPEAT.name, ApplicationType.PL_TOP_UP.name -> PLKycDigiLockerListenerImp(
applicationPlatformVM
)
ApplicationType.PL.name,
ApplicationType.PL_REPEAT.name,
ApplicationType.PL_TOP_UP.name -> PLKycDigiLockerListenerImp(applicationPlatformVM)
else -> null
}
}
}
}

View File

@@ -1,3 +1,10 @@
/*
*
* * Copyright © 2024 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.navi.ap.common.sdk.digilocker.listener
import com.navi.ap.common.sdk.digilocker.model.DigilockerPANVerificationData
@@ -28,4 +35,4 @@ class PLKycDigiLockerListenerImp(private val applicationPlatformVM: ApplicationP
it.handleActions(onFailureAction)
}
}
}
}

View File

@@ -1,3 +1,10 @@
/*
*
* * Copyright © 2024 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.navi.ap.common.sdk.digilocker.model
import android.os.Parcelable
@@ -5,7 +12,6 @@ import com.google.gson.annotations.SerializedName
import com.navi.ap.common.sdk.model.KYCSdkSettingData
import kotlinx.parcelize.Parcelize
@Parcelize
data class DigiLockerSdkSettingData(
@SerializedName("requestId") val requestId: String? = null,

View File

@@ -1,3 +1,10 @@
/*
*
* * Copyright © 2024 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.navi.ap.common.sdk.digilocker.model
import android.os.Parcelable

View File

@@ -1,17 +1,22 @@
/*
*
* * Copyright © 2024 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.navi.ap.common.sdk.digilocker.utils
import com.navi.ap.utils.constants.SDK_ERROR_CODE_MINUS_1000
fun getDigiLockerSDKError(errorCode: Int): String {
return when (errorCode) {
SDK_ERROR_CODE_MINUS_1000 -> DigiLockerSDKError.USER_CANCELLED.name
else -> DigiLockerSDKError.SDK_ERROR.name
}
return when (errorCode) {
SDK_ERROR_CODE_MINUS_1000 -> DigiLockerSDKError.USER_CANCELLED.name
else -> DigiLockerSDKError.SDK_ERROR.name
}
}
enum class DigiLockerSDKError {
USER_CANCELLED,
SDK_ERROR
USER_CANCELLED,
SDK_ERROR
}

View File

@@ -1,3 +1,10 @@
/*
*
* * Copyright © 2024 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.navi.ap.common.sdk.digitap.helper
import android.app.Activity
@@ -24,10 +31,7 @@ import javax.inject.Inject
class DigiTapAadhaarVerificationSdkHelper @Inject constructor() {
fun init(
activity: Activity,
data: DigiTapAadhaarSettingData?
) {
fun init(activity: Activity, data: DigiTapAadhaarSettingData?) {
initAndStartDigiTap(
activity,
data?.customerIdentifier.orEmpty(),
@@ -39,18 +43,14 @@ class DigiTapAadhaarVerificationSdkHelper @Inject constructor() {
val config = DTOkycConfig()
if (
TextUtils.equals(CommonLibManager.buildConfigDetails.flavor, PROD) ||
TextUtils.equals(CommonLibManager.buildConfigDetails.flavor, QA)
TextUtils.equals(CommonLibManager.buildConfigDetails.flavor, QA)
)
config.DTEnvironment = DTEnvironment.PRODUCTION
else {
config.DTEnvironment = DTEnvironment.UAT
}
try {
DigiTapOKYC.init(
activity,
authToken,
config
)
DigiTapOKYC.init(activity, authToken, config)
startDigiTapEkyc(activity, identifier)
} catch (e: Exception) {
logApEvent(
@@ -65,11 +65,7 @@ class DigiTapAadhaarVerificationSdkHelper @Inject constructor() {
private fun startDigiTapEkyc(activity: Activity, identifier: String) {
try {
DTOkycActivity.launch(
activity,
identifier,
activity as OKYCListener
)
DTOkycActivity.launch(activity, identifier, activity as OKYCListener)
} catch (e: Exception) {
logApEvent(
Pair(FAILURE_REASON, e.message.orEmpty()),
@@ -80,4 +76,4 @@ class DigiTapAadhaarVerificationSdkHelper @Inject constructor() {
e.log()
}
}
}
}

View File

@@ -1,3 +1,10 @@
/*
*
* * Copyright © 2024 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.navi.ap.common.sdk.digitap.listner
import com.navi.ap.common.sdk.digitap.model.AadhaarVerificationData
@@ -6,4 +13,4 @@ interface DigiTapAadhaarVerificationListener {
fun onAadhaarVerificationSuccess(aadhaarVerificationData: AadhaarVerificationData)
fun onAadhaarVerificationError(aadhaarVerificationData: AadhaarVerificationData)
}
}

View File

@@ -1,3 +1,10 @@
/*
*
* * Copyright © 2024 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.navi.ap.common.sdk.digitap.listner
import com.navi.ap.common.viewmodel.ApplicationPlatformVM
@@ -10,11 +17,11 @@ class DigiTapAadhaarVerificationListenerStrategy(
fun getDigiTapAadhaarVerificationListenerImpl(): DigiTapAadhaarVerificationListener? {
return when (applicationType) {
ApplicationType.PL.name, ApplicationType.PL_REPEAT.name, ApplicationType.PL_TOP_UP.name -> PLDigiTapAadhaarVerificationListenerImp(
applicationPlatformVM
)
ApplicationType.PL.name,
ApplicationType.PL_REPEAT.name,
ApplicationType.PL_TOP_UP.name ->
PLDigiTapAadhaarVerificationListenerImp(applicationPlatformVM)
else -> null
}
}
}
}

View File

@@ -1,3 +1,10 @@
/*
*
* * Copyright © 2024 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.navi.ap.common.sdk.digitap.listner
import com.navi.ap.common.sdk.digitap.model.AadhaarVerificationData
@@ -8,14 +15,14 @@ import com.navi.ap.utils.constants.DIGI_TAP_AADHAAR_SDK_ON_FAILURE_ACTION
import com.navi.ap.utils.constants.DIGI_TAP_AADHAAR_SDK_ON_SUCCESS_ACTION
import com.navi.uitron.model.data.UiTronActionData
class PLDigiTapAadhaarVerificationListenerImp(private val applicationPlatformVM: ApplicationPlatformVM?) :
DigiTapAadhaarVerificationListener {
class PLDigiTapAadhaarVerificationListenerImp(
private val applicationPlatformVM: ApplicationPlatformVM?
) : DigiTapAadhaarVerificationListener {
override fun onAadhaarVerificationSuccess(aadhaarVerificationData: AadhaarVerificationData) {
applicationPlatformVM?.let {
it.handle[AADHAAR_VERIFICATION_SUCCESS_DATA] = aadhaarVerificationData
val onSuccessAction = it.handle.get<UiTronActionData>(
DIGI_TAP_AADHAAR_SDK_ON_SUCCESS_ACTION
)
val onSuccessAction =
it.handle.get<UiTronActionData>(DIGI_TAP_AADHAAR_SDK_ON_SUCCESS_ACTION)
it.handleActions(onSuccessAction)
}
}
@@ -27,4 +34,4 @@ class PLDigiTapAadhaarVerificationListenerImp(private val applicationPlatformVM:
it.handleActions(onErrorAction)
}
}
}
}

View File

@@ -1,3 +1,10 @@
/*
*
* * Copyright © 2024 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.navi.ap.common.sdk.digitap.model
import android.os.Parcelable
@@ -12,4 +19,3 @@ data class AadhaarVerificationData(
@SerializedName("txnId") val txnId: String? = null,
@SerializedName("errorCode") val errorCode: String? = null
) : Parcelable

View File

@@ -1,3 +1,10 @@
/*
*
* * Copyright © 2024 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.navi.ap.common.sdk.digitap.model
import android.os.Parcelable
@@ -16,4 +23,4 @@ data class DigiTapAadhaarSettingData(
@SerializedName("requestId") val requestId: String? = null,
@SerializedName("token") val token: String? = null
) : Parcelable
}
}

View File

@@ -1,3 +1,10 @@
/*
*
* * Copyright © 2024 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.navi.ap.common.sdk.digitap.utils
import com.navi.ap.utils.constants.SDK_ERROR_CODE_1003
@@ -5,17 +12,17 @@ import com.navi.ap.utils.constants.SDK_ERROR_CODE_1005
import com.navi.ap.utils.constants.SDK_ERROR_CODE_1007
fun getDigitapSDKError(errorCode: Int): String {
return when (errorCode) {
SDK_ERROR_CODE_1003 -> DigitapSDKError.USER_CANCELLED.name
SDK_ERROR_CODE_1005 -> DigitapSDKError.NETWORK_ERROR.name
SDK_ERROR_CODE_1007 -> DigitapSDKError.UIDAI_ERROR.name
else -> DigitapSDKError.SDK_ERROR.name
}
return when (errorCode) {
SDK_ERROR_CODE_1003 -> DigitapSDKError.USER_CANCELLED.name
SDK_ERROR_CODE_1005 -> DigitapSDKError.NETWORK_ERROR.name
SDK_ERROR_CODE_1007 -> DigitapSDKError.UIDAI_ERROR.name
else -> DigitapSDKError.SDK_ERROR.name
}
}
enum class DigitapSDKError {
USER_CANCELLED,
NETWORK_ERROR,
SDK_ERROR,
UIDAI_ERROR
}
USER_CANCELLED,
NETWORK_ERROR,
SDK_ERROR,
UIDAI_ERROR
}

View File

@@ -18,16 +18,15 @@ import com.navi.ap.utils.constants.FAILURE
import com.navi.ap.utils.constants.SUCCESS
import com.navi.common.uitron.model.action.DigioSDKAction
import `in`.digio.sdk.esign.DigioResponse
import javax.inject.Inject
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
import javax.inject.Inject
/**
* This class is responsible for handling Digio SDK related actions
*/
/** This class is responsible for handling Digio SDK related actions */
class DigioHandler @Inject constructor(private val digioHelper: DigioHelper) {
private var collectorJob : Job? = null
private var collectorJob: Job? = null
fun init(activity: ApplicationPlatformActivity) {
digioHelper.initConfig(activity)
}
@@ -38,15 +37,16 @@ class DigioHandler @Inject constructor(private val digioHelper: DigioHelper) {
fun postDigioSdkResultAction(action: DigioSDKAction, viewModel: ApplicationPlatformVM) {
collectorJob?.cancel()
collectorJob = viewModel.viewModelScope.launch {
viewModel.handle.getStateFlow<String?>(DIGIO_STATUS_KEY, null).collect { digioKey ->
if (digioKey == SUCCESS) {
viewModel.handleActions(action.onSuccess)
} else if (digioKey == FAILURE) {
viewModel.handleActions(action.onFailure)
collectorJob =
viewModel.viewModelScope.launch {
viewModel.handle.getStateFlow<String?>(DIGIO_STATUS_KEY, null).collect { digioKey ->
if (digioKey == SUCCESS) {
viewModel.handleActions(action.onSuccess)
} else if (digioKey == FAILURE) {
viewModel.handleActions(action.onFailure)
}
}
}
}
}
fun handleDigioSdkResult(

View File

@@ -24,8 +24,8 @@ import com.navi.ap.utils.constants.SUCCESS
import com.navi.base.utils.orFalse
import com.navi.common.uitron.model.action.ThirdPartySdkAction
import com.navi.common.utils.getProviderConfig
import kotlinx.coroutines.launch
import javax.inject.Inject
import kotlinx.coroutines.launch
class FinoramicHandler @Inject constructor() {
@@ -45,13 +45,11 @@ class FinoramicHandler @Inject constructor() {
viewModel: ApplicationPlatformVM
) {
viewModel.viewModelScope.launch {
viewModel.handle
.getStateFlow<String?>(FINORAMIC_LOGIN_STATUS_KEY, null)
.collect {
if (it.toBoolean()) {
viewModel.handleActions(action.value.onSuccess)
}
viewModel.handle.getStateFlow<String?>(FINORAMIC_LOGIN_STATUS_KEY, null).collect {
if (it.toBoolean()) {
viewModel.handleActions(action.value.onSuccess)
}
}
}
}

View File

@@ -17,16 +17,14 @@ import com.navi.ap.utils.constants.RAZORPAY_STATUS_KEY
import com.navi.ap.utils.constants.SUCCESS
import com.navi.common.uitron.model.action.RazorpaySDKAction
import com.navi.payment.razorpay.RazorpayHelper
import javax.inject.Inject
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
import javax.inject.Inject
/**
* This class is responsible for handling Razorpay SDK related actions
*/
/** This class is responsible for handling Razorpay SDK related actions */
class RazorpayHandler @Inject constructor(private val razorpayHelper: RazorpayHelper) {
private var collectorJob : Job? = null
private var collectorJob: Job? = null
fun init(activity: ApplicationPlatformActivity) {
razorpayHelper.initializeRazorpay(activity)
@@ -38,18 +36,17 @@ class RazorpayHandler @Inject constructor(private val razorpayHelper: RazorpayHe
fun postRazorpaySdkResultAction(action: RazorpaySDKAction, viewModel: ApplicationPlatformVM) {
collectorJob?.cancel()
collectorJob = viewModel.viewModelScope.launch {
viewModel.handle.getStateFlow<String?>(
RAZORPAY_STATUS_KEY, null
).collect { razorpayStatusKey ->
if (razorpayStatusKey != null && razorpayStatusKey == SUCCESS) {
viewModel.handleActions(action.onSuccess)
} else if (razorpayStatusKey != null && razorpayStatusKey == FAILURE) {
viewModel.handleActions(action.onFailure)
collectorJob =
viewModel.viewModelScope.launch {
viewModel.handle.getStateFlow<String?>(RAZORPAY_STATUS_KEY, null).collect {
razorpayStatusKey ->
if (razorpayStatusKey != null && razorpayStatusKey == SUCCESS) {
viewModel.handleActions(action.onSuccess)
} else if (razorpayStatusKey != null && razorpayStatusKey == FAILURE) {
viewModel.handleActions(action.onFailure)
}
}
}
}
}
fun handleRazorpaySdkResult(

View File

@@ -69,13 +69,9 @@ class DigioHelper @Inject constructor() {
} ?: run { digio?.start(documentId.orEmpty(), identifier.orEmpty()) }
}
private fun getAdditionalData(
preferredAuthType: String?
): HashMap<String, String>? {
private fun getAdditionalData(preferredAuthType: String?): HashMap<String, String>? {
var additionalData: HashMap<String, String>? = null
preferredAuthType?.let {
additionalData = hashMapOf(Pair(DIGIO_PREFERRED_AUTH_TYPE, it))
}
preferredAuthType?.let { additionalData = hashMapOf(Pair(DIGIO_PREFERRED_AUTH_TYPE, it)) }
return additionalData
}
}

View File

@@ -20,9 +20,7 @@ class FinarkeinHelper(
fun openFinarkein(consentResponse: ConsentResponse) {
val extraParams: Map<String, String> =
mapOf(
AnubhavConstants.SHOW_EXIT_TRANSITION to AnubhavConstants.TRUE
)
mapOf(AnubhavConstants.SHOW_EXIT_TRANSITION to AnubhavConstants.TRUE)
val inputs = getWebViewConfiguration(extraParams, consentResponse)
resultLauncher?.launch(inputs)
}

View File

@@ -1,3 +1,10 @@
/*
*
* * Copyright © 2024 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.navi.ap.common.sdk.helper
import com.navi.ap.common.sdk.digilocker.helper.KycDigiLockerSdkHelper
@@ -8,9 +15,11 @@ import dagger.hilt.android.scopes.ActivityScoped
import javax.inject.Inject
@ActivityScoped
class SdkHelper @Inject constructor(
class SdkHelper
@Inject
constructor(
val hyperVergeSelfieCaptureHelper: HypervergeSelfieCaptureHelper,
val hyperVergePanCaptureHelper: HyperVergePanCaptureHelper,
val digiTapAadhaarVerificationSdkHelper: DigiTapAadhaarVerificationSdkHelper,
val kycDigiLockerSdkHelper: KycDigiLockerSdkHelper
)
)

Some files were not shown because too many files have changed in this diff Show More