Updated on 2026-08-14
This commit is contained in:
parent
d808a3ddb2
commit
b775329fb3
28 changed files with 768 additions and 73 deletions
|
|
@ -0,0 +1,22 @@
|
|||
package com.tangem.common.ui.expressStatus.state
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import com.tangem.common.ui.tokendetails.TokenDetailsDialogConfig
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
|
||||
import kotlinx.collections.immutable.PersistentList
|
||||
|
||||
data class ExpressTransactionsBlockState(
|
||||
val transactions: PersistentList<ExpressTransactionStateUM>,
|
||||
val bottomSheetSlot: BottomSheetSlot?,
|
||||
val dialogSlot: DialogSlot?,
|
||||
)
|
||||
|
||||
data class BottomSheetSlot(
|
||||
val config: TangemBottomSheetConfig,
|
||||
val content: @Composable () -> Unit,
|
||||
)
|
||||
|
||||
data class DialogSlot(
|
||||
val config: TokenDetailsDialogConfig,
|
||||
val content: @Composable () -> Unit,
|
||||
)
|
||||
|
|
@ -1,9 +1,9 @@
|
|||
package com.tangem.feature.tokendetails.presentation.tokendetails.state.components
|
||||
package com.tangem.common.ui.tokendetails
|
||||
|
||||
import com.tangem.core.ui.R
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.extensions.wrappedList
|
||||
import com.tangem.features.tokendetails.impl.R
|
||||
|
||||
/**
|
||||
* Wallet bottom sheet config
|
||||
|
|
@ -12,7 +12,7 @@ import com.tangem.features.tokendetails.impl.R
|
|||
* @property onDismissRequest lambda be invoked when bottom sheet is dismissed
|
||||
* @property content content config
|
||||
*/
|
||||
internal data class TokenDetailsDialogConfig(
|
||||
data class TokenDetailsDialogConfig(
|
||||
val isShow: Boolean,
|
||||
val onDismissRequest: () -> Unit,
|
||||
val content: DialogContentConfig,
|
||||
|
|
@ -28,7 +28,7 @@ internal data class TokenDetailsDialogConfig(
|
|||
data class ButtonConfig(
|
||||
val text: TextReference,
|
||||
val onClick: () -> Unit,
|
||||
val warning: Boolean = false,
|
||||
val hasWarning: Boolean = false,
|
||||
)
|
||||
|
||||
data class ConfirmHideConfig(
|
||||
|
|
@ -51,7 +51,7 @@ internal data class TokenDetailsDialogConfig(
|
|||
override val confirmButtonConfig: ButtonConfig = ButtonConfig(
|
||||
text = TextReference.Res(R.string.token_details_hide_alert_hide),
|
||||
onClick = onConfirmClick,
|
||||
warning = true,
|
||||
hasWarning = true,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -29,6 +29,7 @@ dependencies {
|
|||
implementation(projects.features.tangempay.details.api)
|
||||
implementation(projects.features.tokenRecieve.api)
|
||||
implementation(projects.features.txhistory.api)
|
||||
implementation(projects.features.tokendetails.api)
|
||||
|
||||
/** Domain */
|
||||
implementation(projects.domain.balanceHiding)
|
||||
|
|
|
|||
|
|
@ -15,16 +15,18 @@ import com.tangem.core.decompose.context.AppComponentContext
|
|||
import com.tangem.core.decompose.context.childByContext
|
||||
import com.tangem.core.decompose.navigation.inner.InnerRouter
|
||||
import com.tangem.core.ui.decompose.ComposableContentComponent
|
||||
import com.tangem.features.tangempay.components.express.ExpressTransactionsComponentProvider
|
||||
import com.tangem.features.tangempay.navigation.TangemPayDetailsInnerRoute
|
||||
import com.tangem.features.tokenreceive.TokenReceiveComponent
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedFactory
|
||||
import dagger.assisted.AssistedInject
|
||||
|
||||
class DefaultTangemPayDetailsContainerComponent @AssistedInject constructor(
|
||||
internal class DefaultTangemPayDetailsContainerComponent @AssistedInject constructor(
|
||||
@Assisted private val appComponentContext: AppComponentContext,
|
||||
@Assisted private val params: TangemPayDetailsContainerComponent.Params,
|
||||
private val tokenReceiveComponentFactory: TokenReceiveComponent.Factory,
|
||||
private val expressTransactionsComponentProvider: ExpressTransactionsComponentProvider,
|
||||
) : AppComponentContext by appComponentContext, TangemPayDetailsContainerComponent {
|
||||
|
||||
private val stackNavigation = StackNavigation<TangemPayDetailsInnerRoute>()
|
||||
|
|
@ -60,6 +62,7 @@ class DefaultTangemPayDetailsContainerComponent @AssistedInject constructor(
|
|||
appComponentContext = childByContext(componentContext = componentContext, router = innerRouter),
|
||||
params = params,
|
||||
tokenReceiveComponentFactory = tokenReceiveComponentFactory,
|
||||
expressTransactionsComponentProvider = expressTransactionsComponentProvider,
|
||||
)
|
||||
TangemPayDetailsInnerRoute.ChangePIN -> TangemPayChangePinComponent(
|
||||
appComponentContext = childByContext(componentContext = componentContext, router = innerRouter),
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ 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.essenty.lifecycle.subscribe
|
||||
import com.tangem.core.decompose.context.AppComponentContext
|
||||
import com.tangem.core.decompose.context.child
|
||||
import com.tangem.core.decompose.context.childByContext
|
||||
|
|
@ -17,6 +18,7 @@ import com.tangem.core.ui.decompose.ComposableBottomSheetComponent
|
|||
import com.tangem.core.ui.decompose.ComposableContentComponent
|
||||
import com.tangem.features.tangempay.components.cardDetails.DefaultTangemPayCardDetailsBlockComponent
|
||||
import com.tangem.features.tangempay.components.cardDetails.TangemPayCardDetailsBlockComponent
|
||||
import com.tangem.features.tangempay.components.express.ExpressTransactionsComponentProvider
|
||||
import com.tangem.features.tangempay.components.txHistory.DefaultTangemPayTxHistoryComponent
|
||||
import com.tangem.features.tangempay.components.txHistory.TangemPayTxHistoryDetailsComponent
|
||||
import com.tangem.features.tangempay.entity.TangemPayDetailsNavigation
|
||||
|
|
@ -28,6 +30,7 @@ internal class TangemPayDetailsComponent(
|
|||
private val appComponentContext: AppComponentContext,
|
||||
private val params: TangemPayDetailsContainerComponent.Params,
|
||||
private val tokenReceiveComponentFactory: TokenReceiveComponent.Factory,
|
||||
private val expressTransactionsComponentProvider: ExpressTransactionsComponentProvider,
|
||||
) : AppComponentContext by appComponentContext, ComposableContentComponent {
|
||||
|
||||
private val model: TangemPayDetailsModel = getOrCreateModel(params = params)
|
||||
|
|
@ -52,6 +55,21 @@ internal class TangemPayDetailsComponent(
|
|||
params = TangemPayCardDetailsBlockComponent.Params(params = params),
|
||||
)
|
||||
|
||||
private val expressTransactionsComponent by lazy {
|
||||
expressTransactionsComponentProvider.create(
|
||||
appComponentContext = child("expressTransactionsComponent"),
|
||||
userWalletId = params.userWalletId,
|
||||
cryptoCurrency = model.cryptoCurrency,
|
||||
)
|
||||
}
|
||||
|
||||
init {
|
||||
lifecycle.subscribe(
|
||||
onPause = model::onPause,
|
||||
onResume = model::onResume,
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
override fun Content(modifier: Modifier) {
|
||||
val state by model.uiState.collectAsStateWithLifecycle()
|
||||
|
|
@ -62,6 +80,7 @@ internal class TangemPayDetailsComponent(
|
|||
state = state,
|
||||
txHistoryComponent = txHistoryComponent,
|
||||
cardDetailsBlockComponent = cardDetailsBlockComponent,
|
||||
expressTransactionsComponent = expressTransactionsComponent,
|
||||
modifier = modifier,
|
||||
)
|
||||
bottomSheet.child?.instance?.BottomSheet()
|
||||
|
|
|
|||
|
|
@ -0,0 +1,34 @@
|
|||
package com.tangem.features.tangempay.components.express
|
||||
|
||||
import androidx.compose.foundation.lazy.LazyListScope
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.ui.Modifier
|
||||
import com.tangem.common.ui.expressStatus.state.ExpressTransactionStateUM
|
||||
import com.tangem.common.ui.expressStatus.state.ExpressTransactionsBlockState
|
||||
import com.tangem.core.decompose.context.AppComponentContext
|
||||
import com.tangem.features.tokendetails.ExpressTransactionsComponent
|
||||
import kotlinx.collections.immutable.PersistentList
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
|
||||
@Stable
|
||||
internal class EmptyExpressTransactionsComponent(
|
||||
context: AppComponentContext,
|
||||
) : AppComponentContext by context, ExpressTransactionsComponent {
|
||||
|
||||
override val state: StateFlow<ExpressTransactionsBlockState> = MutableStateFlow(getInitialState())
|
||||
|
||||
override fun LazyListScope.expressTransactionsContent(
|
||||
state: PersistentList<ExpressTransactionStateUM>,
|
||||
modifier: Modifier,
|
||||
) {}
|
||||
|
||||
private fun getInitialState(): ExpressTransactionsBlockState {
|
||||
return ExpressTransactionsBlockState(
|
||||
transactions = persistentListOf(),
|
||||
bottomSheetSlot = null,
|
||||
dialogSlot = null,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
package com.tangem.features.tangempay.components.express
|
||||
|
||||
import com.tangem.core.decompose.context.AppComponentContext
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.features.tokendetails.ExpressTransactionsComponent
|
||||
import javax.inject.Inject
|
||||
|
||||
internal class ExpressTransactionsComponentProvider @Inject constructor(
|
||||
private val expressTransactionsComponentFactory: ExpressTransactionsComponent.Factory,
|
||||
) {
|
||||
|
||||
fun create(
|
||||
appComponentContext: AppComponentContext,
|
||||
userWalletId: UserWalletId,
|
||||
cryptoCurrency: CryptoCurrency?,
|
||||
): ExpressTransactionsComponent = if (cryptoCurrency != null) {
|
||||
expressTransactionsComponentFactory.create(
|
||||
context = appComponentContext,
|
||||
params = ExpressTransactionsComponent.Params(userWalletId = userWalletId, currency = cryptoCurrency),
|
||||
)
|
||||
} else {
|
||||
EmptyExpressTransactionsComponent(context = appComponentContext)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
package com.tangem.features.tangempay.components.express
|
||||
|
||||
import androidx.compose.foundation.lazy.LazyListScope
|
||||
import androidx.compose.ui.Modifier
|
||||
import com.tangem.common.ui.expressStatus.state.ExpressTransactionStateUM
|
||||
import com.tangem.common.ui.expressStatus.state.ExpressTransactionsBlockState
|
||||
import com.tangem.features.tokendetails.ExpressTransactionsComponent
|
||||
import kotlinx.collections.immutable.PersistentList
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
|
||||
/** Cannot really preview anything here since the UM implementation [ExchangeUM] is in token:details module
|
||||
* For the actual preview @see [TokenDetailsScreen]
|
||||
**/
|
||||
internal class PreviewEmptyExpressTransactionsComponent : ExpressTransactionsComponent {
|
||||
|
||||
override val state: StateFlow<ExpressTransactionsBlockState> = MutableStateFlow(getInitialState())
|
||||
|
||||
override fun LazyListScope.expressTransactionsContent(
|
||||
state: PersistentList<ExpressTransactionStateUM>,
|
||||
modifier: Modifier,
|
||||
) {}
|
||||
|
||||
private fun getInitialState(): ExpressTransactionsBlockState {
|
||||
return ExpressTransactionsBlockState(
|
||||
transactions = persistentListOf(),
|
||||
bottomSheetSlot = null,
|
||||
dialogSlot = null,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -21,6 +21,8 @@ import com.tangem.domain.feedback.SendFeedbackEmailUseCase
|
|||
import com.tangem.domain.feedback.models.FeedbackEmailType
|
||||
import com.tangem.domain.feedback.models.WalletMetaInfo
|
||||
import com.tangem.domain.models.TokenReceiveConfig
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.pay.TangemPayCryptoCurrencyFactory
|
||||
import com.tangem.domain.pay.model.TangemPayCardBalance
|
||||
import com.tangem.domain.pay.model.TangemPayTopUpData
|
||||
|
|
@ -47,6 +49,8 @@ import com.tangem.features.tangempay.utils.TangemPayDetailIntents
|
|||
import com.tangem.features.tangempay.utils.TangemPayMessagesFactory
|
||||
import com.tangem.features.tangempay.utils.TangemPayTxHistoryUiActions
|
||||
import com.tangem.features.tangempay.utils.TangemPayTxHistoryUpdateListener
|
||||
import com.tangem.features.tokendetails.ExpressTransactionsEvent
|
||||
import com.tangem.features.tokendetails.ExpressTransactionsEventListener
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import com.tangem.utils.coroutines.JobHolder
|
||||
import com.tangem.utils.coroutines.saveIn
|
||||
|
|
@ -78,6 +82,7 @@ internal class TangemPayDetailsModel @Inject constructor(
|
|||
private val orderRepository: CustomerOrderRepository,
|
||||
private val getUserWalletUseCase: GetUserWalletUseCase,
|
||||
private val sendFeedbackEmailUseCase: SendFeedbackEmailUseCase,
|
||||
private val expressTransactionsEventListener: ExpressTransactionsEventListener,
|
||||
) : Model(), TangemPayTxHistoryUiActions, TangemPayDetailIntents, AddFundsListener, ViewPinListener {
|
||||
|
||||
private val params: TangemPayDetailsContainerComponent.Params = paramsContainer.require()
|
||||
|
|
@ -99,6 +104,11 @@ internal class TangemPayDetailsModel @Inject constructor(
|
|||
|
||||
private var balance: TangemPayCardBalance? = null
|
||||
|
||||
private val userWallet: UserWallet? = getUserWalletUseCase(params.userWalletId).getOrNull()
|
||||
val cryptoCurrency: CryptoCurrency? = userWallet?.let { wallet ->
|
||||
tangemPayCryptoCurrencyFactory.create(userWallet = wallet, chainId = params.config.chainId).getOrNull()
|
||||
}
|
||||
|
||||
val bottomSheetNavigation: SlotNavigation<TangemPayDetailsNavigation> = SlotNavigation()
|
||||
|
||||
init {
|
||||
|
|
@ -109,6 +119,18 @@ internal class TangemPayDetailsModel @Inject constructor(
|
|||
subscribeToCardFrozenState()
|
||||
}
|
||||
|
||||
fun onResume() {
|
||||
modelScope.launch {
|
||||
expressTransactionsEventListener.send(ExpressTransactionsEvent.Update)
|
||||
}
|
||||
}
|
||||
|
||||
fun onPause() {
|
||||
modelScope.launch {
|
||||
expressTransactionsEventListener.send(ExpressTransactionsEvent.Clear)
|
||||
}
|
||||
}
|
||||
|
||||
private fun subscribeToCardFrozenState() {
|
||||
cardDetailsRepository
|
||||
.cardFrozenState(params.config.cardId)
|
||||
|
|
@ -252,8 +274,8 @@ internal class TangemPayDetailsModel @Inject constructor(
|
|||
if (hasActiveWithdrawal) {
|
||||
showBottomSheetError(TangemPayDetailsErrorType.WithdrawInProgress)
|
||||
} else {
|
||||
val userWallet = getUserWalletUseCase(params.userWalletId).getOrNull()
|
||||
val currency = userWallet?.let {
|
||||
val userWallet = userWallet ?: getUserWalletUseCase(params.userWalletId).getOrNull()
|
||||
val currency = cryptoCurrency ?: userWallet?.let {
|
||||
tangemPayCryptoCurrencyFactory.create(userWallet = userWallet, chainId = params.config.chainId)
|
||||
.getOrNull()
|
||||
}
|
||||
|
|
@ -336,6 +358,7 @@ internal class TangemPayDetailsModel @Inject constructor(
|
|||
modelScope.launch {
|
||||
uiState.update(TangemPayDetailsRefreshTransformer(isRefreshing = refreshState.value))
|
||||
cardDetailsEventListener.send(CardDetailsEvent.Hide)
|
||||
expressTransactionsEventListener.send(ExpressTransactionsEvent.Update)
|
||||
txHistoryUpdateListener.triggerUpdate()
|
||||
fetchBalance().join()
|
||||
uiState.update(TangemPayDetailsRefreshTransformer(isRefreshing = false))
|
||||
|
|
|
|||
|
|
@ -34,17 +34,22 @@ import com.tangem.core.ui.components.dropdownmenu.TangemDropdownMenu
|
|||
import com.tangem.core.ui.components.notifications.Notification
|
||||
import com.tangem.core.ui.components.notifications.NotificationConfig
|
||||
import com.tangem.core.ui.components.text.applyBladeBrush
|
||||
import com.tangem.core.ui.extensions.*
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
import com.tangem.core.ui.extensions.orMaskWithStars
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.core.ui.test.TokenDetailsTopBarTestTags
|
||||
import com.tangem.domain.visa.model.TangemPayCardFrozenState
|
||||
import com.tangem.features.tangempay.components.cardDetails.PreviewTangemPayCardDetailsBlockComponent
|
||||
import com.tangem.features.tangempay.components.cardDetails.TangemPayCardDetailsBlockComponent
|
||||
import com.tangem.features.tangempay.components.express.PreviewEmptyExpressTransactionsComponent
|
||||
import com.tangem.features.tangempay.components.txHistory.PreviewTangemPayTxHistoryComponent
|
||||
import com.tangem.features.tangempay.components.txHistory.TangemPayTxHistoryComponent
|
||||
import com.tangem.features.tangempay.details.impl.R
|
||||
import com.tangem.features.tangempay.entity.*
|
||||
import com.tangem.features.tokendetails.ExpressTransactionsComponent
|
||||
import com.tangem.utils.StringsSigns.DASH_SIGN
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
|
||||
|
|
@ -54,6 +59,7 @@ internal fun TangemPayDetailsScreen(
|
|||
state: TangemPayDetailsUM,
|
||||
txHistoryComponent: TangemPayTxHistoryComponent,
|
||||
cardDetailsBlockComponent: TangemPayCardDetailsBlockComponent,
|
||||
expressTransactionsComponent: ExpressTransactionsComponent,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
Scaffold(
|
||||
|
|
@ -66,6 +72,9 @@ internal fun TangemPayDetailsScreen(
|
|||
val bottomBarHeight = with(LocalDensity.current) { WindowInsets.systemBars.getBottom(this).toDp() }
|
||||
val txHistoryState by txHistoryComponent.state.collectAsStateWithLifecycle()
|
||||
val cardDetailsState by cardDetailsBlockComponent.state.collectAsStateWithLifecycle()
|
||||
val expressState by expressTransactionsComponent.state.collectAsStateWithLifecycle()
|
||||
val expressTransactionsBottomSheetState = expressState.bottomSheetSlot
|
||||
val expressTransactionsDialogState = expressState.dialogSlot
|
||||
|
||||
TangemPullToRefreshContainer(
|
||||
config = state.pullToRefreshConfig,
|
||||
|
|
@ -138,9 +147,19 @@ internal fun TangemPayDetailsScreen(
|
|||
)
|
||||
},
|
||||
)
|
||||
with(expressTransactionsComponent) {
|
||||
expressTransactionsContent(
|
||||
state = expressState.transactions,
|
||||
modifier = modifier
|
||||
.padding(start = 16.dp, end = 16.dp, top = 12.dp)
|
||||
.fillMaxWidth(),
|
||||
)
|
||||
}
|
||||
with(txHistoryComponent) { txHistoryContent(listState = listState, state = txHistoryState) }
|
||||
}
|
||||
}
|
||||
expressTransactionsDialogState?.content()
|
||||
expressTransactionsBottomSheetState?.content()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -292,6 +311,7 @@ private fun TangemPayDetailsScreenPreview(
|
|||
cardFrozenState = TangemPayCardFrozenState.Unfrozen,
|
||||
),
|
||||
),
|
||||
expressTransactionsComponent = PreviewEmptyExpressTransactionsComponent(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -370,6 +390,7 @@ private fun TangemPayDetailsTxHistoryScreenPreview(
|
|||
cardFrozenState = TangemPayCardFrozenState.Unfrozen,
|
||||
),
|
||||
),
|
||||
expressTransactionsComponent = PreviewEmptyExpressTransactionsComponent(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,9 @@ dependencies {
|
|||
implementation(projects.core.decompose)
|
||||
implementation(projects.core.ui)
|
||||
|
||||
/** Common */
|
||||
implementation(projects.common.ui)
|
||||
|
||||
/** Domain models */
|
||||
api(projects.domain.models)
|
||||
implementation(projects.domain.tokens.models)
|
||||
|
|
@ -21,4 +24,9 @@ dependencies {
|
|||
|
||||
/** Compose */
|
||||
implementation(deps.compose.runtime)
|
||||
implementation(deps.compose.ui)
|
||||
implementation(deps.compose.foundation)
|
||||
|
||||
/** Other */
|
||||
implementation(deps.kotlin.immutable.collections)
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
package com.tangem.features.tokendetails
|
||||
|
||||
import androidx.compose.foundation.lazy.LazyListScope
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.ui.Modifier
|
||||
import com.tangem.common.ui.expressStatus.state.ExpressTransactionStateUM
|
||||
import com.tangem.common.ui.expressStatus.state.ExpressTransactionsBlockState
|
||||
import com.tangem.core.decompose.factory.ComponentFactory
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import kotlinx.collections.immutable.PersistentList
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
|
||||
@Stable
|
||||
interface ExpressTransactionsComponent {
|
||||
|
||||
val state: StateFlow<ExpressTransactionsBlockState>
|
||||
|
||||
fun LazyListScope.expressTransactionsContent(state: PersistentList<ExpressTransactionStateUM>, modifier: Modifier)
|
||||
|
||||
data class Params(
|
||||
val userWalletId: UserWalletId,
|
||||
val currency: CryptoCurrency,
|
||||
)
|
||||
|
||||
interface Factory : ComponentFactory<Params, ExpressTransactionsComponent>
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
package com.tangem.features.tokendetails
|
||||
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
interface ExpressTransactionsEventListener {
|
||||
|
||||
val event: Flow<ExpressTransactionsEvent>
|
||||
|
||||
suspend fun send(event: ExpressTransactionsEvent)
|
||||
}
|
||||
|
||||
enum class ExpressTransactionsEvent {
|
||||
Update, Clear
|
||||
}
|
||||
|
|
@ -4,9 +4,14 @@ import com.tangem.core.decompose.di.ModelScoped
|
|||
import com.tangem.core.decompose.di.ModelComponent
|
||||
import com.tangem.core.decompose.model.Model
|
||||
import com.tangem.feature.tokendetails.DefaultTokenDetailsComponent
|
||||
import com.tangem.feature.tokendetails.presentation.DefaultExpressTransactionsComponent
|
||||
import com.tangem.feature.tokendetails.presentation.router.DefaultTokenDetailsRouter
|
||||
import com.tangem.feature.tokendetails.presentation.router.InnerTokenDetailsRouter
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.model.ExpressTransactionsModel
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.model.TokenDetailsModel
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.state.utils.DefaultExpressTransactionsEventListener
|
||||
import com.tangem.features.tokendetails.ExpressTransactionsComponent
|
||||
import com.tangem.features.tokendetails.ExpressTransactionsEventListener
|
||||
import com.tangem.features.tokendetails.TokenDetailsComponent
|
||||
import dagger.Binds
|
||||
import dagger.Module
|
||||
|
|
@ -14,18 +19,35 @@ import dagger.hilt.InstallIn
|
|||
import dagger.hilt.components.SingletonComponent
|
||||
import dagger.multibindings.ClassKey
|
||||
import dagger.multibindings.IntoMap
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Module
|
||||
@InstallIn(SingletonComponent::class)
|
||||
internal interface TokenDetailsModule {
|
||||
|
||||
@Binds
|
||||
fun bindComponentFactory(factory: DefaultTokenDetailsComponent.Factory): TokenDetailsComponent.Factory
|
||||
fun bindTokenDetailsComponentFactory(factory: DefaultTokenDetailsComponent.Factory): TokenDetailsComponent.Factory
|
||||
|
||||
@Binds
|
||||
fun bindExpressTransactionsComponent(
|
||||
factory: DefaultExpressTransactionsComponent.Factory,
|
||||
): ExpressTransactionsComponent.Factory
|
||||
|
||||
@Binds
|
||||
@IntoMap
|
||||
@ClassKey(TokenDetailsModel::class)
|
||||
fun bindModel(model: TokenDetailsModel): Model
|
||||
fun bindTokenDetailsModel(model: TokenDetailsModel): Model
|
||||
|
||||
@Binds
|
||||
@IntoMap
|
||||
@ClassKey(ExpressTransactionsModel::class)
|
||||
fun bindExpressTransactionsModel(model: ExpressTransactionsModel): Model
|
||||
|
||||
@Binds
|
||||
@Singleton
|
||||
fun bindExpressTransactionsEventListener(
|
||||
impl: DefaultExpressTransactionsEventListener,
|
||||
): ExpressTransactionsEventListener
|
||||
}
|
||||
|
||||
@Module
|
||||
|
|
|
|||
|
|
@ -0,0 +1,42 @@
|
|||
package com.tangem.feature.tokendetails.presentation
|
||||
|
||||
import androidx.compose.foundation.lazy.LazyListScope
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.ui.Modifier
|
||||
import com.tangem.common.ui.expressStatus.expressTransactionsItems
|
||||
import com.tangem.common.ui.expressStatus.state.ExpressTransactionStateUM
|
||||
import com.tangem.common.ui.expressStatus.state.ExpressTransactionsBlockState
|
||||
import com.tangem.core.decompose.context.AppComponentContext
|
||||
import com.tangem.core.decompose.model.getOrCreateModel
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.model.ExpressTransactionsModel
|
||||
import com.tangem.features.tokendetails.ExpressTransactionsComponent
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedFactory
|
||||
import dagger.assisted.AssistedInject
|
||||
import kotlinx.collections.immutable.PersistentList
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
|
||||
@Stable
|
||||
internal class DefaultExpressTransactionsComponent @AssistedInject constructor(
|
||||
@Assisted context: AppComponentContext,
|
||||
@Assisted params: ExpressTransactionsComponent.Params,
|
||||
) : AppComponentContext by context, ExpressTransactionsComponent {
|
||||
|
||||
private val model: ExpressTransactionsModel = getOrCreateModel(params = params)
|
||||
override val state: StateFlow<ExpressTransactionsBlockState> = model.uiState
|
||||
|
||||
override fun LazyListScope.expressTransactionsContent(
|
||||
state: PersistentList<ExpressTransactionStateUM>,
|
||||
modifier: Modifier,
|
||||
) {
|
||||
expressTransactionsItems(expressTxs = state, modifier = modifier)
|
||||
}
|
||||
|
||||
@AssistedFactory
|
||||
interface Factory : ExpressTransactionsComponent.Factory {
|
||||
override fun create(
|
||||
context: AppComponentContext,
|
||||
params: ExpressTransactionsComponent.Params,
|
||||
): DefaultExpressTransactionsComponent
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,306 @@
|
|||
package com.tangem.feature.tokendetails.presentation.tokendetails.model
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.Stable
|
||||
import arrow.core.getOrElse
|
||||
import arrow.core.right
|
||||
import com.tangem.common.ui.expressStatus.ExpressStatusBottomSheetConfig
|
||||
import com.tangem.common.ui.expressStatus.state.BottomSheetSlot
|
||||
import com.tangem.common.ui.expressStatus.state.DialogSlot
|
||||
import com.tangem.common.ui.expressStatus.state.ExpressTransactionStateUM
|
||||
import com.tangem.common.ui.expressStatus.state.ExpressTransactionsBlockState
|
||||
import com.tangem.common.ui.tokendetails.TokenDetailsDialogConfig
|
||||
import com.tangem.core.decompose.di.ModelScoped
|
||||
import com.tangem.core.decompose.model.Model
|
||||
import com.tangem.core.decompose.model.ParamsContainer
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
|
||||
import com.tangem.domain.account.featuretoggle.AccountsFeatureToggles
|
||||
import com.tangem.domain.account.status.usecase.GetAccountCurrencyStatusUseCase
|
||||
import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
|
||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.domain.card.common.util.cardTypesResolver
|
||||
import com.tangem.domain.models.account.Account
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.tokens.GetSingleCryptoCurrencyStatusUseCase
|
||||
import com.tangem.domain.wallets.usecase.GetUserWalletUseCase
|
||||
import com.tangem.domain.wallets.usecase.NetworkHasDerivationUseCase
|
||||
import com.tangem.feature.tokendetails.presentation.router.InnerTokenDetailsRouter
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.state.TokenDetailsState
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.state.factory.TokenDetailsStateFactory
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.state.factory.express.ExpressStatusFactory
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.ui.components.TokenDetailsDialogs
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.ui.components.express.ExpressStatusBottomSheet
|
||||
import com.tangem.features.tokendetails.ExpressTransactionsComponent
|
||||
import com.tangem.features.tokendetails.ExpressTransactionsEvent
|
||||
import com.tangem.features.tokendetails.ExpressTransactionsEventListener
|
||||
import com.tangem.features.yield.supply.api.YieldSupplyFeatureToggles
|
||||
import com.tangem.utils.Provider
|
||||
import com.tangem.utils.coroutines.*
|
||||
import kotlinx.collections.immutable.PersistentList
|
||||
import kotlinx.coroutines.flow.*
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
import kotlin.coroutines.cancellation.CancellationException
|
||||
|
||||
@Suppress("LongParameterList", "PropertyUsedBeforeDeclaration")
|
||||
@Stable
|
||||
@ModelScoped
|
||||
internal class ExpressTransactionsModel @Inject constructor(
|
||||
override val dispatchers: CoroutineDispatcherProvider,
|
||||
paramsContainer: ParamsContainer,
|
||||
expressStatusFactory: ExpressStatusFactory.Factory,
|
||||
getUserWalletUseCase: GetUserWalletUseCase,
|
||||
private val getSingleCryptoCurrencyStatusUseCase: GetSingleCryptoCurrencyStatusUseCase,
|
||||
private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase,
|
||||
private val networkHasDerivationUseCase: NetworkHasDerivationUseCase,
|
||||
private val router: InnerTokenDetailsRouter,
|
||||
private val yieldSupplyFeatureToggles: YieldSupplyFeatureToggles,
|
||||
private val accountsFeatureToggles: AccountsFeatureToggles,
|
||||
private val getAccountCryptoCurrencyStatusUseCase: GetAccountCurrencyStatusUseCase,
|
||||
private val expressTransactionsEventListener: ExpressTransactionsEventListener,
|
||||
) : Model(), ExpressTransactionsClickIntents {
|
||||
|
||||
private val params = paramsContainer.require<ExpressTransactionsComponent.Params>()
|
||||
private val userWalletId: UserWalletId = params.userWalletId
|
||||
private val cryptoCurrency: CryptoCurrency = params.currency
|
||||
|
||||
private val userWallet: UserWallet = getUserWalletUseCase(userWalletId).getOrNull() ?: error("UserWallet not found")
|
||||
|
||||
private val marketPriceJobHolder = JobHolder()
|
||||
private val expressTxJobHolder = JobHolder()
|
||||
private val selectedAppCurrencyFlow: StateFlow<AppCurrency> = createSelectedAppCurrencyFlow()
|
||||
|
||||
private var cryptoCurrencyStatus: CryptoCurrencyStatus? = null
|
||||
private var account: Account.CryptoPortfolio? = null
|
||||
private val expressTxStatusTaskScheduler = SingleTaskScheduler<PersistentList<ExpressTransactionStateUM>>()
|
||||
|
||||
private val waitForFirstExpressStatusEmmit = MutableStateFlow(false)
|
||||
|
||||
private val currentStateProvider: Provider<TokenDetailsState> = Provider { internalUiState.value }
|
||||
|
||||
private val stateFactory by lazy(mode = LazyThreadSafetyMode.NONE) {
|
||||
TokenDetailsStateFactory(
|
||||
appCurrencyProvider = Provider(selectedAppCurrencyFlow::value),
|
||||
currentStateProvider = currentStateProvider,
|
||||
cryptoCurrencyStatusProvider = Provider { cryptoCurrencyStatus },
|
||||
tokenDetailsClickIntents = EmptyTokenDetailsClickIntents(),
|
||||
expressTransactionsClickIntents = this,
|
||||
networkHasDerivationUseCase = networkHasDerivationUseCase,
|
||||
getUserWalletUseCase = getUserWalletUseCase,
|
||||
userWalletId = userWalletId,
|
||||
yieldSupplyFeatureToggles = yieldSupplyFeatureToggles,
|
||||
)
|
||||
}
|
||||
|
||||
private val expressStatusFactory by lazy(mode = LazyThreadSafetyMode.NONE) {
|
||||
expressStatusFactory.create(
|
||||
clickIntents = this,
|
||||
appCurrencyProvider = Provider { selectedAppCurrencyFlow.value },
|
||||
currentStateProvider = currentStateProvider,
|
||||
cryptoCurrencyStatusProvider = Provider { cryptoCurrencyStatus },
|
||||
userWallet = userWallet,
|
||||
cryptoCurrency = cryptoCurrency,
|
||||
)
|
||||
}
|
||||
|
||||
private val internalUiState = MutableStateFlow(stateFactory.getInitialState(cryptoCurrency))
|
||||
|
||||
val uiState: StateFlow<ExpressTransactionsBlockState> = internalUiState
|
||||
.map(::mapInnerState)
|
||||
.stateIn(
|
||||
scope = modelScope,
|
||||
started = SharingStarted.Eagerly,
|
||||
initialValue = mapInnerState(internalUiState.value),
|
||||
)
|
||||
|
||||
init {
|
||||
subscribeOnExternalEvents()
|
||||
subscribeOnCurrencyStatusUpdates()
|
||||
subscribeOnExpressTransactionsUpdates()
|
||||
}
|
||||
|
||||
override fun onExpressTransactionClick(txId: String) {
|
||||
val expressTxState = internalUiState.value.expressTxsToDisplay.firstOrNull { it.info.txId == txId }
|
||||
?: return
|
||||
internalUiState.value = expressStatusFactory.getStateWithExpressStatusBottomSheet(expressTxState)
|
||||
}
|
||||
|
||||
override fun onGoToProviderClick(url: String) {
|
||||
router.openUrl(url)
|
||||
}
|
||||
|
||||
override fun onGoToRefundedTokenClick(cryptoCurrency: CryptoCurrency) {
|
||||
router.openTokenDetails(userWalletId, cryptoCurrency)
|
||||
}
|
||||
|
||||
override fun onOpenUrlClick(url: String) {
|
||||
router.openUrl(url)
|
||||
}
|
||||
|
||||
override fun onConfirmDisposeExpressStatus() {
|
||||
internalUiState.value = stateFactory.getStateWithConfirmHideExpressStatus()
|
||||
}
|
||||
|
||||
override fun onDisposeExpressStatus() {
|
||||
val bottomSheetState = internalUiState.value.bottomSheetConfig?.content
|
||||
if (bottomSheetState is ExpressStatusBottomSheetConfig) {
|
||||
modelScope.launch {
|
||||
expressStatusFactory.removeTransactionOnBottomSheetClosed(
|
||||
expressState = bottomSheetState.value,
|
||||
isForceDispose = true,
|
||||
)
|
||||
}
|
||||
}
|
||||
internalUiState.value = stateFactory.getStateWithClosedBottomSheet()
|
||||
}
|
||||
|
||||
override fun onDismissBottomSheet() {
|
||||
when (val bsContent = internalUiState.value.bottomSheetConfig?.content) {
|
||||
is ExpressStatusBottomSheetConfig -> {
|
||||
modelScope.launch(dispatchers.main) {
|
||||
expressStatusFactory.removeTransactionOnBottomSheetClosed(bsContent.value)
|
||||
}
|
||||
}
|
||||
}
|
||||
internalUiState.value = stateFactory.getStateWithClosedBottomSheet()
|
||||
}
|
||||
|
||||
override fun onDismissDialog() {
|
||||
internalUiState.value = stateFactory.getStateWithClosedDialog()
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
clear()
|
||||
super.onDestroy()
|
||||
}
|
||||
|
||||
private fun mapInnerState(innerState: TokenDetailsState): ExpressTransactionsBlockState {
|
||||
val bsContent = innerState.bottomSheetConfig?.content
|
||||
return ExpressTransactionsBlockState(
|
||||
transactions = innerState.expressTxsToDisplay,
|
||||
bottomSheetSlot = if (bsContent != null && bsContent is ExpressStatusBottomSheetConfig) {
|
||||
innerState.bottomSheetConfig.toBottomSheetSlot()
|
||||
} else {
|
||||
null
|
||||
},
|
||||
dialogSlot = innerState.dialogConfig?.toDialogSlot(),
|
||||
)
|
||||
}
|
||||
|
||||
private fun TangemBottomSheetConfig.toBottomSheetSlot(): BottomSheetSlot {
|
||||
val contentLambda: @Composable () -> Unit = {
|
||||
when (this.content) {
|
||||
is ExpressStatusBottomSheetConfig -> ExpressStatusBottomSheet(config = this)
|
||||
}
|
||||
}
|
||||
return BottomSheetSlot(config = this, content = contentLambda)
|
||||
}
|
||||
|
||||
private fun TokenDetailsDialogConfig.toDialogSlot(): DialogSlot {
|
||||
val contentLambda: @Composable () -> Unit = {
|
||||
TokenDetailsDialogs(this)
|
||||
}
|
||||
return DialogSlot(config = this, content = contentLambda)
|
||||
}
|
||||
|
||||
private fun subscribeOnExternalEvents() {
|
||||
modelScope.launch {
|
||||
expressTransactionsEventListener.event.collect { event ->
|
||||
when (event) {
|
||||
ExpressTransactionsEvent.Update -> subscribeOnExpressTransactionsUpdates()
|
||||
ExpressTransactionsEvent.Clear -> clear()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun subscribeOnCurrencyStatusUpdates() {
|
||||
if (accountsFeatureToggles.isFeatureEnabled) {
|
||||
getAccountCryptoCurrencyStatusUseCase(userWalletId, cryptoCurrency)
|
||||
.onEach { account = it.account }
|
||||
.map { it.status.right() }
|
||||
} else {
|
||||
getSingleCryptoCurrencyStatusUseCase.invokeMultiWallet(
|
||||
userWalletId = userWalletId,
|
||||
currencyId = cryptoCurrency.id,
|
||||
isSingleWalletWithTokens = userWallet is UserWallet.Cold &&
|
||||
userWallet.scanResponse.cardTypesResolver.isSingleWalletWithToken(),
|
||||
)
|
||||
}
|
||||
.distinctUntilChanged()
|
||||
.onEach { maybeCurrencyStatus ->
|
||||
internalUiState.value = stateFactory.getCurrencyLoadedBalanceState(maybeCurrencyStatus)
|
||||
maybeCurrencyStatus.onRight { status ->
|
||||
cryptoCurrencyStatus = status
|
||||
}
|
||||
}
|
||||
.flowOn(dispatchers.main)
|
||||
.launchIn(modelScope)
|
||||
.saveIn(marketPriceJobHolder)
|
||||
}
|
||||
|
||||
private fun subscribeOnExpressTransactionsUpdates() {
|
||||
expressTxStatusTaskScheduler.cancelTask()
|
||||
expressStatusFactory.getExpressStatuses()
|
||||
.distinctUntilChanged()
|
||||
.onEach { waitForFirstExpressStatusEmmit.value = true }
|
||||
.onEach { expressTxs ->
|
||||
internalUiState.value = expressStatusFactory.getStateWithUpdatedExpressTxs(
|
||||
expressTxs = expressTxs,
|
||||
updateBalance = { /* no-op */ },
|
||||
)
|
||||
expressTxStatusTaskScheduler.scheduleTask(
|
||||
scope = modelScope,
|
||||
task = PeriodicTask(
|
||||
isDelayFirst = false,
|
||||
delay = EXPRESS_STATUS_UPDATE_DELAY,
|
||||
task = {
|
||||
try {
|
||||
Result.success(
|
||||
expressStatusFactory.getUpdatedExpressStatuses(internalUiState.value.expressTxs),
|
||||
)
|
||||
} catch (exception: CancellationException) {
|
||||
throw exception
|
||||
} catch (exception: Exception) {
|
||||
Result.failure(exception)
|
||||
}
|
||||
},
|
||||
onSuccess = { updatedTxs ->
|
||||
internalUiState.value = expressStatusFactory.getStateWithUpdatedExpressTxs(
|
||||
expressTxs = updatedTxs,
|
||||
updateBalance = { /* no-op */ },
|
||||
)
|
||||
},
|
||||
onError = { /* no-op */ },
|
||||
),
|
||||
)
|
||||
}
|
||||
.flowOn(dispatchers.main)
|
||||
.launchIn(modelScope)
|
||||
.saveIn(expressTxJobHolder)
|
||||
}
|
||||
|
||||
private fun createSelectedAppCurrencyFlow(): StateFlow<AppCurrency> {
|
||||
return getSelectedAppCurrencyUseCase()
|
||||
.map { maybeAppCurrency ->
|
||||
maybeAppCurrency.getOrElse { AppCurrency.Default }
|
||||
}
|
||||
.stateIn(
|
||||
scope = modelScope,
|
||||
started = SharingStarted.Eagerly,
|
||||
initialValue = AppCurrency.Default,
|
||||
)
|
||||
}
|
||||
|
||||
private fun clear() {
|
||||
expressTxStatusTaskScheduler.cancelTask()
|
||||
expressTxJobHolder.cancel()
|
||||
}
|
||||
|
||||
private companion object {
|
||||
const val EXPRESS_STATUS_UPDATE_DELAY = 10_000L
|
||||
}
|
||||
}
|
||||
|
|
@ -24,8 +24,6 @@ interface TokenDetailsClickIntents {
|
|||
|
||||
fun onSellClick(unavailabilityReason: ScenarioUnavailabilityReason)
|
||||
|
||||
fun onDismissDialog()
|
||||
|
||||
fun onHideClick()
|
||||
|
||||
fun onHideConfirmed()
|
||||
|
|
@ -42,14 +40,8 @@ interface TokenDetailsClickIntents {
|
|||
|
||||
fun onAddressTypeSelected(addressModel: AddressModel)
|
||||
|
||||
fun onDismissBottomSheet()
|
||||
|
||||
fun onCloseRentInfoNotification()
|
||||
|
||||
fun onExpressTransactionClick(txId: String)
|
||||
|
||||
fun onGoToProviderClick(url: String)
|
||||
|
||||
fun onSwapPromoDismiss(promoId: PromoId)
|
||||
|
||||
fun onSwapPromoClick(promoId: PromoId)
|
||||
|
|
@ -72,6 +64,15 @@ interface TokenDetailsClickIntents {
|
|||
|
||||
fun onBalanceSelect(config: TokenBalanceSegmentedButtonConfig)
|
||||
|
||||
fun onYieldInfoClick()
|
||||
}
|
||||
|
||||
interface ExpressTransactionsClickIntents {
|
||||
|
||||
fun onExpressTransactionClick(txId: String)
|
||||
|
||||
fun onGoToProviderClick(url: String)
|
||||
|
||||
fun onGoToRefundedTokenClick(cryptoCurrency: CryptoCurrency)
|
||||
|
||||
fun onOpenUrlClick(url: String)
|
||||
|
|
@ -80,5 +81,69 @@ interface TokenDetailsClickIntents {
|
|||
|
||||
fun onDisposeExpressStatus()
|
||||
|
||||
fun onYieldInfoClick()
|
||||
fun onDismissBottomSheet()
|
||||
|
||||
fun onDismissDialog()
|
||||
}
|
||||
|
||||
@Suppress("TooManyFunctions")
|
||||
internal class EmptyTokenDetailsClickIntents : TokenDetailsClickIntents {
|
||||
override fun onRefreshSwipe(isRefreshing: Boolean) { /* no op */ }
|
||||
|
||||
override fun onBackClick() { /* no op */ }
|
||||
|
||||
override fun onBuyClick(unavailabilityReason: ScenarioUnavailabilityReason) { /* no op */ }
|
||||
|
||||
override fun onBuyCoinClick(cryptoCurrency: CryptoCurrency) { /* no op */ }
|
||||
|
||||
override fun onStakeBannerClick() { /* no op */ }
|
||||
|
||||
override fun onReloadClick() { /* no op */ }
|
||||
|
||||
override fun onSendClick(unavailabilityReason: ScenarioUnavailabilityReason) { /* no op */ }
|
||||
|
||||
override fun onReceiveClick(unavailabilityReason: ScenarioUnavailabilityReason) { /* no op */ }
|
||||
|
||||
override fun onStakeClick(unavailabilityReason: ScenarioUnavailabilityReason) { /* no op */ }
|
||||
|
||||
override fun onGenerateExtendedKey() { /* no op */ }
|
||||
|
||||
override fun onSellClick(unavailabilityReason: ScenarioUnavailabilityReason) { /* no op */ }
|
||||
|
||||
override fun onSwapClick(unavailabilityReason: ScenarioUnavailabilityReason) { /* no op */ }
|
||||
|
||||
override fun onHideClick() { /* no op */ }
|
||||
|
||||
override fun onHideConfirmed() { /* no op */ }
|
||||
|
||||
override fun onExploreClick() { /* no op */ }
|
||||
|
||||
override fun onAddressTypeSelected(addressModel: AddressModel) { /* no op */ }
|
||||
|
||||
override fun onTransactionClick(txHash: String) { /* no op */ }
|
||||
|
||||
override fun onCloseRentInfoNotification() { /* no op */ }
|
||||
|
||||
override fun onSwapPromoDismiss(promoId: PromoId) { /* no op */ }
|
||||
|
||||
override fun onSwapPromoClick(promoId: PromoId) { /* no op */ }
|
||||
|
||||
override fun onRetryIncompleteTransactionClick() { /* no op */ }
|
||||
|
||||
override fun onOpenTrustlineClick() { /* no op */ }
|
||||
|
||||
override fun onDismissIncompleteTransactionClick() { /* no op */ }
|
||||
|
||||
override fun onConfirmDismissIncompleteTransactionClick() { /* no op */ }
|
||||
|
||||
override fun onAssociateClick() { /* no op */ }
|
||||
|
||||
override fun onBalanceSelect(config: TokenBalanceSegmentedButtonConfig) { /* no op */ }
|
||||
|
||||
override fun onYieldInfoClick() { /* no op */ }
|
||||
|
||||
override fun onCopyAddress(): TextReference? {
|
||||
/* no op */
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
|
@ -153,7 +153,10 @@ internal class TokenDetailsModel @Inject constructor(
|
|||
private val getAccountCryptoCurrencyStatusUseCase: GetAccountCurrencyStatusUseCase,
|
||||
private val manageCryptoCurrenciesUseCase: ManageCryptoCurrenciesUseCase,
|
||||
private val yieldSupplyGetRewardsBalanceUseCase: YieldSupplyGetRewardsBalanceUseCase,
|
||||
) : Model(), TokenDetailsClickIntents, YieldSupplyDepositedWarningComponent.ModelCallback {
|
||||
) : Model(),
|
||||
TokenDetailsClickIntents,
|
||||
ExpressTransactionsClickIntents,
|
||||
YieldSupplyDepositedWarningComponent.ModelCallback {
|
||||
|
||||
private val params = paramsContainer.require<TokenDetailsComponent.Params>()
|
||||
private val userWalletId: UserWalletId = params.userWalletId
|
||||
|
|
@ -184,7 +187,8 @@ internal class TokenDetailsModel @Inject constructor(
|
|||
currentStateProvider = Provider { uiState.value },
|
||||
appCurrencyProvider = Provider(selectedAppCurrencyFlow::value),
|
||||
cryptoCurrencyStatusProvider = Provider { cryptoCurrencyStatus },
|
||||
clickIntents = this,
|
||||
tokenDetailsClickIntents = this,
|
||||
expressTransactionsClickIntents = this,
|
||||
networkHasDerivationUseCase = networkHasDerivationUseCase,
|
||||
getUserWalletUseCase = getUserWalletUseCase,
|
||||
userWalletId = userWalletId,
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
package com.tangem.feature.tokendetails.presentation.tokendetails.state
|
||||
|
||||
import com.tangem.common.ui.expressStatus.state.ExpressTransactionStateUM
|
||||
import com.tangem.common.ui.tokendetails.TokenDetailsDialogConfig
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
|
||||
import com.tangem.core.ui.components.containers.pullToRefresh.PullToRefreshConfig
|
||||
import com.tangem.core.ui.components.marketprice.MarketPriceBlockState
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.state.components.TokenDetailsDialogConfig
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.state.components.TokenDetailsNotification
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.PersistentList
|
||||
|
|
|
|||
|
|
@ -20,14 +20,14 @@ import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
|||
import com.tangem.domain.onramp.model.OnrampStatus
|
||||
import com.tangem.domain.onramp.model.cache.OnrampTransaction
|
||||
import com.tangem.domain.tokens.model.analytics.TokenOnrampAnalyticsEvent
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.model.TokenDetailsClickIntents
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.model.ExpressTransactionsClickIntents
|
||||
import com.tangem.features.tokendetails.impl.R
|
||||
import com.tangem.utils.Provider
|
||||
import com.tangem.utils.converter.Converter
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
|
||||
internal class TokenDetailsOnrampTransactionStateConverter(
|
||||
private val clickIntents: TokenDetailsClickIntents,
|
||||
private val clickIntents: ExpressTransactionsClickIntents,
|
||||
private val cryptoCurrency: CryptoCurrency,
|
||||
private val cryptoCurrencyStatusProvider: Provider<CryptoCurrencyStatus?>,
|
||||
private val appCurrencyProvider: Provider<AppCurrency>,
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package com.tangem.feature.tokendetails.presentation.tokendetails.state.factory
|
|||
import arrow.core.Either
|
||||
import com.tangem.common.ui.bottomsheet.chooseaddress.ChooseAddressBottomSheetConfig
|
||||
import com.tangem.common.ui.bottomsheet.receive.TokenReceiveBottomSheetConfig
|
||||
import com.tangem.common.ui.tokendetails.TokenDetailsDialogConfig
|
||||
import com.tangem.common.ui.tokens.getUnavailabilityReasonText
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
|
||||
import com.tangem.core.ui.components.dropdownmenu.TangemDropdownMenuItem
|
||||
|
|
@ -27,12 +28,12 @@ import com.tangem.domain.tokens.model.warnings.CryptoCurrencyWarning
|
|||
import com.tangem.domain.wallets.usecase.GetUserWalletUseCase
|
||||
import com.tangem.domain.wallets.usecase.NetworkHasDerivationUseCase
|
||||
import com.tangem.domain.yield.supply.models.YieldSupplyRewardBalance
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.model.ExpressTransactionsClickIntents
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.model.TokenDetailsClickIntents
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.state.TokenBalanceSegmentedButtonConfig
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.state.TokenDetailsAppBarMenuConfig
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.state.TokenDetailsBalanceBlockState
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.state.TokenDetailsState
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.state.components.TokenDetailsDialogConfig
|
||||
import com.tangem.features.tokendetails.impl.R
|
||||
import com.tangem.features.yield.supply.api.YieldSupplyFeatureToggles
|
||||
import com.tangem.utils.Provider
|
||||
|
|
@ -43,7 +44,8 @@ internal class TokenDetailsStateFactory(
|
|||
private val currentStateProvider: Provider<TokenDetailsState>,
|
||||
private val appCurrencyProvider: Provider<AppCurrency>,
|
||||
private val cryptoCurrencyStatusProvider: Provider<CryptoCurrencyStatus?>,
|
||||
private val clickIntents: TokenDetailsClickIntents,
|
||||
private val tokenDetailsClickIntents: TokenDetailsClickIntents,
|
||||
private val expressTransactionsClickIntents: ExpressTransactionsClickIntents,
|
||||
private val networkHasDerivationUseCase: NetworkHasDerivationUseCase,
|
||||
private val getUserWalletUseCase: GetUserWalletUseCase,
|
||||
private val userWalletId: UserWalletId,
|
||||
|
|
@ -52,7 +54,7 @@ internal class TokenDetailsStateFactory(
|
|||
|
||||
private val skeletonStateConverter by lazy {
|
||||
TokenDetailsSkeletonStateConverter(
|
||||
clickIntents = clickIntents,
|
||||
clickIntents = tokenDetailsClickIntents,
|
||||
networkHasDerivationUseCase = networkHasDerivationUseCase,
|
||||
getUserWalletUseCase = getUserWalletUseCase,
|
||||
userWalletId = userWalletId,
|
||||
|
|
@ -64,7 +66,7 @@ internal class TokenDetailsStateFactory(
|
|||
TokenDetailsNotificationConverter(
|
||||
userWalletId = userWalletId,
|
||||
getUserWalletUseCase = getUserWalletUseCase,
|
||||
clickIntents = clickIntents,
|
||||
clickIntents = tokenDetailsClickIntents,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -72,7 +74,7 @@ internal class TokenDetailsStateFactory(
|
|||
TokenDetailsLoadedBalanceConverter(
|
||||
currentStateProvider = currentStateProvider,
|
||||
appCurrencyProvider = appCurrencyProvider,
|
||||
clickIntents = clickIntents,
|
||||
clickIntents = tokenDetailsClickIntents,
|
||||
yieldSupplyFeatureToggles = yieldSupplyFeatureToggles,
|
||||
)
|
||||
}
|
||||
|
|
@ -80,7 +82,7 @@ internal class TokenDetailsStateFactory(
|
|||
private val tokenDetailsButtonsConverter by lazy {
|
||||
TokenDetailsActionButtonsConverter(
|
||||
currentStateProvider = currentStateProvider,
|
||||
clickIntents = clickIntents,
|
||||
clickIntents = tokenDetailsClickIntents,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -117,7 +119,7 @@ internal class TokenDetailsStateFactory(
|
|||
return TokenDetailsStakingInfoConverter(
|
||||
currentState = state,
|
||||
cryptoCurrencyStatus = cryptoCurrencyStatus,
|
||||
clickIntents = clickIntents,
|
||||
clickIntents = tokenDetailsClickIntents,
|
||||
appCurrencyProvider = appCurrencyProvider,
|
||||
stakingEntryInfo = stakingEntryInfo,
|
||||
).convert(stakingAvailability)
|
||||
|
|
@ -136,11 +138,11 @@ internal class TokenDetailsStateFactory(
|
|||
return currentStateProvider().copy(
|
||||
dialogConfig = TokenDetailsDialogConfig(
|
||||
isShow = true,
|
||||
onDismissRequest = clickIntents::onDismissDialog,
|
||||
onDismissRequest = expressTransactionsClickIntents::onDismissDialog,
|
||||
content = TokenDetailsDialogConfig.DialogContentConfig.ConfirmHideConfig(
|
||||
currencyTitle = currency.name,
|
||||
onConfirmClick = clickIntents::onHideConfirmed,
|
||||
onCancelClick = clickIntents::onDismissDialog,
|
||||
onConfirmClick = tokenDetailsClickIntents::onHideConfirmed,
|
||||
onCancelClick = expressTransactionsClickIntents::onDismissDialog,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
|
@ -150,12 +152,12 @@ internal class TokenDetailsStateFactory(
|
|||
return currentStateProvider().copy(
|
||||
dialogConfig = TokenDetailsDialogConfig(
|
||||
isShow = true,
|
||||
onDismissRequest = clickIntents::onDismissDialog,
|
||||
onDismissRequest = expressTransactionsClickIntents::onDismissDialog,
|
||||
content = TokenDetailsDialogConfig.DialogContentConfig.HasLinkedTokensConfig(
|
||||
currencyName = currency.name,
|
||||
currencySymbol = currency.symbol,
|
||||
networkName = currency.network.name,
|
||||
onConfirmClick = clickIntents::onDismissDialog,
|
||||
onConfirmClick = expressTransactionsClickIntents::onDismissDialog,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
|
@ -165,10 +167,10 @@ internal class TokenDetailsStateFactory(
|
|||
return currentStateProvider().copy(
|
||||
dialogConfig = TokenDetailsDialogConfig(
|
||||
isShow = true,
|
||||
onDismissRequest = clickIntents::onDismissDialog,
|
||||
onDismissRequest = expressTransactionsClickIntents::onDismissDialog,
|
||||
content = TokenDetailsDialogConfig.DialogContentConfig.RemoveIncompleteTransactionConfirmDialogConfig(
|
||||
onConfirmClick = clickIntents::onConfirmDismissIncompleteTransactionClick,
|
||||
onCancelClick = clickIntents::onDismissDialog,
|
||||
onConfirmClick = tokenDetailsClickIntents::onConfirmDismissIncompleteTransactionClick,
|
||||
onCancelClick = expressTransactionsClickIntents::onDismissDialog,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
|
@ -178,10 +180,10 @@ internal class TokenDetailsStateFactory(
|
|||
return currentStateProvider().copy(
|
||||
dialogConfig = TokenDetailsDialogConfig(
|
||||
isShow = true,
|
||||
onDismissRequest = clickIntents::onDismissDialog,
|
||||
onDismissRequest = expressTransactionsClickIntents::onDismissDialog,
|
||||
content = TokenDetailsDialogConfig.DialogContentConfig.DisabledButtonReasonDialogConfig(
|
||||
text = unavailabilityReason.getUnavailabilityReasonText(),
|
||||
onConfirmClick = clickIntents::onDismissDialog,
|
||||
onConfirmClick = expressTransactionsClickIntents::onDismissDialog,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
|
@ -191,10 +193,10 @@ internal class TokenDetailsStateFactory(
|
|||
return currentStateProvider().copy(
|
||||
dialogConfig = TokenDetailsDialogConfig(
|
||||
isShow = true,
|
||||
onDismissRequest = clickIntents::onDismissDialog,
|
||||
onDismissRequest = expressTransactionsClickIntents::onDismissDialog,
|
||||
content = TokenDetailsDialogConfig.DialogContentConfig.ErrorDialogConfig(
|
||||
text = text,
|
||||
onConfirmClick = clickIntents::onDismissDialog,
|
||||
onConfirmClick = expressTransactionsClickIntents::onDismissDialog,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
|
@ -217,7 +219,7 @@ internal class TokenDetailsStateFactory(
|
|||
return currentStateProvider().copy(
|
||||
bottomSheetConfig = TangemBottomSheetConfig(
|
||||
isShown = true,
|
||||
onDismissRequest = clickIntents::onDismissBottomSheet,
|
||||
onDismissRequest = expressTransactionsClickIntents::onDismissBottomSheet,
|
||||
content = TokenReceiveBottomSheetConfig(
|
||||
asset = TokenReceiveBottomSheetConfig.Asset.Currency(
|
||||
name = currency.name,
|
||||
|
|
@ -240,7 +242,7 @@ internal class TokenDetailsStateFactory(
|
|||
return currentStateProvider().copy(
|
||||
bottomSheetConfig = TangemBottomSheetConfig(
|
||||
isShown = true,
|
||||
onDismissRequest = clickIntents::onDismissBottomSheet,
|
||||
onDismissRequest = expressTransactionsClickIntents::onDismissBottomSheet,
|
||||
content = ChooseAddressBottomSheetConfig(
|
||||
asset = TokenReceiveBottomSheetConfig.Asset.Currency(
|
||||
name = currency.name,
|
||||
|
|
@ -248,7 +250,7 @@ internal class TokenDetailsStateFactory(
|
|||
),
|
||||
network = currency.network,
|
||||
networkAddress = networkAddress,
|
||||
onClick = clickIntents::onAddressTypeSelected,
|
||||
onClick = tokenDetailsClickIntents::onAddressTypeSelected,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
|
@ -338,13 +340,13 @@ internal class TokenDetailsStateFactory(
|
|||
return currentStateProvider().copy(
|
||||
dialogConfig = TokenDetailsDialogConfig(
|
||||
isShow = true,
|
||||
onDismissRequest = clickIntents::onDismissDialog,
|
||||
onDismissRequest = expressTransactionsClickIntents::onDismissDialog,
|
||||
content = TokenDetailsDialogConfig.DialogContentConfig.ConfirmExpressStatusHideDialogConfig(
|
||||
onConfirmClick = {
|
||||
clickIntents.onDisposeExpressStatus()
|
||||
clickIntents.onDismissDialog()
|
||||
expressTransactionsClickIntents.onDisposeExpressStatus()
|
||||
expressTransactionsClickIntents.onDismissDialog()
|
||||
},
|
||||
onCancelClick = clickIntents::onDismissDialog,
|
||||
onCancelClick = expressTransactionsClickIntents::onDismissDialog,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
|
@ -367,13 +369,13 @@ internal class TokenDetailsStateFactory(
|
|||
TangemDropdownMenuItem(
|
||||
title = resourceReference(R.string.token_details_generate_xpub),
|
||||
textColor = themedColor { TangemTheme.colors.text.primary1 },
|
||||
onClick = clickIntents::onGenerateExtendedKey,
|
||||
onClick = tokenDetailsClickIntents::onGenerateExtendedKey,
|
||||
).let(::add)
|
||||
}
|
||||
TangemDropdownMenuItem(
|
||||
title = TextReference.Res(id = R.string.token_details_hide_token),
|
||||
textColor = themedColor { TangemTheme.colors.text.warning },
|
||||
onClick = clickIntents::onHideClick,
|
||||
onClick = tokenDetailsClickIntents::onHideClick,
|
||||
).let(::add)
|
||||
}.toImmutableList(),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ import com.tangem.feature.swap.domain.models.domain.ExchangeStatus.Companion.isF
|
|||
import com.tangem.feature.swap.domain.models.domain.ExchangeStatusModel
|
||||
import com.tangem.feature.swap.domain.models.domain.SavedSwapTransactionListModel
|
||||
import com.tangem.feature.swap.domain.models.domain.SavedSwapTransactionModel
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.model.TokenDetailsClickIntents
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.model.ExpressTransactionsClickIntents
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.state.components.ExchangeStatusNotification
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.state.express.ExchangeStatusState
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.state.express.ExchangeUM
|
||||
|
|
@ -43,7 +43,7 @@ import java.util.Locale
|
|||
// Fixme [REDACTED_JIRA]
|
||||
@Suppress("LargeClass")
|
||||
internal class TokenDetailsSwapTransactionsStateConverter(
|
||||
private val clickIntents: TokenDetailsClickIntents,
|
||||
private val clickIntents: ExpressTransactionsClickIntents,
|
||||
private val cryptoCurrency: CryptoCurrency,
|
||||
private val analyticsEventsHandler: AnalyticsEventHandler,
|
||||
appCurrencyProvider: Provider<AppCurrency>,
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ import com.tangem.domain.tokens.model.analytics.TokenExchangeAnalyticsEvent
|
|||
import com.tangem.feature.swap.domain.SwapTransactionRepository
|
||||
import com.tangem.feature.swap.domain.api.SwapRepository
|
||||
import com.tangem.feature.swap.domain.models.domain.*
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.model.TokenDetailsClickIntents
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.model.ExpressTransactionsClickIntents
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.state.TokenDetailsState
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.state.express.ExchangeUM
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.state.factory.TokenDetailsSwapTransactionsStateConverter
|
||||
|
|
@ -44,7 +44,7 @@ internal class ExchangeStatusFactory @AssistedInject constructor(
|
|||
private val manageCryptoCurrenciesUseCase: ManageCryptoCurrenciesUseCase,
|
||||
private val swapTransactionStatusStore: SwapTransactionStatusStore,
|
||||
private val analyticsEventsHandler: AnalyticsEventHandler,
|
||||
@Assisted private val clickIntents: TokenDetailsClickIntents,
|
||||
@Assisted private val clickIntents: ExpressTransactionsClickIntents,
|
||||
@Assisted private val appCurrencyProvider: Provider<AppCurrency>,
|
||||
@Assisted private val currentStateProvider: Provider<TokenDetailsState>,
|
||||
@Assisted private val userWallet: UserWallet,
|
||||
|
|
@ -257,7 +257,7 @@ internal class ExchangeStatusFactory @AssistedInject constructor(
|
|||
@AssistedFactory
|
||||
interface Factory {
|
||||
fun create(
|
||||
clickIntents: TokenDetailsClickIntents,
|
||||
clickIntents: ExpressTransactionsClickIntents,
|
||||
appCurrencyProvider: Provider<AppCurrency>,
|
||||
currentStateProvider: Provider<TokenDetailsState>,
|
||||
userWallet: UserWallet,
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import com.tangem.domain.tokens.model.analytics.TokenExchangeAnalyticsEvent
|
|||
import com.tangem.domain.tokens.model.analytics.TokenOnrampAnalyticsEvent
|
||||
import com.tangem.domain.tokens.model.analytics.TokenScreenAnalyticsEvent
|
||||
import com.tangem.feature.swap.domain.models.domain.ExchangeStatus
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.model.TokenDetailsClickIntents
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.model.ExpressTransactionsClickIntents
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.state.TokenDetailsState
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.state.components.ExchangeStatusNotification
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.state.express.ExchangeUM
|
||||
|
|
@ -33,7 +33,7 @@ import kotlinx.coroutines.withContext
|
|||
@Suppress("LongParameterList")
|
||||
internal class ExpressStatusFactory @AssistedInject constructor(
|
||||
@Assisted private val currentStateProvider: Provider<TokenDetailsState>,
|
||||
@Assisted private val clickIntents: TokenDetailsClickIntents,
|
||||
@Assisted private val clickIntents: ExpressTransactionsClickIntents,
|
||||
@Assisted private val cryptoCurrency: CryptoCurrency,
|
||||
@Assisted appCurrencyProvider: Provider<AppCurrency>,
|
||||
@Assisted userWallet: UserWallet,
|
||||
|
|
@ -205,7 +205,7 @@ internal class ExpressStatusFactory @AssistedInject constructor(
|
|||
interface Factory {
|
||||
@Suppress("LongParameterList")
|
||||
fun create(
|
||||
clickIntents: TokenDetailsClickIntents,
|
||||
clickIntents: ExpressTransactionsClickIntents,
|
||||
appCurrencyProvider: Provider<AppCurrency>,
|
||||
currentStateProvider: Provider<TokenDetailsState>,
|
||||
userWallet: UserWallet,
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ import com.tangem.domain.onramp.OnrampUpdateTransactionStatusUseCase
|
|||
import com.tangem.domain.onramp.model.OnrampStatus
|
||||
import com.tangem.domain.onramp.model.OnrampStatus.Status.*
|
||||
import com.tangem.domain.tokens.model.analytics.TokenOnrampAnalyticsEvent
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.model.TokenDetailsClickIntents
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.model.ExpressTransactionsClickIntents
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.state.TokenDetailsState
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.state.factory.TokenDetailsOnrampTransactionStateConverter
|
||||
import com.tangem.utils.Provider
|
||||
|
|
@ -37,7 +37,7 @@ internal class OnrampStatusFactory @AssistedInject constructor(
|
|||
@Assisted private val currentStateProvider: Provider<TokenDetailsState>,
|
||||
@Assisted private val cryptoCurrencyStatusProvider: Provider<CryptoCurrencyStatus?>,
|
||||
@Assisted private val appCurrencyProvider: Provider<AppCurrency>,
|
||||
@Assisted private val clickIntents: TokenDetailsClickIntents,
|
||||
@Assisted private val clickIntents: ExpressTransactionsClickIntents,
|
||||
@Assisted private val cryptoCurrency: CryptoCurrency,
|
||||
@Assisted private val userWallet: UserWallet,
|
||||
) {
|
||||
|
|
@ -157,7 +157,7 @@ internal class OnrampStatusFactory @AssistedInject constructor(
|
|||
currentStateProvider: Provider<TokenDetailsState>,
|
||||
cryptoCurrencyStatusProvider: Provider<CryptoCurrencyStatus?>,
|
||||
appCurrencyProvider: Provider<AppCurrency>,
|
||||
clickIntents: TokenDetailsClickIntents,
|
||||
clickIntents: ExpressTransactionsClickIntents,
|
||||
cryptoCurrency: CryptoCurrency,
|
||||
userWallet: UserWallet,
|
||||
): OnrampStatusFactory
|
||||
|
|
|
|||
|
|
@ -0,0 +1,24 @@
|
|||
package com.tangem.feature.tokendetails.presentation.tokendetails.state.utils
|
||||
|
||||
import com.tangem.features.tokendetails.ExpressTransactionsEvent
|
||||
import com.tangem.features.tokendetails.ExpressTransactionsEventListener
|
||||
import kotlinx.coroutines.channels.BufferOverflow
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Singleton
|
||||
internal class DefaultExpressTransactionsEventListener @Inject constructor() : ExpressTransactionsEventListener {
|
||||
|
||||
private val _event = MutableSharedFlow<ExpressTransactionsEvent>(
|
||||
replay = 1,
|
||||
extraBufferCapacity = 0,
|
||||
onBufferOverflow = BufferOverflow.DROP_OLDEST,
|
||||
)
|
||||
override val event: Flow<ExpressTransactionsEvent> = _event
|
||||
|
||||
override suspend fun send(event: ExpressTransactionsEvent) {
|
||||
_event.emit(event)
|
||||
}
|
||||
}
|
||||
|
|
@ -45,7 +45,7 @@ import kotlinx.coroutines.flow.MutableStateFlow
|
|||
import kotlinx.coroutines.flow.StateFlow
|
||||
|
||||
// TODO: Split to blocks [REDACTED_JIRA]
|
||||
@Suppress("LongMethod")
|
||||
@Suppress("LongMethod", "CyclomaticComplexMethod")
|
||||
@Composable
|
||||
internal fun TokenDetailsScreen(
|
||||
state: TokenDetailsState,
|
||||
|
|
@ -62,6 +62,7 @@ internal fun TokenDetailsScreen(
|
|||
) { scaffoldPaddings ->
|
||||
val listState = rememberLazyListState()
|
||||
val txHistoryComponentState by txHistoryComponent.txHistoryState.collectAsStateWithLifecycle()
|
||||
val dialogConfig = state.dialogConfig
|
||||
val betweenItemsPadding = TangemTheme.dimens.spacing12
|
||||
val horizontalPadding = TangemTheme.dimens.spacing16
|
||||
val itemModifier = Modifier
|
||||
|
|
@ -162,7 +163,9 @@ internal fun TokenDetailsScreen(
|
|||
}
|
||||
}
|
||||
|
||||
TokenDetailsDialogs(state = state)
|
||||
if (dialogConfig != null) {
|
||||
TokenDetailsDialogs(dialogConfig = dialogConfig)
|
||||
}
|
||||
|
||||
state.bottomSheetConfig?.let { config ->
|
||||
when (config.content) {
|
||||
|
|
|
|||
|
|
@ -1,16 +1,14 @@
|
|||
package com.tangem.feature.tokendetails.presentation.tokendetails.ui.components
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import com.tangem.common.ui.tokendetails.TokenDetailsDialogConfig
|
||||
import com.tangem.core.ui.components.BasicDialog
|
||||
import com.tangem.core.ui.components.DialogButtonUM
|
||||
import com.tangem.core.ui.extensions.resolveReference
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.state.TokenDetailsState
|
||||
import com.tangem.feature.tokendetails.presentation.tokendetails.state.components.TokenDetailsDialogConfig
|
||||
|
||||
@Composable
|
||||
internal fun TokenDetailsDialogs(state: TokenDetailsState) {
|
||||
val dialogConfig = state.dialogConfig
|
||||
if (dialogConfig != null && dialogConfig.isShow) {
|
||||
internal fun TokenDetailsDialogs(dialogConfig: TokenDetailsDialogConfig) {
|
||||
if (dialogConfig.isShow) {
|
||||
TokenDetailsDialog(config = dialogConfig)
|
||||
}
|
||||
}
|
||||
|
|
@ -21,7 +19,7 @@ private fun TokenDetailsDialog(config: TokenDetailsDialogConfig) {
|
|||
message = config.content.message.resolveReference(),
|
||||
confirmButton = DialogButtonUM(
|
||||
title = config.content.confirmButtonConfig.text.resolveReference(),
|
||||
isWarning = config.content.confirmButtonConfig.warning,
|
||||
isWarning = config.content.confirmButtonConfig.hasWarning,
|
||||
onClick = config.content.confirmButtonConfig.onClick,
|
||||
),
|
||||
onDismissDialog = config.onDismissRequest,
|
||||
|
|
@ -29,7 +27,7 @@ private fun TokenDetailsDialog(config: TokenDetailsDialogConfig) {
|
|||
dismissButton = config.content.cancelButtonConfig?.let { cancelButtonConfig ->
|
||||
DialogButtonUM(
|
||||
title = cancelButtonConfig.text.resolveReference(),
|
||||
isWarning = cancelButtonConfig.warning,
|
||||
isWarning = cancelButtonConfig.hasWarning,
|
||||
onClick = cancelButtonConfig.onClick,
|
||||
)
|
||||
},
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue