diff --git a/app/src/main/java/com/tangem/tap/common/DialogManager.kt b/app/src/main/java/com/tangem/tap/common/DialogManager.kt index 07582f5c87..96cf1b874b 100644 --- a/app/src/main/java/com/tangem/tap/common/DialogManager.kt +++ b/app/src/main/java/com/tangem/tap/common/DialogManager.kt @@ -59,7 +59,7 @@ class DialogManager : StoreSubscriber { return } val context = context ?: return - if (dialog != null && dialog == state.dialog) return + if (dialog != null) return dialog = when (state.dialog) { is AppDialog.SimpleOkDialog -> SimpleOkDialog.create(state.dialog, context) @@ -101,7 +101,7 @@ class DialogManager : StoreSubscriber { is WalletConnectDialog.ApproveWcSession -> ApproveWcSessionDialog.create(state.dialog.session, state.dialog.networks, context) is WalletConnectDialog.ChooseNetwork -> - ChooseNetworkDialog.create(state.dialog.networks, context) + ChooseNetworkDialog.create(state.dialog.session, state.dialog.networks, context) is WalletConnectDialog.ClipboardOrScanQr -> ClipboardOrScanQrDialog.create(state.dialog.clipboardUri, context) is WalletConnectDialog.RequestTransaction -> diff --git a/app/src/main/java/com/tangem/tap/common/redux/global/GlobalMidlleware.kt b/app/src/main/java/com/tangem/tap/common/redux/global/GlobalMidlleware.kt index db795840ef..4d227fcd92 100644 --- a/app/src/main/java/com/tangem/tap/common/redux/global/GlobalMidlleware.kt +++ b/app/src/main/java/com/tangem/tap/common/redux/global/GlobalMidlleware.kt @@ -15,6 +15,7 @@ import com.tangem.tap.currenciesRepository import com.tangem.tap.domain.configurable.warningMessage.WarningMessagesManager import com.tangem.tap.features.send.redux.SendAction import com.tangem.tap.features.wallet.redux.WalletAction +import com.tangem.tap.network.exchangeServices.CardExchangeRules import com.tangem.tap.network.exchangeServices.CurrencyExchangeManager import com.tangem.tap.network.exchangeServices.mercuryo.MercuryoApi import com.tangem.tap.network.exchangeServices.mercuryo.MercuryoService @@ -23,11 +24,11 @@ import com.tangem.tap.preferencesStorage import com.tangem.tap.scope import com.tangem.tap.store import com.tangem.tap.tangemSdkManager -import java.util.Locale import kotlinx.coroutines.launch import org.rekotlin.Action import org.rekotlin.DispatchFunction import org.rekotlin.Middleware +import java.util.* class GlobalMiddleware { companion object { @@ -62,9 +63,11 @@ private fun handleAction(action: Action, appState: () -> AppState?, dispatch: Di } } is GlobalAction.RestoreAppCurrency -> { - store.dispatch(GlobalAction.RestoreAppCurrency.Success( - preferencesStorage.fiatCurrenciesPrefStorage.getAppCurrency() - )) + store.dispatch( + GlobalAction.RestoreAppCurrency.Success( + preferencesStorage.fiatCurrenciesPrefStorage.getAppCurrency(), + ), + ) } is GlobalAction.HideWarningMessage -> { store.state.globalState.warningManager?.let { @@ -107,7 +110,13 @@ private fun handleAction(action: Action, appState: () -> AppState?, dispatch: Di secret = mercuryoSecret, ) val sellService = MoonPayService(moonPayKey, moonPaySecretKey) - val exchangeManager = CurrencyExchangeManager(buyService, sellService) + val cardProvider = { store.state.globalState.scanResponse?.card } + + val exchangeManager = CurrencyExchangeManager( + buyService = buyService, + sellService = sellService, + primaryRules = CardExchangeRules(cardProvider), + ) store.dispatchOnMain(GlobalAction.ExchangeManager.Init.Success(exchangeManager)) store.dispatchOnMain(GlobalAction.ExchangeManager.Update) } @@ -127,7 +136,7 @@ private fun handleAction(action: Action, appState: () -> AppState?, dispatch: Di store.state.globalState.analyticsHandlers, currenciesRepository, action.additionalBlockchainsToDerive, - action.messageResId + action.messageResId, ) withMainContext { store.dispatch(GlobalAction.ScanFailsCounter.ChooseBehavior(result)) @@ -150,15 +159,15 @@ private fun handleAction(action: Action, appState: () -> AppState?, dispatch: Di is Result.Success -> { store.dispatchOnMain( GlobalAction.FetchUserCountry.Success( - countryCode = result.data.code.lowercase() - ) + countryCode = result.data.code.lowercase(), + ), ) } is Result.Failure -> { store.dispatchOnMain( GlobalAction.FetchUserCountry.Success( - countryCode = Locale.getDefault().country.lowercase() - ) + countryCode = Locale.getDefault().country.lowercase(), + ), ) } } 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 326b59acf3..e54c3744cb 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 @@ -68,16 +68,15 @@ class ScanProductTask( when (processorResult) { is CompletionResult.Success -> ScanTask().run(session) { scanTaskResult -> when (scanTaskResult) { - is CompletionResult.Success -> callback( - CompletionResult.Success( - processorResult.data + is CompletionResult.Success -> { + // it need because processorResult.data.card doesn't contains attestation result + // and CardWallet.derivedKeys + val processorScanResponseWithNewCard = processorResult.data.copy( + card = scanTaskResult.data ) - ) - is CompletionResult.Failure -> callback( - CompletionResult.Failure( - scanTaskResult.error - ) - ) + callback(CompletionResult.Success(processorScanResponseWithNewCard)) + } + is CompletionResult.Failure -> callback(CompletionResult.Failure(scanTaskResult.error)) } } is CompletionResult.Failure -> callback(CompletionResult.Failure(processorResult.error)) @@ -102,11 +101,11 @@ private class ScanNoteProcessor : ProductCommandProcessor { callback( CompletionResult.Success( ScanResponse( - card, - ProductType.Note, - session.environment.walletData - ) - ) + card = card, + productType = ProductType.Note, + walletData = session.environment.walletData, + ), + ), ) } } @@ -117,19 +116,17 @@ private class ScanWalletProcessor( ) : ProductCommandProcessor { var primaryCard: PrimaryCard? = null - override fun proceed( card: Card, session: CardSession, - callback: (result: CompletionResult) -> Unit + callback: (result: CompletionResult) -> Unit, ) { createMissingWalletsIfNeeded(card, session, callback) } - private fun createMissingWalletsIfNeeded( card: Card, session: CardSession, - callback: (result: CompletionResult) -> Unit + callback: (result: CompletionResult) -> Unit, ) { if (card.wallets.isEmpty() || card.firmwareVersion < FirmwareVersion.MultiWalletAvailable) { startLinkingForBackupIfNeeded(card, session, callback) @@ -146,18 +143,12 @@ private class ScanWalletProcessor( when (result) { is CompletionResult.Success -> { PreflightReadTask( - PreflightReadMode.FullCardRead, - card.cardId + readMode = PreflightReadMode.FullCardRead, + cardId = card.cardId ).run(session) { readResult -> when (readResult) { - is CompletionResult.Success -> { - startLinkingForBackupIfNeeded(card, session, callback) - } - is CompletionResult.Failure -> callback( - CompletionResult.Failure( - readResult.error - ) - ) + is CompletionResult.Success -> startLinkingForBackupIfNeeded(card, session, callback) + is CompletionResult.Failure -> callback(CompletionResult.Failure(readResult.error)) } } } @@ -165,18 +156,14 @@ private class ScanWalletProcessor( } } } - private fun startLinkingForBackupIfNeeded( card: Card, session: CardSession, - callback: (result: CompletionResult) -> Unit + callback: (result: CompletionResult) -> Unit, ) { - val activationIsFinished = - preferencesStorage.usedCardsPrefStorage.isActivationFinished(card.cardId) + val activationIsFinished = preferencesStorage.usedCardsPrefStorage.isActivationFinished(card.cardId) - if (card.backupStatus == Card.BackupStatus.NoBackup && - !activationIsFinished && card.wallets.isNotEmpty() - ) { + if (card.backupStatus == Card.BackupStatus.NoBackup && !activationIsFinished && card.wallets.isNotEmpty()) { StartPrimaryCardLinkingTask().run(session) { linkingResult -> when (linkingResult) { is CompletionResult.Success -> { @@ -192,11 +179,10 @@ private class ScanWalletProcessor( deriveKeysIfNeeded(card, session, callback) } } - private fun deriveKeysIfNeeded( card: Card, session: CardSession, - callback: (result: CompletionResult) -> Unit + callback: (result: CompletionResult) -> Unit, ) { scope.launch { val derivations = collectDerivations(card) @@ -235,12 +221,13 @@ private class ScanWalletProcessor( private suspend fun getBlockchainsToDerive(card: Card): List { val currenciesRepository = currenciesRepository ?: return emptyList() - val cardCurrencies = currenciesRepository.loadSavedCurrencies(card.cardId, card.settings.isHDWalletAllowed).toMutableList() + val cardCurrencies = currenciesRepository + .loadSavedCurrencies(card.cardId, card.settings.isHDWalletAllowed).toMutableList() val blockchainsToDerive = cardCurrencies.ifEmpty { mutableListOf( BlockchainNetwork(Blockchain.Bitcoin, card), - BlockchainNetwork(Blockchain.Ethereum, card) + BlockchainNetwork(Blockchain.Ethereum, card), ) } @@ -248,7 +235,7 @@ private class ScanWalletProcessor( blockchainsToDerive.addAll( listOf( BlockchainNetwork(Blockchain.Ethereum, card), - BlockchainNetwork(Blockchain.EthereumTestnet, card) + BlockchainNetwork(Blockchain.EthereumTestnet, card), ) ) } @@ -305,52 +292,44 @@ private class ScanTwinProcessor : ProductCommandProcessor { is CompletionResult.Success -> { val publicKey = card.getSingleWallet()?.publicKey if (publicKey == null) { - callback( - CompletionResult.Success( - ScanResponse( - card, - ProductType.Twins, - null - ) - ) - ) - return@run - } - val verified = - TwinsHelper.verifyTwinPublicKey(readDataResult.data.issuerData, publicKey) - if (verified) { - val twinPublicKey = readDataResult.data.issuerData.sliceArray(0 until 65) - val walletData = session.environment.walletData val response = ScanResponse( - card, - ProductType.Twins, - walletData, - twinPublicKey.toHexString() + card = card, + productType = ProductType.Twins, + walletData = null, ) callback(CompletionResult.Success(response)) + return@run + } + + val verified = TwinsHelper.verifyTwinPublicKey(readDataResult.data.issuerData, publicKey) + val response = if (verified) { + val twinPublicKey = readDataResult.data.issuerData.sliceArray(0 until 65) + val walletData = session.environment.walletData + ScanResponse( + card = card, + productType = ProductType.Twins, + walletData = walletData, + secondTwinPublicKey = twinPublicKey.toHexString(), + ) } else { - callback( - CompletionResult.Success( - ScanResponse( - card, - ProductType.Twins, - null - ) - ) + ScanResponse( + card = card, + productType = ProductType.Twins, + walletData = null, ) } + callback(CompletionResult.Success(response)) } - is CompletionResult.Failure -> + is CompletionResult.Failure -> { callback(CompletionResult.Success(ScanResponse(card, ProductType.Twins, null))) + } } } } - } fun Card.getCurvesForNonCreatedWallets(): List { val curvesPresent = wallets.map { it.curve }.toSet() - val curvesForNonCreatedWallets = supportedCurves - .subtract(curvesPresent + EllipticCurve.Secp256r1) + val curvesForNonCreatedWallets = supportedCurves.subtract(curvesPresent + EllipticCurve.Secp256r1) return curvesForNonCreatedWallets.toList() } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/demo/DemoHelper.kt b/app/src/main/java/com/tangem/tap/features/demo/DemoHelper.kt index 53a0878b74..72b7c51672 100644 --- a/app/src/main/java/com/tangem/tap/features/demo/DemoHelper.kt +++ b/app/src/main/java/com/tangem/tap/features/demo/DemoHelper.kt @@ -14,6 +14,7 @@ import com.tangem.common.CompletionResult import com.tangem.domain.common.ScanResponse import com.tangem.tap.common.extensions.dispatchNotification import com.tangem.tap.common.redux.AppState +import com.tangem.tap.features.details.redux.DetailsAction import com.tangem.tap.features.details.redux.walletconnect.WalletConnectAction import com.tangem.tap.features.onboarding.products.wallet.redux.BackupAction import com.tangem.tap.features.wallet.redux.WalletAction @@ -42,7 +43,8 @@ object DemoHelper { WalletAction.TradeCryptoAction.Buy::class.java, WalletAction.TradeCryptoAction.Sell::class.java, BackupAction.StartBackup::class.java, - WalletAction.ExploreAddress::class.java + WalletAction.ExploreAddress::class.java, + DetailsAction.ResetToFactory.Start::class.java, ) fun isDemoCard(scanResponse: ScanResponse): Boolean = isDemoCardId(scanResponse.card.cardId) diff --git a/app/src/main/java/com/tangem/tap/features/details/redux/DetailsAction.kt b/app/src/main/java/com/tangem/tap/features/details/redux/DetailsAction.kt index 9cb5cfe537..b421b69730 100644 --- a/app/src/main/java/com/tangem/tap/features/details/redux/DetailsAction.kt +++ b/app/src/main/java/com/tangem/tap/features/details/redux/DetailsAction.kt @@ -19,6 +19,7 @@ sealed class DetailsAction : Action { object ReCreateTwinsWallet : DetailsAction() sealed class ResetToFactory : DetailsAction() { + object Start : ResetToFactory() object Proceed : ResetToFactory() data class Confirm(val confirmed: Boolean) : ResetToFactory() object Failure : ResetToFactory() 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 537668094f..7825d58a8f 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 @@ -12,7 +12,7 @@ import com.tangem.tap.common.redux.global.GlobalAction import com.tangem.tap.common.redux.navigation.AppScreen import com.tangem.tap.common.redux.navigation.NavigationAction import com.tangem.tap.currenciesRepository -import com.tangem.tap.features.disclaimer.redux.DisclaimerAction +import com.tangem.tap.features.demo.DemoHelper import com.tangem.tap.features.onboarding.products.twins.redux.CreateTwinWalletMode import com.tangem.tap.features.onboarding.products.twins.redux.TwinCardsAction import com.tangem.tap.features.wallet.models.hasSendableAmountsOrPendingTransactions @@ -22,70 +22,74 @@ import com.tangem.tap.tangemSdkManager import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext +import org.rekotlin.Action import org.rekotlin.Middleware class DetailsMiddleware { private val eraseWalletMiddleware = EraseWalletMiddleware() private val manageSecurityMiddleware = ManageSecurityMiddleware() private val managePrivacyMiddleware = ManagePrivacyMiddleware() - val detailsMiddleware: Middleware = { _, _ -> + val detailsMiddleware: Middleware = { _, state -> { next -> { action -> - when (action) { - is DetailsAction.ResetToFactory -> eraseWalletMiddleware.handle(action) - is DetailsAction.ManageSecurity -> manageSecurityMiddleware.handle(action) - is DetailsAction.AppSettings -> managePrivacyMiddleware.handle(action) - is DetailsAction.ShowDisclaimer -> { - val uri = store.state.detailsState.cardTermsOfUseUrl - if (uri != null) { - store.dispatch(NavigationAction.OpenDocument(uri)) - } else { - store.dispatch(DisclaimerAction.ShowAcceptedDisclaimer) - store.dispatch(NavigationAction.NavigateTo(AppScreen.Disclaimer)) - } + handleAction(state, action) + next(action) + } + } + } + + private fun handleAction(state: () -> AppState?, action: Action) { + if (DemoHelper.tryHandle(state, action)) return + + when (action) { + is DetailsAction.ResetToFactory -> eraseWalletMiddleware.handle(action) + is DetailsAction.ManageSecurity -> manageSecurityMiddleware.handle(action) + is DetailsAction.AppSettings -> managePrivacyMiddleware.handle(action) + is DetailsAction.ShowDisclaimer -> { + val uri = store.state.detailsState.cardTermsOfUseUrl + if (uri != null) { + store.dispatch(NavigationAction.OpenDocument(uri)) + } + } + is DetailsAction.ReCreateTwinsWallet -> { + val wallet = + store.state.walletState.walletManagers.map { it.wallet }.firstOrNull() + if (wallet == null) { + store.dispatch(TwinCardsAction.SetMode(CreateTwinWalletMode.RecreateWallet)) + store.dispatch(NavigationAction.NavigateTo(AppScreen.OnboardingTwins)) + } else { + if (wallet.hasSendableAmountsOrPendingTransactions()) { + val walletIsNotEmpty = + store.state.globalState.resources.strings.walletIsNotEmpty + store.dispatchNotification(walletIsNotEmpty) + } else { + store.dispatch(TwinCardsAction.SetMode(CreateTwinWalletMode.RecreateWallet)) + store.dispatch(NavigationAction.NavigateTo(AppScreen.OnboardingTwins)) } - is DetailsAction.ReCreateTwinsWallet -> { - val wallet = - store.state.walletState.walletManagers.map { it.wallet }.firstOrNull() - if (wallet == null) { - store.dispatch(TwinCardsAction.SetMode(CreateTwinWalletMode.RecreateWallet)) - store.dispatch(NavigationAction.NavigateTo(AppScreen.OnboardingTwins)) - } else { - if (wallet.hasSendableAmountsOrPendingTransactions()) { - val walletIsNotEmpty = - store.state.globalState.resources.strings.walletIsNotEmpty - store.dispatchNotification(walletIsNotEmpty) - } else { - store.dispatch(TwinCardsAction.SetMode(CreateTwinWalletMode.RecreateWallet)) - store.dispatch(NavigationAction.NavigateTo(AppScreen.OnboardingTwins)) - } + } + } + is DetailsAction.CreateBackup -> { + store.state.detailsState.scanResponse?.let { + store.dispatch(NavigationAction.NavigateTo(AppScreen.OnboardingWallet)) + store.dispatch( + GlobalAction.Onboarding.Start( + it, + fromHomeScreen = false, + ), + ) + } + } + DetailsAction.ScanCard -> { + scope.launch { + when (val result = tangemSdkManager.scanCard()) { + is CompletionResult.Success -> { + val card = result.data + store.dispatchOnMain(DetailsAction.PrepareCardSettingsData(card)) } - } - is DetailsAction.CreateBackup -> { - store.state.detailsState.scanResponse?.let { - store.dispatch(NavigationAction.NavigateTo(AppScreen.OnboardingWallet)) - store.dispatch( - GlobalAction.Onboarding.Start( - it, - fromHomeScreen = false, - ), - ) - } - } - DetailsAction.ScanCard -> { - scope.launch { - when (val result = tangemSdkManager.scanCard()) { - is CompletionResult.Success -> { - val card = result.data - store.dispatchOnMain(DetailsAction.PrepareCardSettingsData(card)) - } - is CompletionResult.Failure -> { - } - } + is CompletionResult.Failure -> { } } } - next(action) } } } @@ -93,6 +97,9 @@ class DetailsMiddleware { class EraseWalletMiddleware { fun handle(action: DetailsAction.ResetToFactory) { when (action) { + is DetailsAction.ResetToFactory.Start -> { + store.dispatch(NavigationAction.NavigateTo(AppScreen.ResetToFactory)) + } is DetailsAction.ResetToFactory.Proceed -> { val card = store.state.detailsState.cardSettingsState?.card ?: return if (card.isTangemTwins()) { diff --git a/app/src/main/java/com/tangem/tap/features/details/redux/walletconnect/WalletConnectAction.kt b/app/src/main/java/com/tangem/tap/features/details/redux/walletconnect/WalletConnectAction.kt index 0c852b3467..14a871fbd9 100644 --- a/app/src/main/java/com/tangem/tap/features/details/redux/walletconnect/WalletConnectAction.kt +++ b/app/src/main/java/com/tangem/tap/features/details/redux/walletconnect/WalletConnectAction.kt @@ -47,7 +47,7 @@ sealed class WalletConnectAction : Action { val session: WalletConnectSession, ) : WalletConnectAction() - data class SelectNetwork(val networks: List) : WalletConnectAction() + data class SelectNetwork(val session: WalletConnectSession, val networks: List) : WalletConnectAction() data class ChooseNetwork(val blockchain: Blockchain) : WalletConnectAction() data class UpdateBlockchain( val updatedSession: WalletConnectSession, diff --git a/app/src/main/java/com/tangem/tap/features/details/redux/walletconnect/WalletConnectMiddleware.kt b/app/src/main/java/com/tangem/tap/features/details/redux/walletconnect/WalletConnectMiddleware.kt index 4694af35f2..d98fb0b0f5 100644 --- a/app/src/main/java/com/tangem/tap/features/details/redux/walletconnect/WalletConnectMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/details/redux/walletconnect/WalletConnectMiddleware.kt @@ -62,7 +62,14 @@ class WalletConnectMiddleware { } } is WalletConnectAction.SelectNetwork -> { - store.dispatch(GlobalAction.ShowDialog(WalletConnectDialog.ChooseNetwork(action.networks))) + store.dispatch( + GlobalAction.ShowDialog( + WalletConnectDialog.ChooseNetwork( + session = action.session, + networks = action.networks, + ), + ), + ) } is WalletConnectAction.ChooseNetwork -> { val data = state()?.walletConnectState?.newSessionData ?: return diff --git a/app/src/main/java/com/tangem/tap/features/details/redux/walletconnect/WalletConnectState.kt b/app/src/main/java/com/tangem/tap/features/details/redux/walletconnect/WalletConnectState.kt index 14181de2e6..0bdfaf69f6 100644 --- a/app/src/main/java/com/tangem/tap/features/details/redux/walletconnect/WalletConnectState.kt +++ b/app/src/main/java/com/tangem/tap/features/details/redux/walletconnect/WalletConnectState.kt @@ -95,10 +95,12 @@ sealed class WalletConnectDialog : StateDialog { object OpeningSessionRejected : WalletConnectDialog() object SessionTimeout : WalletConnectDialog() data class ApproveWcSession( - val session: WalletConnectSession, val networks: List, + val session: WalletConnectSession, + val networks: List, ) : WalletConnectDialog() data class ChooseNetwork( + val session: WalletConnectSession, val networks: List, ) : WalletConnectDialog() diff --git a/app/src/main/java/com/tangem/tap/features/details/ui/cardsettings/CardSettingsViewModel.kt b/app/src/main/java/com/tangem/tap/features/details/ui/cardsettings/CardSettingsViewModel.kt index a90886ff81..60affefd8b 100644 --- a/app/src/main/java/com/tangem/tap/features/details/ui/cardsettings/CardSettingsViewModel.kt +++ b/app/src/main/java/com/tangem/tap/features/details/ui/cardsettings/CardSettingsViewModel.kt @@ -3,8 +3,6 @@ package com.tangem.tap.features.details.ui.cardsettings import com.tangem.domain.common.getTwinCardIdForUser import com.tangem.domain.common.isTangemTwins import com.tangem.tap.common.redux.AppState -import com.tangem.tap.common.redux.navigation.AppScreen -import com.tangem.tap.common.redux.navigation.NavigationAction import com.tangem.tap.features.details.redux.CardSettingsState import com.tangem.tap.features.details.redux.DetailsAction import org.rekotlin.Store @@ -64,7 +62,7 @@ class CardSettingsViewModel(private val store: Store) { store.dispatch(DetailsAction.ManageSecurity.ChangeAccessCode) } is CardInfo.ResetToFactorySettings -> { - store.dispatch(NavigationAction.NavigateTo(AppScreen.ResetToFactory)) + store.dispatch(DetailsAction.ResetToFactory.Start) } is CardInfo.SecurityMode -> { store.dispatch(DetailsAction.ManageSecurity.OpenSecurity) diff --git a/app/src/main/java/com/tangem/tap/features/details/ui/common/DetailsComposeElements.kt b/app/src/main/java/com/tangem/tap/features/details/ui/common/DetailsComposeElements.kt index 4c5cd02e86..d8e6bf1b11 100644 --- a/app/src/main/java/com/tangem/tap/features/details/ui/common/DetailsComposeElements.kt +++ b/app/src/main/java/com/tangem/tap/features/details/ui/common/DetailsComposeElements.kt @@ -20,6 +20,7 @@ import androidx.compose.material.Text import androidx.compose.material.TopAppBar import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.colorResource import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource @@ -32,42 +33,61 @@ fun SettingsScreensScaffold( content: @Composable () -> Unit, background: @Composable (() -> Unit)? = null, fab: @Composable (() -> Unit)? = null, - titleRes: Int, + backgroundColor: Color = colorResource(id = R.color.background_primary), + titleRes: Int? = null, onBackClick: () -> Unit, modifier: Modifier = Modifier, ) { BackHandler(true, onBackClick) Scaffold( - topBar = { EmptyTopBarWithNavigation(onBackClick = onBackClick) }, + topBar = { + EmptyTopBarWithNavigation( + onBackClick = onBackClick, + backgroundColor = backgroundColor, + ) + }, modifier = modifier.systemBarsPadding(), - backgroundColor = colorResource(id = R.color.background_primary), + backgroundColor = backgroundColor, floatingActionButton = { fab?.invoke() }, ) { + if (titleRes != null) { + Box(modifier = modifier.fillMaxSize()) { + background?.invoke() - Box(modifier = modifier.fillMaxSize()) { - - background?.invoke() - - Column( - modifier = modifier.fillMaxWidth(), - ) { - Text( - text = stringResource(id = titleRes), - modifier = modifier.padding(start = 20.dp, end = 20.dp, bottom = 52.dp), - style = TangemTypography.headline1, - color = colorResource(id = R.color.text_primary_1), - ) - content() + Column(modifier = modifier.fillMaxWidth()) { + Text( + text = stringResource(id = titleRes), + modifier = modifier.padding(start = 20.dp, end = 20.dp, bottom = 52.dp), + style = TangemTypography.headline1, + color = colorResource(id = R.color.text_primary_1), + ) + content() + } } + } else { + content() } - } } +@Composable +fun ScreenTitle( + titleRes: Int, + modifier: Modifier = Modifier, +) { + Text( + text = stringResource(id = titleRes), + modifier = modifier.padding(start = 20.dp, end = 20.dp), + style = TangemTypography.headline1, + color = colorResource(id = R.color.text_primary_1), + ) +} + @Composable fun EmptyTopBarWithNavigation( onBackClick: () -> Unit, + backgroundColor: Color = colorResource(id = R.color.background_primary), modifier: Modifier = Modifier, ) { TopAppBar( @@ -81,7 +101,7 @@ fun EmptyTopBarWithNavigation( ) } }, - backgroundColor = colorResource(id = R.color.background_primary), + backgroundColor = backgroundColor, elevation = 0.dp, ) } diff --git a/app/src/main/java/com/tangem/tap/features/details/ui/details/DetailsScreen.kt b/app/src/main/java/com/tangem/tap/features/details/ui/details/DetailsScreen.kt index 8d256d2c8b..24129ec514 100644 --- a/app/src/main/java/com/tangem/tap/features/details/ui/details/DetailsScreen.kt +++ b/app/src/main/java/com/tangem/tap/features/details/ui/details/DetailsScreen.kt @@ -10,9 +10,10 @@ import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size -import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyRow import androidx.compose.foundation.lazy.items +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll import androidx.compose.material.Icon import androidx.compose.material.Text import androidx.compose.runtime.Composable @@ -24,6 +25,7 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.tangem.tap.common.compose.TangemTypography +import com.tangem.tap.features.details.ui.common.ScreenTitle import com.tangem.tap.features.details.ui.common.SettingsScreensScaffold import com.tangem.wallet.R @@ -34,10 +36,7 @@ fun DetailsScreen( modifier: Modifier = Modifier, ) { SettingsScreensScaffold( - content = { - Content(state = state, modifier = modifier) - }, - titleRes = R.string.details_title, + content = { Content(state = state, modifier = modifier) }, onBackClick = onBackPressed, ) } @@ -50,37 +49,32 @@ fun Content( Column( modifier = modifier .fillMaxSize() - .padding(bottom = 40.dp), + .verticalScroll(rememberScrollState()), ) { - LazyColumn( - modifier = modifier - .fillMaxWidth() - .padding(bottom = 40.dp) - .weight(1f), - ) { - items(state.elements) { - if (it == SettingsElement.WalletConnect) { - WalletConnectDetailsItem( - onItemsClick = state.onItemsClick, - modifier = modifier, - ) - } else { - DetailsItem( - item = it, - appCurrency = state.appCurrency, - onItemsClick = state.onItemsClick, - modifier = modifier, - ) - } + ScreenTitle(titleRes = R.string.details_title, modifier.padding(bottom = 52.dp)) + state.elements.map { + if (it == SettingsElement.WalletConnect) { + WalletConnectDetailsItem( + onItemsClick = state.onItemsClick, + modifier = modifier, + ) + } else { + DetailsItem( + item = it, + appCurrency = state.appCurrency, + onItemsClick = state.onItemsClick, + modifier = modifier, + ) } } + Spacer(modifier = modifier.weight(1f)) TangemSocialAccounts(state.tangemLinks, state.onSocialNetworkClick) Spacer(modifier = Modifier.size(12.dp)) Text( text = "${stringResource(id = state.appNameRes)} ${state.tangemVersion}", style = TangemTypography.caption, color = colorResource(id = R.color.text_tertiary), - modifier = modifier.padding(start = 16.dp, end = 16.dp), + modifier = modifier.padding(start = 16.dp, end = 16.dp, bottom = 40.dp), ) } } diff --git a/app/src/main/java/com/tangem/tap/features/details/ui/details/DetailsScreenState.kt b/app/src/main/java/com/tangem/tap/features/details/ui/details/DetailsScreenState.kt index 68c8dc4eb0..1962a53261 100644 --- a/app/src/main/java/com/tangem/tap/features/details/ui/details/DetailsScreenState.kt +++ b/app/src/main/java/com/tangem/tap/features/details/ui/details/DetailsScreenState.kt @@ -24,7 +24,8 @@ enum class SettingsElement( AppCurrency(R.drawable.ic_currency, R.string.details_row_title_currency), AppSettings(R.drawable.ic_settings, R.string.app_settings_title), LinkMoreCards(R.drawable.ic_more_cards, R.string.details_row_title_create_backup), - TermsOfService(R.drawable.ic_text, R.string.disclaimer_title), + TermsOfService(R.drawable.ic_text, R.string.disclaimer_title), // General Terms of Service of the App + TermsOfUse(R.drawable.ic_text, R.string.details_row_title_card_tou), // Terms of Use for S2C cards only PrivacyPolicy(R.drawable.ic_lock, R.string.details_row_privacy_policy), ; } diff --git a/app/src/main/java/com/tangem/tap/features/details/ui/details/DetailsViewModel.kt b/app/src/main/java/com/tangem/tap/features/details/ui/details/DetailsViewModel.kt index c732d4350e..97ce019a84 100644 --- a/app/src/main/java/com/tangem/tap/features/details/ui/details/DetailsViewModel.kt +++ b/app/src/main/java/com/tangem/tap/features/details/ui/details/DetailsViewModel.kt @@ -1,5 +1,6 @@ package com.tangem.tap.features.details.ui.details +import com.tangem.domain.common.TapWorkarounds.isStart2Coin import com.tangem.tap.common.feedback.FeedbackEmail import com.tangem.tap.common.feedback.SupportInfo import com.tangem.tap.common.redux.AppState @@ -9,6 +10,7 @@ import com.tangem.tap.common.redux.navigation.NavigationAction import com.tangem.tap.domain.extensions.isMultiwalletAllowed import com.tangem.tap.features.details.redux.DetailsAction import com.tangem.tap.features.details.redux.DetailsState +import com.tangem.tap.features.disclaimer.redux.DisclaimerAction import com.tangem.tap.features.home.LocaleRegionProvider import com.tangem.tap.features.home.RUSSIA_COUNTRY_CODE import com.tangem.tap.features.wallet.redux.WalletAction @@ -30,6 +32,7 @@ class DetailsViewModel(private val store: Store) { } SettingsElement.AppSettings -> null // TODO: until we implement settings from this screen SettingsElement.AppCurrency -> if (state.scanResponse?.card?.isMultiwalletAllowed != true) it else null + SettingsElement.TermsOfUse -> if (state.scanResponse?.card?.isStart2Coin == true) it else null else -> it } } @@ -72,6 +75,10 @@ class DetailsViewModel(private val store: Store) { store.dispatch(DetailsAction.CreateBackup) } SettingsElement.TermsOfService -> { + store.dispatch(DisclaimerAction.ShowAcceptedDisclaimer) + store.dispatch(NavigationAction.NavigateTo(AppScreen.Disclaimer)) + } + SettingsElement.TermsOfUse -> { store.dispatch(DetailsAction.ShowDisclaimer) } SettingsElement.PrivacyPolicy -> { diff --git a/app/src/main/java/com/tangem/tap/features/details/ui/resetcard/ResetCardScreen.kt b/app/src/main/java/com/tangem/tap/features/details/ui/resetcard/ResetCardScreen.kt index 1b8fec5cdb..2c07b092ad 100644 --- a/app/src/main/java/com/tangem/tap/features/details/ui/resetcard/ResetCardScreen.kt +++ b/app/src/main/java/com/tangem/tap/features/details/ui/resetcard/ResetCardScreen.kt @@ -1,13 +1,16 @@ package com.tangem.tap.features.details.ui.resetcard import androidx.compose.foundation.Image +import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.defaultMinSize import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.offset import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.material.Icon @@ -15,6 +18,7 @@ import androidx.compose.material.IconToggleButton import androidx.compose.material.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.colorResource import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource @@ -22,6 +26,7 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.tangem.tap.common.compose.TangemTypography import com.tangem.tap.features.details.ui.common.DetailsMainButton +import com.tangem.tap.features.details.ui.common.ScreenTitle import com.tangem.tap.features.details.ui.common.SettingsScreensScaffold import com.tangem.wallet.R @@ -31,14 +36,18 @@ fun ResetCardScreen( onBackPressed: () -> Unit, modifier: Modifier = Modifier, ) { - - SettingsScreensScaffold( - content = { ResetCardView(state = state, modifier = modifier) }, - background = - { Image(painter = painterResource(id = R.drawable.ic_reset_background), contentDescription = "") }, - titleRes = R.string.reset_card_to_factory_navigation_title, - onBackClick = onBackPressed, - ) + Box(modifier = modifier.background(colorResource(id = R.color.background_primary))) { + Image( + painter = painterResource(id = R.drawable.ic_reset_background), + contentDescription = "", + modifier = modifier.offset(y = (-16).dp), + ) + SettingsScreensScaffold( + content = { ResetCardView(state = state, modifier = modifier) }, + onBackClick = onBackPressed, + backgroundColor = Color.Transparent, + ) + } } @Composable @@ -51,7 +60,16 @@ fun ResetCardView( .fillMaxSize(), verticalArrangement = Arrangement.Bottom, ) { - + Box( + modifier = modifier, + ) { + ScreenTitle(titleRes = R.string.reset_card_to_factory_navigation_title) + } + Spacer( + modifier = modifier + .defaultMinSize(20.dp) + .weight(1f), + ) Text( text = stringResource(id = R.string.common_attention), modifier = modifier.padding(start = 20.dp, end = 20.dp), diff --git a/app/src/main/java/com/tangem/tap/features/details/ui/securitymode/SecurityModeScreen.kt b/app/src/main/java/com/tangem/tap/features/details/ui/securitymode/SecurityModeScreen.kt index 1f8692b350..e18146767f 100644 --- a/app/src/main/java/com/tangem/tap/features/details/ui/securitymode/SecurityModeScreen.kt +++ b/app/src/main/java/com/tangem/tap/features/details/ui/securitymode/SecurityModeScreen.kt @@ -6,10 +6,12 @@ import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.offset import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.selection.selectable import androidx.compose.material.RadioButton +import androidx.compose.material.RadioButtonDefaults import androidx.compose.material.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier @@ -45,7 +47,8 @@ fun SecurityModeOptions( Column( modifier = modifier .fillMaxSize() - .padding(bottom = 28.dp), + .padding(bottom = 28.dp) + .offset(y = (-16).dp), verticalArrangement = Arrangement.SpaceBetween, ) { state.availableOptions.map { @@ -85,12 +88,16 @@ fun SecurityOption( .selectable( selected = selected, onClick = { state.onNewModeSelected(option) }, ) - .padding(start = 20.dp, end = 20.dp, bottom = 32.dp), + .padding(start = 20.dp, end = 20.dp, top = 16.dp, bottom = 16.dp), ) { RadioButton( selected = selected, onClick = null, modifier = modifier.padding(end = 20.dp), + colors = RadioButtonDefaults.colors( + unselectedColor = colorResource(id = R.color.icon_secondary), + selectedColor = colorResource(id = R.color.icon_accent), + ), ) Column { diff --git a/app/src/main/java/com/tangem/tap/features/details/ui/walletconnect/WalletConnectScreen.kt b/app/src/main/java/com/tangem/tap/features/details/ui/walletconnect/WalletConnectScreen.kt index 086c2ae8b8..71a9386b36 100644 --- a/app/src/main/java/com/tangem/tap/features/details/ui/walletconnect/WalletConnectScreen.kt +++ b/app/src/main/java/com/tangem/tap/features/details/ui/walletconnect/WalletConnectScreen.kt @@ -52,11 +52,9 @@ fun WalletConnectScreen( } }, fab = { - AddSessionFab( - onAddSession = { - state.onAddSession(context.getFromClipboard()?.toString()) - }, - ) + if (!state.isLoading) { + AddSessionFab(onAddSession = { state.onAddSession(context.getFromClipboard()?.toString()) }) + } }, titleRes = R.string.wallet_connect_title, onBackClick = onBackPressed, diff --git a/app/src/main/java/com/tangem/tap/features/details/ui/walletconnect/dialogs/ApproveWcSessionDialog.kt b/app/src/main/java/com/tangem/tap/features/details/ui/walletconnect/dialogs/ApproveWcSessionDialog.kt index 1834618476..4af9323fa1 100644 --- a/app/src/main/java/com/tangem/tap/features/details/ui/walletconnect/dialogs/ApproveWcSessionDialog.kt +++ b/app/src/main/java/com/tangem/tap/features/details/ui/walletconnect/dialogs/ApproveWcSessionDialog.kt @@ -27,7 +27,8 @@ class ApproveWcSessionDialog { } if (networks.size > 1) { setNeutralButton(context.getText(R.string.wallet_connect_select_network)) { _, _ -> - store.dispatch(WalletConnectAction.SelectNetwork(networks)) + store.dispatch(GlobalAction.HideDialog(WalletConnectDialog.ApproveWcSession(session, networks))) + store.dispatch(WalletConnectAction.SelectNetwork(session = session, networks = networks)) } } setNegativeButton(context.getText(R.string.common_reject)) { _, _ -> diff --git a/app/src/main/java/com/tangem/tap/features/details/ui/walletconnect/dialogs/ChooseNetworkDialog.kt b/app/src/main/java/com/tangem/tap/features/details/ui/walletconnect/dialogs/ChooseNetworkDialog.kt index 2b1779dafc..dedf44dd04 100644 --- a/app/src/main/java/com/tangem/tap/features/details/ui/walletconnect/dialogs/ChooseNetworkDialog.kt +++ b/app/src/main/java/com/tangem/tap/features/details/ui/walletconnect/dialogs/ChooseNetworkDialog.kt @@ -5,22 +5,26 @@ import androidx.appcompat.app.AlertDialog import com.tangem.blockchain.common.Blockchain import com.tangem.tap.common.redux.global.GlobalAction import com.tangem.tap.features.details.redux.walletconnect.WalletConnectAction +import com.tangem.tap.features.details.redux.walletconnect.WalletConnectSession import com.tangem.tap.store import com.tangem.wallet.R object ChooseNetworkDialog { fun create( - blockchains: List, + session: WalletConnectSession, + networks: List, context: Context, ): AlertDialog { return AlertDialog.Builder(context) .setTitle(context.getString(R.string.wallet_connect_select_network)) - .setNegativeButton(context.getString(R.string.common_cancel)) { _, _ -> /* no-op */ } + .setNegativeButton(context.getString(R.string.common_cancel)) { _, _ -> + store.dispatch(WalletConnectAction.FailureEstablishingSession(session.session)) + } .setOnDismissListener { store.dispatch(GlobalAction.HideDialog()) } - .setSingleChoiceItems(blockchains.map { it.fullName }.toTypedArray(), 0) { _, which -> - blockchains.getOrNull(which)?.let { selectedBlockchain -> + .setSingleChoiceItems(networks.map { it.fullName }.toTypedArray(), 0) { _, which -> + networks.getOrNull(which)?.let { selectedBlockchain -> store.dispatch( WalletConnectAction.ChooseNetwork( blockchain = selectedBlockchain, 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 5eaa250690..df1e3dd5ba 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 @@ -219,8 +219,10 @@ private fun sendTransaction( return@launch } - withContext(Dispatchers.Main) { + withMainContext { + dispatch(SendAction.ChangeSendButtonState(ButtonState.ENABLED)) tangemSdk.config.linkedTerminal = isLinkedTerminal + when (sendResult) { is SimpleResult.Success -> { store.state.globalState.analyticsHandlers?.triggerEvent( @@ -260,12 +262,12 @@ private fun sendTransaction( card = card, ) - val error = (sendResult.error as? BlockchainSdkError) ?: return@withContext + val error = (sendResult.error as? BlockchainSdkError) ?: return@withMainContext when (error) { is BlockchainSdkError.WrappedTangemError -> { - val tangemSdkError = (error.tangemError as? TangemSdkError) ?: return@withContext - if (tangemSdkError is TangemSdkError.UserCancelled) return@withContext + val tangemSdkError = (error.tangemError as? TangemSdkError) ?: return@withMainContext + if (tangemSdkError is TangemSdkError.UserCancelled) return@withMainContext dispatch(SendAction.Dialog.SendTransactionFails.CardSdkError(tangemSdkError)) } @@ -294,7 +296,6 @@ private fun sendTransaction( } } } - dispatch(SendAction.ChangeSendButtonState(ButtonState.ENABLED)) } } } diff --git a/app/src/main/java/com/tangem/tap/network/exchangeServices/CardExchangeRules.kt b/app/src/main/java/com/tangem/tap/network/exchangeServices/CardExchangeRules.kt new file mode 100644 index 0000000000..d6c0cfe6c5 --- /dev/null +++ b/app/src/main/java/com/tangem/tap/network/exchangeServices/CardExchangeRules.kt @@ -0,0 +1,54 @@ +package com.tangem.tap.network.exchangeServices + +import com.tangem.common.card.Card +import com.tangem.domain.common.TapWorkarounds.isStart2Coin +import com.tangem.tap.features.demo.isDemoCard +import com.tangem.tap.features.wallet.models.Currency + +/** +[REDACTED_AUTHOR] + */ +class CardExchangeRules( + val cardProvider: () -> Card?, +) : ExchangeRules { + + override fun isBuyAllowed(): Boolean { + val card = cardProvider() ?: return false + + return when { + card.isDemoCard() -> false + card.isStart2Coin -> false + else -> true + } + } + + override fun isSellAllowed(): Boolean { + val card = cardProvider() ?: return false + + return when { + card.isDemoCard() -> false + card.isStart2Coin -> false + else -> true + } + } + + override fun availableForBuy(currency: Currency): Boolean { + val card = cardProvider() ?: return false + + return when { + card.isDemoCard() -> false + card.isStart2Coin -> false + else -> true + } + } + + override fun availableForSell(currency: Currency): Boolean { + val card = cardProvider() ?: return false + + return when { + card.isDemoCard() -> false + card.isStart2Coin -> false + else -> true + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/network/exchangeServices/CurrencyExchangeManager.kt b/app/src/main/java/com/tangem/tap/network/exchangeServices/CurrencyExchangeManager.kt index 8d1085d316..39f201a9b1 100644 --- a/app/src/main/java/com/tangem/tap/network/exchangeServices/CurrencyExchangeManager.kt +++ b/app/src/main/java/com/tangem/tap/network/exchangeServices/CurrencyExchangeManager.kt @@ -23,6 +23,7 @@ import java.math.BigDecimal class CurrencyExchangeManager( private val buyService: ExchangeService, private val sellService: ExchangeService, + private val primaryRules: ExchangeRules, ) : ExchangeService, ExchangeUrlBuilder { override suspend fun update() { @@ -30,10 +31,16 @@ class CurrencyExchangeManager( sellService.update() } - override fun isBuyAllowed(): Boolean = buyService.isBuyAllowed() - override fun isSellAllowed(): Boolean = sellService.isSellAllowed() - override fun availableForBuy(currency: Currency): Boolean = buyService.availableForBuy(currency) - override fun availableForSell(currency: Currency): Boolean = sellService.availableForSell(currency) + override fun isBuyAllowed(): Boolean = primaryRules.isBuyAllowed() && buyService.isBuyAllowed() + override fun isSellAllowed(): Boolean = primaryRules.isSellAllowed() && sellService.isSellAllowed() + + override fun availableForBuy(currency: Currency): Boolean { + return primaryRules.availableForBuy(currency) && buyService.availableForBuy(currency) + } + + override fun availableForSell(currency: Currency): Boolean { + return primaryRules.availableForSell(currency) && sellService.availableForSell(currency) + } override fun getUrl( action: Action, diff --git a/app/src/main/java/com/tangem/tap/network/exchangeServices/ExchangeService.kt b/app/src/main/java/com/tangem/tap/network/exchangeServices/ExchangeService.kt index 712fd2d5e0..34f37dddf9 100644 --- a/app/src/main/java/com/tangem/tap/network/exchangeServices/ExchangeService.kt +++ b/app/src/main/java/com/tangem/tap/network/exchangeServices/ExchangeService.kt @@ -3,8 +3,11 @@ package com.tangem.tap.network.exchangeServices import com.tangem.blockchain.common.Blockchain import com.tangem.tap.features.wallet.models.Currency -interface ExchangeService { +interface ExchangeService: ExchangeRules { suspend fun update() +} + +interface ExchangeRules { fun isBuyAllowed(): Boolean fun isSellAllowed(): Boolean fun availableForBuy(currency: Currency):Boolean diff --git a/app/src/main/res/values-de/strings_final.xml b/app/src/main/res/values-de/strings_final.xml index 4fb2fa8dcb..96c0876eff 100644 --- a/app/src/main/res/values-de/strings_final.xml +++ b/app/src/main/res/values-de/strings_final.xml @@ -54,7 +54,7 @@ Hide token Hide %s Hide - You hide the token from the main screen, but you can add it back at any time. + You are about to hide this token from the main screen. You can add it back anytime through the manage tokens page. Unable to hide %s The %s token is the main currency on the %s network and cannot be hidden as long as you have other tokens on this network in the list. diff --git a/app/src/main/res/values-fr/strings_final.xml b/app/src/main/res/values-fr/strings_final.xml index 55f342c1af..3fe6eb9f17 100644 --- a/app/src/main/res/values-fr/strings_final.xml +++ b/app/src/main/res/values-fr/strings_final.xml @@ -54,7 +54,7 @@ Hide token Hide %s Hide - You hide the token from the main screen, but you can add it back at any time. + You are about to hide this token from the main screen. You can add it back anytime through the manage tokens page. Unable to hide %s The %s token is the main currency on the %s network and cannot be hidden as long as you have other tokens on this network in the list. diff --git a/app/src/main/res/values-it/strings_final.xml b/app/src/main/res/values-it/strings_final.xml index 939315c9a1..afe988cb58 100644 --- a/app/src/main/res/values-it/strings_final.xml +++ b/app/src/main/res/values-it/strings_final.xml @@ -54,7 +54,7 @@ Hide token Hide %s Hide - You hide the token from the main screen, but you can add it back at any time. + You are about to hide this token from the main screen. You can add it back anytime through the manage tokens page. Unable to hide %s The %s token is the main currency on the %s network and cannot be hidden as long as you have other tokens on this network in the list. diff --git a/app/src/main/res/values-ru/strings_final.xml b/app/src/main/res/values-ru/strings_final.xml index f7ddc1c883..415a83ca56 100644 --- a/app/src/main/res/values-ru/strings_final.xml +++ b/app/src/main/res/values-ru/strings_final.xml @@ -59,7 +59,7 @@ Скрыть токен Скрыть %s Скрыть - Вы скрываете токен с главного экрана, но в любой момент сможете добавить его обратно. + Вы скрываете токен с главного экрана, но в любой момент сможете добавить его обратно через страницу управления токенами. Невозможно скрыть %s Токен %s является основной валютой в сети %s и не может быть скрыт до тех пор, пока у вас в списке есть другие токены этой сети. diff --git a/app/src/main/res/values/strings_final.xml b/app/src/main/res/values/strings_final.xml index 53782ce6b3..ca04743898 100644 --- a/app/src/main/res/values/strings_final.xml +++ b/app/src/main/res/values/strings_final.xml @@ -59,7 +59,7 @@ Hide token Hide %s Hide - You are about to hide this token from the main screen. You can add it back anytime. + You are about to hide this token from the main screen. You can add it back anytime through the manage tokens page. Unable to hide %s The %s token is the main currency on the %s network and cannot be hidden as long as you have other tokens on this network in the list.