NTP-70420 | Sohan | Added Scratch card in Screen Overlay for Coin Drop (#16550)

This commit is contained in:
Sohan Reddy Atukula
2025-06-12 20:00:08 +05:30
committed by GitHub
parent 50de8f485e
commit c510f23043
17 changed files with 461 additions and 1 deletions

View File

@@ -566,6 +566,20 @@ class HomePageActivity :
)
}
}
lifecycleScope.launch {
screenOverlayVM.scratchCardEffect.collect {
screenOverlayEffectHandler.handleScratchCardEffect(
effect = it,
deletedItemsMap = screenOverlayVM.deletedItemsMap,
triggerStateUpdateApiCall = { scratchCardTransitionState ->
screenOverlayVM.triggerStateUpdateApiCall(
scratchCardTransitionState,
naeScreenName = screenName,
)
},
)
}
}
}
private fun observeScreenLockEnableStatus() {

View File

@@ -46,6 +46,9 @@ import com.naviapp.screenOverlay.bottomsheet.ui.HomeScreenBottomSheet
import com.naviapp.screenOverlay.nudge.domain.model.event.NudgeEvent
import com.naviapp.screenOverlay.nudge.initializer.InitScreenOverlayComponents
import com.naviapp.screenOverlay.popup.ui.PopupRenderer
import com.naviapp.screenOverlay.scratchcard.model.ScratchCardOverlayEffect
import com.naviapp.screenOverlay.scratchcard.model.ScratchCardOverlayEvent
import com.naviapp.screenOverlay.scratchcard.ui.ScratchCardOverlayRenderer
import com.naviapp.screenOverlay.viewModel.ScreenOverlayVM
import com.naviapp.utils.navigateTo
import com.naviapp.utils.navigateToGlobalSendMoney
@@ -83,6 +86,7 @@ fun HomeContentFrame(
)
val nudgeState by screenOverlayVM.nudgeState.collectAsStateWithLifecycle()
val popupState by screenOverlayVM.popupState.collectAsStateWithLifecycle()
val scratchCardState by screenOverlayVM.scratchCardOverlayState.collectAsStateWithLifecycle()
val qrScreenVisible by sharedVM.qrScreenVisibility.collectAsStateWithLifecycle()
val drawerState = rememberNaviDrawerState(NaviDrawerValue.Closed)
@@ -175,6 +179,30 @@ fun HomeContentFrame(
) { uiTronResponse ->
HandleUitronRenderer(uiTronResponse, screenOverlayVM)
}
ScratchCardOverlayRenderer(
scratchCardOverlayState = scratchCardState,
popupState = popupState,
hpStates = hpStates,
homeVM = homeVM,
selectedTabId = selectedTabId,
onScratchComplete = { id ->
screenOverlayVM.sendEvent(
ScratchCardOverlayEvent.ScratchCardOverlayScratched(id)
)
screenOverlayVM.setEffect {
ScratchCardOverlayEffect.OnScratchCardOverlayScratched(id)
}
},
onDismiss = { id ->
if (scratchCardState.isScratched.not()) {
screenOverlayVM.setEffect {
ScratchCardOverlayEffect.OnScratchCardOverlayDismiss(id)
}
}
screenOverlayVM.sendEvent(ScratchCardOverlayEvent.DismissScratchCardOverlay(id))
},
)
},
contentScrim = {
/*When the nudge container is expanded, a full-screen scrim will overlay the home page.*/

View File

@@ -14,6 +14,8 @@ import com.naviapp.screenOverlay.model.OverlayItemStateUpdate
import com.naviapp.screenOverlay.nudge.domain.model.effect.NudgeEffect
import com.naviapp.screenOverlay.popup.model.PopupEffect
import com.naviapp.screenOverlay.popup.model.PopupState
import com.naviapp.screenOverlay.scratchcard.handler.ScratchCardEffectHandler
import com.naviapp.screenOverlay.scratchcard.model.ScratchCardOverlayEffect
import javax.inject.Inject
import kotlinx.coroutines.flow.StateFlow
@@ -23,6 +25,7 @@ constructor(
private val nudgeEffectHandler: NudgeEffectHandler,
private val popupEffectHandler: PopupEffectHandler,
private val bottomSheetEffectHandler: BottomSheetEffectHandler,
private val scratchCardEffectHandler: ScratchCardEffectHandler,
) {
fun handleNudgeEffect(
effect: NudgeEffect,
@@ -60,4 +63,17 @@ constructor(
) {
bottomSheetEffectHandler.handleBottomSheetEffect(effect, handleUitronAction)
}
fun handleScratchCardEffect(
effect: ScratchCardOverlayEffect,
deletedItemsMap: MutableMap<String, MutableSet<String>>,
triggerStateUpdateApiCall:
(scratchCardTransitionState: List<OverlayItemStateUpdate>) -> Unit,
) {
scratchCardEffectHandler.handleScratchCardEffect(
effect,
deletedItemsMap,
triggerStateUpdateApiCall,
)
}
}

View File

@@ -18,6 +18,7 @@ import com.naviapp.screenOverlay.nudge.domain.model.data.NudgeListData
import com.naviapp.screenOverlay.nudge.domain.model.data.StaticNudgeData
import com.naviapp.screenOverlay.popup.model.PopupListData
import com.naviapp.screenOverlay.repositories.ScreenOverlayRepository
import com.naviapp.screenOverlay.scratchcard.model.ScratchCardOverlayData
import com.naviapp.screenOverlay.utils.NudgeConstants.NUDGE
import com.naviapp.screenOverlay.utils.PopupConstants.COLLECT_REQUEST
import com.naviapp.screenOverlay.utils.PopupConstants.POPUP
@@ -41,6 +42,7 @@ constructor(
popupListData: PopupListData?,
bottomSheetData: BottomSheetData?,
staticNudgeData: StaticNudgeData?,
scratchCardData: ScratchCardOverlayData?,
) -> Unit,
onError: () -> Unit,
naeScreenName: String,
@@ -71,6 +73,7 @@ constructor(
popupListData: PopupListData?,
bottomSheetData: BottomSheetData?,
staticNudgeData: StaticNudgeData?,
scratchCardData: ScratchCardOverlayData?,
) -> Unit,
) {
response.data?.screenOverlayData?.let { screenOverlayData ->
@@ -87,6 +90,7 @@ constructor(
screenOverlayData.popupListData?.copy(popupList = updatedPopupList),
screenOverlayData.bottomSheetData,
screenOverlayData.staticNudgeData,
screenOverlayData.scratchCardData,
)
collectRequestPopupExists =
updatedPopupList?.any { it.popupType == COLLECT_REQUEST } ?: false

View File

@@ -12,6 +12,7 @@ import com.naviapp.screenOverlay.bottomsheet.model.BottomSheetData
import com.naviapp.screenOverlay.nudge.domain.model.data.NudgeListData
import com.naviapp.screenOverlay.nudge.domain.model.data.StaticNudgeData
import com.naviapp.screenOverlay.popup.model.PopupListData
import com.naviapp.screenOverlay.scratchcard.model.ScratchCardOverlayData
data class OverlayScreenStructure(
@SerializedName("screenStructure") val screenOverlayData: ScreenOverlayData? = null
@@ -22,4 +23,5 @@ data class ScreenOverlayData(
@SerializedName("popupData") val popupListData: PopupListData? = null,
@SerializedName("bottomSheetData") val bottomSheetData: BottomSheetData? = null,
@SerializedName("staticNudgeData") val staticNudgeData: StaticNudgeData? = null,
@SerializedName("scratchCardData") val scratchCardData: ScratchCardOverlayData? = null,
)

View File

@@ -0,0 +1,44 @@
/*
*
* * Copyright © 2024-2025 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.naviapp.screenOverlay.scratchcard.handler
import com.naviapp.screenOverlay.model.OverlayItemStateUpdate
import com.naviapp.screenOverlay.model.OverlayItemTransitionState
import com.naviapp.screenOverlay.scratchcard.model.ScratchCardOverlayEffect
import com.naviapp.screenOverlay.scratchcard.utils.ScratchCardOverlayConstants.SCRATCH_CARD
import javax.inject.Inject
class ScratchCardEffectHandler @Inject constructor() {
fun handleScratchCardEffect(
effect: ScratchCardOverlayEffect,
deletedItemsMap: MutableMap<String, MutableSet<String>>,
triggerStateUpdateApiCall:
(scratchCardTransitionState: List<OverlayItemStateUpdate>) -> Unit,
) {
when (effect) {
is ScratchCardOverlayEffect.OnScratchCardOverlayDismiss -> {
if (deletedItemsMap[SCRATCH_CARD]?.contains(effect.id) != true) {
triggerStateUpdateApiCall(
mutableListOf(
OverlayItemStateUpdate(effect.id, OverlayItemTransitionState.PAUSED)
)
)
}
deletedItemsMap.getOrPut(SCRATCH_CARD) { mutableSetOf() }.add(effect.id)
}
is ScratchCardOverlayEffect.OnScratchCardOverlayScratched -> {
triggerStateUpdateApiCall(
mutableListOf(
OverlayItemStateUpdate(effect.id, OverlayItemTransitionState.COMPLETED)
)
)
}
}
}
}

View File

@@ -0,0 +1,16 @@
/*
*
* * Copyright © 2025 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.naviapp.screenOverlay.scratchcard.model
import com.navi.common.forge.model.ScreenDefinition
data class ScratchCardOverlayData(
val screenDefinition: ScreenDefinition,
val amount: Int? = null,
val scratchCardId: String,
)

View File

@@ -0,0 +1,18 @@
/*
*
* * Copyright © 2024-2025 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.naviapp.screenOverlay.scratchcard.model
import androidx.compose.runtime.Immutable
import com.navi.common.basemvi.UiEffect
@Immutable
sealed interface ScratchCardOverlayEffect : UiEffect {
data class OnScratchCardOverlayDismiss(val id: String) : ScratchCardOverlayEffect
data class OnScratchCardOverlayScratched(val id: String) : ScratchCardOverlayEffect
}

View File

@@ -0,0 +1,21 @@
/*
*
* * Copyright © 2025 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.naviapp.screenOverlay.scratchcard.model
import androidx.compose.runtime.Immutable
import com.navi.common.basemvi.UiEvent
@Immutable
sealed interface ScratchCardOverlayEvent : UiEvent {
data class UpdateScratchCardOverlayData(val data: ScratchCardOverlayData) :
ScratchCardOverlayEvent
data class DismissScratchCardOverlay(val id: String) : ScratchCardOverlayEvent
data class ScratchCardOverlayScratched(val id: String) : ScratchCardOverlayEvent
}

View File

@@ -0,0 +1,29 @@
/*
*
* * Copyright © 2024-2025 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.naviapp.screenOverlay.scratchcard.model
import androidx.compose.runtime.Immutable
import com.navi.common.basemvi.UiState
@Immutable
data class ScratchCardOverlayState(
val isScratchCardVisible: Boolean,
val scratchCardData: ScratchCardOverlayData?,
val isScratched: Boolean,
val showCloseButton: Boolean,
) : UiState {
companion object {
val initialState =
ScratchCardOverlayState(
isScratchCardVisible = false,
scratchCardData = null,
isScratched = false,
showCloseButton = false,
)
}
}

View File

@@ -0,0 +1,43 @@
/*
*
* * Copyright © 2024-2025 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.naviapp.screenOverlay.scratchcard.reducer
import com.navi.common.basemvi.BaseReducer
import com.naviapp.screenOverlay.scratchcard.model.ScratchCardOverlayEvent
import com.naviapp.screenOverlay.scratchcard.model.ScratchCardOverlayState
import javax.inject.Inject
class ScratchCardReducer @Inject constructor() :
BaseReducer<ScratchCardOverlayState, ScratchCardOverlayEvent> {
override fun reduce(
previousState: ScratchCardOverlayState,
event: ScratchCardOverlayEvent,
): ScratchCardOverlayState {
return when (event) {
is ScratchCardOverlayEvent.UpdateScratchCardOverlayData -> {
previousState.copy(
scratchCardData = event.data,
isScratchCardVisible = true,
isScratched = false,
showCloseButton = false,
)
}
is ScratchCardOverlayEvent.DismissScratchCardOverlay -> {
previousState.copy(
isScratchCardVisible = false,
scratchCardData = null,
isScratched = false,
showCloseButton = false,
)
}
is ScratchCardOverlayEvent.ScratchCardOverlayScratched -> {
previousState.copy(isScratched = true, showCloseButton = true)
}
}
}
}

View File

@@ -0,0 +1,172 @@
/*
*
* * Copyright © 2024-2025 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.naviapp.screenOverlay.scratchcard.ui
import androidx.compose.animation.core.Spring
import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.animation.core.spring
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp
import com.navi.base.utils.orElse
import com.navi.base.utils.orZero
import com.navi.common.R
import com.navi.common.utils.EMPTY
import com.navi.rr.scratchcard.model.GratificationResponse
import com.navi.rr.scratchcard.model.ScratchCardResponse
import com.navi.rr.scratchcard.ui.compose.ScratchCardRendererV2
import com.navi.rr.utils.constants.ScratchCardAnimationConstants.SCRATCH_CARD_DEFAULT_POSITION
import com.navi.rr.utils.constants.ScratchCardAnimationConstants.SCRATCH_CARD_INITIAL_POSITION
import com.navi.rr.utils.ext.clickable
import com.naviapp.home.compose.home.ui.content.isDelayedRenderingEnabled
import com.naviapp.home.model.BottomBarTabType
import com.naviapp.home.reducer.HpStates
import com.naviapp.home.viewmodel.HomeViewModel
import com.naviapp.screenOverlay.popup.model.PopupState
import com.naviapp.screenOverlay.scratchcard.model.ScratchCardOverlayState
import com.naviapp.screenOverlay.scratchcard.utils.ScratchCardOverlayConstants.SCRATCH_CARD_DEFAULT_AMOUNT
import com.naviapp.screenOverlay.scratchcard.utils.ScratchCardOverlayConstants.SCRATCH_CARD_DELAY_FOR_DELAYED_RENDERING
import kotlinx.coroutines.delay
@Composable
fun ScratchCardOverlayRenderer(
scratchCardOverlayState: ScratchCardOverlayState,
popupState: PopupState,
selectedTabId: String,
hpStates: () -> HpStates,
homeVM: () -> HomeViewModel,
onScratchComplete: (String) -> Unit,
onDismiss: (String) -> Unit,
) {
var scratchCardDismissed by remember { mutableStateOf(false) }
var scratchCardAbsoluteTranslationState by remember {
mutableFloatStateOf(SCRATCH_CARD_INITIAL_POSITION)
}
val currentCardTranslateYState by
animateFloatAsState(
targetValue = scratchCardAbsoluteTranslationState,
animationSpec =
spring(
dampingRatio = Spring.DampingRatioLowBouncy,
stiffness = Spring.StiffnessLow,
),
label = EMPTY,
)
val delayedRenderingEnabled = isDelayedRenderingEnabled(homeVM)
var isReadyToRender by remember { mutableStateOf(!delayedRenderingEnabled) }
if (
shouldShowScratchCard(
scratchCardOverlayState = scratchCardOverlayState,
popupState = popupState,
hpStates = hpStates,
selectedTabId = selectedTabId,
) && scratchCardDismissed.not()
) {
LaunchedEffect(delayedRenderingEnabled) {
if (delayedRenderingEnabled) {
delay(SCRATCH_CARD_DELAY_FOR_DELAYED_RENDERING)
isReadyToRender = true
}
}
if (isReadyToRender) {
LaunchedEffect(Unit) {
scratchCardAbsoluteTranslationState = SCRATCH_CARD_DEFAULT_POSITION
}
Box(
modifier =
Modifier.fillMaxSize()
.clickable(disableRipple = true) {
if (scratchCardOverlayState.isScratchCardVisible) {
onDismiss(
scratchCardOverlayState.scratchCardData?.scratchCardId.orEmpty()
)
scratchCardDismissed = true
}
}
.background(Color.Black.copy(alpha = 0.9f))
) {
ScratchCardRendererV2(
modifier = Modifier.graphicsLayer { translationY = currentCardTranslateYState },
screenContent =
GratificationResponse(
screenDefinition =
scratchCardOverlayState.scratchCardData?.screenDefinition,
scratchCardResponse =
ScratchCardResponse(
amount =
scratchCardOverlayState.scratchCardData
?.amount
.orElse(SCRATCH_CARD_DEFAULT_AMOUNT)
),
),
shouldRender = true,
onBackPress = {
onDismiss(scratchCardOverlayState.scratchCardData?.scratchCardId.orEmpty())
scratchCardDismissed = true
},
onScratch = {
onScratchComplete(
scratchCardOverlayState.scratchCardData?.scratchCardId.orEmpty()
)
},
)
if (scratchCardOverlayState.showCloseButton) {
Box(
modifier =
Modifier.padding(
start = 16.dp,
top = 40.dp,
bottom = 20.dp,
end = 16.dp,
)
) {
Image(
modifier =
Modifier.clickable(disableRipple = true) {
onDismiss(
scratchCardOverlayState.scratchCardData
?.scratchCardId
.orEmpty()
)
scratchCardDismissed = true
},
painter = painterResource(R.drawable.ic_close_cross_white),
contentDescription = null,
)
}
}
}
}
}
}
private fun shouldShowScratchCard(
scratchCardOverlayState: ScratchCardOverlayState,
popupState: PopupState,
hpStates: () -> HpStates,
selectedTabId: String,
) =
selectedTabId == BottomBarTabType.HOME.name &&
!(popupState.isPopupListVisible && popupState.popupList?.size.orZero() > 0) &&
scratchCardOverlayState.isScratchCardVisible &&
hpStates().isRenderingFirstTime.not() &&
hpStates().profileDrawerState.not()

View File

@@ -0,0 +1,14 @@
/*
*
* * Copyright © 2024-2025 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.naviapp.screenOverlay.scratchcard.utils
object ScratchCardOverlayConstants {
const val SCRATCH_CARD = "scratch_card"
const val SCRATCH_CARD_DELAY_FOR_DELAYED_RENDERING: Long = 2000
const val SCRATCH_CARD_DEFAULT_AMOUNT = 100
}

View File

@@ -37,6 +37,10 @@ import com.naviapp.screenOverlay.popup.model.PopupEvent
import com.naviapp.screenOverlay.popup.model.PopupListData
import com.naviapp.screenOverlay.popup.model.PopupState
import com.naviapp.screenOverlay.popup.reducer.PopupReducer
import com.naviapp.screenOverlay.scratchcard.model.ScratchCardOverlayData
import com.naviapp.screenOverlay.scratchcard.model.ScratchCardOverlayEvent
import com.naviapp.screenOverlay.scratchcard.model.ScratchCardOverlayState
import com.naviapp.screenOverlay.scratchcard.reducer.ScratchCardReducer
import com.naviapp.screenOverlay.usecase.NudgeCacheUseCase
import com.naviapp.utils.SelectiveRefreshHandler
import dagger.hilt.android.lifecycle.HiltViewModel
@@ -67,6 +71,8 @@ constructor(
nudgeReducer = NudgeReducer(),
popupReducer = PopupReducer(),
bottomSheetReducer = BottomSheetReducer(),
initialScratchCardOverlayState = ScratchCardOverlayState.initialState,
scratchCardReducer = ScratchCardReducer(),
) {
private val _redirectionCtaData = MutableSharedFlow<CtaData?>()
val redirectionCtaData = _redirectionCtaData.asSharedFlow()
@@ -151,12 +157,18 @@ constructor(
screenOverlayHandler.fetchNudgeData(
deletedItemsMap = deletedItemsMap,
lastClickedNudgeId = lastClickedNudgeId,
onSuccess = { nudgeData, popupData, bottomSheetData, staticNudgeData ->
onSuccess = {
nudgeData,
popupData,
bottomSheetData,
staticNudgeData,
scratchCardData ->
handleScreenOverlayApiSuccess(
nudgeData,
popupData,
bottomSheetData,
staticNudgeData,
scratchCardData,
)
},
onError = { handleScreenOverlayApiError() },
@@ -186,6 +198,7 @@ constructor(
popupListData: PopupListData?,
bottomSheetData: BottomSheetData?,
staticNudgeData: StaticNudgeData?,
scratchCardData: ScratchCardOverlayData?,
) {
sendEvent(
NudgeEvent.UpdateNudgeList(nudgeCacheUseCase.getUpdatedNudgeList(nudgeListData?.nudges))
@@ -195,6 +208,7 @@ constructor(
}
bottomSheetData?.let { sendEvent(BottomSheetEvent.UpdateBottomSheetData(it)) }
staticNudgeData?.let { sendEvent(NudgeEvent.UpdateStaticNudgeData(it)) }
scratchCardData?.let { sendEvent(ScratchCardOverlayEvent.UpdateScratchCardOverlayData(it)) }
selectiveRefreshHandler.handleSuccessState(
this,
SelectiveRefreshHandler.NUDGE_SUCCESS_STATE,

View File

@@ -21,6 +21,9 @@ import com.naviapp.screenOverlay.nudge.domain.model.state.NudgeState
import com.naviapp.screenOverlay.popup.model.PopupEffect
import com.naviapp.screenOverlay.popup.model.PopupEvent
import com.naviapp.screenOverlay.popup.model.PopupState
import com.naviapp.screenOverlay.scratchcard.model.ScratchCardOverlayEffect
import com.naviapp.screenOverlay.scratchcard.model.ScratchCardOverlayEvent
import com.naviapp.screenOverlay.scratchcard.model.ScratchCardOverlayState
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.MutableStateFlow
@@ -34,9 +37,11 @@ abstract class ScreenOverlayVMComponent(
initialNudgeState: NudgeState,
initialPopupState: PopupState,
initialBottomSheetState: BottomSheetState,
initialScratchCardOverlayState: ScratchCardOverlayState,
private val nudgeReducer: BaseReducer<NudgeState, NudgeEvent>,
private val popupReducer: BaseReducer<PopupState, PopupEvent>,
private val bottomSheetReducer: BaseReducer<BottomSheetState, BottomSheetEvent>,
private val scratchCardReducer: BaseReducer<ScratchCardOverlayState, ScratchCardOverlayEvent>,
) : BaseVM() {
private val _nudgeState: MutableStateFlow<NudgeState> = MutableStateFlow(initialNudgeState)
@@ -50,6 +55,15 @@ abstract class ScreenOverlayVMComponent(
val popupState: StateFlow<PopupState>
get() = _popupState.asStateFlow()
private val _scratchCardOverlayState: MutableStateFlow<ScratchCardOverlayState> =
MutableStateFlow(initialScratchCardOverlayState)
val scratchCardOverlayState: StateFlow<ScratchCardOverlayState>
get() = _scratchCardOverlayState.asStateFlow()
private val _scratchCardOverlayEffects =
Channel<ScratchCardOverlayEffect>(capacity = Channel.UNLIMITED)
val scratchCardEffect = _scratchCardOverlayEffects.receiveAsFlow()
private val _popupEffects = Channel<PopupEffect>(capacity = Channel.UNLIMITED)
val popupEffect = _popupEffects.receiveAsFlow()
@@ -75,6 +89,10 @@ abstract class ScreenOverlayVMComponent(
val newState = bottomSheetReducer.reduce(_bottomSheetState.value, event)
_bottomSheetState.update { newState }
}
is ScratchCardOverlayEvent -> {
val newState = scratchCardReducer.reduce(_scratchCardOverlayState.value, event)
_scratchCardOverlayState.update { newState }
}
}
}
@@ -84,6 +102,8 @@ abstract class ScreenOverlayVMComponent(
is NudgeEffect -> _nudgeEffects.trySend(effect() as NudgeEffect)
is PopupEffect -> _popupEffects.trySend(effect() as PopupEffect)
is BottomSheetEffect -> _bottomSheetEffects.trySend(effect() as BottomSheetEffect)
is ScratchCardOverlayEffect ->
_scratchCardOverlayEffects.trySend(effect() as ScratchCardOverlayEffect)
}
}
}

View File

@@ -279,6 +279,10 @@ private fun CtaActionHandler(
Constants.SCRATCH_MORE -> {
scratchNext.invoke()
}
Constants.SCRATCH_COMPLETE -> {
showConfetti.invoke()
onRewardDisbursement.invoke()
}
Constants.COIN_TRANSFER_COMPLETE -> {
onCoinLottieEnd?.invoke()
}

View File

@@ -61,6 +61,7 @@ object Constants {
const val NEXT_MILESTONE_POSITION = "NEXT_MILESTONE_POSITION"
const val SCRATCH_STARTED = "scratchStarted"
const val SCRATCH_MORE = "SCRATCH_MORE"
const val SCRATCH_COMPLETE = "SCRATCH_COMPLETE"
const val COIN_TRANSFER_COMPLETE = "COIN_TRANSFER_COMPLETE"
const val BALL_TRANSFER_COMPLETE = "BALL_TRANSFER_COMPLETE"
const val BACK = "BACK"