Updated on 2026-08-14

This commit is contained in:
Tangem 2025-10-13 18:19:51 +04:00
parent 9216890135
commit 60b76fb8fd
9 changed files with 183 additions and 26 deletions

View file

@ -5,18 +5,18 @@ import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.arkivanov.decompose.ComponentContext
import com.arkivanov.decompose.extensions.compose.subscribeAsState
import com.arkivanov.decompose.router.slot.childSlot
import com.arkivanov.decompose.router.slot.dismiss
import com.arkivanov.decompose.extensions.compose.subscribeAsState
import com.tangem.core.decompose.context.AppComponentContext
import com.tangem.core.decompose.context.child
import com.tangem.core.decompose.context.childByContext
import com.tangem.core.decompose.model.getOrCreateModel
import com.tangem.core.ui.components.NavigationBar3ButtonsScrim
import com.tangem.core.ui.decompose.ComposableBottomSheetComponent
import com.tangem.domain.models.TokenReceiveConfig
import com.tangem.features.tangempay.components.txHistory.DefaultTangemPayTxHistoryComponent
import com.tangem.features.tangempay.model.TangemPayDetailsModel
import com.tangem.features.tangempay.model.TangemPayDetailsNavigation
import com.tangem.features.tangempay.ui.TangemPayDetailsScreen
import com.tangem.features.tokenreceive.TokenReceiveComponent
import dagger.assisted.Assisted
@ -33,7 +33,7 @@ internal class DefaultTangemPayDetailsComponent @AssistedInject constructor(
private val bottomSheetSlot = childSlot(
source = model.bottomSheetNavigation,
serializer = TokenReceiveConfig.serializer(),
serializer = TangemPayDetailsNavigation.serializer(),
handleBackButton = false,
childFactory = ::bottomSheetChild,
)
@ -57,15 +57,22 @@ internal class DefaultTangemPayDetailsComponent @AssistedInject constructor(
}
private fun bottomSheetChild(
config: TokenReceiveConfig,
navigation: TangemPayDetailsNavigation,
componentContext: ComponentContext,
): ComposableBottomSheetComponent = tokenReceiveComponentFactory.create(
context = childByContext(componentContext),
params = TokenReceiveComponent.Params(
config = config,
): ComposableBottomSheetComponent = when (navigation) {
is TangemPayDetailsNavigation.Error -> TangemPayErrorBottomSheetComponent(
appComponentContext = appComponentContext,
messageUM = navigation.messageUM,
onDismiss = model.bottomSheetNavigation::dismiss,
),
)
)
is TangemPayDetailsNavigation.Receive -> tokenReceiveComponentFactory.create(
context = childByContext(componentContext),
params = TokenReceiveComponent.Params(
config = navigation.config,
onDismiss = model.bottomSheetNavigation::dismiss,
),
)
}
@AssistedFactory
interface Factory : TangemPayDetailsComponent.Factory {

View file

@ -0,0 +1,23 @@
package com.tangem.features.tangempay.components
import androidx.compose.runtime.Composable
import com.tangem.core.decompose.context.AppComponentContext
import com.tangem.core.ui.components.bottomsheets.message.MessageBottomSheetUMV2
import com.tangem.core.ui.components.bottomsheets.message.MessageBottomSheetV2
import com.tangem.core.ui.decompose.ComposableBottomSheetComponent
internal class TangemPayErrorBottomSheetComponent(
appComponentContext: AppComponentContext,
private val messageUM: MessageBottomSheetUMV2,
private val onDismiss: () -> Unit,
) : AppComponentContext by appComponentContext, ComposableBottomSheetComponent {
override fun dismiss() {
onDismiss()
}
@Composable
override fun BottomSheet() {
MessageBottomSheetV2(state = messageUM, onDismissRequest = ::dismiss)
}
}

View file

@ -0,0 +1,5 @@
package com.tangem.features.tangempay.entity
internal enum class TangemPayDetailsErrorType {
Receive,
}

View file

@ -4,6 +4,7 @@ import androidx.compose.runtime.Stable
import androidx.compose.ui.graphics.toArgb
import com.arkivanov.decompose.router.slot.SlotNavigation
import com.arkivanov.decompose.router.slot.activate
import com.arkivanov.decompose.router.slot.dismiss
import com.tangem.core.decompose.di.ModelScoped
import com.tangem.core.decompose.model.Model
import com.tangem.core.decompose.model.ParamsContainer
@ -20,9 +21,11 @@ import com.tangem.domain.pay.DataForReceiveFactory
import com.tangem.domain.pay.repository.CardDetailsRepository
import com.tangem.features.tangempay.components.TangemPayDetailsComponent
import com.tangem.features.tangempay.details.impl.R
import com.tangem.features.tangempay.entity.TangemPayDetailsErrorType
import com.tangem.features.tangempay.entity.TangemPayDetailsStateFactory
import com.tangem.features.tangempay.entity.TangemPayDetailsUM
import com.tangem.features.tangempay.model.transformers.*
import com.tangem.features.tangempay.utils.TangemPayErrorMessageFactory
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import com.tangem.utils.coroutines.JobHolder
import com.tangem.utils.coroutines.saveIn
@ -70,7 +73,7 @@ internal class TangemPayDetailsModel @Inject constructor(
private val fetchBalanceJobHolder = JobHolder()
private val revealCardDetailsJobHolder = JobHolder()
val bottomSheetNavigation: SlotNavigation<TokenReceiveConfig> = SlotNavigation()
val bottomSheetNavigation: SlotNavigation<TangemPayDetailsNavigation> = SlotNavigation()
init {
fetchBalance()
@ -96,9 +99,15 @@ internal class TangemPayDetailsModel @Inject constructor(
fallbackBackground = TangemColorPalette.Meadow.toArgb(),
),
)
bottomSheetNavigation.activate(config)
bottomSheetNavigation.activate(TangemPayDetailsNavigation.Receive(config))
}
.onLeft {
val messageUM = TangemPayErrorMessageFactory.createError(
type = TangemPayDetailsErrorType.Receive,
onDismiss = bottomSheetNavigation::dismiss,
)
bottomSheetNavigation.activate(TangemPayDetailsNavigation.Error(messageUM))
}
.onLeft { showError() }
}
}

View file

@ -0,0 +1,17 @@
package com.tangem.features.tangempay.model
import com.tangem.core.ui.components.bottomsheets.message.MessageBottomSheetUMV2
import com.tangem.domain.models.TokenReceiveConfig
import kotlinx.serialization.Serializable
@Serializable
internal sealed class TangemPayDetailsNavigation {
data class Receive(
val config: TokenReceiveConfig,
) : TangemPayDetailsNavigation()
data class Error(
val messageUM: MessageBottomSheetUMV2,
) : TangemPayDetailsNavigation()
}

View file

@ -0,0 +1,28 @@
package com.tangem.features.tangempay.utils
import com.tangem.core.ui.R
import com.tangem.core.ui.components.bottomsheets.message.*
import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.features.tangempay.entity.TangemPayDetailsErrorType
internal object TangemPayErrorMessageFactory {
fun createError(type: TangemPayDetailsErrorType, onDismiss: () -> Unit): MessageBottomSheetUMV2 {
return when (type) {
TangemPayDetailsErrorType.Receive -> messageBottomSheetUM {
infoBlock {
icon(R.drawable.img_attention_20) {
backgroundType = MessageBottomSheetUMV2.Icon.BackgroundType.Attention
}
title = TextReference.Res(R.string.tangempay_card_details_receive_error_title)
body = TextReference.Res(R.string.tangempay_card_details_receive_error_description)
}
primaryButton {
text = resourceReference(R.string.common_got_it)
onClick { onDismiss() }
}
}
}
}
}