Updated on 2026-08-14
This commit is contained in:
commit
870c3fa9d3
291 changed files with 4985 additions and 5870 deletions
|
|
@ -44,7 +44,6 @@ import com.tangem.feature.wallet.presentation.wallet.ui.components.visa.KycRejec
|
|||
import com.tangem.feature.wallet.presentation.wallet.utils.ScreenLifecycleProvider
|
||||
import com.tangem.features.biometry.AskBiometryComponent
|
||||
import com.tangem.features.feed.entry.featuretoggle.FeedFeatureToggle
|
||||
import com.tangem.features.hotwallet.HotWalletFeatureToggles
|
||||
import com.tangem.features.pushnotifications.api.PushNotificationsModelCallbacks
|
||||
import com.tangem.features.tangempay.TangemPayFeatureToggles
|
||||
import com.tangem.features.wallet.deeplink.WalletDeepLinkActionListener
|
||||
|
|
@ -89,9 +88,7 @@ internal class WalletModel @Inject constructor(
|
|||
private val notificationsRepository: NotificationsRepository,
|
||||
private val getWalletsListForEnablingUseCase: GetWalletsForAutomaticallyPushEnablingUseCase,
|
||||
private val setNotificationsEnabledUseCase: SetNotificationsEnabledUseCase,
|
||||
private val shouldSaveUserWalletsSyncUseCase: ShouldSaveUserWalletsSyncUseCase,
|
||||
private val getIsHuaweiDeviceWithoutGoogleServicesUseCase: GetIsHuaweiDeviceWithoutGoogleServicesUseCase,
|
||||
private val hotWalletFeatureToggles: HotWalletFeatureToggles,
|
||||
private val userWalletsListRepository: UserWalletsListRepository,
|
||||
private val tangemPayFeatureToggles: TangemPayFeatureToggles,
|
||||
private val yieldSupplyApyUpdateUseCase: YieldSupplyApyUpdateUseCase,
|
||||
|
|
@ -212,50 +209,40 @@ internal class WalletModel @Inject constructor(
|
|||
}
|
||||
|
||||
private fun trackScreenOpened() {
|
||||
if (hotWalletFeatureToggles.isHotWalletEnabled) {
|
||||
modelScope.launch {
|
||||
userWalletsListRepository
|
||||
.selectedUserWalletSync()
|
||||
?.let { selectedWallet ->
|
||||
val hasMobileWallet = userWalletsListRepository.userWalletsSync()
|
||||
.any { it is UserWallet.Hot }
|
||||
modelScope.launch {
|
||||
userWalletsListRepository
|
||||
.selectedUserWalletSync()
|
||||
?.let { selectedWallet ->
|
||||
val hasMobileWallet = userWalletsListRepository.userWalletsSync()
|
||||
.any { it is UserWallet.Hot }
|
||||
|
||||
val accountsCount = if (isAccountsModeEnabledUseCase.invokeSync()) {
|
||||
singleAccountListSupplier(selectedWallet.walletId)
|
||||
.first()
|
||||
.accounts
|
||||
.size
|
||||
} else {
|
||||
null
|
||||
}
|
||||
val result = getAppThemeModeUseCase().firstOrNull()
|
||||
val theme = result?.getOrElse { AppThemeMode.FOLLOW_SYSTEM } ?: AppThemeMode.FOLLOW_SYSTEM
|
||||
analyticsEventsHandler.send(
|
||||
WalletScreenAnalyticsEvent.MainScreen.ScreenOpened(
|
||||
hasMobileWallet = hasMobileWallet,
|
||||
accountsCount = accountsCount,
|
||||
theme = theme.value,
|
||||
isImported = selectedWallet.isImported(),
|
||||
referralId = appsFlyerStore.get()?.refcode,
|
||||
),
|
||||
)
|
||||
val accountsCount = if (isAccountsModeEnabledUseCase.invokeSync()) {
|
||||
singleAccountListSupplier(selectedWallet.walletId)
|
||||
.first()
|
||||
.accounts
|
||||
.size
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
} else {
|
||||
analyticsEventsHandler.send(
|
||||
WalletScreenAnalyticsEvent.MainScreen.ScreenOpenedLegacy(),
|
||||
)
|
||||
val result = getAppThemeModeUseCase().firstOrNull()
|
||||
val theme = result?.getOrElse { AppThemeMode.FOLLOW_SYSTEM } ?: AppThemeMode.FOLLOW_SYSTEM
|
||||
analyticsEventsHandler.send(
|
||||
WalletScreenAnalyticsEvent.MainScreen.ScreenOpened(
|
||||
hasMobileWallet = hasMobileWallet,
|
||||
accountsCount = accountsCount,
|
||||
theme = theme.value,
|
||||
isImported = selectedWallet.isImported(),
|
||||
referralId = appsFlyerStore.get()?.refcode,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun shouldShowAskBiometryBottomSheet(): Boolean {
|
||||
return if (hotWalletFeatureToggles.isHotWalletEnabled) {
|
||||
userWalletsListRepository.userWalletsSync().any { it is UserWallet.Cold } &&
|
||||
shouldShowAskBiometryUseCase() &&
|
||||
canUseBiometryUseCase()
|
||||
} else {
|
||||
innerWalletRouter.isWalletLastScreen() && shouldShowAskBiometryUseCase() && canUseBiometryUseCase()
|
||||
}
|
||||
return userWalletsListRepository.userWalletsSync().any { it is UserWallet.Cold } &&
|
||||
shouldShowAskBiometryUseCase() &&
|
||||
canUseBiometryUseCase()
|
||||
}
|
||||
|
||||
private fun subscribeToUserWalletsUpdates() = channelFlow<Unit> {
|
||||
|
|
@ -301,20 +288,16 @@ internal class WalletModel @Inject constructor(
|
|||
modelScope.launch {
|
||||
val shouldAskNotificationPermissionsViaBs = notificationsRepository.shouldAskNotificationPermissionsViaBs()
|
||||
val shouldShow = notificationsRepository.shouldShowSubscribeOnNotificationsAfterUpdate()
|
||||
val isBiometricsEnabled = shouldSaveUserWalletsSyncUseCase()
|
||||
val isHuaweiDevice = getIsHuaweiDeviceWithoutGoogleServicesUseCase()
|
||||
Timber.d(
|
||||
"push BS afterUpdate: $shouldShow," +
|
||||
"isBiometricsEnabled $isBiometricsEnabled," +
|
||||
"isHuaweiDevice $isHuaweiDevice",
|
||||
)
|
||||
if (!shouldAskNotificationPermissionsViaBs) {
|
||||
notificationsRepository.setShouldAskNotificationPermissionsViaBs(true)
|
||||
return@launch
|
||||
}
|
||||
if (!hotWalletFeatureToggles.isHotWalletEnabled && !isBiometricsEnabled) {
|
||||
return@launch
|
||||
}
|
||||
|
||||
if (!shouldShow) {
|
||||
return@launch
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,56 +1,23 @@
|
|||
package com.tangem.feature.wallet.child.wallet.model.intents
|
||||
|
||||
import arrow.core.getOrElse
|
||||
import com.arkivanov.decompose.router.slot.activate
|
||||
import com.tangem.common.routing.AppRoute
|
||||
import com.tangem.common.routing.AppRouter
|
||||
import com.tangem.core.analytics.api.AnalyticsEventHandler
|
||||
import com.tangem.core.decompose.di.ModelScoped
|
||||
import com.tangem.domain.card.DeleteSavedAccessCodesUseCase
|
||||
import com.tangem.domain.redux.ReduxStateHolder
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.wallets.usecase.DeleteWalletUseCase
|
||||
import com.tangem.domain.wallets.usecase.GetSelectedWalletSyncUseCase
|
||||
import com.tangem.domain.wallets.usecase.GetUserWalletUseCase
|
||||
import com.tangem.feature.wallet.presentation.wallet.analytics.WalletScreenAnalyticsEvent.MainScreen
|
||||
import com.tangem.feature.wallet.presentation.wallet.domain.MultiWalletTokenListStore
|
||||
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.WalletDialogConfig
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletEvent
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.utils.WalletEventSender
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
internal interface WalletCardClickIntents {
|
||||
|
||||
fun onRenameBeforeConfirmationClick(userWalletId: UserWalletId)
|
||||
|
||||
fun onDeleteBeforeConfirmationClick(userWalletId: UserWalletId)
|
||||
|
||||
fun onDeleteAfterConfirmationClick(userWalletId: UserWalletId)
|
||||
}
|
||||
|
||||
// TODO: Refactor
|
||||
@Suppress("LongParameterList")
|
||||
@ModelScoped
|
||||
internal class WalletCardClickIntentsImplementor @Inject constructor(
|
||||
private val stateHolder: WalletStateController,
|
||||
private val tokenListStore: MultiWalletTokenListStore,
|
||||
private val walletEventSender: WalletEventSender,
|
||||
private val walletScreenContentLoader: WalletScreenContentLoader,
|
||||
private val getUserWalletUseCase: GetUserWalletUseCase,
|
||||
private val getSelectedWalletSyncUseCase: GetSelectedWalletSyncUseCase,
|
||||
private val deleteWalletUseCase: DeleteWalletUseCase,
|
||||
private val deleteSavedAccessCodesUseCase: DeleteSavedAccessCodesUseCase,
|
||||
private val analyticsEventHandler: AnalyticsEventHandler,
|
||||
private val reduxStateHolder: ReduxStateHolder,
|
||||
private val appRouter: AppRouter,
|
||||
private val dispatchers: CoroutineDispatcherProvider,
|
||||
) : BaseWalletClickIntents(), WalletCardClickIntents {
|
||||
|
||||
override fun onRenameBeforeConfirmationClick(userWalletId: UserWalletId) {
|
||||
|
|
@ -63,47 +30,4 @@ internal class WalletCardClickIntentsImplementor @Inject constructor(
|
|||
),
|
||||
)
|
||||
}
|
||||
|
||||
override fun onDeleteBeforeConfirmationClick(userWalletId: UserWalletId) {
|
||||
analyticsEventHandler.send(MainScreen.DeleteWalletTapped())
|
||||
|
||||
walletEventSender.send(
|
||||
event = WalletEvent.ShowAlert(
|
||||
state = WalletAlertState.RemoveWalletAlert(
|
||||
onConfirmClick = { onDeleteAfterConfirmationClick(userWalletId) },
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
override fun onDeleteAfterConfirmationClick(userWalletId: UserWalletId) {
|
||||
modelScope.launch(dispatchers.main) {
|
||||
walletScreenContentLoader.cancel(userWalletId)
|
||||
tokenListStore.remove(userWalletId)
|
||||
|
||||
val walletToDelete = getUserWalletUseCase(userWalletId).getOrNull() ?: return@launch
|
||||
val hasUserWallets = deleteWalletUseCase(userWalletId).getOrElse {
|
||||
Timber.e("Unable to delete user wallet: $it")
|
||||
return@launch
|
||||
}
|
||||
|
||||
if (walletToDelete is UserWallet.Cold) {
|
||||
deleteSavedAccessCodesUseCase(cardId = walletToDelete.cardId).onLeft {
|
||||
Timber.e("Unable to delete user wallet access code: $it")
|
||||
}
|
||||
}
|
||||
|
||||
if (hasUserWallets) {
|
||||
val selectedWallet = getSelectedWalletSyncUseCase().getOrElse {
|
||||
error("Unable to find selected wallet: $it")
|
||||
}
|
||||
|
||||
reduxStateHolder.onUserWalletSelected(selectedWallet)
|
||||
} else {
|
||||
tokenListStore.clear()
|
||||
stateHolder.clear()
|
||||
appRouter.replaceAll(AppRoute.Home())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -7,13 +7,13 @@ import com.tangem.core.analytics.api.AnalyticsEventHandler
|
|||
import com.tangem.core.analytics.models.AnalyticsParam
|
||||
import com.tangem.core.analytics.models.event.MainScreenAnalyticsEvent
|
||||
import com.tangem.core.decompose.di.ModelScoped
|
||||
import com.tangem.core.decompose.ui.UiMessageSender
|
||||
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.staking.StakingBalance
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.models.wallet.isLocked
|
||||
import com.tangem.domain.nft.analytics.NFTAnalyticsEvent
|
||||
import com.tangem.domain.settings.ShouldShowMarketsTooltipUseCase
|
||||
import com.tangem.domain.tokens.GetCryptoCurrencyActionsUseCase
|
||||
|
|
@ -33,7 +33,6 @@ import com.tangem.feature.wallet.presentation.wallet.state.transformers.CloseBot
|
|||
import com.tangem.feature.wallet.presentation.wallet.state.transformers.OpenBottomSheetTransformer
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.transformers.converter.MultiWalletCurrencyActionsConverter
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.utils.WalletEventSender
|
||||
import com.tangem.features.hotwallet.HotWalletFeatureToggles
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
import kotlinx.coroutines.flow.take
|
||||
|
|
@ -90,7 +89,6 @@ internal interface WalletContentClickIntents {
|
|||
internal class WalletContentClickIntentsImplementor @Inject constructor(
|
||||
private val stateHolder: WalletStateController,
|
||||
private val currencyActionsClickIntents: WalletCurrencyActionsClickIntentsImplementor,
|
||||
private val walletWarningsClickIntents: WalletWarningsClickIntentsImplementor,
|
||||
private val onrampStatusFactory: OnrampStatusFactory,
|
||||
private val getUserWalletUseCase: GetUserWalletUseCase,
|
||||
private val getSingleCryptoCurrencyStatusUseCase: GetSingleCryptoCurrencyStatusUseCase,
|
||||
|
|
@ -100,44 +98,14 @@ internal class WalletContentClickIntentsImplementor @Inject constructor(
|
|||
private val dispatchers: CoroutineDispatcherProvider,
|
||||
private val walletEventSender: WalletEventSender,
|
||||
private val analyticsEventHandler: AnalyticsEventHandler,
|
||||
private val hotWalletFeatureToggles: HotWalletFeatureToggles,
|
||||
private val accountDependencies: AccountDependencies,
|
||||
private val yieldSupplySetShouldShowMainPromoUseCase: YieldSupplySetShouldShowMainPromoUseCase,
|
||||
private val tokenListAnalyticsSender: TokenListAnalyticsSender,
|
||||
private val uiMessageSender: UiMessageSender,
|
||||
) : BaseWalletClickIntents(), WalletContentClickIntents {
|
||||
|
||||
override fun onDetailsClick() {
|
||||
if (hotWalletFeatureToggles.isHotWalletEnabled) {
|
||||
router.openDetailsScreen(stateHolder.getSelectedWalletId())
|
||||
return
|
||||
}
|
||||
|
||||
// Will be removed after Hot Wallet release
|
||||
modelScope.launch(dispatchers.main) {
|
||||
val userWalletId = stateHolder.getSelectedWalletId()
|
||||
val userWallet = getUserWalletUseCase(userWalletId).getOrElse {
|
||||
Timber.e(
|
||||
"""
|
||||
Unable to get user wallet
|
||||
|- ID: $userWalletId
|
||||
|- Exception: $it
|
||||
""".trimIndent(),
|
||||
)
|
||||
|
||||
return@launch
|
||||
}
|
||||
|
||||
if (userWallet.isLocked) {
|
||||
stateHolder.showBottomSheet(
|
||||
WalletBottomSheetConfig.UnlockWallets(
|
||||
onUnlockClick = walletWarningsClickIntents::onUnlockWalletClick,
|
||||
onScanClick = walletWarningsClickIntents::onScanToUnlockWalletClick,
|
||||
),
|
||||
)
|
||||
} else {
|
||||
router.openDetailsScreen(stateHolder.getSelectedWalletId())
|
||||
}
|
||||
}
|
||||
router.openDetailsScreen(stateHolder.getSelectedWalletId())
|
||||
}
|
||||
|
||||
override fun onOrganizeTokensClick() {
|
||||
|
|
@ -345,15 +313,12 @@ internal class WalletContentClickIntentsImplementor @Inject constructor(
|
|||
}
|
||||
|
||||
override fun onConfirmDisposeExpressStatus() {
|
||||
walletEventSender.send(
|
||||
WalletEvent.ShowAlert(
|
||||
WalletAlertState.ConfirmExpressStatusHide(
|
||||
onConfirmClick = {
|
||||
walletEventSender.onConsume()
|
||||
onDisposeExpressStatus()
|
||||
},
|
||||
onCancelClick = walletEventSender::onConsume,
|
||||
),
|
||||
uiMessageSender.send(
|
||||
WalletAlertUM.confirmExpressStatusHide(
|
||||
onConfirmClick = {
|
||||
walletEventSender.onConsume()
|
||||
onDisposeExpressStatus()
|
||||
},
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,13 +12,14 @@ import com.tangem.core.analytics.models.AnalyticsEvent
|
|||
import com.tangem.core.analytics.models.AnalyticsParam
|
||||
import com.tangem.core.analytics.models.event.MainScreenAnalyticsEvent
|
||||
import com.tangem.core.decompose.di.ModelScoped
|
||||
import com.tangem.core.decompose.ui.UiMessageSender
|
||||
import com.tangem.core.ui.clipboard.ClipboardManager
|
||||
import com.tangem.core.ui.components.tokenlist.state.TokensListItemUM
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
import com.tangem.core.ui.extensions.WrappedList
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.haptic.TangemHapticEffect
|
||||
import com.tangem.core.ui.haptic.VibratorHapticManager
|
||||
import com.tangem.core.ui.message.DialogMessage
|
||||
import com.tangem.domain.account.featuretoggle.AccountsFeatureToggles
|
||||
import com.tangem.domain.account.status.usecase.GetAccountCurrencyStatusUseCase
|
||||
import com.tangem.domain.account.status.usecase.ManageCryptoCurrenciesUseCase
|
||||
|
|
@ -56,7 +57,7 @@ import com.tangem.domain.wallets.usecase.GetSelectedWalletSyncUseCase
|
|||
import com.tangem.feature.wallet.impl.R
|
||||
import com.tangem.feature.wallet.presentation.wallet.domain.unwrap
|
||||
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.WalletAlertUM
|
||||
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.model.WalletTokensListState
|
||||
|
|
@ -150,6 +151,7 @@ internal class WalletCurrencyActionsClickIntentsImplementor @Inject constructor(
|
|||
private val accountsFeatureToggles: AccountsFeatureToggles,
|
||||
private val getAccountCurrencyStatusUseCase: GetAccountCurrencyStatusUseCase,
|
||||
private val manageCryptoCurrenciesUseCase: ManageCryptoCurrenciesUseCase,
|
||||
private val uiMessageSender: UiMessageSender,
|
||||
) : BaseWalletClickIntents(), WalletCurrencyActionsClickIntents {
|
||||
|
||||
override fun onSendClick(
|
||||
|
|
@ -269,48 +271,19 @@ internal class WalletCurrencyActionsClickIntentsImplementor @Inject constructor(
|
|||
)
|
||||
|
||||
modelScope.launch(dispatchers.main) {
|
||||
walletEventSender.send(
|
||||
event = WalletEvent.ShowAlert(
|
||||
state = getHideTokeAlertConfig(userWalletId, cryptoCurrencyStatus),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
val currency = cryptoCurrencyStatus.currency
|
||||
val isCryptoCurrencyCoinCouldHide = currency is CryptoCurrency.Coin &&
|
||||
!isCryptoCurrencyCoinCouldHide(userWalletId = userWalletId, cryptoCurrencyCoin = currency)
|
||||
|
||||
private suspend fun getHideTokeAlertConfig(
|
||||
userWalletId: UserWalletId,
|
||||
cryptoCurrencyStatus: CryptoCurrencyStatus,
|
||||
): WalletAlertState.DefaultAlert {
|
||||
val currency = cryptoCurrencyStatus.currency
|
||||
val isCryptoCurrencyCoinCouldHide = currency is CryptoCurrency.Coin &&
|
||||
!isCryptoCurrencyCoinCouldHide(userWalletId = userWalletId, cryptoCurrencyCoin = currency)
|
||||
return if (isCryptoCurrencyCoinCouldHide) {
|
||||
WalletAlertState.DefaultAlert(
|
||||
title = resourceReference(
|
||||
id = R.string.token_details_unable_hide_alert_title,
|
||||
formatArgs = WrappedList(listOf(cryptoCurrencyStatus.currency.name)),
|
||||
),
|
||||
message = resourceReference(
|
||||
id = R.string.token_details_unable_hide_alert_message,
|
||||
formatArgs = WrappedList(
|
||||
listOf(
|
||||
cryptoCurrencyStatus.currency.name,
|
||||
cryptoCurrencyStatus.currency.symbol,
|
||||
cryptoCurrencyStatus.currency.network.name,
|
||||
),
|
||||
),
|
||||
),
|
||||
onConfirmClick = null,
|
||||
)
|
||||
} else {
|
||||
WalletAlertState.DefaultAlert(
|
||||
title = resourceReference(
|
||||
id = R.string.token_details_hide_alert_title,
|
||||
formatArgs = WrappedList(listOf(cryptoCurrencyStatus.currency.name)),
|
||||
),
|
||||
message = resourceReference(R.string.token_details_hide_alert_message),
|
||||
onConfirmClick = { onPerformHideToken(userWalletId, cryptoCurrencyStatus) },
|
||||
)
|
||||
if (isCryptoCurrencyCoinCouldHide) {
|
||||
uiMessageSender.send(WalletAlertUM.unableHideToken(cryptoCurrency = cryptoCurrencyStatus.currency))
|
||||
} else {
|
||||
uiMessageSender.send(
|
||||
WalletAlertUM.hideTokenConfirm(cryptoCurrency = cryptoCurrencyStatus.currency) {
|
||||
onPerformHideToken(userWalletId, cryptoCurrencyStatus)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -618,17 +591,7 @@ internal class WalletCurrencyActionsClickIntentsImplementor @Inject constructor(
|
|||
private fun handleUnavailabilityReason(unavailabilityReason: ScenarioUnavailabilityReason): Boolean {
|
||||
if (unavailabilityReason == ScenarioUnavailabilityReason.None) return false
|
||||
|
||||
modelScope.launch(dispatchers.main) {
|
||||
walletEventSender.send(
|
||||
event = WalletEvent.ShowAlert(
|
||||
state = WalletAlertState.DefaultAlert(
|
||||
title = null,
|
||||
message = unavailabilityReason.getUnavailabilityReasonText(),
|
||||
onConfirmClick = null,
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
uiMessageSender.send(DialogMessage(message = unavailabilityReason.getUnavailabilityReasonText()))
|
||||
|
||||
return true
|
||||
}
|
||||
|
|
@ -641,7 +604,10 @@ internal class WalletCurrencyActionsClickIntentsImplementor @Inject constructor(
|
|||
modelScope.launch {
|
||||
statusFlow.foldStatus(
|
||||
onContent = { handleContent(route, eventCreator) },
|
||||
onError = { handleError(eventCreator = eventCreator) },
|
||||
onError = {
|
||||
analyticsEventHandler.send(event = eventCreator(AnalyticsParam.Status.Error))
|
||||
uiMessageSender.send(WalletAlertUM.unavailableOperation())
|
||||
},
|
||||
onLoading = { handleLoading(eventCreator) },
|
||||
)
|
||||
}
|
||||
|
|
@ -667,21 +633,10 @@ internal class WalletCurrencyActionsClickIntentsImplementor @Inject constructor(
|
|||
appRouter.push(route = route)
|
||||
}
|
||||
|
||||
private fun handleError(
|
||||
alertState: WalletAlertState = WalletAlertState.UnavailableOperation,
|
||||
eventCreator: (AnalyticsParam.Status) -> MainScreenAnalyticsEvent,
|
||||
) {
|
||||
analyticsEventHandler.send(event = eventCreator(AnalyticsParam.Status.Error))
|
||||
|
||||
walletEventSender.send(event = WalletEvent.ShowAlert(state = alertState))
|
||||
}
|
||||
|
||||
private fun handleLoading(eventCreator: (AnalyticsParam.Status) -> MainScreenAnalyticsEvent) {
|
||||
analyticsEventHandler.send(event = eventCreator(AnalyticsParam.Status.Pending))
|
||||
|
||||
walletEventSender.send(
|
||||
event = WalletEvent.ShowAlert(state = WalletAlertState.ProvidersStillLoading),
|
||||
)
|
||||
uiMessageSender.send(WalletAlertUM.providersStillLoading())
|
||||
}
|
||||
|
||||
private suspend fun getSwapRoute(targetRoute: AppRoute): AppRoute {
|
||||
|
|
@ -743,12 +698,8 @@ internal class WalletCurrencyActionsClickIntentsImplementor @Inject constructor(
|
|||
|
||||
private fun checkSwapCryptoAvailability(tokenCount: Int) {
|
||||
if (tokenCount < 2) {
|
||||
handleError(
|
||||
alertState = WalletAlertState.InsufficientTokensCountForSwapping,
|
||||
eventCreator = MainScreenAnalyticsEvent::ButtonSwap,
|
||||
)
|
||||
|
||||
return
|
||||
analyticsEventHandler.send(event = MainScreenAnalyticsEvent.ButtonSwap(AnalyticsParam.Status.Error))
|
||||
uiMessageSender.send(WalletAlertUM.insufficientTokensCountForSwapping())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -11,7 +11,7 @@ import com.tangem.core.analytics.models.AnalyticsParam
|
|||
import com.tangem.core.decompose.di.ModelScoped
|
||||
import com.tangem.core.decompose.ui.UiMessageSender
|
||||
import com.tangem.core.navigation.url.UrlOpener
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.navigation.review.ReviewManager
|
||||
import com.tangem.domain.card.SetCardWasScannedUseCase
|
||||
import com.tangem.domain.common.wallets.UserWalletsListRepository
|
||||
import com.tangem.domain.feedback.GetWalletMetaInfoUseCase
|
||||
|
|
@ -37,22 +37,14 @@ import com.tangem.domain.tokens.model.analytics.PromoAnalyticsEvent
|
|||
import com.tangem.domain.tokens.model.analytics.PromoAnalyticsEvent.Program
|
||||
import com.tangem.domain.tokens.model.analytics.PromoAnalyticsEvent.PromotionBannerClicked
|
||||
import com.tangem.domain.tokens.model.details.NavigationAction
|
||||
import com.tangem.domain.wallets.legacy.UserWalletsListManager.Lockable.UnlockType
|
||||
import com.tangem.domain.wallets.models.UnlockWalletsError
|
||||
import com.tangem.domain.wallets.usecase.*
|
||||
import com.tangem.feature.wallet.impl.R
|
||||
import com.tangem.feature.wallet.presentation.wallet.analytics.WalletScreenAnalyticsEvent
|
||||
import com.tangem.feature.wallet.presentation.wallet.analytics.WalletScreenAnalyticsEvent.Basic
|
||||
import com.tangem.feature.wallet.presentation.wallet.analytics.WalletScreenAnalyticsEvent.MainScreen
|
||||
import com.tangem.feature.wallet.presentation.wallet.domain.ScanCardToUnlockWalletClickHandler
|
||||
import com.tangem.feature.wallet.presentation.wallet.domain.ScanCardToUnlockWalletError
|
||||
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.WalletBottomSheetConfig
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletAlertUM
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletEvent
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.transformers.CloseBottomSheetTransformer
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.utils.WalletEventSender
|
||||
import com.tangem.features.hotwallet.HotWalletFeatureToggles
|
||||
import com.tangem.features.pushnotifications.api.analytics.PushNotificationAnalyticEvents
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import kotlinx.coroutines.async
|
||||
|
|
@ -75,12 +67,6 @@ internal interface WalletWarningsClickIntents {
|
|||
|
||||
fun onOpenUnlockWalletsBottomSheetClick()
|
||||
|
||||
fun onUnlockWalletClick()
|
||||
|
||||
fun onUnlockVisaAccessClick()
|
||||
|
||||
fun onScanToUnlockWalletClick()
|
||||
|
||||
fun onLikeAppClick()
|
||||
|
||||
fun onDislikeAppClick()
|
||||
|
|
@ -93,6 +79,8 @@ internal interface WalletWarningsClickIntents {
|
|||
|
||||
fun onSupportClick()
|
||||
|
||||
fun onBackupErrorClick()
|
||||
|
||||
fun onNoteMigrationButtonClick(url: String)
|
||||
|
||||
fun onSeedPhraseNotificationConfirm()
|
||||
|
|
@ -122,8 +110,6 @@ internal class WalletWarningsClickIntentsImplementor @Inject constructor(
|
|||
private val neverToSuggestRateAppUseCase: NeverToSuggestRateAppUseCase,
|
||||
private val remindToRateAppLaterUseCase: RemindToRateAppLaterUseCase,
|
||||
private val getUserWalletUseCase: GetUserWalletUseCase,
|
||||
private val scanCardToUnlockWalletClickHandler: ScanCardToUnlockWalletClickHandler,
|
||||
private val unlockWalletsUseCase: UnlockWalletsUseCase,
|
||||
private val nonBiometricUnlockWalletUseCase: NonBiometricUnlockWalletUseCase,
|
||||
private val analyticsEventHandler: AnalyticsEventHandler,
|
||||
private val dispatchers: CoroutineDispatcherProvider,
|
||||
|
|
@ -137,13 +123,13 @@ internal class WalletWarningsClickIntentsImplementor @Inject constructor(
|
|||
private val multiStakingBalanceFetcher: MultiStakingBalanceFetcher,
|
||||
private val stakingIdFactory: StakingIdFactory,
|
||||
private val appRouter: AppRouter,
|
||||
private val hotWalletFeatureToggles: HotWalletFeatureToggles,
|
||||
private val userWalletsListRepository: UserWalletsListRepository,
|
||||
private val setShouldShowNotificationUseCase: SetShouldShowNotificationUseCase,
|
||||
private val notificationsRepository: NotificationsRepository,
|
||||
private val setNotificationsEnabledUseCase: SetNotificationsEnabledUseCase,
|
||||
private val getWalletsListForEnablingUseCase: GetWalletsForAutomaticallyPushEnablingUseCase,
|
||||
private val uiMessageSender: UiMessageSender,
|
||||
private val reviewManager: ReviewManager,
|
||||
) : BaseWalletClickIntents(), WalletWarningsClickIntents {
|
||||
|
||||
override fun onAddBackupCardClick() {
|
||||
|
|
@ -205,81 +191,20 @@ internal class WalletWarningsClickIntentsImplementor @Inject constructor(
|
|||
override fun onOpenUnlockWalletsBottomSheetClick() {
|
||||
analyticsEventHandler.send(MainScreen.WalletUnlockTapped())
|
||||
|
||||
if (hotWalletFeatureToggles.isHotWalletEnabled) {
|
||||
modelScope.launch {
|
||||
userWalletsListRepository.unlockAllWallets()
|
||||
.onLeft {
|
||||
val selectedUserWalletId = stateHolder.getSelectedWalletId()
|
||||
nonBiometricUnlockWalletUseCase(selectedUserWalletId)
|
||||
.onLeft { error ->
|
||||
error.handle(
|
||||
onAlreadyUnlocked = {},
|
||||
onUserCancelled = {},
|
||||
analyticsEventHandler = analyticsEventHandler,
|
||||
isFromUnlockAll = true,
|
||||
showMessage = uiMessageSender::send,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Will be removed after hot wallet release
|
||||
stateHolder.showBottomSheet(
|
||||
WalletBottomSheetConfig.UnlockWallets(
|
||||
onUnlockClick = this::onUnlockWalletClick,
|
||||
onScanClick = this::onScanToUnlockWalletClick,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
@Deprecated("Will be removed with hot wallet release")
|
||||
override fun onUnlockWalletClick() {
|
||||
analyticsEventHandler.send(MainScreen.UnlockAllWithBiometrics())
|
||||
|
||||
modelScope.launch(dispatchers.main) {
|
||||
unlockWalletsUseCase(type = UnlockType.ALL_WITHOUT_SELECT)
|
||||
.onRight { stateHolder.update(CloseBottomSheetTransformer(stateHolder.getSelectedWalletId())) }
|
||||
.onLeft(::handleUnlockWalletsError)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onUnlockVisaAccessClick() {
|
||||
openScanCardDialog()
|
||||
}
|
||||
|
||||
private fun handleUnlockWalletsError(error: UnlockWalletsError) {
|
||||
val event = when (error) {
|
||||
is UnlockWalletsError.DataError,
|
||||
is UnlockWalletsError.UnableToUnlockWallets,
|
||||
-> WalletEvent.ShowError(resourceReference(R.string.user_wallet_list_error_unable_to_unlock))
|
||||
is UnlockWalletsError.NoUserWalletSelected,
|
||||
is UnlockWalletsError.NotAllUserWalletsUnlocked,
|
||||
-> WalletEvent.ShowAlert(WalletAlertState.RescanWallets)
|
||||
}
|
||||
|
||||
walletEventSender.send(event)
|
||||
}
|
||||
|
||||
@Deprecated("Will be removed with hot wallet release")
|
||||
override fun onScanToUnlockWalletClick() {
|
||||
analyticsEventHandler.send(MainScreen.UnlockWithCardScan())
|
||||
openScanCardDialog()
|
||||
}
|
||||
|
||||
private fun openScanCardDialog() {
|
||||
modelScope.launch(dispatchers.main) {
|
||||
scanCardToUnlockWalletClickHandler(walletId = stateHolder.getSelectedWalletId())
|
||||
.onLeft { error ->
|
||||
when (error) {
|
||||
ScanCardToUnlockWalletError.WrongCardIsScanned -> {
|
||||
walletEventSender.send(
|
||||
event = WalletEvent.ShowAlert(WalletAlertState.WrongCardIsScanned),
|
||||
modelScope.launch {
|
||||
userWalletsListRepository.unlockAllWallets()
|
||||
.onLeft {
|
||||
val selectedUserWalletId = stateHolder.getSelectedWalletId()
|
||||
nonBiometricUnlockWalletUseCase(selectedUserWalletId)
|
||||
.onLeft { error ->
|
||||
error.handle(
|
||||
onAlreadyUnlocked = {},
|
||||
onUserCancelled = {},
|
||||
analyticsEventHandler = analyticsEventHandler,
|
||||
isFromUnlockAll = true,
|
||||
showMessage = uiMessageSender::send,
|
||||
)
|
||||
}
|
||||
ScanCardToUnlockWalletError.ManyScanFails -> router.openScanFailedDialog(::openScanCardDialog)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -287,15 +212,11 @@ internal class WalletWarningsClickIntentsImplementor @Inject constructor(
|
|||
override fun onLikeAppClick() {
|
||||
analyticsEventHandler.send(MainScreen.NoticeRateAppButton(AnalyticsParam.RateApp.Liked))
|
||||
|
||||
walletEventSender.send(
|
||||
event = WalletEvent.RateApp(
|
||||
onDismissClick = {
|
||||
modelScope.launch(dispatchers.main) {
|
||||
neverToSuggestRateAppUseCase()
|
||||
}
|
||||
},
|
||||
),
|
||||
)
|
||||
reviewManager.request {
|
||||
modelScope.launch(dispatchers.main) {
|
||||
neverToSuggestRateAppUseCase()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDislikeAppClick() {
|
||||
|
|
@ -345,7 +266,6 @@ internal class WalletWarningsClickIntentsImplementor @Inject constructor(
|
|||
action = PromotionBannerClicked.BannerAction.Closed(),
|
||||
)
|
||||
},
|
||||
|
||||
)
|
||||
modelScope.launch(dispatchers.main) {
|
||||
shouldShowPromoWalletUseCase.neverToShow(promoId)
|
||||
|
|
@ -414,6 +334,15 @@ internal class WalletWarningsClickIntentsImplementor @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
override fun onBackupErrorClick() {
|
||||
val userWallet = getSelectedUserWallet() ?: return
|
||||
|
||||
modelScope.launch {
|
||||
val metaInfo = getWalletMetaInfoUseCase(userWallet.walletId).getOrNull() ?: return@launch
|
||||
sendFeedbackEmailUseCase(type = FeedbackEmailType.BackupProblem(walletMetaInfo = metaInfo))
|
||||
}
|
||||
}
|
||||
|
||||
override fun onNoteMigrationButtonClick(url: String) {
|
||||
analyticsEventHandler.send(MainScreen.NotePromoButton())
|
||||
modelScope.launch(dispatchers.main) {
|
||||
|
|
@ -426,21 +355,16 @@ internal class WalletWarningsClickIntentsImplementor @Inject constructor(
|
|||
|
||||
analyticsEventHandler.send(MainScreen.NoticeSeedPhraseSupportButtonYes())
|
||||
|
||||
walletEventSender.send(
|
||||
event = WalletEvent.ShowAlert(
|
||||
state = WalletAlertState.SimpleOkAlert(
|
||||
message = resourceReference(R.string.warning_seedphrase_issue_answer_yes),
|
||||
onOkClick = {
|
||||
modelScope.launch {
|
||||
seedPhraseNotificationUseCase.confirm(userWalletId = userWallet.walletId)
|
||||
uiMessageSender.send(
|
||||
WalletAlertUM.seedPhraseConfirm {
|
||||
modelScope.launch {
|
||||
seedPhraseNotificationUseCase.confirm(userWalletId = userWallet.walletId)
|
||||
|
||||
urlOpener.openUrl(
|
||||
url = TangemBlogUrlBuilder.build(post = TangemBlogUrlBuilder.Post.SeedNotify),
|
||||
)
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
urlOpener.openUrl(
|
||||
url = TangemBlogUrlBuilder.build(post = TangemBlogUrlBuilder.Post.SeedNotify),
|
||||
)
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -449,17 +373,12 @@ internal class WalletWarningsClickIntentsImplementor @Inject constructor(
|
|||
|
||||
analyticsEventHandler.send(MainScreen.NoticeSeedPhraseSupportButtonNo())
|
||||
|
||||
walletEventSender.send(
|
||||
event = WalletEvent.ShowAlert(
|
||||
state = WalletAlertState.SimpleOkAlert(
|
||||
message = resourceReference(R.string.warning_seedphrase_issue_answer_no),
|
||||
onOkClick = {
|
||||
modelScope.launch {
|
||||
seedPhraseNotificationUseCase.decline(userWalletId = userWallet.walletId)
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
uiMessageSender.send(
|
||||
WalletAlertUM.seedPhraseDismiss {
|
||||
modelScope.launch {
|
||||
seedPhraseNotificationUseCase.decline(userWalletId = userWallet.walletId)
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -468,21 +387,16 @@ internal class WalletWarningsClickIntentsImplementor @Inject constructor(
|
|||
|
||||
analyticsEventHandler.send(MainScreen.NoticeSeedPhraseSupportButtonUsed())
|
||||
|
||||
walletEventSender.send(
|
||||
event = WalletEvent.ShowAlert(
|
||||
state = WalletAlertState.SimpleOkAlert(
|
||||
message = resourceReference(R.string.warning_seedphrase_issue_answer_yes),
|
||||
onOkClick = {
|
||||
modelScope.launch {
|
||||
seedPhraseNotificationUseCase.acceptSecond(userWalletId = userWallet.walletId)
|
||||
uiMessageSender.send(
|
||||
WalletAlertUM.seedPhraseConfirm {
|
||||
modelScope.launch {
|
||||
seedPhraseNotificationUseCase.acceptSecond(userWalletId = userWallet.walletId)
|
||||
|
||||
urlOpener.openUrl(
|
||||
url = TangemBlogUrlBuilder.build(post = TangemBlogUrlBuilder.Post.SeedNotifySecond),
|
||||
)
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
urlOpener.openUrl(
|
||||
url = TangemBlogUrlBuilder.build(post = TangemBlogUrlBuilder.Post.SeedNotifySecond),
|
||||
)
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,13 @@
|
|||
package com.tangem.feature.wallet.featuretoggles
|
||||
|
||||
import com.tangem.core.configtoggle.feature.FeatureTogglesManager
|
||||
import com.tangem.features.wallet.featuretoggles.WalletFeatureToggles
|
||||
import javax.inject.Inject
|
||||
|
||||
internal class DefaultWalletFeatureToggles @Inject constructor() : WalletFeatureToggles
|
||||
internal class DefaultWalletFeatureToggles @Inject constructor(
|
||||
private val featureToggles: FeatureTogglesManager,
|
||||
) : WalletFeatureToggles {
|
||||
|
||||
override val isWalletReorderFeatureEnabled: Boolean
|
||||
get() = featureToggles.isFeatureEnabled("WALLET_REORDER_FEATURE_ENABLED")
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
package com.tangem.feature.wallet.presentation.organizetokens.utils.converter.items
|
||||
|
||||
import com.tangem.common.getTotalWithRewardsStakingBalance
|
||||
import com.tangem.core.ui.components.currency.icon.converter.CryptoCurrencyToIconStateConverter
|
||||
import com.tangem.core.ui.components.token.state.TokenItemState
|
||||
import com.tangem.core.ui.extensions.stringReference
|
||||
|
|
@ -9,7 +10,6 @@ import com.tangem.core.ui.format.bigdecimal.format
|
|||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
||||
import com.tangem.domain.models.staking.StakingBalance
|
||||
import com.tangem.domain.staking.utils.getTotalWithRewardsStakingBalance
|
||||
import com.tangem.feature.wallet.presentation.organizetokens.model.DraggableItem
|
||||
import com.tangem.feature.wallet.presentation.organizetokens.utils.common.getGroupHeaderId
|
||||
import com.tangem.feature.wallet.presentation.organizetokens.utils.common.getTokenItemId
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import com.tangem.domain.account.status.model.AccountCryptoCurrencyStatus
|
|||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.domain.models.currency.CryptoCurrencyStatus
|
||||
import com.tangem.domain.models.staking.StakingBalance
|
||||
import com.tangem.domain.staking.utils.getTotalWithRewardsStakingBalance
|
||||
import com.tangem.common.getTotalWithRewardsStakingBalance
|
||||
import com.tangem.feature.wallet.presentation.organizetokens.model.DraggableItem
|
||||
import com.tangem.feature.wallet.presentation.organizetokens.utils.common.getGroupHeaderId
|
||||
import com.tangem.feature.wallet.presentation.organizetokens.utils.common.getTokenItemId
|
||||
|
|
|
|||
|
|
@ -182,7 +182,7 @@ internal class GetMultiWalletWarningsFactory @Inject constructor(
|
|||
|
||||
val cardTypesResolver = userWallet.scanResponse.cardTypesResolver
|
||||
addIf(
|
||||
element = WalletNotification.Critical.BackupError { clickIntents.onSupportClick() },
|
||||
element = WalletNotification.Critical.BackupError { clickIntents.onBackupErrorClick() },
|
||||
condition = !backupValidator.isValidBackupStatus(userWallet.scanResponse.card) || userWallet.hasBackupError,
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,56 +0,0 @@
|
|||
package com.tangem.feature.wallet.presentation.wallet.domain
|
||||
|
||||
import arrow.core.Either
|
||||
import arrow.core.raise.either
|
||||
import arrow.core.raise.ensure
|
||||
import com.tangem.common.CompletionResult
|
||||
import com.tangem.common.core.TangemSdkError
|
||||
import com.tangem.core.analytics.models.AnalyticsParam
|
||||
import com.tangem.domain.card.ScanCardProcessor
|
||||
import com.tangem.domain.wallets.builder.ColdUserWalletBuilder
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.wallets.usecase.SaveWalletUseCase
|
||||
import javax.inject.Inject
|
||||
|
||||
internal class ScanCardToUnlockWalletClickHandler @Inject constructor(
|
||||
private val scanCardProcessor: ScanCardProcessor,
|
||||
private val saveWalletUseCase: SaveWalletUseCase,
|
||||
private val coldUserWalletBuilderFactory: ColdUserWalletBuilder.Factory,
|
||||
) {
|
||||
|
||||
private var scanFailsCounter = 0
|
||||
|
||||
suspend operator fun invoke(walletId: UserWalletId): Either<ScanCardToUnlockWalletError, Unit> {
|
||||
return either {
|
||||
when (val result = scanCardProcessor.scan(analyticsSource = AnalyticsParam.ScreensSources.SignIn)) {
|
||||
is CompletionResult.Failure -> {
|
||||
if (result.error is TangemSdkError.UserCancelled) {
|
||||
scanFailsCounter++
|
||||
ensure(scanFailsCounter < 2) { ScanCardToUnlockWalletError.ManyScanFails }
|
||||
}
|
||||
}
|
||||
is CompletionResult.Success -> {
|
||||
scanFailsCounter = 0
|
||||
|
||||
// If card's public key is null then user wallet will be null
|
||||
val scannedWallet = coldUserWalletBuilderFactory.create(scanResponse = result.data).build()
|
||||
|
||||
ensure(walletId == scannedWallet?.walletId) {
|
||||
ScanCardToUnlockWalletError.WrongCardIsScanned
|
||||
}
|
||||
|
||||
if (scannedWallet != null) {
|
||||
saveWalletUseCase(userWallet = scannedWallet, canOverride = true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class ScanCardToUnlockWalletError {
|
||||
|
||||
object WrongCardIsScanned : ScanCardToUnlockWalletError()
|
||||
|
||||
object ManyScanFails : ScanCardToUnlockWalletError()
|
||||
}
|
||||
|
|
@ -2,14 +2,11 @@ package com.tangem.feature.wallet.presentation.wallet.domain
|
|||
|
||||
import com.tangem.domain.common.wallets.UserWalletsListRepository
|
||||
import com.tangem.domain.models.wallet.copy
|
||||
import com.tangem.domain.wallets.legacy.UserWalletsListManager
|
||||
import com.tangem.domain.wallets.repository.WalletNamesMigrationRepository
|
||||
import timber.log.Timber
|
||||
|
||||
class WalletNameMigrationUseCase(
|
||||
private val userWalletsListManager: UserWalletsListManager,
|
||||
private val userWalletsListRepository: UserWalletsListRepository,
|
||||
private val useNewListRepository: Boolean,
|
||||
private val walletNamesMigrationRepository: WalletNamesMigrationRepository,
|
||||
) {
|
||||
|
||||
|
|
@ -18,28 +15,15 @@ class WalletNameMigrationUseCase(
|
|||
return
|
||||
}
|
||||
|
||||
if (useNewListRepository) {
|
||||
val wallets = userWalletsListRepository.userWalletsSync()
|
||||
val existingNames: MutableSet<String> = mutableSetOf()
|
||||
wallets.forEach {
|
||||
val defaultName = it.name
|
||||
val suggestedWalletName = suggestedWalletName(defaultName, existingNames)
|
||||
if (defaultName != suggestedWalletName) {
|
||||
userWalletsListRepository.saveWithoutLock(it.copy(name = suggestedWalletName), canOverride = true)
|
||||
}
|
||||
Timber.tag("Migrated names").e(it.walletId.toString() + " " + suggestedWalletName)
|
||||
}
|
||||
} else {
|
||||
val wallets = userWalletsListManager.userWalletsSync
|
||||
val existingNames: MutableSet<String> = mutableSetOf()
|
||||
wallets.indices.forEach { i ->
|
||||
val defaultName = wallets[i].name
|
||||
val suggestedWalletName = suggestedWalletName(defaultName, existingNames)
|
||||
if (defaultName != suggestedWalletName) {
|
||||
userWalletsListManager.update(wallets[i].walletId) { it.copy(name = suggestedWalletName) }
|
||||
}
|
||||
Timber.tag("Migrated names").e(i.toString() + " " + suggestedWalletName)
|
||||
val wallets = userWalletsListRepository.userWalletsSync()
|
||||
val existingNames: MutableSet<String> = mutableSetOf()
|
||||
wallets.forEach {
|
||||
val defaultName = it.name
|
||||
val suggestedWalletName = suggestedWalletName(defaultName, existingNames)
|
||||
if (defaultName != suggestedWalletName) {
|
||||
userWalletsListRepository.saveWithoutLock(it.copy(name = suggestedWalletName), canOverride = true)
|
||||
}
|
||||
Timber.tag("Migrated names").e(it.walletId.toString() + " " + suggestedWalletName)
|
||||
}
|
||||
|
||||
walletNamesMigrationRepository.setMigrationDone()
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ import com.tangem.domain.staking.usecase.StakingAvailabilityListUseCase
|
|||
import com.tangem.domain.tokens.ApplyTokenListSortingUseCase
|
||||
import com.tangem.domain.tokens.repository.CurrenciesRepository
|
||||
import com.tangem.domain.wallets.repository.WalletsRepository
|
||||
import com.tangem.domain.wallets.usecase.ShouldSaveUserWalletsUseCase
|
||||
import com.tangem.domain.yield.supply.usecase.YieldSupplyApyFlowUseCase
|
||||
import com.tangem.domain.yield.supply.usecase.YieldSupplyGetShouldShowMainPromoUseCase
|
||||
import com.tangem.feature.wallet.child.wallet.model.intents.WalletClickIntents
|
||||
|
|
@ -21,7 +20,6 @@ import com.tangem.feature.wallet.presentation.wallet.domain.MultiWalletTokenList
|
|||
import com.tangem.feature.wallet.presentation.wallet.domain.WalletWithFundsChecker
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.WalletStateController
|
||||
import com.tangem.feature.wallet.presentation.wallet.subscribers.*
|
||||
import com.tangem.features.hotwallet.HotWalletFeatureToggles
|
||||
import com.tangem.features.tangempay.TangemPayFeatureToggles
|
||||
|
||||
@Suppress("LongParameterList")
|
||||
|
|
@ -40,14 +38,12 @@ internal class MultiWalletContentLoader(
|
|||
private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase,
|
||||
private val applyTokenListSortingUseCase: ApplyTokenListSortingUseCase,
|
||||
private val getMultiWalletWarningsFactory: GetMultiWalletWarningsFactory,
|
||||
private val shouldSaveUserWalletsUseCase: ShouldSaveUserWalletsUseCase,
|
||||
private val getStoryContentUseCase: GetStoryContentUseCase,
|
||||
private val walletsRepository: WalletsRepository,
|
||||
private val currenciesRepository: CurrenciesRepository,
|
||||
private val yieldSupplyApyFlowUseCase: YieldSupplyApyFlowUseCase,
|
||||
private val stakingAvailabilityListUseCase: StakingAvailabilityListUseCase,
|
||||
private val yieldSupplyGetShouldShowMainPromoUseCase: YieldSupplyGetShouldShowMainPromoUseCase,
|
||||
private val hotWalletFeatureToggles: HotWalletFeatureToggles,
|
||||
private val tangemPayFeatureToggles: TangemPayFeatureToggles,
|
||||
private val tangemPayMainSubscriberFactory: TangemPayMainSubscriber.Factory,
|
||||
) : WalletContentLoader(id = userWallet.walletId) {
|
||||
|
|
@ -92,13 +88,6 @@ internal class MultiWalletContentLoader(
|
|||
getStoryContentUseCase = getStoryContentUseCase,
|
||||
).let(::add)
|
||||
|
||||
WalletDropDownItemsSubscriber(
|
||||
stateHolder = stateHolder,
|
||||
shouldSaveUserWalletsUseCase = shouldSaveUserWalletsUseCase,
|
||||
clickIntents = clickIntents,
|
||||
hotWalletFeatureToggles = hotWalletFeatureToggles,
|
||||
).let(::add)
|
||||
|
||||
if (tangemPayFeatureToggles.isTangemPayEnabled) {
|
||||
add(tangemPayMainSubscriberFactory.create(userWallet))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ import com.tangem.domain.staking.usecase.StakingAvailabilityListUseCase
|
|||
import com.tangem.domain.tokens.ApplyTokenListSortingUseCase
|
||||
import com.tangem.domain.tokens.repository.CurrenciesRepository
|
||||
import com.tangem.domain.wallets.repository.WalletsRepository
|
||||
import com.tangem.domain.wallets.usecase.ShouldSaveUserWalletsUseCase
|
||||
import com.tangem.domain.yield.supply.usecase.YieldSupplyApyFlowUseCase
|
||||
import com.tangem.domain.yield.supply.usecase.YieldSupplyGetShouldShowMainPromoUseCase
|
||||
import com.tangem.feature.wallet.child.wallet.model.intents.WalletClickIntents
|
||||
|
|
@ -21,7 +20,6 @@ import com.tangem.feature.wallet.presentation.wallet.domain.MultiWalletTokenList
|
|||
import com.tangem.feature.wallet.presentation.wallet.domain.WalletWithFundsChecker
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.WalletStateController
|
||||
import com.tangem.feature.wallet.presentation.wallet.subscribers.TangemPayMainSubscriber
|
||||
import com.tangem.features.hotwallet.HotWalletFeatureToggles
|
||||
import com.tangem.features.tangempay.TangemPayFeatureToggles
|
||||
import javax.inject.Inject
|
||||
|
||||
|
|
@ -38,7 +36,6 @@ internal class MultiWalletContentLoaderFactory @Inject constructor(
|
|||
private val applyTokenListSortingUseCase: ApplyTokenListSortingUseCase,
|
||||
private val walletWarningsAnalyticsSender: WalletWarningsAnalyticsSender,
|
||||
private val walletWarningsSingleEventSender: WalletWarningsSingleEventSender,
|
||||
private val shouldSaveUserWalletsUseCase: ShouldSaveUserWalletsUseCase,
|
||||
private val getStoryContentUseCase: GetStoryContentUseCase,
|
||||
private val walletsRepository: WalletsRepository,
|
||||
private val getNFTCollectionsUseCase: GetNFTCollectionsUseCase,
|
||||
|
|
@ -46,7 +43,6 @@ internal class MultiWalletContentLoaderFactory @Inject constructor(
|
|||
private val yieldSupplyApyFlowUseCase: YieldSupplyApyFlowUseCase,
|
||||
private val stakingAvailabilityListUseCase: StakingAvailabilityListUseCase,
|
||||
private val yieldSupplyGetShouldShowMainPromoUseCase: YieldSupplyGetShouldShowMainPromoUseCase,
|
||||
private val hotWalletFeatureToggles: HotWalletFeatureToggles,
|
||||
private val tangemPayFeatureToggles: TangemPayFeatureToggles,
|
||||
private val tangemPayMainSubscriberFactory: TangemPayMainSubscriber.Factory,
|
||||
) {
|
||||
|
|
@ -65,13 +61,11 @@ internal class MultiWalletContentLoaderFactory @Inject constructor(
|
|||
walletWarningsSingleEventSender = walletWarningsSingleEventSender,
|
||||
applyTokenListSortingUseCase = applyTokenListSortingUseCase,
|
||||
getStoryContentUseCase = getStoryContentUseCase,
|
||||
shouldSaveUserWalletsUseCase = shouldSaveUserWalletsUseCase,
|
||||
walletsRepository = walletsRepository,
|
||||
getNFTCollectionsUseCase = getNFTCollectionsUseCase,
|
||||
currenciesRepository = currenciesRepository,
|
||||
yieldSupplyApyFlowUseCase = yieldSupplyApyFlowUseCase,
|
||||
stakingAvailabilityListUseCase = stakingAvailabilityListUseCase,
|
||||
hotWalletFeatureToggles = hotWalletFeatureToggles,
|
||||
tangemPayFeatureToggles = tangemPayFeatureToggles,
|
||||
tangemPayMainSubscriberFactory = tangemPayMainSubscriberFactory,
|
||||
yieldSupplyGetShouldShowMainPromoUseCase = yieldSupplyGetShouldShowMainPromoUseCase,
|
||||
|
|
|
|||
|
|
@ -2,14 +2,12 @@ package com.tangem.feature.wallet.presentation.wallet.loaders.implementors
|
|||
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.promo.GetStoryContentUseCase
|
||||
import com.tangem.domain.wallets.usecase.ShouldSaveUserWalletsUseCase
|
||||
import com.tangem.feature.wallet.child.wallet.model.intents.WalletClickIntents
|
||||
import com.tangem.feature.wallet.presentation.wallet.analytics.utils.WalletWarningsAnalyticsSender
|
||||
import com.tangem.feature.wallet.presentation.wallet.analytics.utils.WalletWarningsSingleEventSender
|
||||
import com.tangem.feature.wallet.presentation.wallet.domain.GetMultiWalletWarningsFactory
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.WalletStateController
|
||||
import com.tangem.feature.wallet.presentation.wallet.subscribers.*
|
||||
import com.tangem.features.hotwallet.HotWalletFeatureToggles
|
||||
import com.tangem.features.tangempay.TangemPayFeatureToggles
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedFactory
|
||||
|
|
@ -25,10 +23,8 @@ internal class MultiWalletContentLoaderV2 @AssistedInject constructor(
|
|||
private val walletWarningsAnalyticsSender: WalletWarningsAnalyticsSender,
|
||||
private val walletWarningsSingleEventSender: WalletWarningsSingleEventSender,
|
||||
private val getMultiWalletWarningsFactory: GetMultiWalletWarningsFactory,
|
||||
private val shouldSaveUserWalletsUseCase: ShouldSaveUserWalletsUseCase,
|
||||
private val getStoryContentUseCase: GetStoryContentUseCase,
|
||||
private val checkWalletWithFundsSubscriberFactory: CheckWalletWithFundsSubscriber.Factory,
|
||||
private val hotWalletFeatureToggles: HotWalletFeatureToggles,
|
||||
private val tangemPayFeatureToggles: TangemPayFeatureToggles,
|
||||
private val tangemPayMainSubscriberFactory: TangemPayMainSubscriber.Factory,
|
||||
) : WalletContentLoader(id = userWallet.walletId) {
|
||||
|
|
@ -50,12 +46,6 @@ internal class MultiWalletContentLoaderV2 @AssistedInject constructor(
|
|||
stateHolder = stateController,
|
||||
getStoryContentUseCase = getStoryContentUseCase,
|
||||
),
|
||||
WalletDropDownItemsSubscriber(
|
||||
stateHolder = stateController,
|
||||
shouldSaveUserWalletsUseCase = shouldSaveUserWalletsUseCase,
|
||||
clickIntents = clickIntents,
|
||||
hotWalletFeatureToggles = hotWalletFeatureToggles,
|
||||
),
|
||||
|
||||
if (tangemPayFeatureToggles.isTangemPayEnabled) {
|
||||
tangemPayMainSubscriberFactory.create(userWallet)
|
||||
|
|
|
|||
|
|
@ -10,13 +10,11 @@ import com.tangem.domain.tokens.GetCryptoCurrencyActionsUseCase
|
|||
import com.tangem.domain.tokens.GetSingleCryptoCurrencyStatusUseCase
|
||||
import com.tangem.domain.txhistory.usecase.GetTxHistoryItemsCountUseCase
|
||||
import com.tangem.domain.txhistory.usecase.GetTxHistoryItemsUseCase
|
||||
import com.tangem.domain.wallets.usecase.ShouldSaveUserWalletsUseCase
|
||||
import com.tangem.feature.wallet.child.wallet.model.intents.WalletClickIntents
|
||||
import com.tangem.feature.wallet.presentation.wallet.analytics.utils.WalletWarningsAnalyticsSender
|
||||
import com.tangem.feature.wallet.presentation.wallet.domain.GetSingleWalletWarningsFactory
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.WalletStateController
|
||||
import com.tangem.feature.wallet.presentation.wallet.subscribers.*
|
||||
import com.tangem.features.hotwallet.HotWalletFeatureToggles
|
||||
|
||||
@Suppress("LongParameterList")
|
||||
internal class SingleWalletContentLoader(
|
||||
|
|
@ -33,10 +31,8 @@ internal class SingleWalletContentLoader(
|
|||
private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase,
|
||||
private val getOnrampTransactionsUseCase: GetOnrampTransactionsUseCase,
|
||||
private val onrampRemoveTransactionUseCase: OnrampRemoveTransactionUseCase,
|
||||
private val shouldSaveUserWalletsUseCase: ShouldSaveUserWalletsUseCase,
|
||||
private val analyticsEventHandler: AnalyticsEventHandler,
|
||||
private val walletWarningsAnalyticsSender: WalletWarningsAnalyticsSender,
|
||||
private val hotWalletFeatureToggles: HotWalletFeatureToggles,
|
||||
) : WalletContentLoader(id = userWallet.walletId) {
|
||||
|
||||
override fun create(): List<WalletSubscriber> {
|
||||
|
|
@ -63,12 +59,6 @@ internal class SingleWalletContentLoader(
|
|||
getSingleWalletWarningsFactory = getSingleWalletWarningsFactory,
|
||||
walletWarningsAnalyticsSender = walletWarningsAnalyticsSender,
|
||||
),
|
||||
WalletDropDownItemsSubscriber(
|
||||
stateHolder = stateHolder,
|
||||
shouldSaveUserWalletsUseCase = shouldSaveUserWalletsUseCase,
|
||||
clickIntents = clickIntents,
|
||||
hotWalletFeatureToggles = hotWalletFeatureToggles,
|
||||
),
|
||||
SingleWalletExpressStatusesSubscriber(
|
||||
userWallet = userWallet,
|
||||
stateHolder = stateHolder,
|
||||
|
|
|
|||
|
|
@ -11,12 +11,10 @@ import com.tangem.domain.tokens.GetCryptoCurrencyActionsUseCase
|
|||
import com.tangem.domain.tokens.GetSingleCryptoCurrencyStatusUseCase
|
||||
import com.tangem.domain.txhistory.usecase.GetTxHistoryItemsCountUseCase
|
||||
import com.tangem.domain.txhistory.usecase.GetTxHistoryItemsUseCase
|
||||
import com.tangem.domain.wallets.usecase.ShouldSaveUserWalletsUseCase
|
||||
import com.tangem.feature.wallet.child.wallet.model.intents.WalletClickIntents
|
||||
import com.tangem.feature.wallet.presentation.wallet.analytics.utils.WalletWarningsAnalyticsSender
|
||||
import com.tangem.feature.wallet.presentation.wallet.domain.GetSingleWalletWarningsFactory
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.WalletStateController
|
||||
import com.tangem.features.hotwallet.HotWalletFeatureToggles
|
||||
import javax.inject.Inject
|
||||
|
||||
@ModelScoped
|
||||
|
|
@ -33,10 +31,8 @@ internal class SingleWalletContentLoaderFactory @Inject constructor(
|
|||
private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase,
|
||||
private val getOnrampTransactionsUseCase: GetOnrampTransactionsUseCase,
|
||||
private val onrampRemoveTransactionUseCase: OnrampRemoveTransactionUseCase,
|
||||
private val shouldSaveUserWalletsUseCase: ShouldSaveUserWalletsUseCase,
|
||||
private val analyticsEventHandler: AnalyticsEventHandler,
|
||||
private val walletWarningsAnalyticsSender: WalletWarningsAnalyticsSender,
|
||||
private val hotWalletFeatureToggles: HotWalletFeatureToggles,
|
||||
) {
|
||||
|
||||
fun create(userWallet: UserWallet.Cold, clickIntents: WalletClickIntents, isRefresh: Boolean): WalletContentLoader {
|
||||
|
|
@ -56,8 +52,6 @@ internal class SingleWalletContentLoaderFactory @Inject constructor(
|
|||
walletWarningsAnalyticsSender = walletWarningsAnalyticsSender,
|
||||
getOnrampTransactionsUseCase = getOnrampTransactionsUseCase,
|
||||
onrampRemoveTransactionUseCase = onrampRemoveTransactionUseCase,
|
||||
shouldSaveUserWalletsUseCase = shouldSaveUserWalletsUseCase,
|
||||
hotWalletFeatureToggles = hotWalletFeatureToggles,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -8,7 +8,6 @@ import com.tangem.domain.onramp.GetOnrampTransactionsUseCase
|
|||
import com.tangem.domain.onramp.OnrampRemoveTransactionUseCase
|
||||
import com.tangem.domain.txhistory.usecase.GetTxHistoryItemsCountUseCase
|
||||
import com.tangem.domain.txhistory.usecase.GetTxHistoryItemsUseCase
|
||||
import com.tangem.domain.wallets.usecase.ShouldSaveUserWalletsUseCase
|
||||
import com.tangem.feature.wallet.child.wallet.model.intents.WalletClickIntents
|
||||
import com.tangem.feature.wallet.presentation.account.AccountDependencies
|
||||
import com.tangem.feature.wallet.presentation.wallet.analytics.utils.WalletWarningsAnalyticsSender
|
||||
|
|
@ -16,7 +15,6 @@ import com.tangem.feature.wallet.presentation.wallet.domain.GetSingleWalletWarni
|
|||
import com.tangem.feature.wallet.presentation.wallet.domain.WalletWithFundsChecker
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.WalletStateController
|
||||
import com.tangem.feature.wallet.presentation.wallet.subscribers.*
|
||||
import com.tangem.features.hotwallet.HotWalletFeatureToggles
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedFactory
|
||||
|
|
@ -35,13 +33,11 @@ internal class SingleWalletContentLoaderV2 @AssistedInject constructor(
|
|||
private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase,
|
||||
private val getOnrampTransactionsUseCase: GetOnrampTransactionsUseCase,
|
||||
private val onrampRemoveTransactionUseCase: OnrampRemoveTransactionUseCase,
|
||||
private val shouldSaveUserWalletsUseCase: ShouldSaveUserWalletsUseCase,
|
||||
private val analyticsEventHandler: AnalyticsEventHandler,
|
||||
private val walletWarningsAnalyticsSender: WalletWarningsAnalyticsSender,
|
||||
private val accountDependencies: AccountDependencies,
|
||||
private val walletWithFundsChecker: WalletWithFundsChecker,
|
||||
private val dispatchers: CoroutineDispatcherProvider,
|
||||
private val hotWalletFeatureToggles: HotWalletFeatureToggles,
|
||||
) : WalletContentLoader(id = userWallet.walletId) {
|
||||
|
||||
override fun create(): List<WalletSubscriber> = listOf(
|
||||
|
|
@ -66,12 +62,6 @@ internal class SingleWalletContentLoaderV2 @AssistedInject constructor(
|
|||
getSingleWalletWarningsFactory = getSingleWalletWarningsFactory,
|
||||
walletWarningsAnalyticsSender = walletWarningsAnalyticsSender,
|
||||
),
|
||||
WalletDropDownItemsSubscriber(
|
||||
stateHolder = stateHolder,
|
||||
shouldSaveUserWalletsUseCase = shouldSaveUserWalletsUseCase,
|
||||
clickIntents = clickIntents,
|
||||
hotWalletFeatureToggles = hotWalletFeatureToggles,
|
||||
),
|
||||
SingleWalletExpressStatusesSubscriberV2(
|
||||
userWallet = userWallet,
|
||||
singleAccountStatusListSupplier = accountDependencies.singleAccountStatusListSupplier,
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
|
|||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.promo.GetStoryContentUseCase
|
||||
import com.tangem.domain.staking.usecase.StakingAvailabilityListUseCase
|
||||
import com.tangem.domain.wallets.usecase.ShouldSaveUserWalletsUseCase
|
||||
import com.tangem.domain.yield.supply.usecase.YieldSupplyApyFlowUseCase
|
||||
import com.tangem.domain.yield.supply.usecase.YieldSupplyGetShouldShowMainPromoUseCase
|
||||
import com.tangem.feature.wallet.child.wallet.model.intents.WalletClickIntents
|
||||
|
|
@ -15,8 +14,10 @@ import com.tangem.feature.wallet.presentation.wallet.domain.GetMultiWalletWarnin
|
|||
import com.tangem.feature.wallet.presentation.wallet.domain.MultiWalletTokenListStore
|
||||
import com.tangem.feature.wallet.presentation.wallet.domain.WalletWithFundsChecker
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.WalletStateController
|
||||
import com.tangem.feature.wallet.presentation.wallet.subscribers.*
|
||||
import com.tangem.features.hotwallet.HotWalletFeatureToggles
|
||||
import com.tangem.feature.wallet.presentation.wallet.subscribers.MultiWalletActionButtonsSubscriber
|
||||
import com.tangem.feature.wallet.presentation.wallet.subscribers.MultiWalletWarningsSubscriber
|
||||
import com.tangem.feature.wallet.presentation.wallet.subscribers.SingleWalletWithTokenListSubscriber
|
||||
import com.tangem.feature.wallet.presentation.wallet.subscribers.WalletSubscriber
|
||||
|
||||
@Deprecated("Use SingleWalletWithTokenContentLoaderV2 instead")
|
||||
@Suppress("LongParameterList")
|
||||
|
|
@ -31,11 +32,9 @@ internal class SingleWalletWithTokenContentLoader(
|
|||
private val getMultiWalletWarningsFactory: GetMultiWalletWarningsFactory,
|
||||
private val tokenListStore: MultiWalletTokenListStore,
|
||||
private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase,
|
||||
private val shouldSaveUserWalletsUseCase: ShouldSaveUserWalletsUseCase,
|
||||
private val getStoryContentUseCase: GetStoryContentUseCase,
|
||||
private val yieldSupplyApyFlowUseCase: YieldSupplyApyFlowUseCase,
|
||||
private val stakingAvailabilityListUseCase: StakingAvailabilityListUseCase,
|
||||
private val hotWalletFeatureToggles: HotWalletFeatureToggles,
|
||||
private val yieldSupplyGetShouldShowMainPromoUseCase: YieldSupplyGetShouldShowMainPromoUseCase,
|
||||
) : WalletContentLoader(id = userWallet.walletId) {
|
||||
|
||||
|
|
@ -66,12 +65,6 @@ internal class SingleWalletWithTokenContentLoader(
|
|||
stateHolder = stateHolder,
|
||||
getStoryContentUseCase = getStoryContentUseCase,
|
||||
).let(::add)
|
||||
WalletDropDownItemsSubscriber(
|
||||
stateHolder = stateHolder,
|
||||
shouldSaveUserWalletsUseCase = shouldSaveUserWalletsUseCase,
|
||||
clickIntents = clickIntents,
|
||||
hotWalletFeatureToggles = hotWalletFeatureToggles,
|
||||
).let(::add)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -5,7 +5,6 @@ import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
|
|||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.promo.GetStoryContentUseCase
|
||||
import com.tangem.domain.staking.usecase.StakingAvailabilityListUseCase
|
||||
import com.tangem.domain.wallets.usecase.ShouldSaveUserWalletsUseCase
|
||||
import com.tangem.domain.yield.supply.usecase.YieldSupplyApyFlowUseCase
|
||||
import com.tangem.domain.yield.supply.usecase.YieldSupplyGetShouldShowMainPromoUseCase
|
||||
import com.tangem.feature.wallet.child.wallet.model.intents.WalletClickIntents
|
||||
|
|
@ -16,7 +15,6 @@ import com.tangem.feature.wallet.presentation.wallet.domain.GetMultiWalletWarnin
|
|||
import com.tangem.feature.wallet.presentation.wallet.domain.MultiWalletTokenListStore
|
||||
import com.tangem.feature.wallet.presentation.wallet.domain.WalletWithFundsChecker
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.WalletStateController
|
||||
import com.tangem.features.hotwallet.HotWalletFeatureToggles
|
||||
import javax.inject.Inject
|
||||
|
||||
// TODO: Refactor
|
||||
|
|
@ -32,11 +30,9 @@ internal class SingleWalletWithTokenContentLoaderFactory @Inject constructor(
|
|||
private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase,
|
||||
private val walletWarningsAnalyticsSender: WalletWarningsAnalyticsSender,
|
||||
private val walletWarningsSingleEventSender: WalletWarningsSingleEventSender,
|
||||
private val shouldSaveUserWalletsUseCase: ShouldSaveUserWalletsUseCase,
|
||||
private val getStoryContentUseCase: GetStoryContentUseCase,
|
||||
private val yieldSupplyApyFlowUseCase: YieldSupplyApyFlowUseCase,
|
||||
private val stakingAvailabilityListUseCase: StakingAvailabilityListUseCase,
|
||||
private val hotWalletFeatureToggles: HotWalletFeatureToggles,
|
||||
private val yieldSupplyGetShouldShowMainPromoUseCase: YieldSupplyGetShouldShowMainPromoUseCase,
|
||||
) {
|
||||
|
||||
|
|
@ -53,10 +49,8 @@ internal class SingleWalletWithTokenContentLoaderFactory @Inject constructor(
|
|||
walletWarningsAnalyticsSender = walletWarningsAnalyticsSender,
|
||||
walletWarningsSingleEventSender = walletWarningsSingleEventSender,
|
||||
getStoryContentUseCase = getStoryContentUseCase,
|
||||
shouldSaveUserWalletsUseCase = shouldSaveUserWalletsUseCase,
|
||||
yieldSupplyApyFlowUseCase = yieldSupplyApyFlowUseCase,
|
||||
stakingAvailabilityListUseCase = stakingAvailabilityListUseCase,
|
||||
hotWalletFeatureToggles = hotWalletFeatureToggles,
|
||||
yieldSupplyGetShouldShowMainPromoUseCase = yieldSupplyGetShouldShowMainPromoUseCase,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,14 +1,15 @@
|
|||
package com.tangem.feature.wallet.presentation.wallet.loaders.implementors
|
||||
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.wallets.usecase.ShouldSaveUserWalletsUseCase
|
||||
import com.tangem.feature.wallet.child.wallet.model.intents.WalletClickIntents
|
||||
import com.tangem.feature.wallet.presentation.wallet.analytics.utils.WalletWarningsAnalyticsSender
|
||||
import com.tangem.feature.wallet.presentation.wallet.analytics.utils.WalletWarningsSingleEventSender
|
||||
import com.tangem.feature.wallet.presentation.wallet.domain.GetMultiWalletWarningsFactory
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.WalletStateController
|
||||
import com.tangem.feature.wallet.presentation.wallet.subscribers.*
|
||||
import com.tangem.features.hotwallet.HotWalletFeatureToggles
|
||||
import com.tangem.feature.wallet.presentation.wallet.subscribers.CheckWalletWithFundsSubscriber
|
||||
import com.tangem.feature.wallet.presentation.wallet.subscribers.MultiWalletWarningsSubscriber
|
||||
import com.tangem.feature.wallet.presentation.wallet.subscribers.SingleWalletWithTokenSubscriber
|
||||
import com.tangem.feature.wallet.presentation.wallet.subscribers.WalletSubscriber
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedFactory
|
||||
import dagger.assisted.AssistedInject
|
||||
|
|
@ -23,8 +24,6 @@ internal class SingleWalletWithTokenContentLoaderV2 @AssistedInject constructor(
|
|||
private val walletWarningsAnalyticsSender: WalletWarningsAnalyticsSender,
|
||||
private val walletWarningsSingleEventSender: WalletWarningsSingleEventSender,
|
||||
private val getMultiWalletWarningsFactory: GetMultiWalletWarningsFactory,
|
||||
private val shouldSaveUserWalletsUseCase: ShouldSaveUserWalletsUseCase,
|
||||
private val hotWalletFeatureToggles: HotWalletFeatureToggles,
|
||||
) : WalletContentLoader(id = userWallet.walletId) {
|
||||
|
||||
override fun create(): List<WalletSubscriber> = listOf(
|
||||
|
|
@ -37,12 +36,6 @@ internal class SingleWalletWithTokenContentLoaderV2 @AssistedInject constructor(
|
|||
walletWarningsAnalyticsSender = walletWarningsAnalyticsSender,
|
||||
walletWarningsSingleEventSender = walletWarningsSingleEventSender,
|
||||
),
|
||||
WalletDropDownItemsSubscriber(
|
||||
stateHolder = stateController,
|
||||
shouldSaveUserWalletsUseCase = shouldSaveUserWalletsUseCase,
|
||||
clickIntents = clickIntents,
|
||||
hotWalletFeatureToggles = hotWalletFeatureToggles,
|
||||
),
|
||||
checkWalletWithFundsSubscriberFactory.create(userWallet),
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,113 +0,0 @@
|
|||
package com.tangem.feature.wallet.presentation.wallet.state.model
|
||||
|
||||
import androidx.compose.runtime.Immutable
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.extensions.stringReference
|
||||
import com.tangem.feature.wallet.impl.R
|
||||
|
||||
@Immutable
|
||||
internal sealed interface WalletAlertState {
|
||||
|
||||
@Immutable
|
||||
sealed class Basic : WalletAlertState {
|
||||
abstract val title: TextReference?
|
||||
abstract val message: TextReference
|
||||
open val confirmButtonText: TextReference = resourceReference(id = R.string.common_ok)
|
||||
open val isWarningConfirmButton: Boolean = false
|
||||
abstract val onConfirmClick: (() -> Unit)?
|
||||
open val cancelButtonText: TextReference? = null
|
||||
open val onCancelClick: (() -> Unit)? = null
|
||||
}
|
||||
|
||||
@Immutable
|
||||
sealed class TextInput : WalletAlertState {
|
||||
abstract val title: TextReference
|
||||
abstract val label: TextReference
|
||||
open val text: String = ""
|
||||
open val confirmButtonText: TextReference = resourceReference(id = R.string.common_ok)
|
||||
abstract val onConfirmClick: (String) -> Unit
|
||||
abstract val errorTextProvider: (String) -> TextReference?
|
||||
}
|
||||
|
||||
data class SimpleOkAlert(val message: TextReference, val onOkClick: () -> Unit) : WalletAlertState
|
||||
|
||||
data class DefaultAlert(
|
||||
override val title: TextReference?,
|
||||
override val message: TextReference,
|
||||
override val onConfirmClick: (() -> Unit)?,
|
||||
) : Basic()
|
||||
|
||||
data class RemoveWalletAlert(override val onConfirmClick: (() -> Unit)?) : Basic() {
|
||||
override val title: TextReference? = null
|
||||
override val message: TextReference = resourceReference(id = R.string.user_wallet_list_delete_prompt)
|
||||
override val confirmButtonText: TextReference = resourceReference(id = R.string.common_delete)
|
||||
override val isWarningConfirmButton: Boolean = true
|
||||
}
|
||||
|
||||
data class VisaLimitsInfo(
|
||||
val totalLimit: String,
|
||||
val otherLimit: String,
|
||||
) : Basic() {
|
||||
override val title: TextReference? = null
|
||||
override val message: TextReference = stringReference(
|
||||
value = "Limits are needed to control costs, improve security, manage risk. " +
|
||||
"You can spend $totalLimit during the week for card payments in shops and " +
|
||||
"$otherLimit for other transactions, e. g. subscriptions or debts.",
|
||||
)
|
||||
override val onConfirmClick: (() -> Unit)? = null
|
||||
}
|
||||
|
||||
data object WrongCardIsScanned : Basic() {
|
||||
override val title: TextReference = resourceReference(R.string.common_warning)
|
||||
override val message: TextReference = resourceReference(R.string.error_wrong_wallet_tapped)
|
||||
override val onConfirmClick: (() -> Unit)? = null
|
||||
}
|
||||
|
||||
data object RescanWallets : Basic() {
|
||||
override val title: TextReference = resourceReference(R.string.common_attention)
|
||||
override val message: TextReference = resourceReference(R.string.key_invalidated_warning_description)
|
||||
override val onConfirmClick: (() -> Unit)? = null
|
||||
}
|
||||
|
||||
data object VisaBalancesInfo : Basic() {
|
||||
override val title: TextReference? = null
|
||||
override val message: TextReference = stringReference(
|
||||
value = "Available balance is actual funds available, considering pending transactions, " +
|
||||
"blocked amounts, and debit balance to prevent overdrafts.",
|
||||
)
|
||||
override val onConfirmClick: (() -> Unit)? = null
|
||||
}
|
||||
|
||||
data object ProvidersStillLoading : Basic() {
|
||||
override val title: TextReference = resourceReference(R.string.action_buttons_service_loading_alert_title)
|
||||
override val message: TextReference = resourceReference(R.string.action_buttons_service_loading_alert_message)
|
||||
override val onConfirmClick: (() -> Unit)? = null
|
||||
}
|
||||
|
||||
data object UnavailableOperation : Basic() {
|
||||
override val title: TextReference = resourceReference(R.string.action_buttons_something_wrong_alert_title)
|
||||
override val message: TextReference = resourceReference(R.string.action_buttons_something_wrong_alert_message)
|
||||
override val onConfirmClick: (() -> Unit)? = null
|
||||
}
|
||||
|
||||
data object InsufficientTokensCountForSwapping : Basic() {
|
||||
override val title: TextReference =
|
||||
resourceReference(id = R.string.action_buttons_swap_no_tokens_added_alert_title)
|
||||
|
||||
override val message: TextReference =
|
||||
resourceReference(id = R.string.action_buttons_swap_no_tokens_added_alert_message)
|
||||
|
||||
override val onConfirmClick: (() -> Unit)? = null
|
||||
}
|
||||
|
||||
data class ConfirmExpressStatusHide(
|
||||
override val onConfirmClick: (() -> Unit),
|
||||
override val onCancelClick: (() -> Unit),
|
||||
) : Basic() {
|
||||
override val title: TextReference = resourceReference(R.string.express_status_hide_dialog_title)
|
||||
override val message: TextReference = resourceReference(R.string.express_status_hide_dialog_text)
|
||||
override val confirmButtonText: TextReference = resourceReference(R.string.common_hide)
|
||||
override val cancelButtonText: TextReference = resourceReference(R.string.common_cancel)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,96 @@
|
|||
package com.tangem.feature.wallet.presentation.wallet.state.model
|
||||
|
||||
import com.tangem.core.ui.extensions.WrappedList
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.message.DialogMessage
|
||||
import com.tangem.core.ui.message.EventMessageAction
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import com.tangem.feature.wallet.impl.R
|
||||
|
||||
internal object WalletAlertUM {
|
||||
|
||||
fun seedPhraseConfirm(onClick: () -> Unit): DialogMessage {
|
||||
return DialogMessage(
|
||||
message = resourceReference(R.string.warning_seedphrase_issue_answer_yes),
|
||||
firstActionBuilder = {
|
||||
okAction(onClick = onClick)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
fun seedPhraseDismiss(onClick: () -> Unit): DialogMessage {
|
||||
return DialogMessage(
|
||||
message = resourceReference(R.string.warning_seedphrase_issue_answer_no),
|
||||
firstActionBuilder = {
|
||||
okAction(onClick = onClick)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
fun unableHideToken(cryptoCurrency: CryptoCurrency): DialogMessage {
|
||||
return DialogMessage(
|
||||
title = resourceReference(
|
||||
id = R.string.token_details_unable_hide_alert_title,
|
||||
formatArgs = WrappedList(listOf(cryptoCurrency.name)),
|
||||
),
|
||||
message = resourceReference(
|
||||
id = R.string.token_details_unable_hide_alert_message,
|
||||
formatArgs = WrappedList(
|
||||
listOf(
|
||||
cryptoCurrency.name,
|
||||
cryptoCurrency.symbol,
|
||||
cryptoCurrency.network.name,
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
fun hideTokenConfirm(cryptoCurrency: CryptoCurrency, onClick: () -> Unit): DialogMessage {
|
||||
return DialogMessage(
|
||||
title = resourceReference(
|
||||
id = R.string.token_details_hide_alert_title,
|
||||
formatArgs = WrappedList(listOf(cryptoCurrency.name)),
|
||||
),
|
||||
message = resourceReference(R.string.token_details_hide_alert_message),
|
||||
firstActionBuilder = {
|
||||
okAction(onClick)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
fun providersStillLoading(): DialogMessage {
|
||||
return DialogMessage(
|
||||
title = resourceReference(R.string.action_buttons_service_loading_alert_title),
|
||||
message = resourceReference(R.string.action_buttons_service_loading_alert_message),
|
||||
)
|
||||
}
|
||||
|
||||
fun unavailableOperation(): DialogMessage {
|
||||
return DialogMessage(
|
||||
title = resourceReference(R.string.action_buttons_something_wrong_alert_title),
|
||||
message = resourceReference(R.string.action_buttons_something_wrong_alert_message),
|
||||
)
|
||||
}
|
||||
|
||||
fun insufficientTokensCountForSwapping(): DialogMessage {
|
||||
return DialogMessage(
|
||||
title = resourceReference(R.string.action_buttons_swap_no_tokens_added_alert_title),
|
||||
message = resourceReference(R.string.action_buttons_swap_no_tokens_added_alert_message),
|
||||
)
|
||||
}
|
||||
|
||||
fun confirmExpressStatusHide(onConfirmClick: () -> Unit): DialogMessage {
|
||||
return DialogMessage(
|
||||
title = resourceReference(R.string.express_status_hide_dialog_title),
|
||||
message = resourceReference(R.string.express_status_hide_dialog_text),
|
||||
firstActionBuilder = {
|
||||
EventMessageAction(
|
||||
title = resourceReference(R.string.common_hide),
|
||||
onClick = onConfirmClick,
|
||||
)
|
||||
},
|
||||
secondActionBuilder = { cancelAction() },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -13,12 +13,8 @@ internal sealed class WalletEvent {
|
|||
|
||||
data class ShowError(val text: TextReference) : WalletEvent()
|
||||
|
||||
data class ShowAlert(val state: WalletAlertState) : WalletEvent()
|
||||
|
||||
data object CopyAddress : WalletEvent()
|
||||
|
||||
data class RateApp(val onDismissClick: () -> Unit) : WalletEvent()
|
||||
|
||||
data class DemonstrateWalletsScrollPreview(val direction: Direction) : WalletEvent() {
|
||||
|
||||
enum class Direction {
|
||||
|
|
|
|||
|
|
@ -1,73 +0,0 @@
|
|||
package com.tangem.feature.wallet.presentation.wallet.state.transformers
|
||||
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.feature.wallet.child.wallet.model.intents.WalletCardClickIntents
|
||||
import com.tangem.feature.wallet.impl.R
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletDropDownItems
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletScreenState
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletState
|
||||
import com.tangem.features.hotwallet.HotWalletFeatureToggles
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
|
||||
internal class SetWalletCardDropDownItemsTransformer(
|
||||
private val dropdownEnabled: Boolean,
|
||||
private val clickIntents: WalletCardClickIntents,
|
||||
private val hotWalletFeatureToggles: HotWalletFeatureToggles,
|
||||
) : WalletScreenStateTransformer {
|
||||
override fun transform(prevState: WalletScreenState): WalletScreenState {
|
||||
return prevState.copy(wallets = prevState.wallets.map(::transformWalletState).toImmutableList())
|
||||
}
|
||||
|
||||
private fun transformWalletState(prevState: WalletState): WalletState {
|
||||
return when (prevState) {
|
||||
is WalletState.MultiCurrency.Content -> prevState.copy(
|
||||
walletCardState = prevState.walletCardState.copySealed(
|
||||
dropDownItems = constructDropDownItems(prevState.walletCardState.id),
|
||||
),
|
||||
)
|
||||
is WalletState.SingleCurrency.Content -> prevState.copy(
|
||||
walletCardState = prevState.walletCardState.copySealed(
|
||||
dropDownItems = constructDropDownItems(prevState.walletCardState.id),
|
||||
),
|
||||
)
|
||||
is WalletState.MultiCurrency.Locked -> prevState.copy(
|
||||
walletCardState = prevState.walletCardState.copySealed(
|
||||
dropDownItems = constructDropDownItems(prevState.walletCardState.id),
|
||||
),
|
||||
)
|
||||
is WalletState.SingleCurrency.Locked -> prevState.copy(
|
||||
walletCardState = prevState.walletCardState.copySealed(
|
||||
dropDownItems = constructDropDownItems(prevState.walletCardState.id),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun constructDropDownItems(userWalletId: UserWalletId): ImmutableList<WalletDropDownItems> {
|
||||
return if (dropdownEnabled) {
|
||||
buildList {
|
||||
add(
|
||||
WalletDropDownItems(
|
||||
text = resourceReference(id = R.string.common_rename),
|
||||
icon = R.drawable.ic_edit_24,
|
||||
onClick = { clickIntents.onRenameBeforeConfirmationClick(userWalletId) },
|
||||
),
|
||||
)
|
||||
if (!hotWalletFeatureToggles.isHotWalletEnabled) {
|
||||
add(
|
||||
WalletDropDownItems(
|
||||
text = resourceReference(id = R.string.common_delete),
|
||||
icon = R.drawable.ic_trash_24,
|
||||
onClick = { clickIntents.onDeleteBeforeConfirmationClick(userWalletId) },
|
||||
),
|
||||
)
|
||||
}
|
||||
}.toImmutableList()
|
||||
} else {
|
||||
persistentListOf()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4,12 +4,17 @@ import com.tangem.core.analytics.models.event.MainScreenAnalyticsEvent.Companion
|
|||
import com.tangem.core.ui.components.containers.pullToRefresh.PullToRefreshConfig
|
||||
import com.tangem.core.ui.components.marketprice.MarketPriceBlockState
|
||||
import com.tangem.core.ui.components.transactions.state.TxHistoryState
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.domain.card.common.util.cardTypesResolver
|
||||
import com.tangem.domain.models.wallet.UserWallet
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.models.wallet.isMultiCurrency
|
||||
import com.tangem.feature.wallet.child.wallet.model.intents.WalletClickIntents
|
||||
import com.tangem.feature.wallet.impl.R
|
||||
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.model.*
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.PersistentList
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
|
|
@ -41,13 +46,7 @@ internal class WalletLoadingStateFactory(
|
|||
private fun createLoadingHotWalletContent(userWallet: UserWallet.Hot): WalletState.MultiCurrency.Content {
|
||||
return WalletState.MultiCurrency.Content(
|
||||
pullToRefreshConfig = createPullToRefreshConfig(),
|
||||
walletCardState = WalletCardState.Loading(
|
||||
id = userWallet.walletId,
|
||||
title = userWallet.name,
|
||||
additionalInfo = WalletAdditionalInfoFactory.resolve(wallet = userWallet),
|
||||
imageResId = null,
|
||||
dropDownItems = persistentListOf(),
|
||||
),
|
||||
walletCardState = createLoadingWalletCardState(userWallet),
|
||||
buttons = createMultiWalletActions(userWallet),
|
||||
warnings = persistentListOf(),
|
||||
bottomSheetConfig = null,
|
||||
|
|
@ -61,7 +60,7 @@ internal class WalletLoadingStateFactory(
|
|||
private fun createLoadingMultiCurrencyContent(userWallet: UserWallet.Cold): WalletState.MultiCurrency.Content {
|
||||
return WalletState.MultiCurrency.Content(
|
||||
pullToRefreshConfig = createPullToRefreshConfig(),
|
||||
walletCardState = userWallet.toLoadingWalletCardState(),
|
||||
walletCardState = createLoadingWalletCardState(userWallet),
|
||||
buttons = createMultiWalletActions(userWallet),
|
||||
warnings = persistentListOf(),
|
||||
bottomSheetConfig = null,
|
||||
|
|
@ -76,7 +75,7 @@ internal class WalletLoadingStateFactory(
|
|||
val currencySymbol = userWallet.scanResponse.cardTypesResolver.getBlockchain().currency
|
||||
return WalletState.SingleCurrency.Content(
|
||||
pullToRefreshConfig = createPullToRefreshConfig(),
|
||||
walletCardState = userWallet.toLoadingWalletCardState(),
|
||||
walletCardState = createLoadingWalletCardState(userWallet),
|
||||
warnings = persistentListOf(),
|
||||
bottomSheetConfig = null,
|
||||
buttons = createDimmedButtons(),
|
||||
|
|
@ -98,13 +97,21 @@ internal class WalletLoadingStateFactory(
|
|||
)
|
||||
}
|
||||
|
||||
private fun UserWallet.Cold.toLoadingWalletCardState(): WalletCardState {
|
||||
private fun createLoadingWalletCardState(userWallet: UserWallet): WalletCardState {
|
||||
return WalletCardState.Loading(
|
||||
id = walletId,
|
||||
title = name,
|
||||
additionalInfo = if (isMultiCurrency) WalletAdditionalInfoFactory.resolve(wallet = this) else null,
|
||||
imageResId = walletImageResolver.resolve(userWallet = this),
|
||||
dropDownItems = persistentListOf(),
|
||||
id = userWallet.walletId,
|
||||
title = userWallet.name,
|
||||
additionalInfo = if (!userWallet.isMultiCurrency) {
|
||||
null
|
||||
} else {
|
||||
WalletAdditionalInfoFactory.resolve(wallet = userWallet)
|
||||
},
|
||||
imageResId = if (userWallet is UserWallet.Cold) {
|
||||
walletImageResolver.resolve(userWallet)
|
||||
} else {
|
||||
null
|
||||
},
|
||||
dropDownItems = createDropDownItems(userWalletId = userWallet.walletId),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -150,4 +157,14 @@ internal class WalletLoadingStateFactory(
|
|||
WalletManageButton.Sell(enabled = true, dimContent = true, onClick = {}),
|
||||
)
|
||||
}
|
||||
|
||||
private fun createDropDownItems(userWalletId: UserWalletId): ImmutableList<WalletDropDownItems> {
|
||||
return persistentListOf(
|
||||
WalletDropDownItems(
|
||||
text = resourceReference(id = R.string.common_rename),
|
||||
icon = R.drawable.ic_edit_24,
|
||||
onClick = { clickIntents.onRenameBeforeConfirmationClick(userWalletId) },
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
package com.tangem.feature.wallet.presentation.wallet.subscribers
|
||||
|
||||
import com.tangem.domain.wallets.usecase.ShouldSaveUserWalletsUseCase
|
||||
import com.tangem.feature.wallet.child.wallet.model.intents.WalletClickIntents
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.WalletStateController
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.transformers.SetWalletCardDropDownItemsTransformer
|
||||
import com.tangem.features.hotwallet.HotWalletFeatureToggles
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.flow
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
|
||||
internal class WalletDropDownItemsSubscriber(
|
||||
private val stateHolder: WalletStateController,
|
||||
private val shouldSaveUserWalletsUseCase: ShouldSaveUserWalletsUseCase,
|
||||
private val clickIntents: WalletClickIntents,
|
||||
private val hotWalletFeatureToggles: HotWalletFeatureToggles,
|
||||
) : WalletSubscriber() {
|
||||
override fun create(coroutineScope: CoroutineScope): Flow<*> {
|
||||
if (!hotWalletFeatureToggles.isHotWalletEnabled) {
|
||||
return shouldSaveUserWalletsUseCase.invoke()
|
||||
.distinctUntilChanged()
|
||||
.onEach { shouldSaveUserWallets ->
|
||||
stateHolder.update(
|
||||
SetWalletCardDropDownItemsTransformer(
|
||||
dropdownEnabled = shouldSaveUserWallets,
|
||||
clickIntents = clickIntents,
|
||||
hotWalletFeatureToggles = hotWalletFeatureToggles,
|
||||
),
|
||||
)
|
||||
}
|
||||
} else {
|
||||
return flow<Unit> {
|
||||
stateHolder.update(
|
||||
SetWalletCardDropDownItemsTransformer(
|
||||
dropdownEnabled = true,
|
||||
clickIntents = clickIntents,
|
||||
hotWalletFeatureToggles = hotWalletFeatureToggles,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,98 +0,0 @@
|
|||
package com.tangem.feature.wallet.presentation.wallet.ui
|
||||
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.text.input.TextFieldValue
|
||||
import com.tangem.core.ui.components.AdditionalTextInputDialogUM
|
||||
import com.tangem.core.ui.components.BasicDialog
|
||||
import com.tangem.core.ui.components.DialogButtonUM
|
||||
import com.tangem.core.ui.components.TextInputDialog
|
||||
import com.tangem.core.ui.extensions.resolveReference
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.feature.wallet.impl.R
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletAlertState
|
||||
|
||||
@Composable
|
||||
internal fun WalletAlert(state: WalletAlertState, onDismiss: () -> Unit) {
|
||||
when (state) {
|
||||
is WalletAlertState.Basic -> BasicAlert(state, onDismiss)
|
||||
is WalletAlertState.TextInput -> TextInputAlert(state, onDismiss)
|
||||
is WalletAlertState.SimpleOkAlert -> {
|
||||
BasicDialog(
|
||||
message = state.message.resolveReference(),
|
||||
confirmButton = DialogButtonUM(
|
||||
onClick = {
|
||||
state.onOkClick()
|
||||
onDismiss()
|
||||
},
|
||||
),
|
||||
onDismissDialog = onDismiss,
|
||||
isDismissable = false,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun BasicAlert(state: WalletAlertState.Basic, onDismiss: () -> Unit) {
|
||||
val confirmButton: DialogButtonUM
|
||||
val dismissButton: DialogButtonUM?
|
||||
|
||||
val onActionClick = state.onConfirmClick
|
||||
if (onActionClick != null) {
|
||||
confirmButton = DialogButtonUM(
|
||||
title = state.confirmButtonText.resolveReference(),
|
||||
isWarning = state.isWarningConfirmButton,
|
||||
onClick = {
|
||||
onActionClick()
|
||||
onDismiss()
|
||||
},
|
||||
)
|
||||
dismissButton = DialogButtonUM(
|
||||
title = stringResourceSafe(id = R.string.common_cancel),
|
||||
onClick = onDismiss,
|
||||
)
|
||||
} else {
|
||||
confirmButton = DialogButtonUM(
|
||||
title = state.confirmButtonText.resolveReference(),
|
||||
isWarning = state.isWarningConfirmButton,
|
||||
onClick = onDismiss,
|
||||
)
|
||||
dismissButton = null
|
||||
}
|
||||
|
||||
BasicDialog(
|
||||
message = state.message.resolveReference(),
|
||||
confirmButton = confirmButton,
|
||||
onDismissDialog = onDismiss,
|
||||
title = state.title?.resolveReference(),
|
||||
dismissButton = dismissButton,
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun TextInputAlert(state: WalletAlertState.TextInput, onDismiss: () -> Unit) {
|
||||
var value by remember { mutableStateOf(TextFieldValue(text = state.text)) }
|
||||
|
||||
TextInputDialog(
|
||||
fieldValue = value,
|
||||
confirmButton = DialogButtonUM(
|
||||
title = state.confirmButtonText.resolveReference(),
|
||||
isEnabled = value.text.isNotEmpty() &&
|
||||
value.text != state.text &&
|
||||
state.errorTextProvider(value.text) == null,
|
||||
onClick = {
|
||||
state.onConfirmClick(value.text)
|
||||
onDismiss()
|
||||
},
|
||||
),
|
||||
onDismissDialog = onDismiss,
|
||||
onValueChange = { value = it },
|
||||
title = state.title.resolveReference(),
|
||||
dismissButton = DialogButtonUM(title = stringResourceSafe(id = R.string.common_cancel), onClick = onDismiss),
|
||||
textFieldParams = AdditionalTextInputDialogUM(
|
||||
label = state.label.resolveReference(),
|
||||
isError = state.errorTextProvider(value.text) != null,
|
||||
caption = state.errorTextProvider(value.text)?.resolveReference(),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
@ -11,9 +11,7 @@ import com.tangem.core.ui.event.StateEvent
|
|||
import com.tangem.core.ui.extensions.resolveReference
|
||||
import com.tangem.core.ui.utils.requestPermission
|
||||
import com.tangem.feature.wallet.impl.R
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletAlertState
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletEvent
|
||||
import com.tangem.feature.wallet.presentation.wallet.ui.utils.ReviewManagerRequester
|
||||
import com.tangem.feature.wallet.presentation.wallet.ui.utils.animateScrollByIndex
|
||||
import com.tangem.feature.wallet.presentation.wallet.ui.utils.demonstrateScrolling
|
||||
import com.tangem.features.pushnotifications.api.utils.PUSH_PERMISSION
|
||||
|
|
@ -24,10 +22,8 @@ internal fun WalletEventEffect(
|
|||
snackbarHostState: SnackbarHostState,
|
||||
event: StateEvent<WalletEvent>,
|
||||
onAutoScrollSet: () -> Unit,
|
||||
onAlertConfigSet: (WalletAlertState) -> Unit,
|
||||
) {
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
val context = LocalContext.current
|
||||
val resources = LocalContext.current.resources
|
||||
|
||||
var showPermissionRequest by remember { mutableStateOf<Pair<() -> Unit, () -> Unit>?>(null) }
|
||||
|
|
@ -57,10 +53,6 @@ internal fun WalletEventEffect(
|
|||
duration = SnackbarDuration.Short,
|
||||
)
|
||||
}
|
||||
is WalletEvent.ShowAlert -> onAlertConfigSet(value.state)
|
||||
is WalletEvent.RateApp -> {
|
||||
ReviewManagerRequester.request(context = context, onDismissClick = value.onDismissClick)
|
||||
}
|
||||
is WalletEvent.DemonstrateWalletsScrollPreview -> {
|
||||
walletsListState.demonstrateScrolling(coroutineScope = coroutineScope, direction = value.direction)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -100,13 +100,6 @@ internal fun WalletScreen(
|
|||
val snackbarHostState = remember(::SnackbarHostState)
|
||||
val isAutoScroll = remember { mutableStateOf(value = false) }
|
||||
|
||||
var alertConfig by remember { mutableStateOf<WalletAlertState?>(value = null) }
|
||||
|
||||
val config = alertConfig
|
||||
if (config != null) {
|
||||
WalletAlert(state = config, onDismiss = { alertConfig = null })
|
||||
}
|
||||
|
||||
WalletContent(
|
||||
state = state,
|
||||
walletsListState = walletsListState,
|
||||
|
|
@ -114,7 +107,6 @@ internal fun WalletScreen(
|
|||
isAutoScroll = isAutoScroll,
|
||||
onAutoScrollReset = { isAutoScroll.value = false },
|
||||
bottomSheetContent = bottomSheetContent,
|
||||
alertConfig = alertConfig,
|
||||
bottomSheetHeaderHeightProvider = bottomSheetHeaderHeightProvider,
|
||||
onBottomSheetStateChange = onBottomSheetStateChange,
|
||||
)
|
||||
|
|
@ -124,7 +116,6 @@ internal fun WalletScreen(
|
|||
snackbarHostState = snackbarHostState,
|
||||
event = state.event,
|
||||
onAutoScrollSet = { isAutoScroll.value = true },
|
||||
onAlertConfigSet = { alertConfig = it },
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -135,7 +126,6 @@ private fun WalletContent(
|
|||
walletsListState: LazyListState,
|
||||
snackbarHostState: SnackbarHostState,
|
||||
isAutoScroll: State<Boolean>,
|
||||
alertConfig: WalletAlertState?,
|
||||
onAutoScrollReset: () -> Unit,
|
||||
bottomSheetHeaderHeightProvider: () -> Dp,
|
||||
onBottomSheetStateChange: (BottomSheetState) -> Unit,
|
||||
|
|
@ -279,7 +269,6 @@ private fun WalletContent(
|
|||
selectedWallet = selectedWallet,
|
||||
snackbarHostState = snackbarHostState,
|
||||
bottomSheetHeaderHeightProvider = bottomSheetHeaderHeightProvider,
|
||||
alertConfig = alertConfig,
|
||||
onBottomSheetStateChange = onBottomSheetStateChange,
|
||||
bottomSheetContent = bottomSheetContent,
|
||||
content = scaffoldContent,
|
||||
|
|
@ -294,7 +283,6 @@ private inline fun BaseScaffoldWithMarkets(
|
|||
listState: LazyListState,
|
||||
selectedWallet: WalletState,
|
||||
snackbarHostState: SnackbarHostState,
|
||||
alertConfig: WalletAlertState?,
|
||||
bottomSheetHeaderHeightProvider: () -> Dp,
|
||||
noinline onBottomSheetStateChange: (BottomSheetState) -> Unit,
|
||||
crossinline bottomSheetContent: @Composable () -> Unit,
|
||||
|
|
@ -341,7 +329,6 @@ private inline fun BaseScaffoldWithMarkets(
|
|||
|
||||
BottomSheetStateEffects(
|
||||
bottomSheetState = bottomSheetState,
|
||||
alertConfig = alertConfig,
|
||||
onBottomSheetStateChange = onBottomSheetStateChange,
|
||||
navigationBarVisible = isNavBarVisible,
|
||||
isSearchFieldFocused = isSearchFieldFocused,
|
||||
|
|
@ -615,7 +602,6 @@ private fun BottomSheetScrim(color: Color, visible: Boolean, onDismissRequest: (
|
|||
@Composable
|
||||
private fun BottomSheetStateEffects(
|
||||
bottomSheetState: TangemSheetState,
|
||||
alertConfig: WalletAlertState?,
|
||||
navigationBarVisible: MutableState<Boolean>,
|
||||
onBottomSheetStateChange: (BottomSheetState) -> Unit,
|
||||
isSearchFieldFocused: Boolean,
|
||||
|
|
@ -634,7 +620,7 @@ private fun BottomSheetStateEffects(
|
|||
val isKeyboardVisible by rememberIsKeyboardVisible()
|
||||
|
||||
LaunchedEffect(isKeyboardVisible) {
|
||||
if (isKeyboardVisible && alertConfig == null && isSearchFieldFocused) {
|
||||
if (isKeyboardVisible && isSearchFieldFocused) {
|
||||
bottomSheetState.expand()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,47 +0,0 @@
|
|||
package com.tangem.feature.wallet.presentation.wallet.ui.utils
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import com.google.android.gms.tasks.Task
|
||||
import com.google.android.play.core.review.ReviewInfo
|
||||
import com.google.android.play.core.review.ReviewManager
|
||||
import com.google.android.play.core.review.ReviewManagerFactory
|
||||
import com.tangem.core.ui.utils.findActivity
|
||||
import timber.log.Timber
|
||||
|
||||
internal object ReviewManagerRequester {
|
||||
|
||||
fun request(context: Context, onDismissClick: () -> Unit) {
|
||||
val reviewManager = ReviewManagerFactory.create(context)
|
||||
val requestTask = reviewManager.requestReviewFlow()
|
||||
|
||||
requestTask
|
||||
.addOnCompleteListener {
|
||||
handleOnCompleteRequestTask(
|
||||
reviewManager = reviewManager,
|
||||
activity = context.findActivity(),
|
||||
task = it,
|
||||
onDismissClick = onDismissClick,
|
||||
)
|
||||
}
|
||||
.addOnFailureListener(Timber::e)
|
||||
}
|
||||
|
||||
private fun handleOnCompleteRequestTask(
|
||||
reviewManager: ReviewManager,
|
||||
activity: Activity,
|
||||
task: Task<ReviewInfo>,
|
||||
onDismissClick: () -> Unit,
|
||||
) {
|
||||
if (task.isSuccessful) {
|
||||
val reviewFlow = reviewManager.launchReviewFlow(activity, task.result)
|
||||
reviewFlow
|
||||
.addOnCompleteListener { resultReviewTask ->
|
||||
if (!resultReviewTask.isSuccessful) onDismissClick()
|
||||
}
|
||||
.addOnFailureListener(Timber::e)
|
||||
} else {
|
||||
Timber.e(task.exception)
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue