Updated on 2026-08-14

This commit is contained in:
Tangem 2024-08-26 13:14:53 +03:00
commit 43c376489a
316 changed files with 7586 additions and 3131 deletions

View file

@ -10,7 +10,7 @@ import com.tangem.core.navigation.url.UrlOpener
import com.tangem.datasource.asset.loader.AssetLoader
import com.tangem.datasource.config.ConfigManager
import com.tangem.datasource.connection.NetworkConnectionManager
import com.tangem.datasource.local.token.UserTokensStore
import com.tangem.datasource.local.preferences.AppPreferencesStore
import com.tangem.domain.appcurrency.repository.AppCurrencyRepository
import com.tangem.domain.apptheme.GetAppThemeModeUseCase
import com.tangem.domain.apptheme.repository.AppThemeModeRepository
@ -76,7 +76,7 @@ interface ApplicationEntryPoint {
fun getBalanceHidingRepository(): BalanceHidingRepository
fun getUserTokensStore(): UserTokensStore
fun getAppPreferencesStore(): AppPreferencesStore
fun getGetAppThemeModeUseCase(): GetAppThemeModeUseCase

View file

@ -22,7 +22,7 @@ import com.tangem.datasource.config.ConfigManager
import com.tangem.datasource.config.FeaturesLocalLoader
import com.tangem.datasource.config.models.Config
import com.tangem.datasource.connection.NetworkConnectionManager
import com.tangem.datasource.local.token.UserTokensStore
import com.tangem.datasource.local.preferences.AppPreferencesStore
import com.tangem.domain.appcurrency.repository.AppCurrencyRepository
import com.tangem.domain.apptheme.GetAppThemeModeUseCase
import com.tangem.domain.apptheme.repository.AppThemeModeRepository
@ -126,8 +126,8 @@ abstract class TangemApplication : Application(), ImageLoaderFactory {
private val balanceHidingRepository: BalanceHidingRepository
get() = entryPoint.getBalanceHidingRepository()
private val userTokensStore: UserTokensStore
get() = entryPoint.getUserTokensStore()
private val appPreferencesStore: AppPreferencesStore
get() = entryPoint.getAppPreferencesStore()
val getAppThemeModeUseCase: GetAppThemeModeUseCase
get() = entryPoint.getGetAppThemeModeUseCase()
@ -228,7 +228,7 @@ abstract class TangemApplication : Application(), ImageLoaderFactory {
}
derivationsFinder = DerivationsFinder(
newTokensStore = userTokensStore,
appPreferencesStore = appPreferencesStore,
dispatchers = AppCoroutineDispatcherProvider(),
)
appStateHolder.mainStore = store

View file

@ -1,10 +1,8 @@
package com.tangem.tap.di.domain
import com.tangem.domain.markets.GetMarketsTokenListFlowUseCase
import com.tangem.domain.markets.GetTokenMarketInfoUseCase
import com.tangem.domain.markets.GetTokenPriceChartUseCase
import com.tangem.domain.markets.GetTokenQuotesUseCase
import com.tangem.domain.markets.*
import com.tangem.domain.markets.repositories.MarketsTokenRepository
import com.tangem.domain.tokens.repository.QuotesRepository
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
@ -37,7 +35,13 @@ object MarketsDomainModule {
@Provides
@Singleton
fun provideGetTokenQuotesUseCase(marketsTokenRepository: MarketsTokenRepository): GetTokenQuotesUseCase {
return GetTokenQuotesUseCase(marketsTokenRepository = marketsTokenRepository)
fun provideTokenFullQuotesUseCase(marketsTokenRepository: MarketsTokenRepository): GetTokenFullQuotesUseCase {
return GetTokenFullQuotesUseCase(marketsTokenRepository = marketsTokenRepository)
}
@Provides
@Singleton
fun provideGetTokenQuotesUseCase(quotesRepository: QuotesRepository): GetTokenQuotesUseCase {
return GetTokenQuotesUseCase(quotesRepository = quotesRepository)
}
}

View file

@ -145,18 +145,6 @@ internal object StakingDomainModule {
)
}
@Provides
@Singleton
fun provideIsStakeMoreAvailableUseCase(
stakingRepository: StakingRepository,
stakingErrorResolver: StakingErrorResolver,
): IsStakeMoreAvailableUseCase {
return IsStakeMoreAvailableUseCase(
stakingRepository = stakingRepository,
stakingErrorResolver = stakingErrorResolver,
)
}
@Provides
@Singleton
fun provideIsApproveNeededUseCase(

View file

@ -158,8 +158,9 @@ internal object TokensDomainModule {
currenciesRepository: CurrenciesRepository,
quotesRepository: QuotesRepository,
networksRepository: NetworksRepository,
stakingRepository: StakingRepository,
): FetchCurrencyStatusUseCase {
return FetchCurrencyStatusUseCase(currenciesRepository, networksRepository, quotesRepository)
return FetchCurrencyStatusUseCase(currenciesRepository, networksRepository, quotesRepository, stakingRepository)
}
@Provides

View file

@ -5,7 +5,10 @@ import com.tangem.blockchain.common.Blockchain
import com.tangem.blockchain.common.derivation.DerivationStyle
import com.tangem.blockchainsdk.utils.fromNetworkId
import com.tangem.crypto.hdWallet.DerivationPath
import com.tangem.datasource.local.token.UserTokensStore
import com.tangem.datasource.api.tangemTech.models.UserTokensResponse
import com.tangem.datasource.local.preferences.AppPreferencesStore
import com.tangem.datasource.local.preferences.PreferencesKeys
import com.tangem.datasource.local.preferences.utils.getObjectSyncOrNull
import com.tangem.domain.common.DerivationStyleProvider
import com.tangem.domain.common.TapWorkarounds.useOldStyleDerivation
import com.tangem.domain.models.scan.CardDTO
@ -22,7 +25,7 @@ internal data class BlockchainToDerive(
// FIXME: May be move to DI, currently unnecessary
internal class DerivationsFinder(
private val newTokensStore: UserTokensStore,
private val appPreferencesStore: AppPreferencesStore,
private val dispatchers: CoroutineDispatcherProvider,
) {
@ -64,7 +67,9 @@ internal class DerivationsFinder(
}
private suspend fun getBlockchains(userWalletId: UserWalletId): MutableSet<BlockchainToDerive> {
val responseTokens = newTokensStore.getSyncOrNull(userWalletId)
val responseTokens = appPreferencesStore.getObjectSyncOrNull<UserTokensResponse>(
key = PreferencesKeys.getUserTokensKey(userWalletId.stringValue),
)
?.tokens
?: return hashSetOf()

View file

@ -7,7 +7,7 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider
import com.tangem.core.ui.components.BasicDialog
import com.tangem.core.ui.components.DialogButton
import com.tangem.core.ui.components.DialogButtonUM
import com.tangem.core.ui.extensions.resolveReference
import com.tangem.core.ui.res.TangemThemePreview
import com.tangem.tap.features.details.ui.appsettings.AppSettingsDialogsFactory
@ -20,12 +20,12 @@ internal fun SettingsAlertDialog(dialog: Dialog.Alert) {
title = dialog.title.resolveReference(),
message = dialog.description.resolveReference(),
isDismissable = false,
confirmButton = DialogButton(
confirmButton = DialogButtonUM(
title = dialog.confirmText.resolveReference(),
warning = true,
onClick = dialog.onConfirm,
),
dismissButton = DialogButton(
dismissButton = DialogButtonUM(
title = stringResource(id = R.string.common_cancel),
onClick = dialog.onDismiss,
),

View file

@ -6,7 +6,7 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider
import com.tangem.core.ui.components.DialogButton
import com.tangem.core.ui.components.DialogButtonUM
import com.tangem.core.ui.components.SelectorDialog
import com.tangem.core.ui.extensions.resolveReference
import com.tangem.core.ui.res.TangemThemePreview
@ -21,7 +21,7 @@ internal fun SettingsSelectorDialog(dialog: Dialog.Selector) {
title = dialog.title.resolveReference(),
selectedItemIndex = dialog.selectedItemIndex,
items = dialog.items.map { it.resolveReference() }.toImmutableList(),
confirmButton = DialogButton(
confirmButton = DialogButtonUM(
title = stringResource(R.string.common_cancel),
onClick = dialog.onDismiss,
),

View file

@ -13,6 +13,7 @@ import com.tangem.core.analytics.Analytics
import com.tangem.domain.card.ScanCardProcessor
import com.tangem.domain.common.CardTypesResolver
import com.tangem.domain.common.util.cardTypesResolver
import com.tangem.domain.common.util.getBackupCardsCount
import com.tangem.domain.models.scan.CardDTO
import com.tangem.domain.models.scan.ScanResponse
import com.tangem.domain.wallets.builder.UserWalletIdBuilder
@ -173,13 +174,7 @@ internal class CardSettingsViewModel @Inject constructor(
userWalletId = userWalletId,
cardId = card.cardId,
isActiveBackupStatus = card.backupStatus?.isActive == true,
backupCardsCount = when (val status = card.backupStatus) {
is CardDTO.BackupStatus.Active -> status.cardCount
is CardDTO.BackupStatus.CardLinked,
CardDTO.BackupStatus.NoBackup,
null,
-> 0
},
backupCardsCount = scanResponse.getBackupCardsCount() ?: 0,
),
)
}

View file

@ -190,11 +190,11 @@ private fun CommonResetDialog(dialog: ResetCardScreenState.Dialog) {
BasicDialog(
title = stringResource(dialog.titleResId),
message = stringResource(dialog.messageResId),
dismissButton = DialogButton(
dismissButton = DialogButtonUM(
title = stringResource(id = R.string.common_cancel),
onClick = dialog.onDismiss,
),
confirmButton = DialogButton(
confirmButton = DialogButtonUM(
title = stringResource(id = R.string.card_settings_action_sheet_reset),
warning = true,
onClick = dialog.onConfirmClick,
@ -208,7 +208,7 @@ private fun CompletedResetDialog(dialog: ResetCardDialog) {
BasicDialog(
title = stringResource(id = dialog.titleResId),
message = stringResource(id = dialog.messageResId),
confirmButton = DialogButton(
confirmButton = DialogButtonUM(
title = stringResource(id = R.string.common_ok),
onClick = dialog.onConfirmClick,
),

View file

@ -98,7 +98,7 @@ internal class HomeFragment : ComposeFragment(), StoreSubscriber<HomeState> {
viewModel.onSearchClick()
} else {
Analytics.send(IntroductionProcess.ButtonTokensList())
store.dispatchNavigationAction { push(AppRoute.ManageTokens(readOnlyContent = true)) }
store.dispatchNavigationAction { push(AppRoute.ManageTokens()) }
store.dispatch(TokensAction.SetArgs.ReadAccess)
}
},

View file

@ -61,7 +61,7 @@ internal class HomeViewModel @Inject constructor(
analyticsEventHandler.send(IntroductionProcess.ButtonTokensList())
store.dispatch(TokensAction.SetArgs.ReadAccess)
store.dispatchNavigationAction { push(AppRoute.ManageTokens(readOnlyContent = true)) }
store.dispatchNavigationAction { push(AppRoute.ManageTokens()) }
}
private fun scanCard() {

View file

@ -9,9 +9,9 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import com.tangem.core.ui.R
import com.tangem.core.ui.components.BasicDialog
import com.tangem.core.ui.components.DialogButton
import com.tangem.core.ui.res.TangemThemePreview
import com.tangem.core.ui.components.DialogButtonUM
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreview
import com.tangem.tap.features.saveWallet.ui.models.EnrollBiometricsDialog
@Composable
@ -19,11 +19,11 @@ fun EnrollBiometricsDialogContent(dialog: EnrollBiometricsDialog) {
BasicDialog(
title = stringResource(R.string.save_user_wallet_agreement_enroll_biometrics_title),
message = stringResource(R.string.save_user_wallet_agreement_enroll_biometrics_description),
confirmButton = DialogButton(
confirmButton = DialogButtonUM(
title = stringResource(R.string.common_enable),
onClick = dialog.onEnroll,
),
dismissButton = DialogButton(
dismissButton = DialogButtonUM(
onClick = dialog.onCancel,
),
onDismissDialog = dialog.onCancel,

View file

@ -7,7 +7,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import com.tangem.core.ui.components.BasicDialog
import com.tangem.core.ui.components.DialogButton
import com.tangem.core.ui.components.DialogButtonUM
import com.tangem.core.ui.res.TangemThemePreview
import com.tangem.tap.features.welcome.ui.model.WarningModel
import com.tangem.wallet.R
@ -27,7 +27,7 @@ internal fun WarningDialog(warning: WarningModel?) {
},
),
onDismissDialog = warning.onDismiss,
confirmButton = DialogButton(
confirmButton = DialogButtonUM(
title = stringResource(id = R.string.common_ok),
onClick = warning.onDismiss,
),
@ -38,7 +38,7 @@ internal fun WarningDialog(warning: WarningModel?) {
title = stringResource(id = R.string.common_attention),
message = stringResource(id = R.string.key_invalidated_warning_description),
onDismissDialog = warning.onDismiss,
confirmButton = DialogButton(
confirmButton = DialogButtonUM(
title = stringResource(id = R.string.common_ok),
onClick = warning.onDismiss,
),
@ -50,7 +50,7 @@ internal fun WarningDialog(warning: WarningModel?) {
message = stringResource(id = R.string.biometric_unavailable_warning),
onDismissDialog = warning.onDismiss,
isDismissable = false,
confirmButton = DialogButton(
confirmButton = DialogButtonUM(
title = stringResource(id = R.string.common_ok),
onClick = warning.onDismiss,
),

View file

@ -11,6 +11,7 @@ import com.tangem.features.details.component.DetailsComponent
import com.tangem.features.disclaimer.api.components.DisclaimerComponent
import com.tangem.features.managetokens.ManageTokensToggles
import com.tangem.features.managetokens.component.ManageTokensComponent
import com.tangem.features.markets.details.MarketsTokenDetailsComponent
import com.tangem.features.pushnotifications.api.featuretoggles.PushNotificationsFeatureToggles
import com.tangem.features.pushnotifications.api.navigation.PushNotificationsRouter
import com.tangem.features.send.api.navigation.SendRouter
@ -50,6 +51,7 @@ internal class ChildFactory @Inject constructor(
private val walletSettingsComponentFactory: WalletSettingsComponent.Factory,
private val disclaimerComponentFactory: DisclaimerComponent.Factory,
private val manageTokensComponentFactory: ManageTokensComponent.Factory,
private val marketsTokenDetailsComponentFactory: MarketsTokenDetailsComponent.Factory,
private val sendRouter: SendRouter,
private val tokenDetailsRouter: TokenDetailsRouter,
private val walletRouter: WalletRouter,
@ -126,13 +128,7 @@ internal class ChildFactory @Inject constructor(
if (manageTokensToggles.isFeatureEnabled) {
route.asComponentChild(
contextProvider = contextProvider(route, contextFactory),
params = ManageTokensComponent.Params(
mode = if (route.readOnlyContent) {
ManageTokensComponent.Mode.READ_ONLY
} else {
ManageTokensComponent.Mode.MANAGE
},
),
params = ManageTokensComponent.Params(route.userWalletId),
componentFactory = manageTokensComponentFactory,
)
} else {
@ -191,6 +187,16 @@ internal class ChildFactory @Inject constructor(
componentFactory = walletSettingsComponentFactory,
)
}
is AppRoute.MarketsTokenDetails -> {
route.asComponentChild(
contextProvider = contextProvider(route, contextFactory),
params = MarketsTokenDetailsComponent.Params(
token = route.token,
appCurrency = route.appCurrency,
),
componentFactory = marketsTokenDetailsComponentFactory,
)
}
}
}