Updated on 2026-08-14
This commit is contained in:
parent
6bc1179aa3
commit
c668c24d27
6 changed files with 65 additions and 49 deletions
|
|
@ -10,6 +10,7 @@ internal class ScrollToWalletTransformer(
|
|||
private val index: Int,
|
||||
private val currentStateProvider: Provider<WalletScreenState>,
|
||||
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()
|
||||
},
|
||||
),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
@ -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,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,17 +26,21 @@ internal class WalletsUpdateActionResolver @Inject constructor(
|
|||
private var canSaveWallets: Boolean = false
|
||||
|
||||
fun resolve(wallets: List<UserWallet>, 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<UserWallet>.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<UserWallet>): 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()
|
||||
}
|
||||
}
|
||||
|
|
@ -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,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue