diff --git a/app/src/main/ic_fp-web.png b/app/src/main/ic_fp-web.png deleted file mode 100644 index 85a16951a6..0000000000 Binary files a/app/src/main/ic_fp-web.png and /dev/null differ diff --git a/app/src/main/ic_launcher-playstore.png b/app/src/main/ic_launcher-playstore.png index 8e9c7d9162..5e8563dc00 100644 Binary files a/app/src/main/ic_launcher-playstore.png and b/app/src/main/ic_launcher-playstore.png differ diff --git a/app/src/main/ic_launcher-web.png b/app/src/main/ic_launcher-web.png deleted file mode 100644 index 11e69a8089..0000000000 Binary files a/app/src/main/ic_launcher-web.png and /dev/null differ diff --git a/app/src/main/ic_launcher_2-web.png b/app/src/main/ic_launcher_2-web.png deleted file mode 100644 index 8639ebe991..0000000000 Binary files a/app/src/main/ic_launcher_2-web.png and /dev/null differ diff --git a/app/src/main/ic_launcher_round-web.png b/app/src/main/ic_launcher_round-web.png deleted file mode 100644 index 026a409e86..0000000000 Binary files a/app/src/main/ic_launcher_round-web.png and /dev/null differ diff --git a/app/src/main/ic_logo_small-web.png b/app/src/main/ic_logo_small-web.png deleted file mode 100644 index 76a713ee01..0000000000 Binary files a/app/src/main/ic_logo_small-web.png and /dev/null differ diff --git a/app/src/main/java/com/tangem/tap/MainActivity.kt b/app/src/main/java/com/tangem/tap/MainActivity.kt index 06ca8efa85..52e9ff1262 100644 --- a/app/src/main/java/com/tangem/tap/MainActivity.kt +++ b/app/src/main/java/com/tangem/tap/MainActivity.kt @@ -187,13 +187,18 @@ class MainActivity : AppCompatActivity(), SnackbarHandler, ActivityResultCallbac override fun onDestroy() { store.dispatch(NavigationAction.ActivityDestroyed(WeakReference(this))) intentProcessor.removeAll() - cardSdkLifecycleObserver.onDestroy() + cardSdkLifecycleObserver.onDestroy(this) super.onDestroy() } private fun initIntentHandlers() { val hasSavedWalletsProvider = { store.state.globalState.userWalletsListManager?.hasUserWallets == true } - intentProcessor.addHandler(BackgroundScanIntentHandler(hasSavedWalletsProvider)) + intentProcessor.addHandler( + BackgroundScanIntentHandler( + hasSavedWalletsProvider, + lifecycleScope, + ), + ) intentProcessor.addHandler(WalletConnectLinkIntentHandler()) intentProcessor.addHandler(BuyCurrencyIntentHandler()) intentProcessor.addHandler(SellCurrencyIntentHandler()) @@ -246,7 +251,7 @@ class MainActivity : AppCompatActivity(), SnackbarHandler, ActivityResultCallbac */ cardSdkLifecycleObserver.onCreate(context = this) - scope.launch { + lifecycleScope.launch { intentProcessor.handleIntent(intent) } } @@ -318,8 +323,11 @@ class MainActivity : AppCompatActivity(), SnackbarHandler, ActivityResultCallbac if (store.state.globalState.userWalletsListManager?.hasUserWallets == true) { store.dispatchOnMain(NavigationAction.NavigateTo(AppScreen.Welcome)) store.dispatchOnMain(WelcomeAction.SetInitialIntent(intentWhichStartedActivity)) - scope.launch { - val handler = BackgroundScanIntentHandler(hasSavedUserWalletsProvider = { true }) + lifecycleScope.launch { + val handler = BackgroundScanIntentHandler( + hasSavedUserWalletsProvider = { true }, + lifecycleCoroutineScope = lifecycleScope, + ) val isBackgroundScanHandled = handler.handleIntent(intentWhichStartedActivity) val hasNotIncompletedBackup = !backupService.hasIncompletedBackup if (!isBackgroundScanHandled && hasNotIncompletedBackup) { @@ -328,7 +336,7 @@ class MainActivity : AppCompatActivity(), SnackbarHandler, ActivityResultCallbac } } else { store.dispatchOnMain(NavigationAction.NavigateTo(AppScreen.Home)) - scope.launch { + lifecycleScope.launch { intentProcessor.handleIntent(intentWhichStartedActivity) } } diff --git a/app/src/main/java/com/tangem/tap/TapApplication.kt b/app/src/main/java/com/tangem/tap/TapApplication.kt index 99a413b1af..a051f8f5a4 100644 --- a/app/src/main/java/com/tangem/tap/TapApplication.kt +++ b/app/src/main/java/com/tangem/tap/TapApplication.kt @@ -29,7 +29,6 @@ import com.tangem.domain.common.LogConfig import com.tangem.domain.tokens.repository.CurrenciesRepository import com.tangem.domain.walletmanager.WalletManagersFacade import com.tangem.domain.wallets.legacy.WalletManagersRepository -import com.tangem.feature.learn2earn.domain.api.Learn2earnInteractor import com.tangem.features.tokendetails.featuretoggles.TokenDetailsFeatureToggles import com.tangem.features.wallet.featuretoggles.WalletFeatureToggles import com.tangem.tap.common.analytics.AnalyticsFactory @@ -153,8 +152,8 @@ class TapApplication : Application(), ImageLoaderFactory { @Inject lateinit var walletConnectSessionsRepository: WalletConnectSessionsRepository - @Inject - lateinit var learn2earnInteractor: Learn2earnInteractor + // @Inject + // lateinit var learn2earnInteractor: Learn2earnInteractor @Inject lateinit var tokenDetailsFeatureToggles: TokenDetailsFeatureToggles @@ -247,7 +246,7 @@ class TapApplication : Application(), ImageLoaderFactory { // [REDACTED_JIRA] runBlocking { featureTogglesManager.init() - learn2earnInteractor.init() + // learn2earnInteractor.init() } initTopUpController() diff --git a/app/src/main/java/com/tangem/tap/common/analytics/events/Onboarding.kt b/app/src/main/java/com/tangem/tap/common/analytics/events/Onboarding.kt index 9612f2b972..a9432ad404 100644 --- a/app/src/main/java/com/tangem/tap/common/analytics/events/Onboarding.kt +++ b/app/src/main/java/com/tangem/tap/common/analytics/events/Onboarding.kt @@ -45,6 +45,16 @@ sealed class Onboarding( event = "Backup Finished", params = mapOf("Cards count" to "$cardsCount"), ) + + object ResetCancelEvent : Backup( + event = "Reset Card Notification", + params = mapOf("Option" to "Cancel"), + ) + + object ResetPerformEvent : Backup( + event = "Reset Card Notification", + params = mapOf("Option" to "Reset"), + ) } sealed class Topup( diff --git a/app/src/main/java/com/tangem/tap/common/redux/global/GlobalReducer.kt b/app/src/main/java/com/tangem/tap/common/redux/global/GlobalReducer.kt index a380ee16b0..2b282844d5 100644 --- a/app/src/main/java/com/tangem/tap/common/redux/global/GlobalReducer.kt +++ b/app/src/main/java/com/tangem/tap/common/redux/global/GlobalReducer.kt @@ -2,10 +2,13 @@ package com.tangem.tap.common.redux.global import com.tangem.domain.redux.domainStore import com.tangem.domain.redux.global.DomainGlobalAction +import com.tangem.tap.common.extensions.dispatchOnMain import com.tangem.tap.common.redux.AppState +import com.tangem.tap.features.home.redux.HomeAction import com.tangem.tap.features.onboarding.OnboardingManager import com.tangem.tap.preferencesStorage import com.tangem.tap.proxy.AppStateHolder +import com.tangem.tap.store import com.tangem.utils.extensions.replaceBy import org.rekotlin.Action @@ -82,9 +85,12 @@ fun globalReducer(action: Action, state: AppState, appStateHolder: AppStateHolde } is GlobalAction.SetIfCardVerifiedOnline -> globalState.copy(cardVerifiedOnline = action.verified) - is GlobalAction.FetchUserCountry.Success -> globalState.copy( - userCountryCode = action.countryCode, - ) + is GlobalAction.FetchUserCountry.Success -> { + store.dispatchOnMain(HomeAction.UpdateCountryCode(action.countryCode)) + globalState.copy( + userCountryCode = action.countryCode, + ) + } is GlobalAction.UpdateUserWalletsListManager -> { appStateHolder.userWalletsListManager = action.manager globalState.copy( diff --git a/app/src/main/java/com/tangem/tap/domain/TangemSdkManager.kt b/app/src/main/java/com/tangem/tap/domain/TangemSdkManager.kt index 51e0adb686..6796da1e72 100644 --- a/app/src/main/java/com/tangem/tap/domain/TangemSdkManager.kt +++ b/app/src/main/java/com/tangem/tap/domain/TangemSdkManager.kt @@ -134,9 +134,12 @@ class TangemSdkManager(private val cardSdkConfigRepository: CardSdkConfigReposit return runTaskAsyncReturnOnMain(DeriveMultipleWalletPublicKeysTask(derivations), cardId) } - suspend fun resetToFactorySettings(cardId: String): CompletionResult { + suspend fun resetToFactorySettings( + cardId: String, + allowsRequestAccessCodeFromRepository: Boolean, + ): CompletionResult { return runTaskAsyncReturnOnMain( - runnable = ResetToFactorySettingsTask(), + runnable = ResetToFactorySettingsTask(allowsRequestAccessCodeFromRepository), cardId = cardId, initialMessage = Message(resources.getString(R.string.card_settings_reset_card_to_factory)), ) diff --git a/app/src/main/java/com/tangem/tap/domain/tasks/product/CreateProductWalletTask.kt b/app/src/main/java/com/tangem/tap/domain/tasks/product/CreateProductWalletTask.kt index 78d1ce464f..3c0467b1da 100644 --- a/app/src/main/java/com/tangem/tap/domain/tasks/product/CreateProductWalletTask.kt +++ b/app/src/main/java/com/tangem/tap/domain/tasks/product/CreateProductWalletTask.kt @@ -151,7 +151,9 @@ private class CreateWalletTangemWallet( ) { val config = CardConfig.createConfig(card) val walletsOnCard = card.wallets.map { it.curve }.toSet() - val curves = card.supportedCurves.intersect(config.mandatoryCurves.toSet()).subtract(walletsOnCard).toList() + val curves = config.mandatoryCurves.toSet() + .intersect(card.supportedCurves.toSet()) + .subtract(walletsOnCard).toList() if (curves.isEmpty()) { val createWalletResponses = card.wallets.map { wallet -> diff --git a/app/src/main/java/com/tangem/tap/domain/tasks/product/ResetToFactorySettingsTask.kt b/app/src/main/java/com/tangem/tap/domain/tasks/product/ResetToFactorySettingsTask.kt index a2622b218d..96b0593c4e 100644 --- a/app/src/main/java/com/tangem/tap/domain/tasks/product/ResetToFactorySettingsTask.kt +++ b/app/src/main/java/com/tangem/tap/domain/tasks/product/ResetToFactorySettingsTask.kt @@ -8,7 +8,9 @@ import com.tangem.common.extensions.guard import com.tangem.operations.backup.ResetBackupCommand import com.tangem.operations.wallet.PurgeWalletCommand -class ResetToFactorySettingsTask : CardSessionRunnable { +class ResetToFactorySettingsTask( + override val allowsRequestAccessCodeFromRepository: Boolean, +) : CardSessionRunnable { override fun run(session: CardSession, callback: (result: CompletionResult) -> Unit) { deleteWallets(session, callback) diff --git a/app/src/main/java/com/tangem/tap/domain/tasks/product/ScanProductTask.kt b/app/src/main/java/com/tangem/tap/domain/tasks/product/ScanProductTask.kt index 7008747005..31a7a1ade4 100644 --- a/app/src/main/java/com/tangem/tap/domain/tasks/product/ScanProductTask.kt +++ b/app/src/main/java/com/tangem/tap/domain/tasks/product/ScanProductTask.kt @@ -249,7 +249,10 @@ private class ScanWalletProcessor( derivationStyleProvider: DerivationStyleProvider, ): List { val userTokensRepository = userTokensRepository ?: return emptyList() - val blockchainsToDerive = userTokensRepository.loadBlockchainsToDerive(card) + val blockchainsToDerive = userTokensRepository.loadBlockchainsToDerive( + card, + derivationStyleProvider.getDerivationStyle(), + ) .toMutableList() .ifEmpty { getDefaultBlockchains(derivationStyleProvider) } diff --git a/app/src/main/java/com/tangem/tap/domain/tokens/UserTokensRepository.kt b/app/src/main/java/com/tangem/tap/domain/tokens/UserTokensRepository.kt index 1304588781..7026203db3 100644 --- a/app/src/main/java/com/tangem/tap/domain/tokens/UserTokensRepository.kt +++ b/app/src/main/java/com/tangem/tap/domain/tokens/UserTokensRepository.kt @@ -28,18 +28,23 @@ class UserTokensRepository( private val networkConnectionManager: NetworkConnectionManager, ) { - suspend fun getUserTokens(card: CardDTO): List = withContext(dispatchers.io) { - val userWalletId = getUserWalletId(card) ?: return@withContext emptyList() + suspend fun getUserTokens(card: CardDTO, derivationStyle: DerivationStyle?): List = + withContext(dispatchers.io) { + val userWalletId = getUserWalletId(card) ?: return@withContext emptyList() - if (DemoHelper.isDemoCardId(card.cardId)) { - return@withContext loadTokensOffline(userWalletId = userWalletId).ifEmpty(::loadDemoCurrencies) + if (DemoHelper.isDemoCardId(card.cardId)) { + return@withContext loadTokensOffline(userWalletId = userWalletId).ifEmpty { + loadDemoCurrencies( + derivationStyle, + ) + } + } + + if (!networkConnectionManager.isOnline) return@withContext loadTokensOffline(userWalletId = userWalletId) + + return@withContext remoteGetUserTokens(userWalletId = userWalletId) } - if (!networkConnectionManager.isOnline) return@withContext loadTokensOffline(userWalletId = userWalletId) - - return@withContext remoteGetUserTokens(userWalletId = userWalletId) - } - suspend fun saveUserTokens(card: CardDTO, tokens: List) = withContext(dispatchers.io) { val userWalletId = getUserWalletId(card) ?: return@withContext val userTokens = tokens.toUserTokensResponse() @@ -48,28 +53,29 @@ class UserTokensRepository( } // FIXME: Move to data layer - suspend fun loadBlockchainsToDerive(card: CardDTO): List = withContext(dispatchers.io) { - val userWalletId = getUserWalletId(card) ?: return@withContext emptyList() - val blockchainNetworks = loadTokensOffline(userWalletId = userWalletId).toBlockchainNetworks() + suspend fun loadBlockchainsToDerive(card: CardDTO, derivationStyle: DerivationStyle?): List = + withContext(dispatchers.io) { + val userWalletId = getUserWalletId(card) ?: return@withContext emptyList() + val blockchainNetworks = loadTokensOffline(userWalletId = userWalletId).toBlockchainNetworks() - if (DemoHelper.isDemoCardId(card.cardId)) { - return@withContext blockchainNetworks.ifEmpty(loadDemoCurrencies()::toBlockchainNetworks) + if (DemoHelper.isDemoCardId(card.cardId)) { + return@withContext blockchainNetworks.ifEmpty(loadDemoCurrencies(derivationStyle)::toBlockchainNetworks) + } + + return@withContext blockchainNetworks } - return@withContext blockchainNetworks - } - private fun loadTokensOffline(userWalletId: String): List { return storageService.getUserTokens(userWalletId = userWalletId) ?: emptyList() } // FIXME: Move to user wallet config - private fun loadDemoCurrencies(): List { + private fun loadDemoCurrencies(derivationStyle: DerivationStyle?): List { return DemoHelper.config.demoBlockchains .map { blockchain -> BlockchainNetwork( blockchain = blockchain, - derivationPath = blockchain.derivationPath(DerivationStyle.LEGACY)?.rawPath, + derivationPath = blockchain.derivationPath(derivationStyle)?.rawPath, tokens = emptyList(), ) } diff --git a/app/src/main/java/com/tangem/tap/domain/walletStores/implementation/DefaultWalletStoresManager.kt b/app/src/main/java/com/tangem/tap/domain/walletStores/implementation/DefaultWalletStoresManager.kt index f2af46b082..4e60254106 100644 --- a/app/src/main/java/com/tangem/tap/domain/walletStores/implementation/DefaultWalletStoresManager.kt +++ b/app/src/main/java/com/tangem/tap/domain/walletStores/implementation/DefaultWalletStoresManager.kt @@ -3,6 +3,7 @@ package com.tangem.tap.domain.walletStores.implementation import com.tangem.blockchain.common.WalletManager import com.tangem.blockchain.common.address.AddressType import com.tangem.common.* +import com.tangem.domain.common.util.derivationStyleProvider import com.tangem.domain.wallets.legacy.WalletManagersRepository import com.tangem.domain.wallets.models.UserWallet import com.tangem.domain.wallets.models.UserWalletId @@ -126,8 +127,9 @@ internal class DefaultWalletStoresManager( private suspend fun fetchMultiWallets(userWallet: UserWallet): CompletionResult { val scanResponse = userWallet.scanResponse + val derivationStyle = scanResponse.derivationStyleProvider.getDerivationStyle() val userTokens = withContext(Dispatchers.IO) { - userTokensRepository.getUserTokens(scanResponse.card) + userTokensRepository.getUserTokens(scanResponse.card, derivationStyle) } val userWalletId = userWallet.walletId diff --git a/app/src/main/java/com/tangem/tap/features/customtoken/impl/presentation/viewmodels/AddCustomTokenViewModel.kt b/app/src/main/java/com/tangem/tap/features/customtoken/impl/presentation/viewmodels/AddCustomTokenViewModel.kt index 831823009f..dffe1709dd 100644 --- a/app/src/main/java/com/tangem/tap/features/customtoken/impl/presentation/viewmodels/AddCustomTokenViewModel.kt +++ b/app/src/main/java/com/tangem/tap/features/customtoken/impl/presentation/viewmodels/AddCustomTokenViewModel.kt @@ -12,6 +12,7 @@ import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.tangem.blockchain.common.Blockchain import com.tangem.blockchain.common.Token +import com.tangem.blockchain.common.derivation.DerivationStyle import com.tangem.core.analytics.api.AnalyticsEventHandler import com.tangem.crypto.hdWallet.DerivationPath import com.tangem.crypto.hdWallet.HDWalletError @@ -212,13 +213,21 @@ internal class AddCustomTokenViewModel @Inject constructor( return listOf(defaultNetwork) + Blockchain.values() .filter { blockchain -> scanResponse?.card?.supportedBlockchains(scanResponse.cardTypesResolver) - ?.contains(blockchain) == true && - blockchain.derivationPath(derivationStyle)?.rawPath?.isNotEmpty() == true + ?.contains(blockchain) == true && isDerivationPathNotEmpty(derivationStyle, blockchain) } .sortedBy(Blockchain::fullName) .map(::createNetworkSelectorItem) } + private fun isDerivationPathNotEmpty(derivationStyle: DerivationStyle?, blockchain: Blockchain): Boolean { + // derivationStyle is null for cards without HD wallets, always return true + return if (derivationStyle != null) { + blockchain.derivationPath(derivationStyle)?.rawPath?.isNotEmpty() == true + } else { + true + } + } + private fun createTokenNameInputField(): AddCustomTokenInputField.TokenName { return AddCustomTokenInputField.TokenName( value = "", @@ -288,7 +297,12 @@ internal class AddCustomTokenViewModel @Inject constructor( } .sortedBy(Blockchain::fullName) .mapNotNull { - val derivationPath = it.derivationPath(derivationStyle)?.rawPath + val derivationPath = if (derivationStyle != null) { + it.derivationPath(derivationStyle)?.rawPath + } else { + // derivationStyle is null for cards without HDWallet, use DerivationStyle.V1 + it.derivationPath(DerivationStyle.V1)?.rawPath + } if (derivationPath?.isNotEmpty() == true) { createDerivationPathSelectorAdditionalItem( blockchain = it, @@ -628,6 +642,7 @@ internal class AddCustomTokenViewModel @Inject constructor( if (blockchain == null) return null val derivationStyle = reduxStateHolder.scanResponse?.derivationStyleProvider?.getDerivationStyle() + ?: DerivationStyle.V1 val derivationNetwork = if (blockchain == Blockchain.Unknown) { uiState.form.networkSelectorField.selectedItem.blockchain diff --git a/app/src/main/java/com/tangem/tap/features/details/redux/DetailsMiddleware.kt b/app/src/main/java/com/tangem/tap/features/details/redux/DetailsMiddleware.kt index 2f6f8ec7cc..47497bd0b1 100644 --- a/app/src/main/java/com/tangem/tap/features/details/redux/DetailsMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/details/redux/DetailsMiddleware.kt @@ -124,7 +124,7 @@ class DetailsMiddleware { scope.launch { val userWalletId = UserWalletIdBuilder.card(card).build() - tangemSdkManager.resetToFactorySettings(card.cardId) + tangemSdkManager.resetToFactorySettings(card.cardId, true) .flatMap { userWalletsListManager.delete(listOfNotNull(userWalletId)) } .flatMap { tangemSdkManager.deleteSavedUserCodes(setOf(card.cardId)) } .doOnSuccess { diff --git a/app/src/main/java/com/tangem/tap/features/home/HomeFragment.kt b/app/src/main/java/com/tangem/tap/features/home/HomeFragment.kt index 6332136b24..2127b6e8c6 100644 --- a/app/src/main/java/com/tangem/tap/features/home/HomeFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/home/HomeFragment.kt @@ -12,20 +12,19 @@ import androidx.compose.ui.platform.ComposeView import androidx.core.view.WindowCompat import androidx.core.view.WindowInsetsControllerCompat import androidx.fragment.app.Fragment -import androidx.fragment.app.activityViewModels +import androidx.lifecycle.lifecycleScope import com.tangem.core.analytics.Analytics import com.tangem.core.navigation.AppScreen import com.tangem.core.navigation.NavigationAction import com.tangem.core.ui.res.TangemTheme import com.tangem.domain.tokens.TokensAction -import com.tangem.feature.learn2earn.presentation.Learn2earnViewModel import com.tangem.tap.common.analytics.events.IntroductionProcess import com.tangem.tap.features.home.compose.StoriesScreen import com.tangem.tap.features.home.redux.HomeAction import com.tangem.tap.features.home.redux.HomeState -import com.tangem.tap.features.home.redux.Stories import com.tangem.tap.store import dagger.hilt.android.AndroidEntryPoint +import kotlinx.coroutines.launch import org.rekotlin.StoreSubscriber @AndroidEntryPoint @@ -33,7 +32,7 @@ class HomeFragment : Fragment(), StoreSubscriber { private var homeState: MutableState = mutableStateOf(store.state.homeState) - private val learn2earnViewModel by activityViewModels() + // private val learn2earnViewModel by activityViewModels() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -43,10 +42,10 @@ class HomeFragment : Fragment(), StoreSubscriber { override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { // sync adding story before screen creation - if (learn2earnViewModel.uiState.storyScreenState.isVisible) { - store.dispatch(HomeAction.InsertStory(position = 0, Stories.OneInchPromo)) - homeState.value = store.state.homeState - } + // if (learn2earnViewModel.uiState.storyScreenState.isVisible) { + // store.dispatch(HomeAction.InsertStory(position = 0, Stories.OneInchPromo)) + // homeState.value = store.state.homeState + // } return ComposeView(inflater.context).apply { setContent { TangemTheme { @@ -91,10 +90,14 @@ class HomeFragment : Fragment(), StoreSubscriber { private fun ScreenContent() { StoriesScreen( homeState = homeState, - onLearn2earnClick = learn2earnViewModel.uiState.storyScreenState.onClick, + onLearn2earnClick = {}, // learn2earnViewModel.uiState.storyScreenState.onClick, onScanButtonClick = { Analytics.send(IntroductionProcess.ButtonScanCard()) - store.dispatch(HomeAction.ReadCard()) + lifecycleScope.launch { + store.dispatch( + HomeAction.ReadCard(lifecycleCoroutineScope = lifecycleScope), + ) + } }, onShopButtonClick = { Analytics.send(IntroductionProcess.ButtonBuyCards()) diff --git a/app/src/main/java/com/tangem/tap/features/home/compose/StoriesScreen.kt b/app/src/main/java/com/tangem/tap/features/home/compose/StoriesScreen.kt index d29b602c5d..cd4af4ff04 100644 --- a/app/src/main/java/com/tangem/tap/features/home/compose/StoriesScreen.kt +++ b/app/src/main/java/com/tangem/tap/features/home/compose/StoriesScreen.kt @@ -23,6 +23,7 @@ import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider import androidx.compose.ui.unit.dp import com.google.accompanist.systemuicontroller.rememberSystemUiController +import com.tangem.core.ui.res.TangemColorPalette import com.tangem.core.ui.res.TangemTheme import com.tangem.feature.learn2earn.presentation.ui.Learn2earnStoriesScreen import com.tangem.tap.features.home.compose.content.* @@ -169,15 +170,27 @@ private fun StoriesScreenContent(config: StoriesScreenContentConfig, modifier: M .height(17.dp) .alpha(if (hideContent) 0f else 1f) .align(Alignment.Start), - colorFilter = if (config.currentStory.isDarkBackground) null else ColorFilter.tint(Color.Black), + colorFilter = if (config.currentStory.isDarkBackground) { + null + } else { + ColorFilter.tint(TangemColorPalette.Dark6) + }, ) when (config.currentStory) { Stories.OneInchPromo -> Learn2earnStoriesScreen(config.onLearn2earnClick) - Stories.TangemIntro -> FirstStoriesContent(isPaused, currentStoryDuration) { + Stories.TangemIntro -> FirstStoriesContent( + isPaused = isPaused, + duration = currentStoryDuration, + isNewWalletAvailable = config.currentStory.isNewWalletAvailable, + ) { hideContent = it } Stories.RevolutionaryWallet -> StoriesRevolutionaryWallet(currentStoryDuration) - Stories.UltraSecureBackup -> StoriesUltraSecureBackup(isPaused, currentStoryDuration) + is Stories.UltraSecureBackup -> StoriesUltraSecureBackup( + isPaused = isPaused, + stepDuration = currentStoryDuration, + isNewWalletAvailable = config.currentStory.isNewWalletAvailable, + ) Stories.Currencies -> StoriesCurrencies(isPaused, currentStoryDuration) Stories.Web3 -> StoriesWeb3(isPaused, currentStoryDuration) Stories.WalletForEveryone -> StoriesWalletForEveryone(currentStoryDuration) diff --git a/app/src/main/java/com/tangem/tap/features/home/compose/content/Content.kt b/app/src/main/java/com/tangem/tap/features/home/compose/content/Content.kt index 2c430b48db..406064b704 100644 --- a/app/src/main/java/com/tangem/tap/features/home/compose/content/Content.kt +++ b/app/src/main/java/com/tangem/tap/features/home/compose/content/Content.kt @@ -2,13 +2,12 @@ package com.tangem.tap.features.home.compose.content import androidx.annotation.DrawableRes import androidx.compose.foundation.Image -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.* import androidx.compose.material.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.MutableState +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color @@ -56,7 +55,7 @@ fun StoriesRevolutionaryWallet(stepDuration: Int) { } @Composable -fun StoriesUltraSecureBackup(isPaused: Boolean, stepDuration: Int) { +fun StoriesUltraSecureBackup(isPaused: Boolean, stepDuration: Int, isNewWalletAvailable: MutableState) { val subtitleText = buildAnnotatedString { append(stringResource(id = R.string.story_backup_description_1)) append(" ") @@ -75,7 +74,11 @@ fun StoriesUltraSecureBackup(isPaused: Boolean, stepDuration: Int) { ) }, bottomContent = { - FloatingCardsContent(isPaused, stepDuration) + FloatingCardsContent( + isPaused = isPaused, + stepDuration = stepDuration, + isNewWalletAvailable = isNewWalletAvailable, + ) }, ) } @@ -230,7 +233,13 @@ private fun RevolutionaryWalletPreview() { @Preview @Composable private fun UltraSecureBackupPreview() { - StoriesUltraSecureBackup(false, 6000) + StoriesUltraSecureBackup( + false, + 6000, + remember { + mutableStateOf(true) + }, + ) } @Preview diff --git a/app/src/main/java/com/tangem/tap/features/home/compose/content/FirstStoriesContent.kt b/app/src/main/java/com/tangem/tap/features/home/compose/content/FirstStoriesContent.kt index 4904a47c5b..14f51add03 100644 --- a/app/src/main/java/com/tangem/tap/features/home/compose/content/FirstStoriesContent.kt +++ b/app/src/main/java/com/tangem/tap/features/home/compose/content/FirstStoriesContent.kt @@ -32,7 +32,12 @@ import com.tangem.wallet.R @Suppress("LongMethod", "ComplexMethod", "MagicNumber") @Composable -fun FirstStoriesContent(isPaused: Boolean, duration: Int, onHideContent: (Boolean) -> Unit) { +fun FirstStoriesContent( + isPaused: Boolean, + duration: Int, + isNewWalletAvailable: MutableState, + onHideContent: (Boolean) -> Unit, +) { val bottomInsetsPx = WindowInsets.navigationBars.getBottom(LocalDensity.current) val screenState = remember { mutableStateOf(StartingScreenState.INIT) } @@ -115,13 +120,18 @@ fun FirstStoriesContent(isPaused: Boolean, duration: Int, onHideContent: (Boolea .weight(1.2f) .wrapContentSize(), ) { + val painter = if (isNewWalletAvailable.value) { + painterResource(id = R.drawable.img_meet_tangem2) + } else { + painterResource(id = R.drawable.img_meet_tangem) + } StoriesBottomImageAnimation( totalDuration = duration, firstStepDuration = 400, ) { modifier -> Image( modifier = modifier.fillMaxWidth(), - painter = painterResource(id = R.drawable.img_meet_tangem), + painter = painter, contentDescription = "Tangem Wallet card", ) } @@ -178,5 +188,11 @@ private fun MutableState.isMeetTangemDisplaying(): Boolean @Preview @Composable private fun FirstStoriesPreview() { - FirstStoriesContent(false, 8000) {} + FirstStoriesContent( + false, + 8000, + remember { + mutableStateOf(false) + }, + ) {} } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/home/compose/content/FloatingCardsContent.kt b/app/src/main/java/com/tangem/tap/features/home/compose/content/FloatingCardsContent.kt index 81d26d4855..3731a0e13c 100644 --- a/app/src/main/java/com/tangem/tap/features/home/compose/content/FloatingCardsContent.kt +++ b/app/src/main/java/com/tangem/tap/features/home/compose/content/FloatingCardsContent.kt @@ -4,6 +4,7 @@ import androidx.compose.foundation.Image import androidx.compose.foundation.background import androidx.compose.foundation.layout.* import androidx.compose.runtime.Composable +import androidx.compose.runtime.MutableState import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Brush @@ -21,9 +22,13 @@ import com.tangem.wallet.R [REDACTED_AUTHOR] */ @Composable -fun FloatingCardsContent(isPaused: Boolean, stepDuration: Int) { +fun FloatingCardsContent(isPaused: Boolean, stepDuration: Int, isNewWalletAvailable: MutableState) { val bottomInsetsPx = WindowInsets.navigationBars.getBottom(LocalDensity.current) - val imageBitmap = asImageBitmap(R.drawable.img_card_placeholder_wallet_2) + val imageBitmap = if (isNewWalletAvailable.value) { + asImageBitmap(R.drawable.img_card_placeholder_wallet_2) + } else { + asImageBitmap(R.drawable.card_placeholder_wallet) + } val cards = listOf( FloatingCard.first(), FloatingCard.second(), diff --git a/app/src/main/java/com/tangem/tap/features/home/redux/HomeAction.kt b/app/src/main/java/com/tangem/tap/features/home/redux/HomeAction.kt index 93479d1767..033171c4f4 100644 --- a/app/src/main/java/com/tangem/tap/features/home/redux/HomeAction.kt +++ b/app/src/main/java/com/tangem/tap/features/home/redux/HomeAction.kt @@ -1,5 +1,6 @@ package com.tangem.tap.features.home.redux +import androidx.lifecycle.LifecycleCoroutineScope import com.tangem.core.analytics.models.AnalyticsEvent import com.tangem.tap.common.analytics.events.AnalyticsParam import com.tangem.tap.common.analytics.events.Basic @@ -13,12 +14,22 @@ sealed class HomeAction : Action { data class InsertStory(val position: Int, val story: Stories) : HomeAction() + /** + * Action for scanning card + * + * @property analyticsEvent analytics event + * @property lifecycleCoroutineScope lifecycle scope. It will be canceled when lifecycle-aware component is + * destroyed. + */ data class ReadCard( val analyticsEvent: AnalyticsEvent? = Basic.CardWasScanned(AnalyticsParam.ScannedFrom.Introduction), + val lifecycleCoroutineScope: LifecycleCoroutineScope, ) : HomeAction() data class ScanInProgress(val scanInProgress: Boolean) : HomeAction() data class GoToShop(val userCountryCode: String?) : HomeAction() + data class UpdateCountryCode(val userCountryCode: String) : HomeAction() + data class ChangeScanCardButtonState(val state: IndeterminateProgressButton) : HomeAction() } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/home/redux/HomeMiddleware.kt b/app/src/main/java/com/tangem/tap/features/home/redux/HomeMiddleware.kt index 162d99281a..48f2f37be5 100644 --- a/app/src/main/java/com/tangem/tap/features/home/redux/HomeMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/home/redux/HomeMiddleware.kt @@ -1,5 +1,6 @@ package com.tangem.tap.features.home.redux +import androidx.lifecycle.LifecycleCoroutineScope import com.tangem.common.doOnFailure import com.tangem.common.doOnResult import com.tangem.common.doOnSuccess @@ -62,7 +63,7 @@ private fun handleHomeAction(action: Action) { store.dispatch(GlobalAction.FetchUserCountry) } is HomeAction.ReadCard -> { - readCard(action.analyticsEvent) + readCard(action.analyticsEvent, action.lifecycleCoroutineScope) } is HomeAction.GoToShop -> { Analytics.send(Shop.ScreenOpened()) @@ -77,32 +78,34 @@ private fun handleHomeAction(action: Action) { } } -private fun readCard(analyticsEvent: AnalyticsEvent?) = scope.launch { - delay(timeMillis = 200) - store.state.daggerGraphState.get(DaggerGraphState::cardSdkConfigRepository).setAccessCodeRequestPolicy( - isBiometricsRequestPolicy = preferencesStorage.shouldSaveAccessCodes, - ) +private fun readCard(analyticsEvent: AnalyticsEvent?, lifecycleCoroutineScope: LifecycleCoroutineScope) { + lifecycleCoroutineScope.launch { + delay(timeMillis = 200) + store.state.daggerGraphState.get(DaggerGraphState::cardSdkConfigRepository).setAccessCodeRequestPolicy( + isBiometricsRequestPolicy = preferencesStorage.shouldSaveAccessCodes, + ) - store.state.daggerGraphState.get(DaggerGraphState::scanCardProcessor).scan( - analyticsEvent = analyticsEvent, - onProgressStateChange = { showProgress -> - if (showProgress) { - changeButtonState(ButtonState.PROGRESS) - } else { + store.state.daggerGraphState.get(DaggerGraphState::scanCardProcessor).scan( + analyticsEvent = analyticsEvent, + onProgressStateChange = { showProgress -> + if (showProgress) { + changeButtonState(ButtonState.PROGRESS) + } else { + changeButtonState(ButtonState.ENABLED) + } + }, + onScanStateChange = { scanInProgress -> + store.dispatch(HomeAction.ScanInProgress(scanInProgress)) + }, + onFailure = { + Timber.e(it, "Unable to scan card") changeButtonState(ButtonState.ENABLED) - } - }, - onScanStateChange = { scanInProgress -> - store.dispatch(HomeAction.ScanInProgress(scanInProgress)) - }, - onFailure = { - Timber.e(it, "Unable to scan card") - changeButtonState(ButtonState.ENABLED) - }, - onSuccess = { scanResponse -> - proceedWithScanResponse(scanResponse) - }, - ) + }, + onSuccess = { scanResponse -> + proceedWithScanResponse(scanResponse) + }, + ) + } } private fun proceedWithScanResponse(scanResponse: ScanResponse) = scope.launch { diff --git a/app/src/main/java/com/tangem/tap/features/home/redux/HomeReducer.kt b/app/src/main/java/com/tangem/tap/features/home/redux/HomeReducer.kt index 6843253f5a..81f1adee30 100644 --- a/app/src/main/java/com/tangem/tap/features/home/redux/HomeReducer.kt +++ b/app/src/main/java/com/tangem/tap/features/home/redux/HomeReducer.kt @@ -7,10 +7,10 @@ object HomeReducer { fun reduce(action: Action, state: AppState): HomeState = internalReduce(action, state) } -private fun internalReduce(action: Action, state: AppState): HomeState { - if (action !is HomeAction) return state.homeState +private fun internalReduce(action: Action, appState: AppState): HomeState { + if (action !is HomeAction) return appState.homeState - var state = state.homeState + var state = appState.homeState when (action) { is HomeAction.InsertStory -> { state = state.copy( @@ -25,6 +25,9 @@ private fun internalReduce(action: Action, state: AppState): HomeState { is HomeAction.ChangeScanCardButtonState -> { state = state.copy(btnScanState = action.state) } + is HomeAction.UpdateCountryCode -> { + state.onCountryCodeUpdate(state, action.userCountryCode) + } else -> {} } diff --git a/app/src/main/java/com/tangem/tap/features/home/redux/HomeState.kt b/app/src/main/java/com/tangem/tap/features/home/redux/HomeState.kt index 415deb938d..3456bafb5d 100644 --- a/app/src/main/java/com/tangem/tap/features/home/redux/HomeState.kt +++ b/app/src/main/java/com/tangem/tap/features/home/redux/HomeState.kt @@ -1,9 +1,12 @@ package com.tangem.tap.features.home.redux +import androidx.compose.runtime.MutableState +import androidx.compose.runtime.mutableStateOf import com.tangem.tap.common.entities.IndeterminateProgressButton import com.tangem.tap.features.send.redux.states.ButtonState import com.tangem.tap.features.wallet.redux.ProgressState import org.rekotlin.StateType +import java.util.Locale data class HomeState( val scanInProgress: Boolean = false, @@ -19,7 +22,16 @@ data class HomeState( fun stepOf(story: Stories): Int = stories.indexOf(story) + fun onCountryCodeUpdate(homeState: HomeState, countryCode: String) { + val isNewWalletAvailable = !(countryCode == RUSSIA_COUNTRY_CODE || countryCode == BELARUS_COUNTRY_CODE) + homeState.stories.forEach { + it.isNewWalletAvailable.value = isNewWalletAvailable + } + } + companion object { + private const val RUSSIA_COUNTRY_CODE = "ru" + private const val BELARUS_COUNTRY_CODE = "by" fun initDefaultStories(): List = listOf( Stories.TangemIntro, Stories.RevolutionaryWallet, @@ -28,12 +40,18 @@ data class HomeState( Stories.Web3, Stories.WalletForEveryone, ) + + fun isNewWalletAvailableInit(): Boolean { + val locale = Locale.getDefault().language + return !(locale == RUSSIA_COUNTRY_CODE || locale == BELARUS_COUNTRY_CODE) + } } } sealed class Stories( val isDarkBackground: Boolean, val duration: Int, + val isNewWalletAvailable: MutableState = mutableStateOf(HomeState.isNewWalletAvailableInit()), ) { object OneInchPromo : Stories(true, duration = 8000) object TangemIntro : Stories(true, duration = 8000) diff --git a/app/src/main/java/com/tangem/tap/features/intentHandler/handlers/BackgroundScanIntentHandler.kt b/app/src/main/java/com/tangem/tap/features/intentHandler/handlers/BackgroundScanIntentHandler.kt index df5b3759d8..09a682cdb5 100644 --- a/app/src/main/java/com/tangem/tap/features/intentHandler/handlers/BackgroundScanIntentHandler.kt +++ b/app/src/main/java/com/tangem/tap/features/intentHandler/handlers/BackgroundScanIntentHandler.kt @@ -4,11 +4,11 @@ import android.content.Intent import android.nfc.NfcAdapter import android.nfc.Tag import android.os.Build +import androidx.lifecycle.LifecycleCoroutineScope import com.tangem.tap.common.extensions.dispatchWithMain import com.tangem.tap.features.home.redux.HomeAction import com.tangem.tap.features.intentHandler.IntentHandler import com.tangem.tap.features.welcome.redux.WelcomeAction -import com.tangem.tap.scope import com.tangem.tap.store import kotlinx.coroutines.delay import kotlinx.coroutines.launch @@ -18,6 +18,7 @@ import kotlinx.coroutines.launch */ class BackgroundScanIntentHandler( private val hasSavedUserWalletsProvider: () -> Boolean, + private val lifecycleCoroutineScope: LifecycleCoroutineScope, ) : IntentHandler { private val nfcActions = arrayOf( @@ -40,12 +41,12 @@ class BackgroundScanIntentHandler( intent.action = null if (hasSavedUserWalletsProvider.invoke()) { // TODO: Remove delay after [REDACTED_JIRA] - scope.launch { + lifecycleCoroutineScope.launch { delay(timeMillis = 200) - store.dispatchWithMain(WelcomeAction.ProceedWithCard) + store.dispatchWithMain(WelcomeAction.ProceedWithCard(lifecycleCoroutineScope)) } } else { - store.dispatchWithMain(HomeAction.ReadCard()) + store.dispatchWithMain(HomeAction.ReadCard(lifecycleCoroutineScope = lifecycleCoroutineScope)) } return true diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/redux/OnboardingWalletAction.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/redux/OnboardingWalletAction.kt index c021c9fad5..9446f718c1 100644 --- a/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/redux/OnboardingWalletAction.kt +++ b/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/redux/OnboardingWalletAction.kt @@ -1,6 +1,7 @@ package com.tangem.tap.features.onboarding.products.wallet.redux import android.net.Uri +import androidx.lifecycle.LifecycleCoroutineScope import com.tangem.common.CompletionResult import com.tangem.feature.onboarding.data.model.CreateWalletResponse import com.tangem.feature.onboarding.presentation.wallet2.analytics.SeedPhraseSource @@ -12,11 +13,12 @@ sealed class OnboardingWalletAction : Action { object GetToCreateWalletStep : OnboardingWalletAction() object CreateWallet : OnboardingWalletAction() data class WalletWasCreated( + val shouldSendAnalyticsEvent: Boolean, val result: CompletionResult, ) : OnboardingWalletAction() object Done : OnboardingWalletAction() - object FinishOnboarding : OnboardingWalletAction() + data class FinishOnboarding(val lifecycleCoroutineScope: LifecycleCoroutineScope) : OnboardingWalletAction() object ResumeBackup : OnboardingWalletAction() diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/redux/OnboardingWalletMiddleware.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/redux/OnboardingWalletMiddleware.kt index d1a927c252..b255ab3536 100644 --- a/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/redux/OnboardingWalletMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/redux/OnboardingWalletMiddleware.kt @@ -104,14 +104,16 @@ private fun handleWalletAction(action: Action) { scanResponse ?: return scope.launch { val result = tangemSdkManager.createProductWallet(scanResponse) - store.dispatchOnMain(OnboardingWalletAction.WalletWasCreated(result)) + store.dispatchOnMain(OnboardingWalletAction.WalletWasCreated(true, result)) } } is OnboardingWalletAction.WalletWasCreated -> { scanResponse ?: return when (val result = action.result) { is CompletionResult.Success -> { - Analytics.send(Onboarding.CreateWallet.WalletCreatedSuccessfully()) + if (action.shouldSendAnalyticsEvent) { + Analytics.send(Onboarding.CreateWallet.WalletCreatedSuccessfully()) + } // here we must use updated scanResponse after createWallet & derivation val updatedResponse = globalState.onboardingState.onboardingManager.scanResponse.copy( card = result.data.card, @@ -144,12 +146,12 @@ private fun handleWalletAction(action: Action) { is CompletionResult.Failure -> Unit } } - OnboardingWalletAction.FinishOnboarding -> { + is OnboardingWalletAction.FinishOnboarding -> { store.dispatch(GlobalAction.Onboarding.Stop) if (scanResponse == null) { store.dispatch(NavigationAction.PopBackTo()) - store.dispatch(HomeAction.ReadCard()) + store.dispatch(HomeAction.ReadCard(lifecycleCoroutineScope = action.lifecycleCoroutineScope)) } else { val backupState = store.state.onboardingWalletState.backupState val updatedScanResponse = updateScanResponseAfterBackup(scanResponse, backupState) @@ -268,7 +270,8 @@ private fun handleWallet2Action(action: OnboardingWallet2Action) { CompletionResult.Failure(mediateResult.error) } } - store.dispatchOnMain(OnboardingWalletAction.WalletWasCreated(result)) + // do not send analytics event for wallet2 flow, cause its already sent + store.dispatchOnMain(OnboardingWalletAction.WalletWasCreated(false, result)) } else -> Unit @@ -457,7 +460,7 @@ private fun handleBackupAction(appState: () -> AppState?, action: BackupAction) } is BackupAction.ResetBackupCard -> { - scope.launch { tangemSdkManager.resetToFactorySettings(action.cardId) } + scope.launch { tangemSdkManager.resetToFactorySettings(action.cardId, false) } } else -> Unit diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/ui/OnboardingWalletFragment.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/ui/OnboardingWalletFragment.kt index 50a7af5d2a..ff40ab5ad6 100644 --- a/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/ui/OnboardingWalletFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/ui/OnboardingWalletFragment.kt @@ -11,6 +11,7 @@ import android.widget.ImageView import androidx.appcompat.app.AppCompatActivity import androidx.core.view.MenuProvider import androidx.fragment.app.viewModels +import androidx.lifecycle.lifecycleScope import androidx.transition.TransitionInflater import androidx.transition.TransitionManager import by.kirich1409.viewbindingdelegate.viewBinding @@ -21,6 +22,7 @@ import com.tangem.common.CardIdFormatter import com.tangem.common.CompletionResult import com.tangem.common.core.CardIdDisplayFormat import com.tangem.core.analytics.Analytics +import com.tangem.domain.common.util.cardTypesResolver import com.tangem.feature.onboarding.data.model.CreateWalletResponse import com.tangem.feature.onboarding.presentation.wallet2.analytics.SeedPhraseSource import com.tangem.feature.onboarding.presentation.wallet2.viewmodel.SeedPhraseMediator @@ -64,6 +66,7 @@ class OnboardingWalletFragment : private val seedPhraseViewModel by viewModels() private lateinit var cardsWidget: WalletCardsWidget + private var seedPhraseRouter: SeedPhraseRouter? = null private var accessCodeDialog: AccessCodeDialog? = null private lateinit var animator: BackupAnimator @@ -77,7 +80,9 @@ class OnboardingWalletFragment : override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - seedPhraseViewModel.setRouter(makeSeedPhraseRouter()) + val newSeedPhraseRouter = makeSeedPhraseRouter() + seedPhraseRouter = newSeedPhraseRouter + seedPhraseViewModel.setRouter(newSeedPhraseRouter) seedPhraseViewModel.setMediator(makeSeedPhraseMediator()) } @@ -172,6 +177,12 @@ class OnboardingWalletFragment : when { state.wallet2State != null -> { seedPhraseStateHandler.newState(this, state, seedPhraseViewModel) + state.cardArtworkUri?.let { + seedPhraseViewModel.setCardArtworkUri(it.toString()) + loadImageIntoImageView(it, binding.imvFrontCard) + loadImageIntoImageView(it, binding.imvFirstBackupCard) + loadImageIntoImageView(it, binding.imvSecondBackupCard) + } } else -> { loadImageIntoImageView(state.cardArtworkUri, binding.imvFrontCard) @@ -195,7 +206,6 @@ class OnboardingWalletFragment : OnboardingWalletStep.CreateWallet -> setupCreateWalletState() OnboardingWalletStep.Backup -> setBackupState( state = state.backupState, - isWallet2 = state.wallet2State != null, ) else -> {} @@ -220,9 +230,9 @@ class OnboardingWalletFragment : animator.setupCreateWalletState() } - private fun setBackupState(state: BackupState, isWallet2: Boolean) { + private fun setBackupState(state: BackupState) { when (state.backupStep) { - BackupStep.InitBackup -> showBackupIntro(state, isWallet2) + BackupStep.InitBackup -> showBackupIntro(state) BackupStep.ScanOriginCard -> showScanOriginCard() BackupStep.AddBackupCards -> showAddBackupCards(state) BackupStep.SetAccessCode -> showSetAccessCode() @@ -234,7 +244,7 @@ class OnboardingWalletFragment : } } - private fun showBackupIntro(state: BackupState, isWallet2: Boolean) = with(binding) { + private fun showBackupIntro(state: BackupState) = with(binding) { imvFirstBackupCard.show() imvSecondBackupCard.show() @@ -250,7 +260,7 @@ class OnboardingWalletFragment : btnWalletAlternativeAction.text = getText(R.string.onboarding_button_skip_backup) btnWalletAlternativeAction.setOnClickListener { store.dispatch(BackupAction.SkipBackup) } - btnWalletAlternativeAction.show(state.canSkipBackup && !isWallet2) + btnWalletAlternativeAction.show(state.canSkipBackup) } animator.showBackupIntro(state) } @@ -419,7 +429,9 @@ class OnboardingWalletFragment : layoutButtonsCommon.btnWalletAlternativeAction.hide() layoutButtonsCommon.btnWalletMainAction.setOnClickListener { showConfetti(false) - store.dispatch(OnboardingWalletAction.FinishOnboarding) + lifecycleScope.launch { + store.dispatch(OnboardingWalletAction.FinishOnboarding(lifecycleCoroutineScope = lifecycleScope)) + } } animator.showSuccess { @@ -443,6 +455,19 @@ class OnboardingWalletFragment : } override fun handleOnBackPressed() { + // workaround to use right navigation back for toolbar back btn on seed phrase flow + val isWallet2 = + store.state.globalState.onboardingState.onboardingManager?.scanResponse?.cardTypesResolver?.isWallet2() + ?: false + val seedPhraseRouter = seedPhraseRouter + if (seedPhraseRouter != null && isWallet2) { + seedPhraseRouter.navigateBack() + } else { + legacyOnBackHandler() + } + } + + private fun legacyOnBackHandler() { store.dispatch(OnboardingWalletAction.OnBackPressed) } @@ -453,7 +478,7 @@ class OnboardingWalletFragment : } private fun makeSeedPhraseRouter(): SeedPhraseRouter = SeedPhraseRouter( - onBack = ::handleOnBackPressed, + onBack = ::legacyOnBackHandler, onOpenChat = { store.dispatch(GlobalAction.OpenChat(SupportInfo())) }, diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/ui/dialogs/ResetBackupCardDialog.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/ui/dialogs/ResetBackupCardDialog.kt index 0e7acbaa00..d2f4d2392a 100644 --- a/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/ui/dialogs/ResetBackupCardDialog.kt +++ b/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/ui/dialogs/ResetBackupCardDialog.kt @@ -2,6 +2,8 @@ package com.tangem.tap.features.onboarding.products.wallet.ui.dialogs import android.content.Context import androidx.appcompat.app.AlertDialog +import com.tangem.core.analytics.Analytics +import com.tangem.tap.common.analytics.events.Onboarding import com.tangem.tap.common.redux.global.GlobalAction import com.tangem.tap.features.onboarding.products.wallet.redux.BackupAction import com.tangem.tap.store @@ -13,9 +15,10 @@ object ResetBackupCardDialog { setTitle(R.string.common_attention) setMessage(R.string.onboarding_linking_error_card_with_wallets) setPositiveButton(R.string.common_cancel) { _, _ -> - /* no-op */ + Analytics.send(Onboarding.Backup.ResetCancelEvent) } setNegativeButton(R.string.card_settings_action_sheet_reset) { _, _ -> + Analytics.send(Onboarding.Backup.ResetPerformEvent) store.dispatch(BackupAction.ResetBackupCard(cardId)) } setOnDismissListener { diff --git a/app/src/main/java/com/tangem/tap/features/send/redux/SendScreenAction.kt b/app/src/main/java/com/tangem/tap/features/send/redux/SendScreenAction.kt index cd9ad2160d..4c9eaf36a5 100644 --- a/app/src/main/java/com/tangem/tap/features/send/redux/SendScreenAction.kt +++ b/app/src/main/java/com/tangem/tap/features/send/redux/SendScreenAction.kt @@ -155,6 +155,13 @@ sealed class SendAction : SendScreenAction { val onOk: () -> Unit, ) : Dialog() + data class ChiaWarningDialog( + val blockchainName: String, + val maxOutputs: Int, + val maxAmount: BigDecimal, + val onOk: () -> Unit, + ) : Dialog() + sealed class SendTransactionFails : Dialog() { data class CardSdkError(val error: TangemSdkError) : Dialog() data class BlockchainSdkError(val error: com.tangem.blockchain.common.BlockchainSdkError) : Dialog() diff --git a/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/SendMiddleware.kt b/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/SendMiddleware.kt index cb2e4c26bd..eeb7c0cf20 100644 --- a/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/SendMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/send/redux/middlewares/SendMiddleware.kt @@ -307,6 +307,19 @@ private fun sendTransaction( ), ) } + is BlockchainSdkError.Chia.UtxoAmountError -> { + dispatch( + SendAction.Dialog.ChiaWarningDialog( + blockchainName = Blockchain.Chia.fullName, + maxOutputs = error.maxOutputs, + maxAmount = error.maxAmount, + onOk = { + dispatch(AmountAction.SetAmount(error.maxAmount, isUserInput = false)) + dispatch(AmountActionUi.CheckAmountToSend) + }, + ), + ) + } else -> { when { error.customMessage.contains(DemoTransactionSender.ID) -> { diff --git a/app/src/main/java/com/tangem/tap/features/send/redux/reducers/SendScreenReducer.kt b/app/src/main/java/com/tangem/tap/features/send/redux/reducers/SendScreenReducer.kt index 463b0dcaea..8a9cab2329 100644 --- a/app/src/main/java/com/tangem/tap/features/send/redux/reducers/SendScreenReducer.kt +++ b/app/src/main/java/com/tangem/tap/features/send/redux/reducers/SendScreenReducer.kt @@ -46,6 +46,7 @@ private class SendReducer : SendInternalReducer { } is SendAction.Dialog.TezosWarningDialog -> sendState.copy(dialog = action) is SendAction.Dialog.KaspaWarningDialog -> sendState.copy(dialog = action) + is SendAction.Dialog.ChiaWarningDialog -> sendState.copy(dialog = action) is SendAction.Dialog.SendTransactionFails.CardSdkError -> sendState.copy(dialog = action) is SendAction.Dialog.SendTransactionFails.BlockchainSdkError -> sendState.copy(dialog = action) is SendAction.Dialog.RequestFeeError -> sendState.copy(dialog = action) diff --git a/app/src/main/java/com/tangem/tap/features/send/ui/dialogs/ChiaWarningDialog.kt b/app/src/main/java/com/tangem/tap/features/send/ui/dialogs/ChiaWarningDialog.kt new file mode 100644 index 0000000000..b4ba056146 --- /dev/null +++ b/app/src/main/java/com/tangem/tap/features/send/ui/dialogs/ChiaWarningDialog.kt @@ -0,0 +1,32 @@ +package com.tangem.tap.features.send.ui.dialogs + +import android.content.Context +import androidx.appcompat.app.AlertDialog +import com.tangem.tap.features.send.redux.SendAction +import com.tangem.tap.store +import com.tangem.wallet.R + +// TODO: [REDACTED_JIRA] +object ChiaWarningDialog { + + fun create(context: Context, dialog: SendAction.Dialog.ChiaWarningDialog): AlertDialog { + return AlertDialog.Builder(context).apply { + setTitle(R.string.common_warning) + setMessage( + context.getString( + R.string.common_utxo_validate_withdrawal_message_warning, + dialog.blockchainName, + dialog.maxOutputs, + dialog.maxAmount.toPlainString(), + ), + ) + setPositiveButton(R.string.common_ok) { _, _ -> + dialog.onOk() + } + setOnDismissListener { + store.dispatch(SendAction.Dialog.Hide) + } + } + .create() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/send/ui/stateSubscribers/SendStateSubscriber.kt b/app/src/main/java/com/tangem/tap/features/send/ui/stateSubscribers/SendStateSubscriber.kt index 568f1529d0..1e44546acc 100644 --- a/app/src/main/java/com/tangem/tap/features/send/ui/stateSubscribers/SendStateSubscriber.kt +++ b/app/src/main/java/com/tangem/tap/features/send/ui/stateSubscribers/SendStateSubscriber.kt @@ -18,10 +18,7 @@ import com.tangem.tap.features.send.redux.SendAction import com.tangem.tap.features.send.redux.states.* import com.tangem.tap.features.send.ui.FeeUiHelper import com.tangem.tap.features.send.ui.SendFragment -import com.tangem.tap.features.send.ui.dialogs.KaspaWarningDialog -import com.tangem.tap.features.send.ui.dialogs.RequestFeeErrorDialog -import com.tangem.tap.features.send.ui.dialogs.SendTransactionFailsDialog -import com.tangem.tap.features.send.ui.dialogs.TezosWarningDialog +import com.tangem.tap.features.send.ui.dialogs.* import com.tangem.tap.features.wallet.redux.ProgressState import com.tangem.tap.features.wallet.redux.utils.ROUGH_SIGN import com.tangem.tap.features.wallet.redux.utils.UNKNOWN_AMOUNT_SIGN @@ -124,6 +121,7 @@ class SendStateSubscriber(fragment: BaseStoreFragment) : FragmentStateSubscriber } } + @Suppress("ComplexMethod") private fun handleSendScreen(fg: SendFragment, state: SendState) = with(fg.binding) { when (state.dialog) { is SendAction.Dialog.TezosWarningDialog -> { @@ -138,6 +136,12 @@ class SendStateSubscriber(fragment: BaseStoreFragment) : FragmentStateSubscriber dialog?.show() } } + is SendAction.Dialog.ChiaWarningDialog -> { + if (dialog == null) { + dialog = ChiaWarningDialog.create(fg.requireContext(), state.dialog) + dialog?.show() + } + } is SendAction.Dialog.SendTransactionFails.CardSdkError -> { if (dialog == null) { dialog = SendTransactionFailsDialog.create(fg.requireContext(), state.dialog) diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletAction.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletAction.kt index 10803cf57f..adca4f96f4 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletAction.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/WalletAction.kt @@ -1,6 +1,7 @@ package com.tangem.tap.features.wallet.redux import android.content.Context +import androidx.lifecycle.LifecycleCoroutineScope import com.tangem.blockchain.common.Amount import com.tangem.blockchain.common.address.AddressType import com.tangem.core.analytics.models.AnalyticsEvent @@ -73,7 +74,10 @@ sealed class WalletAction : Action { class CheckRemainingSignatures(val remainingSignatures: Int?) : Warnings() } - data class Scan(val onScanSuccessEvent: AnalyticsEvent?) : WalletAction() + data class Scan( + val onScanSuccessEvent: AnalyticsEvent?, + val lifecycleScope: LifecycleCoroutineScope, + ) : WalletAction() data class Send(val amount: Amount? = null) : WalletAction() @@ -109,7 +113,7 @@ sealed class WalletAction : Action { data class ExploreAddress(val exploreUrl: String, val context: Context) : WalletAction() object CreateWallet : WalletAction() - object ChangeWallet : WalletAction() + data class ChangeWallet(val lifecycleScope: LifecycleCoroutineScope) : WalletAction() object ShowSaveWalletIfNeeded : WalletAction() sealed class TradeCryptoAction : WalletAction() { diff --git a/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WalletMiddleware.kt b/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WalletMiddleware.kt index a6a5fa0e78..889dab19e8 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WalletMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/redux/middlewares/WalletMiddleware.kt @@ -1,5 +1,6 @@ package com.tangem.tap.features.wallet.redux.middlewares +import androidx.lifecycle.LifecycleCoroutineScope import com.google.firebase.crashlytics.FirebaseCrashlytics import com.tangem.blockchain.common.Amount import com.tangem.blockchain.common.AmountType @@ -115,9 +116,9 @@ class WalletMiddleware { } is WalletAction.Scan -> { store.dispatch(NavigationAction.PopBackTo(AppScreen.Home)) - scope.launch { + action.lifecycleScope.launch { delay(timeMillis = 700) - store.dispatchOnMain(HomeAction.ReadCard(action.onScanSuccessEvent)) + store.dispatchOnMain(HomeAction.ReadCard(action.onScanSuccessEvent, action.lifecycleScope)) } } is WalletAction.LoadData, @@ -226,7 +227,7 @@ class WalletMiddleware { showSaveWalletIfNeeded() } is WalletAction.ChangeWallet -> { - changeWallet(walletState) + changeWallet(walletState, action.lifecycleScope) } is WalletAction.UserWalletChanged -> Unit is WalletAction.WalletStoresChanged -> { @@ -379,7 +380,7 @@ class WalletMiddleware { } } - private fun changeWallet(state: WalletState) { + private fun changeWallet(state: WalletState, lifecycleScope: LifecycleCoroutineScope) { when { state.canSaveUserWallets -> { Analytics.send(MainScreen.ButtonMyWallets()) @@ -387,7 +388,12 @@ class WalletMiddleware { } else -> { Analytics.send(MainScreen.ButtonScanCard()) - store.dispatch(WalletAction.Scan(Basic.CardWasScanned(AnalyticsParam.ScannedFrom.Main))) + store.dispatch( + WalletAction.Scan( + onScanSuccessEvent = Basic.CardWasScanned(AnalyticsParam.ScannedFrom.Main), + lifecycleScope = lifecycleScope, + ), + ) } } } diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletFragment.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletFragment.kt index 2164a5028d..a8b503903d 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/WalletFragment.kt @@ -8,9 +8,7 @@ import android.view.View import androidx.activity.OnBackPressedCallback import androidx.appcompat.app.AppCompatActivity import androidx.compose.runtime.mutableStateOf -import androidx.compose.ui.platform.ViewCompositionStrategy import androidx.fragment.app.Fragment -import androidx.fragment.app.activityViewModels import androidx.fragment.app.viewModels import androidx.lifecycle.Lifecycle import androidx.lifecycle.flowWithLifecycle @@ -26,16 +24,12 @@ import com.tangem.core.analytics.Analytics import com.tangem.core.navigation.AppScreen import com.tangem.core.navigation.NavigationAction import com.tangem.core.ui.extensions.setStatusBarColor -import com.tangem.core.ui.res.TangemTheme import com.tangem.core.ui.utils.OneTouchClickListener import com.tangem.datasource.connection.NetworkConnectionManager -import com.tangem.feature.learn2earn.presentation.Learn2earnViewModel -import com.tangem.feature.learn2earn.presentation.ui.Learn2earnMainPageScreen import com.tangem.feature.swap.api.SwapFeatureToggleManager import com.tangem.feature.swap.domain.SwapInteractor import com.tangem.tap.MainActivity import com.tangem.tap.common.analytics.events.Portfolio -import com.tangem.tap.common.extensions.beginDelayedTransition import com.tangem.tap.common.extensions.show import com.tangem.tap.common.recyclerView.SpaceItemDecoration import com.tangem.tap.common.redux.global.GlobalAction @@ -78,7 +72,7 @@ class WalletFragment : Fragment(R.layout.fragment_wallet), SafeStoreSubscriber() + // private val learn2earnViewModel by activityViewModels() private val viewModel by viewModels() private val totalBalanceWatcher = modelWatcher { @@ -108,7 +102,7 @@ class WalletFragment : Fragment(R.layout.fragment_wallet), SafeStoreSubscriber) { diff --git a/app/src/main/java/com/tangem/tap/features/welcome/redux/WelcomeAction.kt b/app/src/main/java/com/tangem/tap/features/welcome/redux/WelcomeAction.kt index e7ce3e5957..338743a569 100644 --- a/app/src/main/java/com/tangem/tap/features/welcome/redux/WelcomeAction.kt +++ b/app/src/main/java/com/tangem/tap/features/welcome/redux/WelcomeAction.kt @@ -1,6 +1,7 @@ package com.tangem.tap.features.welcome.redux import android.content.Intent +import androidx.lifecycle.LifecycleCoroutineScope import com.tangem.common.core.TangemError import org.rekotlin.Action @@ -10,7 +11,7 @@ internal sealed interface WelcomeAction : Action { data class Error(val error: TangemError) : WelcomeAction } - object ProceedWithCard : WelcomeAction { + data class ProceedWithCard(val lifecycleCoroutineScope: LifecycleCoroutineScope) : WelcomeAction { object Success : WelcomeAction data class Error(val error: TangemError) : WelcomeAction } diff --git a/app/src/main/java/com/tangem/tap/features/welcome/redux/WelcomeMiddleware.kt b/app/src/main/java/com/tangem/tap/features/welcome/redux/WelcomeMiddleware.kt index ee103b5965..1ab1cee43d 100644 --- a/app/src/main/java/com/tangem/tap/features/welcome/redux/WelcomeMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/welcome/redux/WelcomeMiddleware.kt @@ -1,5 +1,6 @@ package com.tangem.tap.features.welcome.redux +import androidx.lifecycle.LifecycleCoroutineScope import com.tangem.common.core.TangemSdkError import com.tangem.common.doOnFailure import com.tangem.common.doOnResult @@ -40,7 +41,7 @@ internal class WelcomeMiddleware { private fun handleAction(action: WelcomeAction, state: WelcomeState) { when (action) { is WelcomeAction.ProceedWithBiometrics -> proceedWithBiometrics(state) - is WelcomeAction.ProceedWithCard -> proceedWithCard(state) + is WelcomeAction.ProceedWithCard -> proceedWithCard(state, action.lifecycleCoroutineScope) is WelcomeAction.ClearUserWallets -> disableUserWalletsSaving() else -> Unit } @@ -77,25 +78,27 @@ internal class WelcomeMiddleware { } } - private fun proceedWithCard(state: WelcomeState) = scope.launch { - scanCardInternal { scanResponse -> - val userWallet = UserWalletBuilder(scanResponse).build() ?: return@scanCardInternal + private fun proceedWithCard(state: WelcomeState, lifecycleCoroutineScope: LifecycleCoroutineScope) { + lifecycleCoroutineScope.launch { + scanCardInternal { scanResponse -> + val userWallet = UserWalletBuilder(scanResponse).build() ?: return@scanCardInternal - userWalletsListManager.save(userWallet, canOverride = true) - .doOnFailure { error -> - Timber.e(error, "Unable to save user wallet") - store.dispatchOnMain(WelcomeAction.ProceedWithCard.Error(error)) - } - .doOnSuccess { - store.dispatchOnMain(SignInAction.SetSignInType(Basic.SignedIn.SignInType.Card)) - store.dispatchOnMain(NavigationAction.NavigateTo(AppScreen.Wallet)) - store.dispatchOnMain(WelcomeAction.ProceedWithCard.Success) - store.onUserWalletSelected(userWallet = userWallet) - - state.intent?.let { - WalletConnectLinkIntentHandler().handleIntent(it) + userWalletsListManager.save(userWallet, canOverride = true) + .doOnFailure { error -> + Timber.e(error, "Unable to save user wallet") + store.dispatchOnMain(WelcomeAction.ProceedWithCard.Error(error)) } - } + .doOnSuccess { + store.dispatchOnMain(SignInAction.SetSignInType(Basic.SignedIn.SignInType.Card)) + store.dispatchOnMain(NavigationAction.NavigateTo(AppScreen.Wallet)) + store.dispatchOnMain(WelcomeAction.ProceedWithCard.Success) + store.onUserWalletSelected(userWallet = userWallet) + + state.intent?.let { + WalletConnectLinkIntentHandler().handleIntent(it) + } + } + } } } diff --git a/app/src/main/java/com/tangem/tap/features/welcome/ui/WelcomeFragment.kt b/app/src/main/java/com/tangem/tap/features/welcome/ui/WelcomeFragment.kt index 9e2c09d0d5..f3d9cd27f1 100644 --- a/app/src/main/java/com/tangem/tap/features/welcome/ui/WelcomeFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/welcome/ui/WelcomeFragment.kt @@ -13,6 +13,7 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.fragment.app.viewModels import androidx.lifecycle.compose.collectAsStateWithLifecycle +import androidx.lifecycle.lifecycleScope import com.tangem.core.analytics.Analytics import com.tangem.core.ui.components.SystemBarsEffect import com.tangem.core.ui.res.TangemTheme @@ -65,7 +66,7 @@ internal class WelcomeFragment : ComposeFragment() { showUnlockProgress = state.showUnlockWithBiometricsProgress, showScanCardProgress = state.showUnlockWithCardProgress, onUnlockClick = viewModel::unlockWallets, - onScanCardClick = viewModel::scanCard, + onScanCardClick = { viewModel.scanCard(lifecycleCoroutineScope = lifecycleScope) }, ) SnackbarHost( diff --git a/app/src/main/java/com/tangem/tap/features/welcome/ui/WelcomeViewModel.kt b/app/src/main/java/com/tangem/tap/features/welcome/ui/WelcomeViewModel.kt index 3731da6378..4f7587289d 100644 --- a/app/src/main/java/com/tangem/tap/features/welcome/ui/WelcomeViewModel.kt +++ b/app/src/main/java/com/tangem/tap/features/welcome/ui/WelcomeViewModel.kt @@ -1,5 +1,6 @@ package com.tangem.tap.features.welcome.ui +import androidx.lifecycle.LifecycleCoroutineScope import androidx.lifecycle.ViewModel import com.tangem.common.core.TangemError import com.tangem.core.analytics.Analytics @@ -30,9 +31,9 @@ internal class WelcomeViewModel : ViewModel(), StoreSubscriber { store.dispatch(WelcomeAction.ProceedWithBiometrics) } - fun scanCard() { + fun scanCard(lifecycleCoroutineScope: LifecycleCoroutineScope) { Analytics.send(SignIn.ButtonCardSignIn()) - store.dispatch(WelcomeAction.ProceedWithCard) + store.dispatch(WelcomeAction.ProceedWithCard(lifecycleCoroutineScope)) } fun closeError() { diff --git a/app/src/main/java/com/tangem/tap/proxy/UserWalletManagerImpl.kt b/app/src/main/java/com/tangem/tap/proxy/UserWalletManagerImpl.kt index 432dc559a1..0403ad4383 100644 --- a/app/src/main/java/com/tangem/tap/proxy/UserWalletManagerImpl.kt +++ b/app/src/main/java/com/tangem/tap/proxy/UserWalletManagerImpl.kt @@ -40,7 +40,7 @@ class UserWalletManagerImpl( val userTokensRepository = requireNotNull(appStateHolder.userTokensRepository) { "userTokensRepository is null" } return if (card != null) { - userTokensRepository.getUserTokens(card) + userTokensRepository.getUserTokens(card, null) // refactor in [REDACTED_JIRA] .filter { val checkCustom = if (isExcludeCustom) { !it.isCustomCurrency(null) diff --git a/app/src/main/res/drawable-hdpi/img_meet_tangem.webp b/app/src/main/res/drawable-hdpi/img_meet_tangem.webp index 38e70d91d4..e9b4ef6b19 100644 Binary files a/app/src/main/res/drawable-hdpi/img_meet_tangem.webp and b/app/src/main/res/drawable-hdpi/img_meet_tangem.webp differ diff --git a/app/src/main/res/drawable-hdpi/img_meet_tangem2.webp b/app/src/main/res/drawable-hdpi/img_meet_tangem2.webp new file mode 100644 index 0000000000..38e70d91d4 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/img_meet_tangem2.webp differ diff --git a/app/src/main/res/drawable-mdpi/img_meet_tangem.webp b/app/src/main/res/drawable-mdpi/img_meet_tangem.webp index 2e5371a066..7bd5ec80c5 100644 Binary files a/app/src/main/res/drawable-mdpi/img_meet_tangem.webp and b/app/src/main/res/drawable-mdpi/img_meet_tangem.webp differ diff --git a/app/src/main/res/drawable-mdpi/img_meet_tangem2.webp b/app/src/main/res/drawable-mdpi/img_meet_tangem2.webp new file mode 100644 index 0000000000..2e5371a066 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/img_meet_tangem2.webp differ diff --git a/app/src/main/res/drawable-xhdpi/img_meet_tangem.webp b/app/src/main/res/drawable-xhdpi/img_meet_tangem.webp index 48326d332c..9bc7cba662 100644 Binary files a/app/src/main/res/drawable-xhdpi/img_meet_tangem.webp and b/app/src/main/res/drawable-xhdpi/img_meet_tangem.webp differ diff --git a/app/src/main/res/drawable-xhdpi/img_meet_tangem2.webp b/app/src/main/res/drawable-xhdpi/img_meet_tangem2.webp new file mode 100644 index 0000000000..48326d332c Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/img_meet_tangem2.webp differ diff --git a/app/src/main/res/drawable-xxhdpi/img_meet_tangem.webp b/app/src/main/res/drawable-xxhdpi/img_meet_tangem.webp index c8d74aeffe..941a671afb 100644 Binary files a/app/src/main/res/drawable-xxhdpi/img_meet_tangem.webp and b/app/src/main/res/drawable-xxhdpi/img_meet_tangem.webp differ diff --git a/app/src/main/res/drawable-xxhdpi/img_meet_tangem2.webp b/app/src/main/res/drawable-xxhdpi/img_meet_tangem2.webp new file mode 100644 index 0000000000..c8d74aeffe Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/img_meet_tangem2.webp differ diff --git a/app/src/main/res/drawable-xxxhdpi/img_meet_tangem.webp b/app/src/main/res/drawable-xxxhdpi/img_meet_tangem2.webp similarity index 100% rename from app/src/main/res/drawable-xxxhdpi/img_meet_tangem.webp rename to app/src/main/res/drawable-xxxhdpi/img_meet_tangem2.webp diff --git a/app/src/main/res/drawable-xxxhdpi/meet_tangem.webp b/app/src/main/res/drawable-xxxhdpi/meet_tangem.webp new file mode 100644 index 0000000000..8ca89394bc Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/meet_tangem.webp differ diff --git a/app/src/main/res/drawable/ic_launcher_foreground.xml b/app/src/main/res/drawable/ic_launcher_foreground.xml new file mode 100644 index 0000000000..3b1aea3367 --- /dev/null +++ b/app/src/main/res/drawable/ic_launcher_foreground.xml @@ -0,0 +1,21 @@ + + + + + + + diff --git a/app/src/main/res/drawable/ic_tangem_logo.xml b/app/src/main/res/drawable/ic_tangem_logo.xml index 08d67c8cf7..8cd0cc5ff8 100644 --- a/app/src/main/res/drawable/ic_tangem_logo.xml +++ b/app/src/main/res/drawable/ic_tangem_logo.xml @@ -1,33 +1,10 @@ - - - - - - - - - + android:width="51dp" + android:height="11dp" + android:viewportWidth="74" + android:viewportHeight="16"> + diff --git a/app/src/main/res/drawable/img_tangem_logo_96.xml b/app/src/main/res/drawable/img_tangem_logo_96.xml index 93fe8d9c0f..f12f6ccf0b 100644 --- a/app/src/main/res/drawable/img_tangem_logo_96.xml +++ b/app/src/main/res/drawable/img_tangem_logo_96.xml @@ -1,15 +1,15 @@ + android:viewportWidth="98" + android:viewportHeight="98"> + android:pathData="M59.285,24.464H38.715C35.469,24.464 33.848,24.464 32.607,25.095C31.517,25.652 30.629,26.536 30.076,27.626C29.444,28.867 29.444,30.488 29.444,33.734V37.175H68.555V33.734C68.555,30.488 68.555,28.867 67.924,27.626C67.367,26.536 66.483,25.648 65.393,25.095C64.152,24.464 62.531,24.464 59.285,24.464Z" /> + android:pathData="M55.516,47.93H68.554V64.082C68.554,67.328 68.554,68.949 67.923,70.19C67.366,71.28 66.482,72.168 65.392,72.721C64.151,73.353 62.53,73.353 59.284,73.353H55.52L55.516,47.93Z" /> + android:pathData="M29.444,47.93H42.479V73.353H38.715C35.469,73.353 33.848,73.353 32.607,72.721C31.517,72.168 30.633,71.28 30.076,70.19C29.444,68.949 29.444,67.328 29.444,64.082V47.93Z" /> diff --git a/app/src/main/res/drawable/splash_logo.xml b/app/src/main/res/drawable/splash_logo.xml index 29cb6365cf..ef37dfda51 100644 --- a/app/src/main/res/drawable/splash_logo.xml +++ b/app/src/main/res/drawable/splash_logo.xml @@ -1,15 +1,15 @@ + android:viewportWidth="450" + android:viewportHeight="450"> + android:fillColor="#ffffff" + android:pathData="M284.96,82H165.04C146.12,82 136.67,82 129.44,85.68C123.08,88.93 117.91,94.08 114.68,100.44C111,107.67 111,117.12 111,136.04V156.1H339V136.04C339,117.12 339,107.67 335.32,100.44C332.07,94.08 326.92,88.91 320.56,85.68C313.33,82 303.88,82 284.96,82Z" /> + android:fillColor="#ffffff" + android:pathData="M262.99,218.8H338.99V312.96C338.99,331.88 338.99,341.33 335.31,348.56C332.07,354.92 326.91,360.09 320.56,363.32C313.32,367 303.87,367 284.95,367H263.01L262.99,218.8Z" /> + android:fillColor="#ffffff" + android:pathData="M111,218.8H186.99V367H165.04C146.12,367 136.67,367 129.44,363.32C123.08,360.09 117.93,354.92 114.68,348.56C111,341.33 111,331.88 111,312.96V218.8Z" /> diff --git a/app/src/main/res/layout/layout_onboarding_buttons_common.xml b/app/src/main/res/layout/layout_onboarding_buttons_common.xml index 919923f821..1c756307dc 100644 --- a/app/src/main/res/layout/layout_onboarding_buttons_common.xml +++ b/app/src/main/res/layout/layout_onboarding_buttons_common.xml @@ -8,7 +8,6 @@ - + \ No newline at end of file diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml new file mode 100644 index 0000000000..6f2acb4f09 --- /dev/null +++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.webp b/app/src/main/res/mipmap-hdpi/ic_launcher.webp index 553cf934c1..7ea0844e8f 100644 Binary files a/app/src/main/res/mipmap-hdpi/ic_launcher.webp and b/app/src/main/res/mipmap-hdpi/ic_launcher.webp differ diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_background.webp b/app/src/main/res/mipmap-hdpi/ic_launcher_background.webp new file mode 100644 index 0000000000..2c0847e8e4 Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher_background.webp differ diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp new file mode 100644 index 0000000000..2dfc3301bb Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp differ diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.webp b/app/src/main/res/mipmap-mdpi/ic_launcher.webp index 166f2867c7..606dc57185 100644 Binary files a/app/src/main/res/mipmap-mdpi/ic_launcher.webp and b/app/src/main/res/mipmap-mdpi/ic_launcher.webp differ diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_background.webp b/app/src/main/res/mipmap-mdpi/ic_launcher_background.webp new file mode 100644 index 0000000000..92e3a1a1bb Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher_background.webp differ diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp new file mode 100644 index 0000000000..f72de707f9 Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xhdpi/ic_launcher.webp index e143972134..6eddba5a47 100644 Binary files a/app/src/main/res/mipmap-xhdpi/ic_launcher.webp and b/app/src/main/res/mipmap-xhdpi/ic_launcher.webp differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_background.webp b/app/src/main/res/mipmap-xhdpi/ic_launcher_background.webp new file mode 100644 index 0000000000..d0f3046077 Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher_background.webp differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp new file mode 100644 index 0000000000..9fa7fa1a1a Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp index 8c9245318b..af45939d2f 100644 Binary files a/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp and b/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_background.webp b/app/src/main/res/mipmap-xxhdpi/ic_launcher_background.webp new file mode 100644 index 0000000000..a49f6d4d4d Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher_background.webp differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp new file mode 100644 index 0000000000..29f79d98c3 Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp index 3b746049eb..be8d793f03 100644 Binary files a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_background.webp b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_background.webp index 541a4842d7..d43e8c6889 100644 Binary files a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_background.webp and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_background.webp differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp deleted file mode 100644 index 6b7e439344..0000000000 Binary files a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp and /dev/null differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp new file mode 100644 index 0000000000..fee364db25 Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp differ diff --git a/app/src/main/res/values-v29/styles.xml b/app/src/main/res/values-v29/styles.xml new file mode 100644 index 0000000000..6d423390d2 --- /dev/null +++ b/app/src/main/res/values-v29/styles.xml @@ -0,0 +1,7 @@ + + + + + diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index f97ed69d87..52253e723d 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -68,10 +68,11 @@ 14dp false 14sp - @font/roboto_regular - 0 + @font/roboto_medium + 0.01 500 16sp + 4dp