Updated on 2026-08-14
This commit is contained in:
parent
9ce639e080
commit
7e992b986b
19 changed files with 349 additions and 460 deletions
|
|
@ -1,37 +0,0 @@
|
|||
package com.tangem.feature.wallet.presentation.wallet.state
|
||||
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.components.*
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
|
||||
/**
|
||||
* Loading wallet state
|
||||
*
|
||||
* @property onBackClick Lambda be invoked when back button is clicked
|
||||
*
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
internal data class WalletLoading(override val onBackClick: () -> Unit) : WalletStateHolder() {
|
||||
|
||||
override val topBarConfig = WalletTopBarConfig(onScanCardClick = {}, onMoreClick = {})
|
||||
|
||||
override val walletsListConfig = WalletsListConfig(
|
||||
selectedWalletIndex = 0,
|
||||
wallets = persistentListOf(
|
||||
WalletCardState.Loading(
|
||||
id = UserWalletId(stringValue = ""),
|
||||
title = "",
|
||||
additionalInfo = "",
|
||||
imageResId = null,
|
||||
),
|
||||
),
|
||||
onWalletChange = {},
|
||||
)
|
||||
|
||||
override val pullToRefreshConfig = WalletPullToRefreshConfig(isRefreshing = false, onRefresh = {})
|
||||
|
||||
override val notifications: ImmutableList<WalletNotification> = persistentListOf()
|
||||
|
||||
override val bottomSheetConfig = null
|
||||
}
|
||||
|
|
@ -9,7 +9,7 @@ import kotlinx.collections.immutable.persistentListOf
|
|||
*
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
internal sealed class WalletMultiCurrencyState : WalletStateHolder() {
|
||||
internal sealed class WalletMultiCurrencyState : WalletState.ContentState() {
|
||||
|
||||
/** Tokens list state */
|
||||
abstract val tokensListState: WalletTokensListState
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import kotlinx.collections.immutable.persistentListOf
|
|||
*
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
internal sealed class WalletSingleCurrencyState : WalletStateHolder() {
|
||||
internal sealed class WalletSingleCurrencyState : WalletState.ContentState() {
|
||||
|
||||
/** Manage buttons */
|
||||
abstract val buttons: ImmutableList<WalletManageButton>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,41 @@
|
|||
package com.tangem.feature.wallet.presentation.wallet.state
|
||||
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.components.*
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
|
||||
/**
|
||||
* Wallet screen state
|
||||
*
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
internal sealed class WalletState {
|
||||
|
||||
/** Lambda be invoked when back button is clicked */
|
||||
abstract val onBackClick: () -> Unit
|
||||
|
||||
/** Wallet screen content state */
|
||||
sealed class ContentState : WalletState() {
|
||||
|
||||
/** Top bar config */
|
||||
abstract val topBarConfig: WalletTopBarConfig
|
||||
|
||||
/** Wallets list config */
|
||||
abstract val walletsListConfig: WalletsListConfig
|
||||
|
||||
/** Pull to refresh config */
|
||||
abstract val pullToRefreshConfig: WalletPullToRefreshConfig
|
||||
|
||||
/** Notifications */
|
||||
abstract val notifications: ImmutableList<WalletNotification>
|
||||
|
||||
/** Bottom sheet config */
|
||||
abstract val bottomSheetConfig: WalletBottomSheetConfig?
|
||||
}
|
||||
|
||||
/**
|
||||
* Initial state
|
||||
*
|
||||
* @property onBackClick lambda be invoked when back button is clicked
|
||||
*/
|
||||
data class Initial(override val onBackClick: () -> Unit) : WalletState()
|
||||
}
|
||||
|
|
@ -1,103 +0,0 @@
|
|||
package com.tangem.feature.wallet.presentation.wallet.state
|
||||
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.components.*
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
|
||||
/**
|
||||
* Wallet screen state holder
|
||||
*
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
internal sealed class WalletStateHolder {
|
||||
|
||||
/** Lambda be invoked when back button is clicked */
|
||||
abstract val onBackClick: () -> Unit
|
||||
|
||||
/** Top bar config */
|
||||
abstract val topBarConfig: WalletTopBarConfig
|
||||
|
||||
/** Wallets list config */
|
||||
abstract val walletsListConfig: WalletsListConfig
|
||||
|
||||
/** Pull to refresh config */
|
||||
abstract val pullToRefreshConfig: WalletPullToRefreshConfig
|
||||
|
||||
/** Notifications */
|
||||
abstract val notifications: ImmutableList<WalletNotification>
|
||||
|
||||
/** Bottom sheet config */
|
||||
abstract val bottomSheetConfig: WalletBottomSheetConfig?
|
||||
|
||||
fun copySealed(
|
||||
onBackClick: () -> Unit = this.onBackClick,
|
||||
topBarConfig: WalletTopBarConfig = this.topBarConfig,
|
||||
walletsListConfig: WalletsListConfig = this.walletsListConfig,
|
||||
pullToRefreshConfig: WalletPullToRefreshConfig = this.pullToRefreshConfig,
|
||||
notifications: ImmutableList<WalletNotification> = this.notifications,
|
||||
bottomSheet: WalletBottomSheetConfig? = this.bottomSheetConfig,
|
||||
): WalletStateHolder {
|
||||
return when (this) {
|
||||
is WalletLoading -> {
|
||||
copy(onBackClick = onBackClick)
|
||||
}
|
||||
is WalletMultiCurrencyState.Content -> {
|
||||
copy(
|
||||
onBackClick = onBackClick,
|
||||
topBarConfig = topBarConfig,
|
||||
walletsListConfig = walletsListConfig,
|
||||
pullToRefreshConfig = pullToRefreshConfig,
|
||||
notifications = notifications,
|
||||
bottomSheetConfig = bottomSheet,
|
||||
)
|
||||
}
|
||||
is WalletMultiCurrencyState.Locked -> {
|
||||
if (bottomSheet != null) {
|
||||
copy(
|
||||
onBackClick = onBackClick,
|
||||
topBarConfig = topBarConfig,
|
||||
walletsListConfig = walletsListConfig,
|
||||
pullToRefreshConfig = pullToRefreshConfig,
|
||||
isBottomSheetShow = bottomSheet.isShow,
|
||||
onBottomSheetDismiss = bottomSheet.onDismissRequest,
|
||||
)
|
||||
} else {
|
||||
copy(
|
||||
onBackClick = onBackClick,
|
||||
topBarConfig = topBarConfig,
|
||||
walletsListConfig = walletsListConfig,
|
||||
pullToRefreshConfig = pullToRefreshConfig,
|
||||
)
|
||||
}
|
||||
}
|
||||
is WalletSingleCurrencyState.Content -> {
|
||||
copy(
|
||||
onBackClick = onBackClick,
|
||||
topBarConfig = topBarConfig,
|
||||
walletsListConfig = walletsListConfig,
|
||||
pullToRefreshConfig = pullToRefreshConfig,
|
||||
notifications = notifications,
|
||||
bottomSheetConfig = bottomSheet,
|
||||
)
|
||||
}
|
||||
is WalletSingleCurrencyState.Locked -> {
|
||||
if (bottomSheet != null) {
|
||||
copy(
|
||||
onBackClick = onBackClick,
|
||||
topBarConfig = topBarConfig,
|
||||
walletsListConfig = walletsListConfig,
|
||||
pullToRefreshConfig = pullToRefreshConfig,
|
||||
isBottomSheetShow = bottomSheet.isShow,
|
||||
onBottomSheetDismiss = bottomSheet.onDismissRequest,
|
||||
)
|
||||
} else {
|
||||
copy(
|
||||
onBackClick = onBackClick,
|
||||
topBarConfig = topBarConfig,
|
||||
walletsListConfig = walletsListConfig,
|
||||
pullToRefreshConfig = pullToRefreshConfig,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -5,28 +5,30 @@ import com.tangem.common.Provider
|
|||
import com.tangem.domain.common.CardTypesResolver
|
||||
import com.tangem.domain.tokens.error.TokenListError
|
||||
import com.tangem.domain.tokens.model.TokenList
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.WalletStateHolder
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.WalletMultiCurrencyState
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.WalletState
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.factory.WalletLoadedTokensListConverter.LoadedTokensListModel
|
||||
import com.tangem.feature.wallet.presentation.wallet.utils.TokenListErrorToWalletStateConverter
|
||||
import com.tangem.feature.wallet.presentation.wallet.utils.TokenListErrorConverter
|
||||
import com.tangem.feature.wallet.presentation.wallet.utils.TokenListToWalletStateConverter
|
||||
import com.tangem.feature.wallet.presentation.wallet.viewmodels.WalletClickIntents
|
||||
import com.tangem.utils.converter.Converter
|
||||
|
||||
/**
|
||||
* Converter from loaded [TokenListError] or [TokenList] to [WalletStateHolder]
|
||||
* Converter from loaded [TokenListError] or [TokenList] to [WalletMultiCurrencyState]
|
||||
*
|
||||
* @property currentStateProvider current ui state provider
|
||||
* @param cardTypeResolverProvider card type resolver
|
||||
* @param isLockedWalletProvider current wallet is locked or not provider
|
||||
* @param clickIntents screen click intents
|
||||
*
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
internal class WalletLoadedTokensListConverter(
|
||||
private val currentStateProvider: Provider<WalletStateHolder>,
|
||||
private val currentStateProvider: Provider<WalletState>,
|
||||
cardTypeResolverProvider: Provider<CardTypesResolver>,
|
||||
isLockedWalletProvider: Provider<Boolean>,
|
||||
clickIntents: WalletClickIntents,
|
||||
) : Converter<LoadedTokensListModel, WalletStateHolder> {
|
||||
) : Converter<LoadedTokensListModel, WalletMultiCurrencyState.Content> {
|
||||
|
||||
private val tokenListStateConverter = TokenListToWalletStateConverter(
|
||||
currentStateProvider = currentStateProvider,
|
||||
|
|
@ -38,11 +40,11 @@ internal class WalletLoadedTokensListConverter(
|
|||
clickIntents = clickIntents,
|
||||
)
|
||||
|
||||
private val tokenListErrorStateConverter = TokenListErrorToWalletStateConverter(
|
||||
private val tokenListErrorStateConverter = TokenListErrorConverter(
|
||||
currentStateProvider = currentStateProvider,
|
||||
)
|
||||
|
||||
override fun convert(value: LoadedTokensListModel): WalletStateHolder {
|
||||
override fun convert(value: LoadedTokensListModel): WalletMultiCurrencyState.Content {
|
||||
return value.tokenListEither.fold(
|
||||
ifLeft = tokenListErrorStateConverter::convert,
|
||||
ifRight = {
|
||||
|
|
|
|||
|
|
@ -1,15 +1,14 @@
|
|||
package com.tangem.feature.wallet.presentation.wallet.state.factory
|
||||
|
||||
import androidx.paging.PagingData
|
||||
import com.tangem.common.Provider
|
||||
import com.tangem.core.ui.components.marketprice.MarketPriceBlockState
|
||||
import com.tangem.domain.common.CardTypesResolver
|
||||
import com.tangem.domain.common.util.cardTypesResolver
|
||||
import com.tangem.domain.wallets.models.UserWallet
|
||||
import com.tangem.feature.wallet.presentation.wallet.domain.WalletAdditionalInfoFactory
|
||||
import com.tangem.feature.wallet.presentation.wallet.domain.WalletImageResolver
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.WalletMultiCurrencyState
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.WalletSingleCurrencyState
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.WalletStateHolder
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.WalletState
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.components.*
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.factory.WalletSkeletonStateConverter.SkeletonModel
|
||||
import com.tangem.feature.wallet.presentation.wallet.viewmodels.WalletClickIntents
|
||||
|
|
@ -17,62 +16,43 @@ import com.tangem.utils.converter.Converter
|
|||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
import kotlinx.coroutines.flow.flow
|
||||
|
||||
/**
|
||||
* Converter from loaded list of [UserWallet] to skeleton state of screen [WalletStateHolder]
|
||||
* Converter from loaded list of [UserWallet] to skeleton state of screen [WalletState.ContentState]
|
||||
*
|
||||
* @property clickIntents screen click intents
|
||||
* @property currentStateProvider current ui state provider
|
||||
* @property clickIntents screen click intents
|
||||
*
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
internal class WalletSkeletonStateConverter(
|
||||
private val currentStateProvider: Provider<WalletState>,
|
||||
private val clickIntents: WalletClickIntents,
|
||||
) : Converter<SkeletonModel, WalletStateHolder> {
|
||||
) : Converter<SkeletonModel, WalletState.ContentState> {
|
||||
|
||||
override fun convert(value: SkeletonModel): WalletStateHolder {
|
||||
val wallet = requireNotNull(value.wallets.getOrNull(value.selectedWalletIndex)) { "Empty wallet list" }
|
||||
val cardTypeResolver = wallet.scanResponse.cardTypesResolver
|
||||
override fun convert(value: SkeletonModel): WalletState.ContentState {
|
||||
val cardTypeResolver = value.wallets[value.selectedWalletIndex].scanResponse.cardTypesResolver
|
||||
|
||||
return when {
|
||||
cardTypeResolver.isMultiwalletAllowed() -> createMultiCurrencyState(value)
|
||||
!cardTypeResolver.isMultiwalletAllowed() -> createSingleCurrencyState(value, cardTypeResolver)
|
||||
else -> error("Illegal wallet state: $wallet")
|
||||
return if (cardTypeResolver.isMultiwalletAllowed()) {
|
||||
createMultiCurrencyState(value = value)
|
||||
} else {
|
||||
createSingleCurrencyState(value = value, currencyName = cardTypeResolver.getBlockchain().currency)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create [WalletMultiCurrencyState.Content].
|
||||
* Tokens and notifications are updated asynchronously.
|
||||
*
|
||||
* @param value converted value
|
||||
*/
|
||||
private fun createMultiCurrencyState(value: SkeletonModel): WalletMultiCurrencyState.Content {
|
||||
private fun createMultiCurrencyState(value: SkeletonModel): WalletMultiCurrencyState {
|
||||
return WalletMultiCurrencyState.Content(
|
||||
onBackClick = clickIntents::onBackClick,
|
||||
topBarConfig = createTopBarConfig(),
|
||||
walletsListConfig = createWalletsListConfig(value),
|
||||
pullToRefreshConfig = createPullToRefreshConfig(),
|
||||
tokensListState = WalletTokensListState.Content(
|
||||
items = persistentListOf(),
|
||||
onOrganizeTokensClick = null,
|
||||
),
|
||||
tokensListState = WalletTokensListState.Loading,
|
||||
notifications = persistentListOf(),
|
||||
bottomSheetConfig = null,
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Create [WalletSingleCurrencyState.Content].
|
||||
* Transactions, notifications and market price are updated asynchronously.
|
||||
*
|
||||
* @param value converted value
|
||||
* @param cardTypeResolver card type resolver
|
||||
*/
|
||||
private fun createSingleCurrencyState(
|
||||
value: SkeletonModel,
|
||||
cardTypeResolver: CardTypesResolver,
|
||||
): WalletSingleCurrencyState.Content {
|
||||
private fun createSingleCurrencyState(value: SkeletonModel, currencyName: String): WalletSingleCurrencyState {
|
||||
return WalletSingleCurrencyState.Content(
|
||||
onBackClick = clickIntents::onBackClick,
|
||||
topBarConfig = createTopBarConfig(),
|
||||
|
|
@ -81,12 +61,8 @@ internal class WalletSkeletonStateConverter(
|
|||
notifications = persistentListOf(),
|
||||
bottomSheetConfig = null,
|
||||
buttons = getButtons(),
|
||||
marketPriceBlockState = MarketPriceBlockState.Loading(
|
||||
currencyName = cardTypeResolver.getBlockchain().currency,
|
||||
),
|
||||
txHistoryState = WalletTxHistoryState.Content(
|
||||
items = flow { PagingData.empty<WalletTxHistoryState.TxHistoryItemState>() },
|
||||
),
|
||||
marketPriceBlockState = MarketPriceBlockState.Loading(currencyName = currencyName),
|
||||
txHistoryState = WalletTxHistoryState.Loading(onExploreClick = clickIntents::onExploreClick),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -100,22 +76,43 @@ internal class WalletSkeletonStateConverter(
|
|||
private fun createWalletsListConfig(value: SkeletonModel): WalletsListConfig {
|
||||
return WalletsListConfig(
|
||||
selectedWalletIndex = value.selectedWalletIndex,
|
||||
wallets = value.wallets.map { wallet ->
|
||||
val cardTypeResolver = wallet.scanResponse.cardTypesResolver
|
||||
WalletCardState.Loading(
|
||||
id = wallet.walletId,
|
||||
title = wallet.name,
|
||||
additionalInfo = WalletAdditionalInfoFactory.resolve(
|
||||
cardTypesResolver = cardTypeResolver,
|
||||
isLocked = wallet.isLocked,
|
||||
),
|
||||
imageResId = WalletImageResolver.resolve(cardTypesResolver = cardTypeResolver),
|
||||
)
|
||||
}.toImmutableList(),
|
||||
wallets = value.wallets.map(::createWalletState).toImmutableList(),
|
||||
onWalletChange = clickIntents::onWalletChange,
|
||||
)
|
||||
}
|
||||
|
||||
private fun createWalletState(wallet: UserWallet): WalletCardState {
|
||||
val state = currentStateProvider()
|
||||
|
||||
// If it isn't first initialization (example, when user unlocks wallet)
|
||||
return if (state is WalletState.ContentState) {
|
||||
val initializedWallet = state.walletsListConfig.wallets.first { it.id == wallet.walletId }
|
||||
|
||||
// If wallet is initialized, return it, otherwise return loading state
|
||||
if (initializedWallet !is WalletCardState.Loading) {
|
||||
initializedWallet
|
||||
} else {
|
||||
createWalletLoadingState(wallet)
|
||||
}
|
||||
} else {
|
||||
createWalletLoadingState(wallet)
|
||||
}
|
||||
}
|
||||
|
||||
private fun createWalletLoadingState(wallet: UserWallet): WalletCardState {
|
||||
val cardTypeResolver = wallet.scanResponse.cardTypesResolver
|
||||
|
||||
return WalletCardState.Loading(
|
||||
id = wallet.walletId,
|
||||
title = wallet.name,
|
||||
additionalInfo = WalletAdditionalInfoFactory.resolve(
|
||||
cardTypesResolver = cardTypeResolver,
|
||||
isLocked = wallet.isLocked,
|
||||
),
|
||||
imageResId = WalletImageResolver.resolve(cardTypesResolver = cardTypeResolver),
|
||||
)
|
||||
}
|
||||
|
||||
private fun createPullToRefreshConfig(): WalletPullToRefreshConfig {
|
||||
return WalletPullToRefreshConfig(isRefreshing = false, onRefresh = clickIntents::onRefreshSwipe)
|
||||
}
|
||||
|
|
@ -123,16 +120,14 @@ internal class WalletSkeletonStateConverter(
|
|||
// TODO: [REDACTED_JIRA]
|
||||
private fun getButtons(): ImmutableList<WalletManageButton> {
|
||||
return persistentListOf(
|
||||
WalletManageButton.Buy(onClick = {}),
|
||||
WalletManageButton.Send(onClick = {}),
|
||||
WalletManageButton.Buy(),
|
||||
WalletManageButton.Send(),
|
||||
WalletManageButton.Receive(onClick = {}),
|
||||
WalletManageButton.Exchange(onClick = {}),
|
||||
WalletManageButton.Exchange(),
|
||||
WalletManageButton.Sell(),
|
||||
WalletManageButton.CopyAddress(onClick = {}),
|
||||
)
|
||||
}
|
||||
|
||||
data class SkeletonModel(
|
||||
val wallets: List<UserWallet>,
|
||||
val selectedWalletIndex: Int,
|
||||
)
|
||||
data class SkeletonModel(val wallets: List<UserWallet>, val selectedWalletIndex: Int)
|
||||
}
|
||||
|
|
@ -10,14 +10,12 @@ import com.tangem.domain.txhistory.models.TxHistoryItem
|
|||
import com.tangem.domain.txhistory.models.TxHistoryListError
|
||||
import com.tangem.domain.txhistory.models.TxHistoryStateError
|
||||
import com.tangem.domain.wallets.models.UserWallet
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.WalletLoading
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.WalletMultiCurrencyState
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.WalletSingleCurrencyState
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.WalletStateHolder
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.WalletState
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.components.WalletBottomSheetConfig
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.components.WalletManageButton
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.components.WalletNotification
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.factory.WalletLoadedTokensListConverter.LoadedTokensListModel
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.factory.txhistory.WalletLoadedTxHistoryConverter
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.factory.txhistory.WalletLoadingTxHistoryConverter
|
||||
import com.tangem.feature.wallet.presentation.wallet.viewmodels.WalletClickIntents
|
||||
|
|
@ -26,7 +24,7 @@ import kotlinx.collections.immutable.persistentListOf
|
|||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
/**
|
||||
* Main factory for creating [WalletStateHolder]
|
||||
* Main factory for creating [WalletState]
|
||||
*
|
||||
* @property currentStateProvider current ui state provider
|
||||
* @property currentCardTypeResolverProvider current card type resolver
|
||||
|
|
@ -34,13 +32,13 @@ import kotlinx.coroutines.flow.Flow
|
|||
* @property clickIntents screen click intents
|
||||
*/
|
||||
internal class WalletStateFactory(
|
||||
private val currentStateProvider: Provider<WalletStateHolder>,
|
||||
private val currentStateProvider: Provider<WalletState>,
|
||||
private val currentCardTypeResolverProvider: Provider<CardTypesResolver>,
|
||||
private val isLockedWalletProvider: Provider<Boolean>,
|
||||
private val clickIntents: WalletClickIntents,
|
||||
) {
|
||||
|
||||
private val skeletonConverter by lazy { WalletSkeletonStateConverter(clickIntents = clickIntents) }
|
||||
private val skeletonConverter by lazy { WalletSkeletonStateConverter(currentStateProvider, clickIntents) }
|
||||
|
||||
private val loadedTokensListConverter by lazy {
|
||||
WalletLoadedTokensListConverter(
|
||||
|
|
@ -54,7 +52,6 @@ internal class WalletStateFactory(
|
|||
private val loadingTransactionsStateConverter by lazy {
|
||||
WalletLoadingTxHistoryConverter(
|
||||
currentStateProvider = currentStateProvider,
|
||||
currentCardTypeResolverProvider = currentCardTypeResolverProvider,
|
||||
clickIntents = clickIntents,
|
||||
)
|
||||
}
|
||||
|
|
@ -67,70 +64,97 @@ internal class WalletStateFactory(
|
|||
)
|
||||
}
|
||||
|
||||
fun getInitialState(): WalletStateHolder = WalletLoading(onBackClick = clickIntents::onBackClick)
|
||||
fun getInitialState(): WalletState = WalletState.Initial(onBackClick = clickIntents::onBackClick)
|
||||
|
||||
fun getSkeletonState(wallets: List<UserWallet>, index: Int): WalletStateHolder {
|
||||
fun getSkeletonState(wallets: List<UserWallet>, selectedWalletIndex: Int): WalletState {
|
||||
return skeletonConverter.convert(
|
||||
value = WalletSkeletonStateConverter.SkeletonModel(wallets = wallets, selectedWalletIndex = index),
|
||||
value = WalletSkeletonStateConverter.SkeletonModel(
|
||||
wallets = wallets,
|
||||
selectedWalletIndex = selectedWalletIndex,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
fun getStateByTokensList(
|
||||
tokenListEither: Either<TokenListError, TokenList>,
|
||||
isRefreshing: Boolean,
|
||||
): WalletStateHolder {
|
||||
fun getStateByTokensList(tokenListEither: Either<TokenListError, TokenList>, isRefreshing: Boolean): WalletState {
|
||||
return loadedTokensListConverter.convert(
|
||||
value = LoadedTokensListModel(tokenListEither = tokenListEither, isRefreshing = isRefreshing),
|
||||
value = WalletLoadedTokensListConverter.LoadedTokensListModel(
|
||||
tokenListEither = tokenListEither,
|
||||
isRefreshing = isRefreshing,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
fun getStateByNotifications(notifications: ImmutableList<WalletNotification>): WalletStateHolder {
|
||||
return currentStateProvider().copySealed(notifications = notifications)
|
||||
}
|
||||
|
||||
fun getStateAfterWalletChanging(index: Int): WalletStateHolder {
|
||||
return currentStateProvider().let { stateHolder ->
|
||||
stateHolder.copySealed(walletsListConfig = stateHolder.walletsListConfig.copy(selectedWalletIndex = index))
|
||||
fun getStateByNotifications(notifications: ImmutableList<WalletNotification>): WalletState {
|
||||
return when (val state = currentStateProvider()) {
|
||||
is WalletMultiCurrencyState.Content -> state.copy(notifications = notifications)
|
||||
is WalletSingleCurrencyState.Content -> state.copy(notifications = notifications)
|
||||
else -> state
|
||||
}
|
||||
}
|
||||
|
||||
fun getStateAfterContentRefreshing(): WalletStateHolder {
|
||||
return currentStateProvider().let { state ->
|
||||
state.copySealed(pullToRefreshConfig = state.pullToRefreshConfig.copy(isRefreshing = true))
|
||||
}
|
||||
fun getStateAfterContentRefreshing(): WalletState {
|
||||
return currentStateProvider()
|
||||
}
|
||||
|
||||
fun getStateWithOpenBottomSheet(content: WalletBottomSheetConfig.BottomSheetContentConfig): WalletStateHolder {
|
||||
return currentStateProvider().let { state ->
|
||||
state.copySealed(
|
||||
bottomSheet = WalletBottomSheetConfig(
|
||||
fun getStateWithOpenBottomSheet(content: WalletBottomSheetConfig.BottomSheetContentConfig): WalletState {
|
||||
return when (val state = currentStateProvider() as WalletState.ContentState) {
|
||||
is WalletMultiCurrencyState.Content -> state.copy(
|
||||
bottomSheetConfig = WalletBottomSheetConfig(
|
||||
isShow = true,
|
||||
onDismissRequest = {
|
||||
state.copySealed(bottomSheet = state.bottomSheetConfig?.copy(isShow = false))
|
||||
},
|
||||
onDismissRequest = clickIntents::onBottomSheetDismiss,
|
||||
content = content,
|
||||
),
|
||||
)
|
||||
is WalletMultiCurrencyState.Locked -> state.copy(
|
||||
isBottomSheetShow = true,
|
||||
onBottomSheetDismiss = clickIntents::onBottomSheetDismiss,
|
||||
)
|
||||
is WalletSingleCurrencyState.Content -> state.copy(
|
||||
bottomSheetConfig = WalletBottomSheetConfig(
|
||||
isShow = true,
|
||||
onDismissRequest = clickIntents::onBottomSheetDismiss,
|
||||
content = content,
|
||||
),
|
||||
)
|
||||
is WalletSingleCurrencyState.Locked -> state.copy(
|
||||
isBottomSheetShow = true,
|
||||
onBottomSheetDismiss = clickIntents::onBottomSheetDismiss,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun getLoadingTxHistoryState(itemsCountEither: Either<TxHistoryStateError, Int>): WalletStateHolder {
|
||||
fun getStateWithClosedBottomSheet(): WalletState {
|
||||
return when (val state = currentStateProvider() as WalletState.ContentState) {
|
||||
is WalletMultiCurrencyState.Content -> state.copy(
|
||||
bottomSheetConfig = state.bottomSheetConfig?.copy(isShow = false),
|
||||
)
|
||||
is WalletMultiCurrencyState.Locked -> state.copy(isBottomSheetShow = false)
|
||||
is WalletSingleCurrencyState.Content -> state.copy(
|
||||
bottomSheetConfig = state.bottomSheetConfig?.copy(isShow = false),
|
||||
)
|
||||
is WalletSingleCurrencyState.Locked -> state.copy(isBottomSheetShow = false)
|
||||
}
|
||||
}
|
||||
|
||||
fun getLoadingTxHistoryState(itemsCountEither: Either<TxHistoryStateError, Int>): WalletState {
|
||||
return loadingTransactionsStateConverter.convert(value = itemsCountEither)
|
||||
}
|
||||
|
||||
fun getLoadedTxHistoryState(
|
||||
txHistoryEither: Either<TxHistoryListError, Flow<PagingData<TxHistoryItem>>>,
|
||||
): WalletStateHolder {
|
||||
): WalletState {
|
||||
return loadedTxHistoryConverter.convert(txHistoryEither)
|
||||
}
|
||||
|
||||
fun getLockedState(): WalletStateHolder {
|
||||
fun getLockedState(): WalletState {
|
||||
val cardTypeResolver = currentCardTypeResolverProvider()
|
||||
val state = currentStateProvider()
|
||||
val state = requireNotNull(currentStateProvider() as? WalletState.ContentState)
|
||||
return if (cardTypeResolver.isMultiwalletAllowed()) {
|
||||
WalletMultiCurrencyState.Locked(
|
||||
onBackClick = state.onBackClick,
|
||||
topBarConfig = state.topBarConfig,
|
||||
topBarConfig = state.topBarConfig.copy(
|
||||
onMoreClick = clickIntents::onUnlockWalletNotificationClick,
|
||||
),
|
||||
walletsListConfig = state.walletsListConfig,
|
||||
pullToRefreshConfig = state.pullToRefreshConfig,
|
||||
onUnlockWalletsNotificationClick = clickIntents::onUnlockWalletNotificationClick,
|
||||
|
|
@ -140,7 +164,9 @@ internal class WalletStateFactory(
|
|||
} else {
|
||||
WalletSingleCurrencyState.Locked(
|
||||
onBackClick = state.onBackClick,
|
||||
topBarConfig = state.topBarConfig,
|
||||
topBarConfig = state.topBarConfig.copy(
|
||||
onMoreClick = clickIntents::onUnlockWalletNotificationClick,
|
||||
),
|
||||
walletsListConfig = state.walletsListConfig,
|
||||
pullToRefreshConfig = state.pullToRefreshConfig,
|
||||
buttons = getButtons(),
|
||||
|
|
@ -155,10 +181,11 @@ internal class WalletStateFactory(
|
|||
// TODO: [REDACTED_JIRA]
|
||||
private fun getButtons(): ImmutableList<WalletManageButton> {
|
||||
return persistentListOf(
|
||||
WalletManageButton.Buy(onClick = {}),
|
||||
WalletManageButton.Send(onClick = {}),
|
||||
WalletManageButton.Buy(),
|
||||
WalletManageButton.Send(),
|
||||
WalletManageButton.Receive(onClick = {}),
|
||||
WalletManageButton.Exchange(onClick = {}),
|
||||
WalletManageButton.Exchange(),
|
||||
WalletManageButton.Sell(),
|
||||
WalletManageButton.CopyAddress(onClick = {}),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,18 +3,14 @@ package com.tangem.feature.wallet.presentation.wallet.state.factory.txhistory
|
|||
import androidx.paging.PagingData
|
||||
import arrow.core.Either
|
||||
import com.tangem.common.Provider
|
||||
import com.tangem.core.ui.components.marketprice.MarketPriceBlockState
|
||||
import com.tangem.domain.common.CardTypesResolver
|
||||
import com.tangem.domain.txhistory.models.TxHistoryItem
|
||||
import com.tangem.domain.txhistory.models.TxHistoryListError
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.WalletSingleCurrencyState
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.WalletStateHolder
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.components.WalletManageButton
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.WalletState
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.components.WalletTxHistoryState
|
||||
import com.tangem.feature.wallet.presentation.wallet.viewmodels.WalletClickIntents
|
||||
import com.tangem.utils.converter.Converter
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
/**
|
||||
|
|
@ -27,10 +23,10 @@ import kotlinx.coroutines.flow.Flow
|
|||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
internal class WalletLoadedTxHistoryConverter(
|
||||
private val currentStateProvider: Provider<WalletStateHolder>,
|
||||
private val currentStateProvider: Provider<WalletState>,
|
||||
private val currentCardTypeResolverProvider: Provider<CardTypesResolver>,
|
||||
private val clickIntents: WalletClickIntents,
|
||||
) : Converter<Either<TxHistoryListError, Flow<PagingData<TxHistoryItem>>>, WalletStateHolder> {
|
||||
) : Converter<Either<TxHistoryListError, Flow<PagingData<TxHistoryItem>>>, WalletState> {
|
||||
|
||||
private val walletTxHistoryItemFlowConverter by lazy {
|
||||
WalletTxHistoryItemFlowConverter(
|
||||
|
|
@ -39,12 +35,12 @@ internal class WalletLoadedTxHistoryConverter(
|
|||
)
|
||||
}
|
||||
|
||||
override fun convert(value: Either<TxHistoryListError, Flow<PagingData<TxHistoryItem>>>): WalletStateHolder {
|
||||
override fun convert(value: Either<TxHistoryListError, Flow<PagingData<TxHistoryItem>>>): WalletState {
|
||||
return value.fold(ifLeft = ::convertError, ifRight = ::convert)
|
||||
}
|
||||
|
||||
private fun convertError(error: TxHistoryListError): WalletStateHolder {
|
||||
return currentStateProvider().copySingleCurrencyContent(
|
||||
private fun convertError(error: TxHistoryListError): WalletState {
|
||||
return requireNotNull(currentStateProvider() as? WalletSingleCurrencyState.Content).copy(
|
||||
txHistoryState = when (error) {
|
||||
is TxHistoryListError.DataError -> {
|
||||
WalletTxHistoryState.Error(onReloadClick = clickIntents::onReloadClick)
|
||||
|
|
@ -53,40 +49,9 @@ internal class WalletLoadedTxHistoryConverter(
|
|||
)
|
||||
}
|
||||
|
||||
private fun convert(items: Flow<PagingData<TxHistoryItem>>): WalletStateHolder {
|
||||
return currentStateProvider().copySingleCurrencyContent(
|
||||
private fun convert(items: Flow<PagingData<TxHistoryItem>>): WalletState {
|
||||
return requireNotNull(currentStateProvider() as? WalletSingleCurrencyState.Content).copy(
|
||||
txHistoryState = walletTxHistoryItemFlowConverter.convert(value = items),
|
||||
)
|
||||
}
|
||||
|
||||
private fun WalletStateHolder.copySingleCurrencyContent(
|
||||
txHistoryState: WalletTxHistoryState,
|
||||
): WalletSingleCurrencyState {
|
||||
return WalletSingleCurrencyState.Content(
|
||||
onBackClick = onBackClick,
|
||||
topBarConfig = topBarConfig,
|
||||
walletsListConfig = walletsListConfig,
|
||||
pullToRefreshConfig = pullToRefreshConfig,
|
||||
notifications = notifications,
|
||||
bottomSheetConfig = bottomSheetConfig,
|
||||
buttons = getButtons(),
|
||||
marketPriceBlockState = getLoadingMarketPriceBlockState(),
|
||||
txHistoryState = txHistoryState,
|
||||
)
|
||||
}
|
||||
|
||||
// TODO: [REDACTED_JIRA]
|
||||
private fun getButtons(): ImmutableList<WalletManageButton> {
|
||||
return persistentListOf(
|
||||
WalletManageButton.Buy(onClick = {}),
|
||||
WalletManageButton.Send(onClick = {}),
|
||||
WalletManageButton.Receive(onClick = {}),
|
||||
WalletManageButton.Exchange(onClick = {}),
|
||||
WalletManageButton.CopyAddress(onClick = {}),
|
||||
)
|
||||
}
|
||||
|
||||
private fun getLoadingMarketPriceBlockState(): MarketPriceBlockState {
|
||||
return MarketPriceBlockState.Loading(currencyName = currentCardTypeResolverProvider().getBlockchain().currency)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,57 +1,33 @@
|
|||
package com.tangem.feature.wallet.presentation.wallet.state.factory.txhistory
|
||||
|
||||
import androidx.paging.PagingData
|
||||
import arrow.core.Either
|
||||
import com.tangem.common.Provider
|
||||
import com.tangem.core.ui.components.marketprice.MarketPriceBlockState
|
||||
import com.tangem.core.ui.components.transactions.TransactionState
|
||||
import com.tangem.domain.common.CardTypesResolver
|
||||
import com.tangem.domain.txhistory.models.TxHistoryStateError
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.WalletSingleCurrencyState
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.WalletStateHolder
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.components.WalletManageButton
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.WalletState
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.components.WalletTxHistoryState
|
||||
import com.tangem.feature.wallet.presentation.wallet.viewmodels.WalletClickIntents
|
||||
import com.tangem.utils.converter.Converter
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.coroutines.flow.flowOf
|
||||
|
||||
/**
|
||||
* Converter from loading tx history to [WalletTxHistoryState]
|
||||
* Converter from loading tx history state to [WalletSingleCurrencyState.Content]
|
||||
*
|
||||
* @property currentStateProvider current state provider
|
||||
* @property currentCardTypeResolverProvider current card type resolver provider
|
||||
* @property clickIntents screen click intents
|
||||
*
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
internal class WalletLoadingTxHistoryConverter(
|
||||
private val currentStateProvider: Provider<WalletStateHolder>,
|
||||
private val currentCardTypeResolverProvider: Provider<CardTypesResolver>,
|
||||
private val currentStateProvider: Provider<WalletState>,
|
||||
private val clickIntents: WalletClickIntents,
|
||||
) : Converter<Either<TxHistoryStateError, Int>, WalletStateHolder> {
|
||||
) : Converter<Either<TxHistoryStateError, Int>, WalletSingleCurrencyState.Content> {
|
||||
|
||||
override fun convert(value: Either<TxHistoryStateError, Int>): WalletStateHolder {
|
||||
override fun convert(value: Either<TxHistoryStateError, Int>): WalletSingleCurrencyState.Content {
|
||||
return value.fold(ifLeft = ::convertError, ifRight = ::convert)
|
||||
}
|
||||
|
||||
private fun convert(value: Int): WalletStateHolder {
|
||||
return currentStateProvider().copySingleCurrencyContent(
|
||||
txHistoryState = WalletTxHistoryState.Content(
|
||||
items = flowOf(
|
||||
value = PagingData.from(
|
||||
data = buildList(capacity = value) {
|
||||
add(WalletTxHistoryState.TxHistoryItemState.Transaction(state = TransactionState.Loading))
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
private fun convertError(error: TxHistoryStateError): WalletStateHolder {
|
||||
return currentStateProvider().copySingleCurrencyContent(
|
||||
private fun convertError(error: TxHistoryStateError): WalletSingleCurrencyState.Content {
|
||||
return requireNotNull(currentStateProvider() as? WalletSingleCurrencyState.Content).copy(
|
||||
txHistoryState = when (error) {
|
||||
is TxHistoryStateError.EmptyTxHistories -> {
|
||||
WalletTxHistoryState.Empty(onBuyClick = clickIntents::onBuyClick)
|
||||
|
|
@ -66,34 +42,9 @@ internal class WalletLoadingTxHistoryConverter(
|
|||
)
|
||||
}
|
||||
|
||||
private fun WalletStateHolder.copySingleCurrencyContent(
|
||||
txHistoryState: WalletTxHistoryState,
|
||||
): WalletSingleCurrencyState {
|
||||
return WalletSingleCurrencyState.Content(
|
||||
onBackClick = onBackClick,
|
||||
topBarConfig = topBarConfig,
|
||||
walletsListConfig = walletsListConfig,
|
||||
pullToRefreshConfig = pullToRefreshConfig,
|
||||
notifications = notifications,
|
||||
bottomSheetConfig = bottomSheetConfig,
|
||||
buttons = getButtons(),
|
||||
marketPriceBlockState = getLoadingMarketPriceBlockState(),
|
||||
txHistoryState = txHistoryState,
|
||||
private fun convert(value: Int): WalletSingleCurrencyState.Content {
|
||||
return requireNotNull(currentStateProvider() as? WalletSingleCurrencyState.Content).copy(
|
||||
txHistoryState = WalletTxHistoryState.ContentWithLoadingItems(itemsCount = value),
|
||||
)
|
||||
}
|
||||
|
||||
// TODO: [REDACTED_JIRA]
|
||||
private fun getButtons(): ImmutableList<WalletManageButton> {
|
||||
return persistentListOf(
|
||||
WalletManageButton.Buy(onClick = {}),
|
||||
WalletManageButton.Send(onClick = {}),
|
||||
WalletManageButton.Receive(onClick = {}),
|
||||
WalletManageButton.Exchange(onClick = {}),
|
||||
WalletManageButton.CopyAddress(onClick = {}),
|
||||
)
|
||||
}
|
||||
|
||||
private fun getLoadingMarketPriceBlockState(): MarketPriceBlockState {
|
||||
return MarketPriceBlockState.Loading(currencyName = currentCardTypeResolverProvider().getBlockchain().currency)
|
||||
}
|
||||
}
|
||||
|
|
@ -20,7 +20,7 @@ import com.tangem.core.ui.res.TangemTheme
|
|||
import com.tangem.feature.wallet.presentation.common.WalletPreviewData
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.WalletMultiCurrencyState
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.WalletSingleCurrencyState
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.WalletStateHolder
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.WalletState
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.components.WalletTxHistoryState
|
||||
import com.tangem.feature.wallet.presentation.wallet.ui.components.WalletsList
|
||||
import com.tangem.feature.wallet.presentation.wallet.ui.components.common.*
|
||||
|
|
@ -36,11 +36,19 @@ import com.tangem.feature.wallet.presentation.wallet.ui.utils.changeWalletAnimat
|
|||
*
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
@OptIn(ExperimentalMaterialApi::class)
|
||||
@Composable
|
||||
internal fun WalletScreen(state: WalletStateHolder) {
|
||||
internal fun WalletScreen(state: WalletState) {
|
||||
BackHandler(onBack = state.onBackClick)
|
||||
|
||||
when (state) {
|
||||
is WalletState.ContentState -> WalletContent(state = state)
|
||||
is WalletState.Initial -> Unit
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalMaterialApi::class)
|
||||
@Composable
|
||||
private fun WalletContent(state: WalletState.ContentState) {
|
||||
val walletsListState = rememberLazyListState()
|
||||
|
||||
Scaffold(
|
||||
|
|
@ -121,9 +129,7 @@ internal fun WalletScreen(state: WalletStateHolder) {
|
|||
// region Preview
|
||||
@Preview
|
||||
@Composable
|
||||
private fun WalletScreenPreview_Light(
|
||||
@PreviewParameter(WalletScreenParameterProvider::class) state: WalletStateHolder,
|
||||
) {
|
||||
private fun WalletScreenPreview_Light(@PreviewParameter(WalletScreenParameterProvider::class) state: WalletState) {
|
||||
TangemTheme {
|
||||
WalletScreen(state)
|
||||
}
|
||||
|
|
@ -131,15 +137,13 @@ private fun WalletScreenPreview_Light(
|
|||
|
||||
@Preview
|
||||
@Composable
|
||||
private fun WalletScreenPreview_Dark(
|
||||
@PreviewParameter(WalletScreenParameterProvider::class) state: WalletStateHolder,
|
||||
) {
|
||||
private fun WalletScreenPreview_Dark(@PreviewParameter(WalletScreenParameterProvider::class) state: WalletState) {
|
||||
TangemTheme(isDark = true) {
|
||||
WalletScreen(state)
|
||||
}
|
||||
}
|
||||
|
||||
private class WalletScreenParameterProvider : CollectionPreviewParameterProvider<WalletStateHolder>(
|
||||
private class WalletScreenParameterProvider : CollectionPreviewParameterProvider<WalletState>(
|
||||
collection = listOf(
|
||||
WalletPreviewData.multicurrencyWalletScreenState,
|
||||
WalletPreviewData.singleWalletScreenState,
|
||||
|
|
|
|||
|
|
@ -3,10 +3,9 @@ package com.tangem.feature.wallet.presentation.wallet.ui.components.common
|
|||
import androidx.compose.foundation.lazy.LazyListScope
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.paging.compose.LazyPagingItems
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.WalletLoading
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.WalletMultiCurrencyState
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.WalletSingleCurrencyState
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.WalletStateHolder
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.WalletState
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.components.WalletTxHistoryState
|
||||
import com.tangem.feature.wallet.presentation.wallet.ui.components.multicurrency.tokensListItems
|
||||
import com.tangem.feature.wallet.presentation.wallet.ui.components.singlecurrency.txHistoryItems
|
||||
|
|
@ -21,14 +20,12 @@ import com.tangem.feature.wallet.presentation.wallet.ui.components.singlecurrenc
|
|||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
internal fun LazyListScope.contentItems(
|
||||
state: WalletStateHolder,
|
||||
state: WalletState.ContentState,
|
||||
txHistoryItems: LazyPagingItems<WalletTxHistoryState.TxHistoryItemState>?,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
when (state) {
|
||||
is WalletMultiCurrencyState -> tokensListItems(state.tokensListState, modifier)
|
||||
is WalletSingleCurrencyState -> txHistoryItems(state.txHistoryState, txHistoryItems, modifier)
|
||||
is WalletLoading,
|
||||
-> Unit
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
package com.tangem.feature.wallet.presentation.wallet.ui.components.common
|
||||
|
||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||
import androidx.compose.foundation.lazy.LazyListScope
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.ui.Modifier
|
||||
|
|
@ -15,6 +16,11 @@ import kotlinx.collections.immutable.ImmutableList
|
|||
*
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
@OptIn(ExperimentalFoundationApi::class)
|
||||
internal fun LazyListScope.notifications(configs: ImmutableList<WalletNotification>, modifier: Modifier = Modifier) {
|
||||
items(items = configs, itemContent = { Notification(state = it.state, modifier = modifier) })
|
||||
items(
|
||||
items = configs,
|
||||
key = { it.state.title.hashCode() },
|
||||
itemContent = { Notification(state = it.state, modifier = modifier.animateItemPlacement()) },
|
||||
)
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
package com.tangem.feature.wallet.presentation.wallet.utils
|
||||
|
||||
import com.tangem.common.Provider
|
||||
import com.tangem.domain.tokens.error.TokenListError
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.WalletMultiCurrencyState
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.WalletState
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.components.WalletTokensListState
|
||||
import com.tangem.utils.converter.Converter
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
|
||||
internal class TokenListErrorConverter(
|
||||
private val currentStateProvider: Provider<WalletState>,
|
||||
) : Converter<TokenListError, WalletMultiCurrencyState.Content> {
|
||||
|
||||
// TODO: [REDACTED_JIRA]
|
||||
override fun convert(value: TokenListError): WalletMultiCurrencyState.Content {
|
||||
return requireNotNull(currentStateProvider() as? WalletMultiCurrencyState.Content).copy(
|
||||
tokensListState = WalletTokensListState.Content(items = persistentListOf(), onOrganizeTokensClick = null),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
package com.tangem.feature.wallet.presentation.wallet.utils
|
||||
|
||||
import com.tangem.common.Provider
|
||||
import com.tangem.domain.tokens.error.TokenListError
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.WalletMultiCurrencyState
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.WalletStateHolder
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.components.WalletTokensListState
|
||||
import com.tangem.utils.converter.Converter
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
|
||||
internal class TokenListErrorToWalletStateConverter(
|
||||
private val currentStateProvider: Provider<WalletStateHolder>,
|
||||
) : Converter<TokenListError, WalletStateHolder> {
|
||||
|
||||
// TODO: [REDACTED_JIRA]
|
||||
override fun convert(value: TokenListError): WalletStateHolder {
|
||||
val state = currentStateProvider()
|
||||
return WalletMultiCurrencyState.Content(
|
||||
onBackClick = state.onBackClick,
|
||||
topBarConfig = state.topBarConfig,
|
||||
walletsListConfig = state.walletsListConfig,
|
||||
pullToRefreshConfig = state.pullToRefreshConfig,
|
||||
notifications = state.notifications,
|
||||
bottomSheetConfig = state.bottomSheetConfig,
|
||||
tokensListState = WalletTokensListState.Content(items = persistentListOf(), onOrganizeTokensClick = null),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -5,7 +5,7 @@ import com.tangem.domain.common.CardTypesResolver
|
|||
import com.tangem.domain.tokens.model.TokenList
|
||||
import com.tangem.feature.wallet.presentation.common.state.TokenItemState
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.WalletMultiCurrencyState
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.WalletStateHolder
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.WalletState
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.components.WalletTokensListState
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.components.WalletsListConfig
|
||||
import com.tangem.feature.wallet.presentation.wallet.utils.TokenListToWalletStateConverter.TokensListModel
|
||||
|
|
@ -15,14 +15,14 @@ import kotlinx.collections.immutable.toPersistentList
|
|||
|
||||
@Suppress("LongParameterList")
|
||||
internal class TokenListToWalletStateConverter(
|
||||
private val currentStateProvider: Provider<WalletStateHolder>,
|
||||
private val currentStateProvider: Provider<WalletState>,
|
||||
private val cardTypeResolverProvider: Provider<CardTypesResolver>,
|
||||
private val isLockedWalletProvider: Provider<Boolean>,
|
||||
private val isWalletContentHidden: Boolean,
|
||||
private val fiatCurrencyCode: String,
|
||||
private val fiatCurrencySymbol: String,
|
||||
clickIntents: WalletClickIntents,
|
||||
) : Converter<TokensListModel, WalletStateHolder> {
|
||||
) : Converter<TokensListModel, WalletMultiCurrencyState.Content> {
|
||||
|
||||
private val tokenListToContentConverter = TokenListToContentItemsConverter(
|
||||
isWalletContentHidden = isWalletContentHidden,
|
||||
|
|
@ -31,33 +31,20 @@ internal class TokenListToWalletStateConverter(
|
|||
clickIntents = clickIntents,
|
||||
)
|
||||
|
||||
override fun convert(value: TokensListModel): WalletStateHolder {
|
||||
val state = currentStateProvider()
|
||||
return state
|
||||
.updateWithTokenList(tokenList = value.tokenList)
|
||||
.copySealed(
|
||||
walletsListConfig = state.updateSelectedWallet(value.tokenList.totalFiatBalance),
|
||||
pullToRefreshConfig = if (value.isRefreshing) {
|
||||
state.pullToRefreshConfig.copy(isRefreshing = state.getRefreshingStatus())
|
||||
} else {
|
||||
state.pullToRefreshConfig
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
private fun WalletStateHolder.updateWithTokenList(tokenList: TokenList): WalletMultiCurrencyState.Content {
|
||||
return WalletMultiCurrencyState.Content(
|
||||
onBackClick = onBackClick,
|
||||
topBarConfig = topBarConfig,
|
||||
walletsListConfig = walletsListConfig,
|
||||
pullToRefreshConfig = pullToRefreshConfig,
|
||||
notifications = notifications,
|
||||
bottomSheetConfig = bottomSheetConfig,
|
||||
tokensListState = tokenListToContentConverter.convert(value = tokenList),
|
||||
override fun convert(value: TokensListModel): WalletMultiCurrencyState.Content {
|
||||
val state = requireNotNull(currentStateProvider() as? WalletMultiCurrencyState.Content)
|
||||
return state.copy(
|
||||
walletsListConfig = state.updateSelectedWallet(fiatBalance = value.tokenList.totalFiatBalance),
|
||||
pullToRefreshConfig = if (value.isRefreshing) {
|
||||
state.pullToRefreshConfig.copy(isRefreshing = state.getRefreshingStatus())
|
||||
} else {
|
||||
state.pullToRefreshConfig
|
||||
},
|
||||
tokensListState = tokenListToContentConverter.convert(value = value.tokenList),
|
||||
)
|
||||
}
|
||||
|
||||
private fun WalletStateHolder.updateSelectedWallet(fiatBalance: TokenList.FiatBalance): WalletsListConfig {
|
||||
private fun WalletMultiCurrencyState.updateSelectedWallet(fiatBalance: TokenList.FiatBalance): WalletsListConfig {
|
||||
val selectedWalletIndex = walletsListConfig.selectedWalletIndex
|
||||
val selectedWalletCard = walletsListConfig.wallets[selectedWalletIndex]
|
||||
val converter = FiatBalanceToWalletCardConverter(
|
||||
|
|
@ -70,13 +57,12 @@ internal class TokenListToWalletStateConverter(
|
|||
)
|
||||
|
||||
return walletsListConfig.copy(
|
||||
wallets = walletsListConfig.wallets
|
||||
.toPersistentList()
|
||||
wallets = walletsListConfig.wallets.toPersistentList()
|
||||
.set(index = selectedWalletIndex, element = converter.convert(fiatBalance)),
|
||||
)
|
||||
}
|
||||
|
||||
private fun WalletStateHolder.getRefreshingStatus(): Boolean {
|
||||
private fun WalletState.getRefreshingStatus(): Boolean {
|
||||
return if (this is WalletMultiCurrencyState.Content) {
|
||||
tokensListState.items.any { tokensListItemState ->
|
||||
tokensListItemState is WalletTokensListState.TokensListItemState.Token &&
|
||||
|
|
|
|||
|
|
@ -35,4 +35,6 @@ internal interface WalletClickIntents {
|
|||
fun onUnlockWalletClick()
|
||||
|
||||
fun onUnlockWalletNotificationClick()
|
||||
|
||||
fun onBottomSheetDismiss()
|
||||
}
|
||||
|
|
@ -7,7 +7,7 @@ import com.tangem.domain.tokens.model.NetworkGroup
|
|||
import com.tangem.domain.tokens.model.TokenList
|
||||
import com.tangem.feature.wallet.presentation.common.state.TokenItemState
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.WalletMultiCurrencyState
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.WalletStateHolder
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.WalletState
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.components.WalletNotification
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.components.WalletTokensListState
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
|
|
@ -26,7 +26,7 @@ import kotlinx.coroutines.flow.flow
|
|||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
internal class WalletNotificationsListFactory(
|
||||
private val currentStateProvider: Provider<WalletStateHolder>,
|
||||
private val currentStateProvider: Provider<WalletState>,
|
||||
private val wasCardScannedCallback: suspend (String) -> Boolean,
|
||||
private val isUserAlreadyRateAppCallback: suspend () -> Boolean,
|
||||
private val isDemoCardCallback: (String) -> Boolean,
|
||||
|
|
|
|||
|
|
@ -21,17 +21,20 @@ import com.tangem.domain.txhistory.usecase.GetTxHistoryItemsCountUseCase
|
|||
import com.tangem.domain.txhistory.usecase.GetTxHistoryItemsUseCase
|
||||
import com.tangem.domain.userwallets.UserWalletBuilder
|
||||
import com.tangem.domain.wallets.models.UserWallet
|
||||
import com.tangem.domain.wallets.usecase.GetExploreUrlUseCase
|
||||
import com.tangem.domain.wallets.usecase.GetWalletsUseCase
|
||||
import com.tangem.domain.wallets.usecase.SaveWalletUseCase
|
||||
import com.tangem.domain.wallets.usecase.UnlockWalletsUseCase
|
||||
import com.tangem.domain.wallets.usecase.*
|
||||
import com.tangem.feature.wallet.presentation.router.InnerWalletRouter
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.*
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.WalletLockedState
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.WalletMultiCurrencyState
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.WalletSingleCurrencyState
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.WalletState
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.components.WalletBottomSheetConfig
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.factory.WalletStateFactory
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.flow.*
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.flowOn
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
import kotlin.properties.Delegates
|
||||
|
|
@ -41,11 +44,13 @@ import kotlin.properties.Delegates
|
|||
*
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
@Suppress("LongParameterList")
|
||||
@Suppress("LongParameterList", "TooManyFunctions")
|
||||
@HiltViewModel
|
||||
internal class WalletViewModel @Inject constructor(
|
||||
private val getWalletsUseCase: GetWalletsUseCase,
|
||||
private val saveWalletUseCase: SaveWalletUseCase,
|
||||
private val getSelectedWalletUseCase: GetSelectedWalletUseCase,
|
||||
private val selectWalletUseCase: SelectWalletUseCase,
|
||||
private val getBiometricsStatusUseCase: GetBiometricsStatusUseCase,
|
||||
private val setAccessCodeRequestPolicyUseCase: SetAccessCodeRequestPolicyUseCase,
|
||||
private val getAccessCodeSavingStatusUseCase: GetAccessCodeSavingStatusUseCase,
|
||||
|
|
@ -75,14 +80,18 @@ internal class WalletViewModel @Inject constructor(
|
|||
private val stateFactory = WalletStateFactory(
|
||||
currentStateProvider = Provider { uiState },
|
||||
currentCardTypeResolverProvider = Provider {
|
||||
getCardTypeResolver(index = uiState.walletsListConfig.selectedWalletIndex)
|
||||
getCardTypeResolver(
|
||||
index = requireNotNull(uiState as? WalletState.ContentState).walletsListConfig.selectedWalletIndex,
|
||||
)
|
||||
},
|
||||
isLockedWalletProvider = Provider {
|
||||
wallets[requireNotNull(uiState as? WalletState.ContentState).walletsListConfig.selectedWalletIndex].isLocked
|
||||
},
|
||||
isLockedWalletProvider = Provider { wallets[uiState.walletsListConfig.selectedWalletIndex].isLocked },
|
||||
clickIntents = this,
|
||||
)
|
||||
|
||||
/** Screen state */
|
||||
var uiState: WalletStateHolder by mutableStateOf(stateFactory.getInitialState())
|
||||
var uiState: WalletState by mutableStateOf(stateFactory.getInitialState())
|
||||
private set
|
||||
|
||||
private var wallets: List<UserWallet> by Delegates.notNull()
|
||||
|
|
@ -100,17 +109,26 @@ internal class WalletViewModel @Inject constructor(
|
|||
}
|
||||
|
||||
private fun updateWallets(sourceList: List<UserWallet>) {
|
||||
if (sourceList.isEmpty() || sourceList.all(UserWallet::isLocked)) return
|
||||
if (sourceList.isEmpty()) return
|
||||
|
||||
wallets = sourceList
|
||||
|
||||
val unlockedWalletIndex = sourceList.indexOfFirst { !it.isLocked }
|
||||
uiState = stateFactory.getSkeletonState(
|
||||
wallets = wallets,
|
||||
index = if (unlockedWalletIndex == -1) 0 else unlockedWalletIndex,
|
||||
)
|
||||
val currentState = uiState
|
||||
val selectedWalletIndex = if (currentState is WalletLockedState) {
|
||||
when (currentState) {
|
||||
is WalletMultiCurrencyState.Locked -> currentState.walletsListConfig.selectedWalletIndex
|
||||
is WalletSingleCurrencyState.Locked -> currentState.walletsListConfig.selectedWalletIndex
|
||||
}
|
||||
} else {
|
||||
val selectedWallet = getSelectedWalletUseCase().fold(
|
||||
ifLeft = { error("Selected wallet is null") },
|
||||
ifRight = { it },
|
||||
)
|
||||
sourceList.indexOfFirst { it.walletId == selectedWallet.walletId }
|
||||
}
|
||||
|
||||
updateContentItems(index = unlockedWalletIndex)
|
||||
uiState = stateFactory.getSkeletonState(wallets = sourceList, selectedWalletIndex = selectedWalletIndex)
|
||||
updateContentItems(index = selectedWalletIndex)
|
||||
}
|
||||
|
||||
private fun updateContentItems(index: Int, isRefreshing: Boolean = false) {
|
||||
|
|
@ -122,8 +140,12 @@ internal class WalletViewModel @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private fun updateByTokensList(index: Int, isRefreshing: Boolean) {
|
||||
getTokenListUseCase(userWalletId = uiState.walletsListConfig.wallets[index].id)
|
||||
private fun updateByTokensList(index: Int, isRefreshing: Boolean = false) {
|
||||
val state = requireNotNull(uiState as? WalletMultiCurrencyState) {
|
||||
"Impossible to update tokens list if state isn't WalletMultiCurrencyState"
|
||||
}
|
||||
|
||||
getTokenListUseCase(userWalletId = state.walletsListConfig.wallets[index].id)
|
||||
.distinctUntilChanged()
|
||||
.onEach { tokenListEither ->
|
||||
uiState = stateFactory.getStateByTokensList(
|
||||
|
|
@ -144,7 +166,7 @@ internal class WalletViewModel @Inject constructor(
|
|||
private fun updateByTxHistory(index: Int) {
|
||||
viewModelScope.launch(dispatchers.io) {
|
||||
val wallet = getWallet(index)
|
||||
val blockchain = wallet.scanResponse.cardTypesResolver.getBlockchain()
|
||||
val blockchain = getCardTypeResolver(index).getBlockchain()
|
||||
val derivationPath = blockchain.derivationPath(style = wallet.scanResponse.card.derivationStyle)?.rawPath
|
||||
|
||||
val txHistoryItemsCountEither = txHistoryItemsCountUseCase(
|
||||
|
|
@ -160,8 +182,9 @@ internal class WalletViewModel @Inject constructor(
|
|||
derivationPath = derivationPath,
|
||||
)
|
||||
}
|
||||
updateNotifications(index)
|
||||
}
|
||||
|
||||
updateNotifications(index)
|
||||
}
|
||||
|
||||
private fun updateTxHistory(networkId: Network.ID, derivationPath: String?) {
|
||||
|
|
@ -179,7 +202,20 @@ internal class WalletViewModel @Inject constructor(
|
|||
.onEach { uiState = stateFactory.getStateByNotifications(notifications = it) }
|
||||
.flowOn(dispatchers.io)
|
||||
.launchIn(viewModelScope)
|
||||
.saveIn(jobHolder = notificationsJobHolder)
|
||||
.saveIn(notificationsJobHolder)
|
||||
}
|
||||
|
||||
override fun onStop(owner: LifecycleOwner) {
|
||||
viewModelScope.launch(dispatchers.io) {
|
||||
saveSelectedWallet()
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun saveSelectedWallet() {
|
||||
val state = uiState
|
||||
if (state is WalletState.ContentState) {
|
||||
selectWalletUseCase(getWallet(index = state.walletsListConfig.selectedWalletIndex).walletId)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getWallet(index: Int): UserWallet {
|
||||
|
|
@ -258,21 +294,30 @@ internal class WalletViewModel @Inject constructor(
|
|||
}
|
||||
|
||||
override fun onWalletChange(index: Int) {
|
||||
if (uiState.walletsListConfig.selectedWalletIndex == index) return
|
||||
val state = requireNotNull(uiState as? WalletState.ContentState) {
|
||||
"Impossible to change wallet if state isn't WalletState.ContentState"
|
||||
}
|
||||
|
||||
uiState = stateFactory.getStateAfterWalletChanging(index = index)
|
||||
if (state.walletsListConfig.selectedWalletIndex == index) return
|
||||
|
||||
uiState = stateFactory.getSkeletonState(wallets = wallets, selectedWalletIndex = index)
|
||||
|
||||
updateContentItems(index = index)
|
||||
}
|
||||
|
||||
override fun onRefreshSwipe() {
|
||||
uiState = stateFactory.getStateAfterContentRefreshing()
|
||||
updateContentItems(index = uiState.walletsListConfig.selectedWalletIndex, isRefreshing = true)
|
||||
|
||||
updateContentItems(
|
||||
index = requireNotNull(uiState as? WalletState.ContentState).walletsListConfig.selectedWalletIndex,
|
||||
isRefreshing = true,
|
||||
)
|
||||
}
|
||||
|
||||
override fun onOrganizeTokensClick() {
|
||||
val index = uiState.walletsListConfig.selectedWalletIndex
|
||||
val walletId = uiState.walletsListConfig.wallets[index].id
|
||||
val state = requireNotNull(uiState as? WalletState.ContentState)
|
||||
val index = state.walletsListConfig.selectedWalletIndex
|
||||
val walletId = state.walletsListConfig.wallets[index].id
|
||||
|
||||
router.openOrganizeTokensScreen(walletId)
|
||||
}
|
||||
|
|
@ -283,12 +328,16 @@ internal class WalletViewModel @Inject constructor(
|
|||
|
||||
override fun onReloadClick() {
|
||||
uiState = stateFactory.getStateAfterContentRefreshing()
|
||||
updateByTxHistory(index = uiState.walletsListConfig.selectedWalletIndex)
|
||||
updateByTxHistory(
|
||||
index = requireNotNull(uiState as? WalletState.ContentState).walletsListConfig.selectedWalletIndex,
|
||||
)
|
||||
}
|
||||
|
||||
override fun onExploreClick() {
|
||||
viewModelScope.launch(dispatchers.io) {
|
||||
val wallet = getWallet(uiState.walletsListConfig.selectedWalletIndex)
|
||||
val wallet = getWallet(
|
||||
index = requireNotNull(uiState as? WalletState.ContentState).walletsListConfig.selectedWalletIndex,
|
||||
)
|
||||
router.openTxHistoryWebsite(
|
||||
url = getExploreUrlUseCase(
|
||||
userWalletId = wallet.walletId,
|
||||
|
|
@ -307,8 +356,19 @@ internal class WalletViewModel @Inject constructor(
|
|||
}
|
||||
|
||||
override fun onUnlockWalletNotificationClick() {
|
||||
val state = requireNotNull(uiState as? WalletLockedState) {
|
||||
"Impossible to unlock wallet if state isn't WalletLockedState"
|
||||
}
|
||||
|
||||
uiState = stateFactory.getStateWithOpenBottomSheet(
|
||||
content = requireNotNull(uiState.bottomSheetConfig?.content),
|
||||
content = when (state) {
|
||||
is WalletMultiCurrencyState.Locked -> state.bottomSheetConfig.content
|
||||
is WalletSingleCurrencyState.Locked -> state.bottomSheetConfig.content
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
override fun onBottomSheetDismiss() {
|
||||
uiState = stateFactory.getStateWithClosedBottomSheet()
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue