diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/ScrollToWalletTransformer.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/ScrollToWalletTransformer.kt index 6381c98d9d..d7135f0fdf 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/ScrollToWalletTransformer.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/ScrollToWalletTransformer.kt @@ -10,6 +10,7 @@ internal class ScrollToWalletTransformer( private val index: Int, private val currentStateProvider: Provider, private val stateUpdater: (WalletScreenState) -> Unit, + private val onConsume: () -> Unit = {}, ) : WalletScreenStateTransformer { override fun transform(prevState: WalletScreenState): WalletScreenState { @@ -23,6 +24,8 @@ internal class ScrollToWalletTransformer( event = consumedEvent(), ), ) + + onConsume() }, ), ) diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/WalletScreen.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/WalletScreen.kt index 9d6dc72199..9819f09790 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/WalletScreen.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/WalletScreen.kt @@ -113,7 +113,7 @@ private fun WalletContent( alertConfig: WalletAlertState?, ) { var selectedWalletIndex by remember(state.selectedWalletIndex) { mutableIntStateOf(state.selectedWalletIndex) } - val selectedWallet = state.wallets[selectedWalletIndex] + val selectedWallet = state.wallets.getOrElse(selectedWalletIndex) { state.wallets[state.selectedWalletIndex] } val scaffoldContent: @Composable () -> Unit = { val movableItemModifier = Modifier.changeWalletAnimator(walletsListState) diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/utils/LazyListStateExt.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/utils/LazyListStateExt.kt index a9ccd192d4..d1b702c3b9 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/utils/LazyListStateExt.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/utils/LazyListStateExt.kt @@ -20,5 +20,12 @@ internal suspend fun LazyListState.animateScrollByIndex(prevIndex: Int, newIndex } private fun calculateOffset(layoutInfo: LazyListLayoutInfo, prevIndex: Int, newIndex: Int): Float { - return layoutInfo.viewportSize.width.times(other = newIndex - prevIndex).toFloat() + val indexDifference = newIndex - prevIndex + val coefficient = if (indexDifference == 0) 1 else indexDifference + + return layoutInfo.getItemSizeWithSpacing().times(other = coefficient).toFloat() +} + +private fun LazyListLayoutInfo.getItemSizeWithSpacing(): Int { + return viewportSize.width - afterContentPadding - beforeContentPadding + mainAxisItemSpacing } \ No newline at end of file diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/WalletViewModel.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/WalletViewModel.kt index 4c3c0b6cff..1581b36984 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/WalletViewModel.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/WalletViewModel.kt @@ -5,6 +5,7 @@ import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.tangem.core.analytics.api.AnalyticsEventHandler +import com.tangem.core.navigation.AppScreen import com.tangem.domain.balancehiding.GetBalanceHidingSettingsUseCase import com.tangem.domain.redux.ReduxStateHolder import com.tangem.domain.settings.CanUseBiometryUseCase @@ -199,6 +200,14 @@ internal class WalletViewModel @Inject constructor( is WalletsUpdateActionResolver.Action.UpdateWalletName -> { stateHolder.update(transformer = RenameWalletTransformer(action.selectedWalletId, action.name)) } + is WalletsUpdateActionResolver.Action.NoAccessibleWallets -> { + stateHolder.clear() + router.popBackStack(screen = AppScreen.Welcome) + } + is WalletsUpdateActionResolver.Action.NoWallets -> { + stateHolder.clear() + router.popBackStack(screen = AppScreen.Home) + } is WalletsUpdateActionResolver.Action.Unknown -> Unit } } @@ -274,23 +283,22 @@ internal class WalletViewModel @Inject constructor( coroutineScope = viewModelScope, ) - if (action.selectedWalletIndex != 0) { - /* - * If card is reset to factory settings, then Compose need some time to draw the WalletScreen. - * Otherwise, scroll isn't happened - */ - withContext(dispatchers.io) { delay(timeMillis = 700) } + /* + * If card is reset to factory settings, then Compose need some time to draw the WalletScreen. + * Otherwise, scroll isn't happened + */ + withContext(dispatchers.io) { delay(timeMillis = 1000) } - scrollToWallet(index = action.selectedWalletIndex) - - withContext(dispatchers.io) { delay(timeMillis = 1000) } - } - - stateHolder.update( - DeleteWalletTransformer( - selectedWalletIndex = action.selectedWalletIndex, - deletedWalletId = action.deletedWalletId, - ), + scrollToWallet( + index = action.selectedWalletIndex, + onConsume = { + stateHolder.update( + DeleteWalletTransformer( + selectedWalletIndex = action.selectedWalletIndex, + deletedWalletId = action.deletedWalletId, + ), + ) + }, ) } @@ -311,12 +319,13 @@ internal class WalletViewModel @Inject constructor( ) } - private fun scrollToWallet(index: Int) { + private fun scrollToWallet(index: Int, onConsume: () -> Unit = {}) { stateHolder.update( ScrollToWalletTransformer( index = index, currentStateProvider = Provider(action = stateHolder::value), stateUpdater = { newState -> stateHolder.update { newState } }, + onConsume = onConsume, ), ) } diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/WalletsUpdateActionResolver.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/WalletsUpdateActionResolver.kt index bdfd27558d..5e221221de 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/WalletsUpdateActionResolver.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/WalletsUpdateActionResolver.kt @@ -26,17 +26,21 @@ internal class WalletsUpdateActionResolver @Inject constructor( private var canSaveWallets: Boolean = false fun resolve(wallets: List, currentState: WalletScreenState, canSaveWallets: Boolean): Action { - val selectedWallet = wallets.getSelectedWallet() ?: return Action.Unknown + val selectedWallet = wallets.getSelectedWallet() - val action = when { - isFirstInitialization(currentState) -> { - createInitializeWalletsAction(wallets, selectedWallet, canSaveWallets) + val action = if (selectedWallet == null) { + createNoSelectedWalletAction(wallets) + } else { + when { + isFirstInitialization(currentState) -> { + createInitializeWalletsAction(wallets, selectedWallet, canSaveWallets) + } + isReinitialization(canSaveWallets) -> { + this.canSaveWallets = canSaveWallets + Action.ReinitializeWallets(selectedWallet = selectedWallet) + } + else -> getUpdateContentAction(currentState, wallets, selectedWallet) } - isReinitialization(canSaveWallets) -> { - this.canSaveWallets = canSaveWallets - Action.ReinitializeWallets(selectedWallet = selectedWallet) - } - else -> getUpdateContentAction(currentState, wallets, selectedWallet) } Timber.d("Resolved action: $action") @@ -47,11 +51,19 @@ internal class WalletsUpdateActionResolver @Inject constructor( private fun List.getSelectedWallet(): UserWallet? { return when { isEmpty() -> null - size == 1 -> first() + size == 1 -> if (first().isLocked) null else first() else -> getSelectedWalletSyncUseCase().fold(ifLeft = { null }, ifRight = { it }) } } + private fun createNoSelectedWalletAction(wallets: List): Action { + return when { + wallets.isEmpty() -> Action.NoWallets + wallets.all(UserWallet::isLocked) -> Action.NoAccessibleWallets + else -> Action.Unknown + } + } + private fun isFirstInitialization(state: WalletScreenState): Boolean { return state.selectedWalletIndex == NOT_INITIALIZED_WALLET_INDEX } @@ -305,8 +317,10 @@ internal class WalletsUpdateActionResolver @Inject constructor( } } - object Unknown : Action() { - override fun toString(): String = "Unknown" - } + data object NoAccessibleWallets : Action() + + data object NoWallets : Action() + + data object Unknown : Action() } } \ No newline at end of file diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/intents/WalletCardClickIntents.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/intents/WalletCardClickIntents.kt index fcbbdab810..7e47a2a490 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/intents/WalletCardClickIntents.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/intents/WalletCardClickIntents.kt @@ -1,7 +1,6 @@ package com.tangem.feature.wallet.presentation.wallet.viewmodels.intents import com.tangem.core.analytics.api.AnalyticsEventHandler -import com.tangem.core.navigation.AppScreen import com.tangem.domain.wallets.models.UserWalletId import com.tangem.domain.wallets.usecase.DeleteWalletUseCase import com.tangem.domain.wallets.usecase.UpdateWalletUseCase @@ -9,9 +8,7 @@ import com.tangem.feature.wallet.presentation.wallet.analytics.WalletScreenAnaly import com.tangem.feature.wallet.presentation.wallet.loaders.WalletScreenContentLoader import com.tangem.feature.wallet.presentation.wallet.state.WalletStateController import com.tangem.feature.wallet.presentation.wallet.state.model.WalletAlertState -import com.tangem.feature.wallet.presentation.wallet.state.model.WalletCardState import com.tangem.feature.wallet.presentation.wallet.state.model.WalletEvent -import com.tangem.feature.wallet.presentation.wallet.state.model.WalletState import com.tangem.feature.wallet.presentation.wallet.state.utils.WalletEventSender import com.tangem.utils.coroutines.CoroutineDispatcherProvider import kotlinx.coroutines.launch @@ -76,21 +73,7 @@ internal class WalletCardClickIntentsImplementor @Inject constructor( viewModelScope.launch(dispatchers.main) { walletScreenContentLoader.cancel(userWalletId) deleteWalletUseCase(userWalletId) - .onRight { popBackIfAllWalletsIsLocked() } .onLeft { Timber.e(it.toString()) } } } - - private fun popBackIfAllWalletsIsLocked() { - val wallets = stateHolder.value.wallets.map(WalletState::walletCardState) - val unlockedWallet = wallets.count { it !is WalletCardState.LockedContent } - - if (unlockedWallet == 1) { - stateHolder.clear() - - router.popBackStack( - screen = if (wallets.size > 1) AppScreen.Welcome else AppScreen.Home, - ) - } - } } \ No newline at end of file