Updated on 2026-08-14
This commit is contained in:
commit
d994b7840a
150 changed files with 971 additions and 4621 deletions
|
|
@ -21,9 +21,7 @@ internal class PreviewDetailsComponent : DetailsComponent {
|
|||
ItemsBuilder(
|
||||
router = DummyRouter(),
|
||||
hotWalletFeatureToggles = object : HotWalletFeatureToggles {
|
||||
override val isHotWalletEnabled: Boolean = true
|
||||
override val isWalletCreationRestrictionEnabled: Boolean = true
|
||||
override val isHotWalletVisible: Boolean = true
|
||||
},
|
||||
).buildAll(
|
||||
isWalletConnectAvailable = true,
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ package com.tangem.features.details.model
|
|||
import android.content.res.Resources
|
||||
import arrow.core.getOrElse
|
||||
import com.tangem.common.routing.AppRoute
|
||||
import com.tangem.core.analytics.AppInstanceIdProvider
|
||||
import com.tangem.core.analytics.api.AnalyticsEventHandler
|
||||
import com.tangem.core.analytics.models.AnalyticsParam
|
||||
import com.tangem.core.analytics.models.Basic
|
||||
|
|
@ -34,7 +33,6 @@ import com.tangem.features.details.entity.DetailsUM
|
|||
import com.tangem.features.details.entity.SelectEmailFeedbackTypeBS
|
||||
import com.tangem.features.details.utils.ItemsBuilder
|
||||
import com.tangem.features.details.utils.SocialsBuilder
|
||||
import com.tangem.features.hotwallet.HotWalletFeatureToggles
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import com.tangem.utils.version.AppVersionProvider
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
|
|
@ -59,7 +57,6 @@ internal class DetailsModel @Inject constructor(
|
|||
private val checkIsWalletConnectAvailableUseCase: CheckIsWalletConnectAvailableUseCase,
|
||||
private val router: Router,
|
||||
private val urlOpener: UrlOpener,
|
||||
private val appInstanceIdProvider: AppInstanceIdProvider,
|
||||
private val getSelectedWalletSyncUseCase: GetSelectedWalletSyncUseCase,
|
||||
private val appStateHolder: ReduxStateHolder,
|
||||
private val getWalletMetaInfoUseCase: GetWalletMetaInfoUseCase,
|
||||
|
|
@ -67,7 +64,6 @@ internal class DetailsModel @Inject constructor(
|
|||
private val getWalletsUseCase: GetWalletsUseCase,
|
||||
override val dispatchers: CoroutineDispatcherProvider,
|
||||
private val generateBuyTangemCardLinkUseCase: GenerateBuyTangemCardLinkUseCase,
|
||||
private val hotWalletFeatureToggles: HotWalletFeatureToggles,
|
||||
private val analyticsEventHandler: AnalyticsEventHandler,
|
||||
private val tangemPayEligibilityManager: TangemPayEligibilityManager,
|
||||
) : Model() {
|
||||
|
|
@ -229,14 +225,10 @@ internal class DetailsModel @Inject constructor(
|
|||
|
||||
private fun onBuyClick() {
|
||||
modelScope.launch {
|
||||
if (hotWalletFeatureToggles.isHotWalletEnabled) {
|
||||
analyticsEventHandler.send(Basic.ButtonBuy(source = AnalyticsParam.ScreensSources.Settings))
|
||||
generateBuyTangemCardLinkUseCase
|
||||
.invoke(GenerateBuyTangemCardLinkUseCase.Source.Settings).let { urlOpener.openUrl(it) }
|
||||
} else {
|
||||
// This is incorrect implementation of buy link generation, but it is left here
|
||||
urlOpener.openUrl(buildBuyLink())
|
||||
}
|
||||
analyticsEventHandler.send(Basic.ButtonBuy(source = AnalyticsParam.ScreensSources.Settings))
|
||||
|
||||
val url = generateBuyTangemCardLinkUseCase(GenerateBuyTangemCardLinkUseCase.Source.Settings)
|
||||
urlOpener.openUrl(url)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -270,12 +262,6 @@ internal class DetailsModel @Inject constructor(
|
|||
|
||||
private fun getAppVersion(): String = "${appVersionProvider.versionName} (${appVersionProvider.versionCode})"
|
||||
|
||||
private suspend fun buildBuyLink(): String {
|
||||
return appInstanceIdProvider.getAppInstanceId()?.let {
|
||||
"$BUY_TANGEM_URL&app_instance_id=$it"
|
||||
} ?: BUY_TANGEM_URL
|
||||
}
|
||||
|
||||
private companion object {
|
||||
val SYSTEM_LANGUAGE = runCatching { Resources.getSystem().configuration.locales[0].language }.getOrElse { "" }
|
||||
val APP_LANGUAGE = Locale.getDefault().language
|
||||
|
|
@ -283,7 +269,5 @@ internal class DetailsModel @Inject constructor(
|
|||
"&utm_medium=app" +
|
||||
"&utm_campaign=users-$SYSTEM_LANGUAGE" +
|
||||
"&utm_content=devicelang-$APP_LANGUAGE"
|
||||
|
||||
val BUY_TANGEM_URL = "https://buy.tangem.com/?$UTM_MARKS"
|
||||
}
|
||||
}
|
||||
|
|
@ -13,7 +13,6 @@ import com.tangem.core.decompose.ui.UiMessageSender
|
|||
import com.tangem.core.ui.extensions.TextReference
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.wallets.usecase.ShouldSaveUserWalletsUseCase
|
||||
import com.tangem.domain.wallets.usecase.UnlockWalletUseCase
|
||||
import com.tangem.features.details.entity.UserWalletListUM
|
||||
import com.tangem.features.details.impl.R
|
||||
|
|
@ -32,7 +31,6 @@ import javax.inject.Inject
|
|||
@ModelScoped
|
||||
internal class UserWalletListModel @Inject constructor(
|
||||
userWalletsFetcherFactory: UserWalletsFetcher.Factory,
|
||||
shouldSaveUserWalletsUseCase: ShouldSaveUserWalletsUseCase,
|
||||
private val router: Router,
|
||||
private val messageSender: UiMessageSender,
|
||||
override val dispatchers: CoroutineDispatcherProvider,
|
||||
|
|
@ -47,7 +45,7 @@ internal class UserWalletListModel @Inject constructor(
|
|||
messageSender = messageSender,
|
||||
onlyMultiCurrency = false,
|
||||
isAuthMode = false,
|
||||
isClickableIfLocked = hotWalletFeatureToggles.isHotWalletEnabled,
|
||||
isClickableIfLocked = true,
|
||||
onWalletClick = ::onWalletClicked,
|
||||
)
|
||||
|
||||
|
|
@ -67,67 +65,48 @@ internal class UserWalletListModel @Inject constructor(
|
|||
|
||||
combine(
|
||||
flow = userWalletsFlow,
|
||||
flow2 = shouldSaveUserWalletsUseCase(),
|
||||
flow3 = isWalletSavingInProgress,
|
||||
) { userWallets, shouldSaveUserWallets, isWalletSavingInProgress ->
|
||||
updateState(userWallets, shouldSaveUserWallets, isWalletSavingInProgress)
|
||||
flow2 = isWalletSavingInProgress,
|
||||
) { userWallets, isWalletSavingInProgress ->
|
||||
updateState(userWallets, isWalletSavingInProgress)
|
||||
}.collect()
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateState(
|
||||
userWallets: ImmutableList<UserWalletItemUM>,
|
||||
shouldSaveUserWallets: Boolean,
|
||||
isWalletSavingInProgress: Boolean,
|
||||
) = state.update { value ->
|
||||
value.copy(
|
||||
userWallets = userWallets,
|
||||
isWalletSavingInProgress = isWalletSavingInProgress,
|
||||
addNewWalletText = when {
|
||||
shouldSaveUserWallets || hotWalletFeatureToggles.isHotWalletEnabled -> {
|
||||
resourceReference(R.string.user_wallet_list_add_button)
|
||||
}
|
||||
else -> resourceReference(R.string.scan_card_settings_button)
|
||||
},
|
||||
)
|
||||
}
|
||||
private fun updateState(userWallets: ImmutableList<UserWalletItemUM>, isWalletSavingInProgress: Boolean) =
|
||||
state.update { value ->
|
||||
value.copy(
|
||||
userWallets = userWallets,
|
||||
isWalletSavingInProgress = isWalletSavingInProgress,
|
||||
addNewWalletText = resourceReference(R.string.user_wallet_list_add_button),
|
||||
)
|
||||
}
|
||||
|
||||
private fun onAddNewWalletClick() {
|
||||
if (hotWalletFeatureToggles.isHotWalletEnabled) {
|
||||
analyticsEventHandler.send(SignIn.ButtonAddWallet(AnalyticsParam.ScreensSources.Settings))
|
||||
analyticsEventHandler.send(SignIn.ButtonAddWallet(AnalyticsParam.ScreensSources.Settings))
|
||||
|
||||
if (hotWalletFeatureToggles.isWalletCreationRestrictionEnabled) {
|
||||
withProgress(isWalletSavingInProgress) {
|
||||
userWalletSaver.scanAndSaveUserWallet(modelScope)
|
||||
}
|
||||
} else {
|
||||
router.push(AppRoute.CreateWalletSelection)
|
||||
}
|
||||
} else {
|
||||
if (hotWalletFeatureToggles.isWalletCreationRestrictionEnabled) {
|
||||
withProgress(isWalletSavingInProgress) {
|
||||
userWalletSaver.scanAndSaveUserWallet(modelScope)
|
||||
}
|
||||
} else {
|
||||
router.push(AppRoute.CreateWalletSelection)
|
||||
}
|
||||
}
|
||||
|
||||
private fun onWalletClicked(userWalletId: UserWalletId) {
|
||||
if (hotWalletFeatureToggles.isHotWalletEnabled) {
|
||||
modelScope.launch {
|
||||
unlockWalletUseCase(userWalletId)
|
||||
.onRight { router.push(AppRoute.WalletSettings(userWalletId)) }
|
||||
.onLeft { error ->
|
||||
Timber.e("Failed to unlock wallet $userWalletId: $error")
|
||||
error.handle(
|
||||
onUserCancelled = {},
|
||||
isFromUnlockAll = false,
|
||||
onAlreadyUnlocked = { router.push(AppRoute.WalletSettings(userWalletId)) },
|
||||
analyticsEventHandler = analyticsEventHandler,
|
||||
showMessage = messageSender::send,
|
||||
)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
router.push(AppRoute.WalletSettings(userWalletId))
|
||||
modelScope.launch {
|
||||
unlockWalletUseCase(userWalletId)
|
||||
.onRight { router.push(AppRoute.WalletSettings(userWalletId)) }
|
||||
.onLeft { error ->
|
||||
Timber.e("Failed to unlock wallet $userWalletId: $error")
|
||||
error.handle(
|
||||
onUserCancelled = {},
|
||||
isFromUnlockAll = false,
|
||||
onAlreadyUnlocked = { router.push(AppRoute.WalletSettings(userWalletId)) },
|
||||
analyticsEventHandler = analyticsEventHandler,
|
||||
showMessage = messageSender::send,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -24,7 +24,6 @@ import com.tangem.domain.models.wallet.UserWallet
|
|||
import com.tangem.domain.redux.ReduxStateHolder
|
||||
import com.tangem.domain.wallets.builder.ColdUserWalletBuilder
|
||||
import com.tangem.domain.wallets.usecase.SaveWalletUseCase
|
||||
import com.tangem.domain.wallets.usecase.ShouldSaveUserWalletsSyncUseCase
|
||||
import com.tangem.features.details.impl.R
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.launch
|
||||
|
|
@ -38,7 +37,6 @@ internal class UserWalletSaver @Inject constructor(
|
|||
private val scanCardProcessor: ScanCardProcessor,
|
||||
private val saveWalletUseCase: SaveWalletUseCase,
|
||||
private val coldUserWalletBuilderFactory: ColdUserWalletBuilder.Factory,
|
||||
private val shouldSaveUserWalletsSyncUseCase: ShouldSaveUserWalletsSyncUseCase,
|
||||
private val reduxStateHolder: ReduxStateHolder,
|
||||
private val messageSender: UiMessageSender,
|
||||
private val router: Router,
|
||||
|
|
@ -84,11 +82,7 @@ internal class UserWalletSaver @Inject constructor(
|
|||
recover = { error ->
|
||||
when (error) {
|
||||
is SaveWalletError.WalletAlreadySaved -> {
|
||||
if (shouldSaveUserWalletsSyncUseCase()) {
|
||||
selectUserWallet()
|
||||
} else {
|
||||
router.popTo<AppRoute.Wallet>()
|
||||
}
|
||||
selectUserWallet()
|
||||
}
|
||||
is SaveWalletError.DataError -> {
|
||||
val messageRef = ensureNotNull(error.messageId?.let(::resourceReference)) {
|
||||
|
|
@ -116,7 +110,7 @@ internal class UserWalletSaver @Inject constructor(
|
|||
)
|
||||
}
|
||||
|
||||
private suspend fun Raise<Error>.createUserWallet(response: ScanResponse): UserWallet {
|
||||
private fun Raise<Error>.createUserWallet(response: ScanResponse): UserWallet {
|
||||
val userWallet = coldUserWalletBuilderFactory.create(scanResponse = response).build()
|
||||
|
||||
return ensureNotNull(userWallet) { Error.Unknown }
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue