Updated on 2026-08-14

This commit is contained in:
Tangem 2024-08-12 11:09:55 +02:00
commit aa50a54d59
28 changed files with 254 additions and 175 deletions

View file

@ -27,7 +27,6 @@ import com.arkivanov.essenty.lifecycle.asEssentyLifecycle
import com.google.android.material.snackbar.BaseTransientBottomBar
import com.google.android.material.snackbar.Snackbar
import com.tangem.common.routing.AppRoute
import com.tangem.common.routing.AppRouter
import com.tangem.common.routing.entity.SerializableIntent
import com.tangem.core.analytics.api.AnalyticsEventHandler
import com.tangem.core.decompose.context.AppComponentContext
@ -181,9 +180,6 @@ class MainActivity : AppCompatActivity(), SnackbarHandler, ActivityResultCallbac
@Inject
internal lateinit var routingComponentFactory: RoutingComponent.Factory
@Inject
internal lateinit var appRouter: AppRouter
@Inject
lateinit var pushNotificationsRouter: PushNotificationsRouter
@ -512,7 +508,9 @@ class MainActivity : AppCompatActivity(), SnackbarHandler, ActivityResultCallbac
}
private fun navigateToInitialScreenIfNeeded(intentWhichStartedActivity: Intent?) {
val backStack = appRouter.stack
val backStack = appRouterConfig.stack ?: emptyList()
// TODO move inital navigation to navigation component ([REDACTED_JIRA])
val isOnlyInitialRoute = backStack.all { it is AppRoute.Initial }
val isOnInitialScreen = backStack.all { it is AppRoute.Welcome || it is AppRoute.Home }
val isNotScannedBefore = store.state.globalState.scanResponse == null
val isOnboardingServiceNotActive = !store.state.globalState.onboardingState.onboardingStarted
@ -524,6 +522,7 @@ class MainActivity : AppCompatActivity(), SnackbarHandler, ActivityResultCallbac
backStack.isEmpty() -> {
navigateToInitialScreen(intentWhichStartedActivity)
}
isOnlyInitialRoute -> navigateToInitialScreen(intentWhichStartedActivity)
else -> Unit
}
}

View file

@ -3,15 +3,16 @@ package com.tangem.tap.common.extensions
import com.tangem.blockchain.common.Blockchain
import com.tangem.common.extensions.remove
fun Blockchain.getNetworkName(): String {
fun Blockchain.getNetworkStandardName(): String {
return when (this) {
Blockchain.Ethereum, Blockchain.EthereumTestnet -> "ERC20"
Blockchain.BSC, Blockchain.BSCTestnet -> "BEP20"
Blockchain.Binance, Blockchain.BinanceTestnet -> "BEP2"
Blockchain.Tron, Blockchain.TronTestnet -> "TRC20"
Blockchain.TON -> "TON"
else -> ""
}
}
val Blockchain.fullNameWithoutTestnet
get() = this.fullName.remove(" Testnet")
val Blockchain.networkNameWithoutTestnet
get() = this.getNetworkName().remove(" Testnet")

View file

@ -25,7 +25,7 @@ internal class DefaultCustomTokenRouter : CustomTokenRouter {
val alert = AppDialog.SimpleOkDialogRes(
headerId = R.string.common_warning,
messageId = R.string.alert_manage_tokens_unsupported_curve_message,
args = listOf(blockchain.fullName),
args = listOf(blockchain.getNetworkName()),
)
store.dispatchDialogShow(alert)
}

View file

@ -190,7 +190,7 @@ internal class AddCustomTokenViewModel @Inject constructor(
)
DerivationPathSelectorType.BLOCKCHAIN -> SelectorItem.TitleWithSubtitle(
title = TextReference.Str(derivationPath),
subtitle = TextReference.Str(blockchain.fullName),
subtitle = TextReference.Str(blockchain.getNetworkName()),
blockchain = blockchain,
)
}
@ -204,7 +204,7 @@ internal class AddCustomTokenViewModel @Inject constructor(
)
} else {
SelectorItem.Title(
title = TextReference.Str(blockchain.fullName),
title = TextReference.Str(blockchain.getNetworkName()),
blockchain = blockchain,
)
}
@ -501,7 +501,7 @@ internal class AddCustomTokenViewModel @Inject constructor(
return buildSet {
if (!isSupportedToken && !isContractAddressFieldEmpty) {
add(AddCustomTokenWarning.UnsupportedToken(networkSelectorValue.fullName))
add(AddCustomTokenWarning.UnsupportedToken(networkSelectorValue.getNetworkName()))
}
if (isCustomTokenAlreadyAdded()) {
add(AddCustomTokenWarning.TokenAlreadyAdded)

View file

@ -1,25 +1,18 @@
package com.tangem.tap.features.details.ui.securitymode
import android.os.Bundle
import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import arrow.core.getOrElse
import com.tangem.common.CompletionResult
import com.tangem.common.core.TangemSdkError
import com.tangem.common.routing.AppRoute
import com.tangem.common.routing.AppRouter
import com.tangem.common.routing.bundle.unbundle
import com.tangem.core.analytics.Analytics
import com.tangem.domain.common.util.cardTypesResolver
import com.tangem.domain.wallets.models.UserWallet
import com.tangem.domain.wallets.models.UserWalletId
import com.tangem.domain.wallets.usecase.GetUserWalletUseCase
import com.tangem.tap.common.analytics.events.AnalyticsParam
import com.tangem.tap.common.analytics.events.Settings
import com.tangem.tap.common.extensions.dispatchNavigationAction
import com.tangem.tap.domain.sdk.TangemSdkManager
import com.tangem.tap.features.details.redux.SecurityOption
import com.tangem.tap.features.details.ui.cardsettings.domain.CardSettingsInteractor
import com.tangem.tap.features.details.ui.common.utils.getAllowedSecurityOptions
import com.tangem.tap.features.details.ui.common.utils.getCurrentSecurityOption
import com.tangem.tap.store
@ -31,24 +24,18 @@ import javax.inject.Inject
@HiltViewModel
internal class SecurityModeViewModel @Inject constructor(
private val getUserWalletUseCase: GetUserWalletUseCase,
private val tangemSdkManager: TangemSdkManager,
savedStateHandle: SavedStateHandle,
private val cardSettingsInteractor: CardSettingsInteractor,
) : ViewModel() {
private val userWalletId = savedStateHandle.get<Bundle>(AppRoute.DetailsSecurity.USER_WALLET_ID_KEY)
?.unbundle(UserWalletId.serializer())
?: error("UserWalletId is required for SecurityModeViewModel")
private val scannedScanResponse = cardSettingsInteractor.scannedScanResponse.value
?: error("Scan response is null")
val screenState = MutableStateFlow(
value = getInitialState(),
)
val screenState = MutableStateFlow(value = getInitialState())
private fun getInitialState(): SecurityModeScreenState {
val userWallet = getUserWallet()
val scanResponse = userWallet.scanResponse
val card = scanResponse.card
val cardTypesResolver = scanResponse.cardTypesResolver
val card = scannedScanResponse.card
val cardTypesResolver = scannedScanResponse.cardTypesResolver
val currentSecurityOption = getCurrentSecurityOption(card)
val allowedSecurityOptions = getAllowedSecurityOptions(card, cardTypesResolver, currentSecurityOption)
@ -66,14 +53,13 @@ internal class SecurityModeViewModel @Inject constructor(
screenState.update { state ->
state.copy(
selectedSecurityMode = securityOption,
isSaveChangesEnabled = securityOption != getCurrentSecurityOption(getUserWallet().scanResponse.card),
isSaveChangesEnabled = securityOption != getCurrentSecurityOption(scannedScanResponse.card),
)
}
}
private fun saveChanges() {
val userWallet = getUserWallet()
val cardId = userWallet.cardId
val cardId = scannedScanResponse.card.cardId
val selectedOption = screenState.value.selectedSecurityMode
viewModelScope.launch {
@ -83,6 +69,15 @@ internal class SecurityModeViewModel @Inject constructor(
SecurityOption.AccessCode -> tangemSdkManager.setAccessCode(cardId)
}
cardSettingsInteractor.update {
it.copy(
card = it.card.copy(
isAccessCodeSet = selectedOption == SecurityOption.AccessCode,
isPasscodeSet = selectedOption == SecurityOption.PassCode,
),
)
}
val paramValue = AnalyticsParam.SecurityMode.from(selectedOption)
when (result) {
is CompletionResult.Success -> {
@ -100,10 +95,4 @@ internal class SecurityModeViewModel @Inject constructor(
}
}
}
private fun getUserWallet(): UserWallet {
return getUserWalletUseCase(userWalletId).getOrElse {
error("Unable to get user wallet $userWalletId: $it")
}
}
}

View file

@ -51,7 +51,7 @@ internal class DefaultTokensListRouter : TokensListRouter {
val alert = AppDialog.SimpleOkDialogRes(
headerId = R.string.common_warning,
messageId = R.string.alert_manage_tokens_unsupported_curve_message,
args = listOf(blockchain.fullName),
args = listOf(blockchain.getNetworkName()),
)
store.dispatchDialogShow(alert)
}

View file

@ -24,8 +24,8 @@ import com.tangem.domain.tokens.AddCryptoCurrenciesUseCase
import com.tangem.domain.tokens.GetCryptoCurrenciesUseCase
import com.tangem.domain.tokens.TokenWithBlockchain
import com.tangem.domain.wallets.usecase.GetSelectedWalletSyncUseCase
import com.tangem.tap.common.extensions.fullNameWithoutTestnet
import com.tangem.tap.common.extensions.getNetworkName
import com.tangem.tap.common.extensions.networkNameWithoutTestnet
import com.tangem.tap.common.extensions.getNetworkStandardName
import com.tangem.tap.features.customtoken.impl.presentation.models.SupportBlockchainType
import com.tangem.tap.features.tokens.impl.domain.TokensListInteractor
import com.tangem.tap.features.tokens.impl.domain.models.Token
@ -185,7 +185,7 @@ internal class TokensListViewModel @Inject constructor(
private fun createManageNetworkContent(network: Network): NetworkItemState.ManageContent {
return NetworkItemState.ManageContent(
name = network.blockchain.fullNameWithoutTestnet.uppercase(),
name = network.blockchain.networkNameWithoutTestnet.uppercase(),
protocolName = getNetworkProtocolName(network),
iconResId = mutableIntStateOf(value = getNetworkIconResId(network.address, network.blockchain)),
isMainNetwork = isMainNetwork(network),
@ -214,7 +214,7 @@ internal class TokensListViewModel @Inject constructor(
private fun createReadNetworkContent(network: Network): NetworkItemState.ReadContent {
return NetworkItemState.ReadContent(
name = network.blockchain.fullNameWithoutTestnet.uppercase(),
name = network.blockchain.networkNameWithoutTestnet.uppercase(),
protocolName = getNetworkProtocolName(network),
iconResId = mutableIntStateOf(value = getNetworkIconResId(network.address, network.blockchain)),
isMainNetwork = isMainNetwork(network),
@ -227,7 +227,7 @@ internal class TokensListViewModel @Inject constructor(
return if (network.address == null) {
MAIN_NETWORK_LABEL
} else {
network.blockchain.getNetworkName().uppercase()
network.blockchain.getNetworkStandardName().uppercase()
}
}
@ -361,7 +361,7 @@ internal class TokensListViewModel @Inject constructor(
router.openUnableHideMainTokenAlert(
tokenName = blockchain.name,
tokenSymbol = blockchain.currency,
networkName = blockchain.fullName,
networkName = blockchain.getNetworkName(),
)
} else if (isAddedOnMainScreen) {
router.openRemoveWalletAlert(
@ -431,7 +431,7 @@ internal class TokensListViewModel @Inject constructor(
} else {
when (isUnsupportedToken(token.blockchain)) {
SupportTokensState.NetworkTokensUnsupported -> {
router.openNetworkTokensNotSupportAlert(token.blockchain.fullName)
router.openNetworkTokensNotSupportAlert(token.blockchain.getNetworkName())
}
SupportTokensState.SupportedToken -> {
analyticsSender.sendWhenTokenAdded(token.token)

View file

@ -44,7 +44,7 @@ internal class DefaultRoutingComponent @AssistedInject constructor(
private fun getInitialRoute(): AppRoute = AppRoute.Initial
private fun child(route: AppRoute, context: ComponentContext): Child {
return childFactory.createChild(route, { childByContext(context) })
return childFactory.createChild(route) { childByContext(context) }
}
@AssistedFactory

View file

@ -58,7 +58,7 @@ internal class CryptoCurrenciesMocks(private val scanResponse: ScanResponse) {
network = Network(
id = Network.ID(value = blockchain.id),
backendId = "NEVER-MIND",
name = blockchain.fullName,
name = blockchain.getNetworkName(),
currencySymbol = "NEVER-MIND",
derivationPath = Network.DerivationPath.Custom(
value = derivationBlockchain.derivationPath(

View file

@ -28,13 +28,14 @@ import com.tangem.common.ui.R
import com.tangem.common.ui.bottomsheet.permission.state.*
import com.tangem.core.ui.components.*
import com.tangem.core.ui.components.appbar.models.TopAppBarButtonUM
import com.tangem.core.ui.components.atoms.text.EllipsisText
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheet
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
import com.tangem.core.ui.components.containers.FooterContainer
import com.tangem.core.ui.components.inputrow.InputRowDefault
import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.extensions.resolveReference
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.extensions.wrappedList
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreview
import kotlinx.collections.immutable.ImmutableList
@ -136,33 +137,13 @@ private fun ApprovalBottomSheetInfo(data: GiveTxPermissionState.ReadyForRequest)
@Composable
private fun FeeItem(fee: TextReference) {
Row(
InputRowDefault(
title = resourceReference(R.string.common_network_fee_title),
text = fee,
modifier = Modifier
.fillMaxWidth()
.clip(TangemTheme.shapes.roundedCornersXMedium)
.background(TangemTheme.colors.background.action)
.padding(
top = TangemTheme.dimens.spacing16,
bottom = TangemTheme.dimens.spacing16,
start = TangemTheme.dimens.spacing12,
end = TangemTheme.dimens.spacing16,
),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically,
) {
Text(
text = stringResource(R.string.common_network_fee_title),
color = TangemTheme.colors.text.primary1,
style = TangemTheme.typography.subtitle1,
maxLines = 1,
)
EllipsisText(
text = fee.resolveReference(),
color = TangemTheme.colors.text.tertiary,
style = TangemTheme.typography.body1,
modifier = Modifier.padding(start = TangemTheme.dimens.spacing16),
)
}
.background(TangemTheme.colors.background.action),
)
}
@Composable
@ -193,7 +174,7 @@ private fun AmountItem(
top = TangemTheme.dimens.spacing16,
bottom = TangemTheme.dimens.spacing16,
start = TangemTheme.dimens.spacing12,
end = TangemTheme.dimens.spacing16,
end = TangemTheme.dimens.spacing12,
),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically,
@ -204,6 +185,7 @@ private fun AmountItem(
style = TangemTheme.typography.subtitle1,
maxLines = 1,
)
SpacerWMax()
Text(
text = stringResource(
when (approveType) {
@ -215,6 +197,12 @@ private fun AmountItem(
style = TangemTheme.typography.body1,
maxLines = 1,
)
Icon(
painter = rememberVectorPainter(ImageVector.vectorResource(id = R.drawable.ic_chevron_24)),
contentDescription = null,
tint = TangemTheme.colors.icon.informative,
modifier = Modifier.padding(start = TangemTheme.dimens.spacing2),
)
}
DropdownSelector(
isExpanded = isExpandSelector,
@ -303,6 +291,7 @@ private fun DropdownSelector(
@Composable
@Preview(showBackground = true)
@Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES)
@Preview(showBackground = true, locale = "ru")
private fun Preview_GiveTxPermissionBottomSheet() {
TangemThemePreview {
GiveTxPermissionBottomSheet(
@ -321,12 +310,12 @@ private val previewData = GiveTxPermissionBottomSheetConfig(
amount = "1",
walletAddress = "",
spenderAddress = "",
fee = TextReference.Str("2,14$"),
approveType = ApproveType.UNLIMITED,
fee = TextReference.Str("0.1233 BTC (2,14$)"),
approveType = ApproveType.LIMITED,
approveButton = ApprovePermissionButton(true) {},
cancelButton = CancelPermissionButton(true),
onChangeApproveType = { ApproveType.UNLIMITED },
subtitle = resourceReference(R.string.give_permission_staking_subtitle),
onChangeApproveType = { ApproveType.LIMITED },
subtitle = resourceReference(R.string.give_permission_staking_subtitle, wrappedList("1")),
dialogText = resourceReference(R.string.give_permission_staking_footer),
),
onCancel = {},

View file

@ -46,7 +46,7 @@
</plurals>
<string name="card_settings_access_code_recovery_disabled_description">Deaktiviere diese Option, wenn du nicht möchtest, dass diese Karte zum Zurücksetzen von Zugangscodes auf anderen Karten in dieser Wallets verwendet wird. Bitte beachte, dass du dann auch den Zugangscode auf dieser Karte nicht zurücksetzen kannst.</string>
<string name="card_settings_access_code_recovery_enabled_description">Ermöglicht die Verwendung dieser Karte zum Zurücksetzen des Zugangscodes auf anderen Karten in dieser Brieftasche</string>
<string name="card_settings_access_code_recovery_title">Zugangscodes wiederherstellen</string>
<string name="card_settings_access_code_recovery_title">Zugangspin resetten</string>
<string name="card_settings_action_sheet_reset">Zurücksetzen</string>
<string name="card_settings_action_sheet_title">Möchtest du das wirklich tun?</string>
<string name="card_settings_change_access_code">Zugangscode ändern</string>
@ -653,6 +653,7 @@
<string name="staking_details_apr">Effektiver Jahreszins</string>
<string name="staking_details_available">Verfügbar</string>
<string name="staking_details_average_reward_rate">Durchschnittliche Belohnungsquote</string>
<string name="staking_details_banner_text">Was sit Staking?</string>
<string name="staking_details_estimated_profit">%s geschätzter Profit</string>
<string name="staking_details_market_rating">Marktbewertung</string>
<string name="staking_details_metrics_block_header">Metriken</string>
@ -668,10 +669,9 @@
<string name="staking_details_unbonding_period_info">Der Zeitraum, den du nach der Beantragung der Abhebung von Geldern aus dem Staking warten musst, bevor die Token verfügbar werden.</string>
<string name="staking_details_warmup_period">Aufwärmphase</string>
<string name="staking_details_warmup_period_info">Die zugewiesene Zeit für die Aktivierung der Teilnahme am Staking.</string>
<string name="staking_initial_info_title">Stake %s</string>
<string name="staking_migrate">Migrieren</string>
<string name="staking_native">Natives Staking</string>
<string name="staking_notification_earn_rewards_text" formatted="false">Mit Staking kannst du %1s verdienen. Deine Staking-Belohnungen kommen alle ~%2s Tage.</string>
<string name="staking_notification_earn_rewards_text">Mit Staking kannst du %1$s verdienen. Deine Staking-Belohnungen kommen alle ~%2$s Tage.</string>
<string name="staking_notification_earn_rewards_title">Verdiene Staking-Belohnungen</string>
<string name="staking_notification_unstake_text">Die Belohnungen werden sofort nach dem unstaken gestoppt. Der unstakingprozess dauert %s.</string>
<string name="staking_rebond">Erneut binden</string>
@ -679,14 +679,26 @@
<string name="staking_restake_rewards">Belohnungen erneut staken</string>
<string name="staking_revoke">Widerrufen</string>
<string name="staking_revote">Neuwahl</string>
<string name="staking_reward_claiming_auto">automatisch</string>
<string name="staking_reward_claiming_manual">händisch</string>
<string name="staking_reward_schedule_block">Block</string>
<string name="staking_reward_schedule_day">Tag</string>
<string name="staking_reward_schedule_epoch">Epoche</string>
<string name="staking_reward_schedule_era">Ära</string>
<string name="staking_reward_schedule_hour">Stunde</string>
<string name="staking_reward_schedule_month">Monat</string>
<string name="staking_reward_schedule_week">Woche</string>
<string name="staking_rewards">Belohnungen</string>
<string name="staking_stake_locked">Stake gesperrt</string>
<string name="staking_stake_more">Mehr staken</string>
<string name="staking_title_stake">Stake %s</string>
<string name="staking_title_unstake">Staking beenden%s</string>
<string name="staking_unlocked_locked">gelocktes unlocken</string>
<string name="staking_unstaked">Unstaken</string>
<string name="staking_unstaked_footer">Prüfe, was nicht eingesetzt wurde, um dein Vermögen zu beanspruchen</string>
<string name="staking_unstaking">Staking beenden</string>
<string name="staking_validator">Validator/ Prüfer</string>
<string name="staking_validators">Validatoren</string>
<string name="staking_vote">Abstimmung</string>
<string name="staking_vote_locked">Abstimmung gesperrt</string>
<string name="staking_withdraw">Zurückziehen</string>
@ -822,7 +834,7 @@
<string name="warning_backup_errors_title">Aktivierungsfehler</string>
<string name="warning_beacon_chain_retirement_content">Laut den Entwicklern des BNB-Netzes wird die Unterstützung für den BEP-2-Standard im Juni 2024 enden. Um den Verlust von Vermögenswerten mit diesem Standard zu vermeiden, konvertiere bitte in den BEP-20 Standard. Nutze gerne unseren Swap-Service, um sie auf das BNB Smart Chain Netzwerk zu übertragen.</string>
<string name="warning_beacon_chain_retirement_title">BNB Beacon Chain wird abgeschaltet</string>
<string name="warning_button_could_be_better">verbesserungswürdig</string>
<string name="warning_button_could_be_better">ausbaufähig</string>
<string name="warning_button_like_it">Gefällt mir</string>
<string name="warning_button_ok">OK, habe ich verstanden!</string>
<string name="warning_button_really_cool">Echt toll!</string>

View file

@ -594,7 +594,7 @@
<string name="staking_details_warmup_period">Période d\'échauffement</string>
<string name="staking_details_warmup_period_info">Le temps imparti pour activer la participation au staking.</string>
<string name="staking_native">Native staking</string>
<string name="staking_notification_earn_rewards_text" formatted="false">Le staking vous permet d\'en gagner %1s. Vos récompenses de staking arrivent tous les ~%2s jours.</string>
<string name="staking_notification_earn_rewards_text">Le staking vous permet d\'en gagner %1$s. Vos récompenses de staking arrivent tous les ~%2$s jours.</string>
<string name="staking_notification_earn_rewards_title">Gagnez des récompenses de staking</string>
<string name="staking_rewards">Récompenses</string>
<string name="staking_stake_more">Staker plus</string>

View file

@ -657,10 +657,9 @@
<string name="staking_details_unbonding_period_info">ステーキングから資金の引き出しを要求した後、トークンが利用可能になるまでの待機期間。</string>
<string name="staking_details_warmup_period">ウォームアップ期間</string>
<string name="staking_details_warmup_period_info">ステーキングへの参加を有効にするために割り当てられた時間。</string>
<string name="staking_initial_info_title">%sをステーキングする</string>
<string name="staking_migrate">移行</string>
<string name="staking_native">ネイティブステーキング</string>
<string name="staking_notification_earn_rewards_text" formatted="false">ステーキングにより%1sを獲得できます。ステーキング報酬は ~ %2s日ごとに届きます。</string>
<string name="staking_notification_earn_rewards_text">ステーキングにより%1$sを獲得できます。ステーキング報酬は ~ %2$s日ごとに届きます。</string>
<string name="staking_notification_earn_rewards_title">ステーキング報酬を獲得</string>
<string name="staking_notification_unstake_text">ステーキング解除後、報酬の獲得はすぐに停止します。ステーキング解除プロセスには%sかかります。</string>
<string name="staking_rebond">再結束</string>
@ -668,9 +667,20 @@
<string name="staking_restake_rewards">報酬をステーキングする</string>
<string name="staking_revoke">取り消す</string>
<string name="staking_revote">再投票</string>
<string name="staking_reward_claiming_auto">自動</string>
<string name="staking_reward_claiming_manual">手動</string>
<string name="staking_reward_schedule_block">ブロック</string>
<string name="staking_reward_schedule_day"></string>
<string name="staking_reward_schedule_epoch">エポック</string>
<string name="staking_reward_schedule_era">時代</string>
<string name="staking_reward_schedule_hour"></string>
<string name="staking_reward_schedule_month"></string>
<string name="staking_reward_schedule_week"></string>
<string name="staking_rewards">報酬</string>
<string name="staking_stake_locked">ステーキングはロックされています</string>
<string name="staking_stake_more">もっとステーキングする</string>
<string name="staking_title_stake">%sをステーキングする</string>
<string name="staking_title_unstake">%sのステーキング解除</string>
<string name="staking_unlocked_locked">ステーキング解除はロックされています</string>
<string name="staking_unstaked">スタックされていない</string>
<string name="staking_unstaked_footer">資産を請求するために、unstakedを確認してください</string>

View file

@ -38,6 +38,7 @@
<string name="biometric_lockout_warning_title">Слишком много попыток</string>
<string name="biometric_unavailable_warning">Вы отключили биометрическую аутентификацию на вашем телефоне и не сможете сохранять кошельки в приложении. Для сохранения кошельков, пожалуйста, включите функцию биометрической аутентификации в настройках телефона.</string>
<string name="button_start_backup_process">Начать резервное копирование</string>
<string name="buy_token_description">С помощью банковской карты или банковского аккаунта</string>
<plurals name="card_label_card_count">
<item quantity="one">%d карта</item>
<item quantity="few">%d карты</item>
@ -134,7 +135,7 @@
<string name="common_rename">Переименовать</string>
<string name="common_save">Сохранить</string>
<string name="common_save_changes">Сохранить изменения</string>
<string name="common_search">Искать</string>
<string name="common_search">Поиск на маркете</string>
<string name="common_search_tokens">Поиск токенов</string>
<string name="common_seed_phrase">Seed-фраза</string>
<string name="common_select_action">Выберите действие</string>
@ -268,6 +269,7 @@
<string name="express_token_list_empty_search">Токены не найдены. Пожалуйста, попробуйте другой запрос</string>
<string name="express_transaction_id">ID: %s</string>
<string name="express_transaction_id_copied">ID транзакции скопирован</string>
<string name="exсhange_token_description">С другой валютой в вашем кошельке</string>
<string name="feedback_data_collection_message">Информация ниже не является обязательной. Вы можете стереть её, если хотите.</string>
<string name="feedback_preface_rate_negative">Расскажите, каких функций вам не хватает, и мы постараемся вам помочь.</string>
<string name="feedback_preface_scan_failed">Скажите, пожалуйста, какая у вас карта?</string>
@ -278,7 +280,7 @@
<string name="feedback_subject_support">Обращение в поддержку</string>
<string name="feedback_subject_support_tangem">Обращение в поддержку Tangem</string>
<string name="feedback_subject_tx_failed">Не могу отправить транзакцию</string>
<string name="give_permission_current_transaction">Текущая транзакция</string>
<string name="give_permission_current_transaction">Транзакция</string>
<string name="give_permission_fee_footer">Комиссия сети за одобрение токена будет взиматься за подтверждение того, что именно вы разрешаете использовать ваш токен для обмена.</string>
<string name="give_permission_policy_type_footer">Укажите лимит доступа к выбранному токену</string>
<string name="give_permission_rows_amount">Количество %s</string>
@ -334,9 +336,50 @@
<string name="manage_tokens_unavailable_vote">Голосовать</string>
<string name="manage_tokens_wallet_selector_title">Выберите кошелек</string>
<string name="manage_tokens_wallet_support_only_one_network_title">Кошелёк не поддерживает более одной сети</string>
<string name="markets_generate_addresses_notification">Чтобы создать адреса для выбранных сетей, необходимо отсканировать свой кошелек Tangem.</string>
<string name="markets_add_to_my_portfolio_description">Чтобы купить, обменять или получить данный токен вам нужно добавить его к себе в портфель</string>
<string name="markets_add_to_my_portfolio_unavailable_description">Этот актив недоступен</string>
<string name="markets_add_to_portfolio_button">Добавить в портфель</string>
<string name="markets_available_networks">Доступные сети</string>
<string name="markets_common_my_portfolio">Мой портфель</string>
<string name="markets_common_title">Рынок</string>
<string name="markets_generate_addresses_notification">Чтобы создать адреса для выбранных сетей, отсканируйте вашу карту Tangem кошелька</string>
<string name="markets_search_result_title">Результат</string>
<string name="markets_search_see_tokens_under_100k">Токены с капитализацией меньше 100к</string>
<string name="markets_search_show_tokens">Показать токены</string>
<string name="markets_search_token_no_result_title">Нет результата</string>
<string name="markets_select_wallet">Выберите кошелек</string>
<string name="markets_selector_interval_1m_title">1мин</string>
<string name="markets_selector_interval_1y_title">1год</string>
<string name="markets_selector_interval_24h_title">24ч</string>
<string name="markets_selector_interval_3m_title"></string>
<string name="markets_selector_interval_6m_title"></string>
<string name="markets_selector_interval_all_title">Все</string>
<string name="markets_sort_by_experienced_buyers_title">Опытные покупатели</string>
<string name="markets_sort_by_rating_title">Рейтинг</string>
<string name="markets_sort_by_title">Сортировать по</string>
<string name="markets_sort_by_top_gainers_title">Лидеры роста</string>
<string name="markets_sort_by_top_losers_title">Лидеры падения</string>
<string name="markets_sort_by_trending_title">В тренде</string>
<string name="markets_token_details_blockchain_site">Сайт блокчейна</string>
<string name="markets_token_details_buy_pressure_description">Разница между объемом покупателей и продавцов</string>
<string name="markets_token_details_high">Высокий</string>
<string name="markets_token_details_holders">Держатели</string>
<string name="markets_token_details_holders_description">Изменение количества держателей токенов в течение выбранного периода времени</string>
<string name="markets_token_details_insights">Инсайты</string>
<string name="markets_token_details_links">Ссылки</string>
<string name="markets_token_details_liquidity">Ликвидность</string>
<string name="markets_token_details_liquidity_description">Изменение объема ликвидности, доступной для токена в течение указанного периода времени.</string>
<string name="markets_token_details_low">Низкий</string>
<string name="markets_token_details_market_capitalization">Рыночная капитализация</string>
<string name="markets_token_details_market_capitalization_description">Общая рыночная стоимость криптовалюты, рассчитываемая путем умножения текущей цены монеты на общее количество монет в обращении.</string>
<string name="markets_token_details_market_rating">Рыночный рейтинг</string>
<string name="markets_token_details_metrics">Метрики</string>
<string name="markets_token_details_official_links">Официальные ссылки</string>
<string name="markets_token_details_repository">Репозиторий</string>
<string name="markets_token_details_security_score">Оценка безопасности</string>
<string name="markets_token_details_social">Социальные</string>
<string name="markets_token_details_trading_volume">Объем торгов (24ч)</string>
<string name="markets_token_details_trading_volume_24h_description">Общая сумма криптовалюты, которая была продана за последние 24 часа, показывающая уровень активности и ликвидности на рынке.</string>
<string name="onboarding_access_code_feature_1_description">Вам необходимо установить единый код доступа для защиты всех ваших карт</string>
<string name="onboarding_access_code_feature_1_title">Защита</string>
<string name="onboarding_access_code_feature_2_description">Позже вы сможете установить индивидуальный код доступа для каждой карты</string>
@ -441,6 +484,7 @@
<string name="qr_scanner_camera_denied_title">Доступ к камере запрещен</string>
<string name="receive_bottom_sheet_warning_message">%1$s (%2$s) в сети %3$s</string>
<string name="receive_bottom_sheet_warning_message_full">Отправляйте только %s на этот адрес. Использование другой сети может привести к утрате средств.</string>
<string name="receive_token_description">Покажи QR-код или поделись своим адресом</string>
<string name="referral_button_participate">Участвовать</string>
<string name="referral_error_failed_to_load_info">Не удалось загрузить информацию по реферальной программе. Пожалуйста, попробуйте позже.</string>
<string name="referral_error_failed_to_load_info_with_reason">Не удалось загрузить информацию по реферальной программе. Код ошибки: %s. Пожалуйста, попробуйте позже.</string>
@ -604,10 +648,9 @@
<string name="staking_details_unbonding_period_info">Период, который необходимо подождать после запроса на вывод средств из стейкинга, прежде чем токены станут доступны.</string>
<string name="staking_details_warmup_period">Период прогрева</string>
<string name="staking_details_warmup_period_info">Время, необходимое для начала процесса стейкинга и активации процесса начисления наград</string>
<string name="staking_initial_info_title">Застейкать %s</string>
<string name="staking_migrate">Переместить</string>
<string name="staking_native">Нативный стейкинг</string>
<string name="staking_notification_earn_rewards_text" formatted="false">Стейкинг дает возможность вам получать %1s. Награда будет зачисляться каждый %2s</string>
<string name="staking_notification_earn_rewards_text">Стейкинг дает возможность вам получать %1$s. Награда будет зачисляться каждый %2$s</string>
<string name="staking_notification_earn_rewards_title">Получите награду за стейкинг</string>
<string name="staking_notification_unstake_text">Награда перестанет начисляться сразу после завершения стейкинга. Процесс завершения длится %s.</string>
<string name="staking_restake">Повторный стейкинг</string>
@ -616,6 +659,7 @@
<string name="staking_revote">Переголосовать</string>
<string name="staking_rewards">Вознаграждения</string>
<string name="staking_stake_more">Застейкать еще</string>
<string name="staking_title_stake">Застейкать %s</string>
<string name="staking_unlocked_locked">Разблокировать</string>
<string name="staking_unstaked">Выведено из стейкинга</string>
<string name="staking_unstaked_footer">Проверьте процесс завершения стейкинга, чтобы вывести свои средства.</string>

View file

@ -2,7 +2,7 @@
<resources>
<string name="add_custom_token_choose_network">Оберіть мережу</string>
<string name="add_custom_token_title">Додати токен</string>
<string name="add_tokens_title">Керування токенами</string>
<string name="add_tokens_title">Токени</string>
<string name="address_qr_code_message_format">Надсилайте тільки %1$s (%2$s) в мережі %3$s на цю адресу. Використання іншої мережі може призвести до втрати коштів.</string>
<string name="alert_button_how_to_scan">Як сканувати</string>
<string name="alert_button_request_support">Звернутися в підтримку</string>
@ -659,10 +659,12 @@
<string name="staking_active">Активний</string>
<string name="staking_active_footer">Щоб вивести активи зі стейкінгу, натисніть тут.</string>
<string name="staking_amount_requirement_error">Сума для стейкінгу має бути не менше %s</string>
<string name="staking_claim_unstaked">Зняти кошти</string>
<string name="staking_details_annual_percentage_rate_info">Річний відсоток, який ви можете отримати, беручи участь у стейкінгу.</string>
<string name="staking_details_apr">APR</string>
<string name="staking_details_available">Доступно</string>
<string name="staking_details_average_reward_rate">Середня ставка винагороди</string>
<string name="staking_details_banner_text">Що таке стейкінг?</string>
<string name="staking_details_estimated_profit">~ прибуток за %s</string>
<string name="staking_details_market_rating">Рейтинг ринку</string>
<string name="staking_details_metrics_block_header">Метрики</string>
@ -678,15 +680,38 @@
<string name="staking_details_unbonding_period_info">Період, який ви повинні чекати після запиту на виведення коштів зі стейкінгу, перш ніж токени стануть доступними.</string>
<string name="staking_details_warmup_period">Період блокування</string>
<string name="staking_details_warmup_period_info">Відведений час для активації участі в стейкінгу.</string>
<string name="staking_initial_info_title">Стейкінг %s</string>
<string name="staking_migrate">Перемістити</string>
<string name="staking_native">Нативний стейкінг</string>
<string name="staking_notification_earn_rewards_text" formatted="false">Стейкінг дозволяє заробляти %1s. Ваші винагороди за стейкінг надходять кожні ~%2s днів.</string>
<string name="staking_notification_earn_rewards_text">Стейкінг дозволяє заробляти %1$s. Ваші винагороди за стейкінг надходять кожні ~%2$s днів.</string>
<string name="staking_notification_earn_rewards_title">Отримуйте винагороду за стейкінг</string>
<string name="staking_notification_unstake_text">Винагороди припиняють нараховуватися одразу після того, як ви знімаєте ставку. Процес зняття займає %s.</string>
<string name="staking_rebond">Зʼєднати ще раз</string>
<string name="staking_restake">Повторно застейкати</string>
<string name="staking_restake_rewards">Застейкати винагороди</string>
<string name="staking_revoke">Відкликати</string>
<string name="staking_revote">Переголосувати</string>
<string name="staking_reward_claiming_auto">Автоматично</string>
<string name="staking_reward_claiming_manual">Вручну</string>
<string name="staking_reward_schedule_block">Блок</string>
<string name="staking_reward_schedule_day">День</string>
<string name="staking_reward_schedule_epoch">Епоха</string>
<string name="staking_reward_schedule_era">Ера</string>
<string name="staking_reward_schedule_hour">Година</string>
<string name="staking_reward_schedule_month">Місяць</string>
<string name="staking_reward_schedule_week">Тиждень</string>
<string name="staking_rewards">Винагороди</string>
<string name="staking_stake_locked">Застейкати</string>
<string name="staking_stake_more">Застейкати більше</string>
<string name="staking_unstaked">Не застейканий</string>
<string name="staking_title_stake">Застейкати %s</string>
<string name="staking_title_unstake">Зняти зі стейкінгу %s</string>
<string name="staking_unlocked_locked">Розблокувати</string>
<string name="staking_unstaked">Скасовано зі стейкінгу</string>
<string name="staking_unstaked_footer">Перевірити незастейкані, щоб отримати свої активи</string>
<string name="staking_unstaking">Зняти зі стейкінгу</string>
<string name="staking_validator">Валідатор</string>
<string name="staking_vote">Проголосувати</string>
<string name="staking_vote_locked">Голос заблоковано</string>
<string name="staking_withdraw">Зняти</string>
<string name="story_awe_description">Тримайте свою криптовалюту в безпеці. Приватні ключі надійно зберігаються на картці.</string>
<string name="story_awe_title">Революційний апаратний гаманець</string>
<string name="story_backup_description">До трьох карток з одним гаманцем</string>
@ -886,7 +911,7 @@
<string name="welcome_interrupted_backup_alert_resume">Так, поновити</string>
<string name="welcome_interrupted_backup_discard_discard">Відмовитися</string>
<string name="welcome_interrupted_backup_discard_message">Якщо зараз відмовитися, то доведеться скинути картки до заводських налаштувань, щоб почати спочатку</string>
<string name="welcome_interrupted_backup_discard_resume">Відновити резервне копіювання</string>
<string name="welcome_interrupted_backup_discard_resume">Відновити бекап</string>
<string name="welcome_interrupted_backup_discard_title">Це незворотна дія</string>
<string name="welcome_unlock">Увійдіть за допомогою %s</string>
<string name="welcome_unlock_card">Сканувати картку</string>

View file

@ -133,7 +133,7 @@
<string name="common_rename">Rename</string>
<string name="common_save">Save</string>
<string name="common_save_changes">Save changes</string>
<string name="common_search">Search</string>
<string name="common_search">Search through the market</string>
<string name="common_search_tokens">Search tokens</string>
<string name="common_seed_phrase">Seed phrase</string>
<string name="common_select_action">Select action</string>
@ -278,7 +278,7 @@
<string name="feedback_subject_support">Feedback</string>
<string name="feedback_subject_support_tangem">Tangem feedback</string>
<string name="feedback_subject_tx_failed">Can\'t send a transaction</string>
<string name="give_permission_current_transaction">Current transaction</string>
<string name="give_permission_current_transaction">Transaction</string>
<string name="give_permission_fee_footer">The network will charge a token approval fee to verify that you are authorizing the use of your token for the swap.</string>
<string name="give_permission_policy_type_footer">Specify the approve limit for the selected token</string>
<string name="give_permission_rows_amount">Amount %s</string>
@ -334,14 +334,14 @@
<string name="manage_tokens_unavailable_vote">Upvote</string>
<string name="manage_tokens_wallet_selector_title">Choose wallet</string>
<string name="manage_tokens_wallet_support_only_one_network_title">The wallet doesn\'t support more than one network</string>
<string name="markets_add_to_my_portfolio_description">To start buying, exchanging or receiving this asset, add this token to at least 1 network</string>
<string name="markets_add_to_my_portfolio_description">To buy, exchange, or receive this asset, add it to your portfolio</string>
<string name="markets_add_to_my_portfolio_unavailable_description">This asset is not available</string>
<string name="markets_add_to_portfolio_button">Add to portfolio</string>
<string name="markets_add_token">Add token</string>
<string name="markets_available_networks">Available networks</string>
<string name="markets_common_my_portfolio">My portfolio</string>
<string name="markets_common_title">Market</string>
<string name="markets_generate_addresses_notification">To generate addresses for selected networks, you must scan your Tangem Wallet card.</string>
<string name="markets_generate_addresses_notification">To generate addresses for selected networks, you must scan your Tangem Wallet card</string>
<string name="markets_loading_error_title">Unable to load the data…</string>
<string name="markets_quick_actions">Quick actions</string>
<string name="markets_search_result_title">Result</string>
@ -361,7 +361,7 @@
<string name="markets_sort_by_rating_title">Rating</string>
<string name="markets_sort_by_title">Sort By</string>
<string name="markets_sort_by_top_gainers_title">Top Gainers</string>
<string name="markets_sort_by_top_losers_title">Top losers</string>
<string name="markets_sort_by_top_losers_title">Top Losers</string>
<string name="markets_sort_by_trending_title">Trending</string>
<string name="markets_token_details_about_token_title">About %s</string>
<plurals name="markets_token_details_based_on_ratings">
@ -656,7 +656,7 @@
<string name="staking_details_minimum_requirement">Minimum Requirement</string>
<string name="staking_details_no_rewards_to_claim">No rewards to claim</string>
<string name="staking_details_reward_claiming">Reward claiming</string>
<string name="staking_details_reward_claiming_info">A way to receive staking rewards. It can be claimed automatically or manually.</string>
<string name="staking_details_reward_claiming_info">Method of receiving staking rewards.\nIt can be either automatic, where the reward is credited to your address, or manual, where you need to withdraw the reward by creating a transaction to receive it.</string>
<string name="staking_details_reward_schedule">Reward schedule</string>
<string name="staking_details_reward_schedule_info">This is a schedule that determines when participants in staking receive their rewards.</string>
<string name="staking_details_rewards_to_claim">Rewards to claim: %s</string>
@ -665,10 +665,9 @@
<string name="staking_details_unbonding_period_info">The period you must wait after requesting to withdraw funds from staking before the tokens become available.</string>
<string name="staking_details_warmup_period">Warmup period</string>
<string name="staking_details_warmup_period_info">The allocated time for activating participation in staking.</string>
<string name="staking_initial_info_title">Stake %s</string>
<string name="staking_migrate">Migrate</string>
<string name="staking_native">Native staking</string>
<string name="staking_notification_earn_rewards_text" formatted="false">Staking allow you to earn %1s. Your staking rewards arrive every ~%2s days.</string>
<string name="staking_notification_earn_rewards_text">Staking allow you to earn %1$s. Your staking rewards arrive every ~%2$s days.</string>
<string name="staking_notification_earn_rewards_title">Earn staking rewards</string>
<string name="staking_notification_unstake_text">Rewards stop accruing immediately after you unstake. The unstaking process takes %s.</string>
<string name="staking_rebond">Rebond</string>
@ -676,14 +675,26 @@
<string name="staking_restake_rewards">Restake rewards</string>
<string name="staking_revoke">Revoke</string>
<string name="staking_revote">Revote</string>
<string name="staking_reward_claiming_auto">Auto</string>
<string name="staking_reward_claiming_manual">Manual</string>
<string name="staking_reward_schedule_block">Block</string>
<string name="staking_reward_schedule_day">Day</string>
<string name="staking_reward_schedule_epoch">Epoch</string>
<string name="staking_reward_schedule_era">Era</string>
<string name="staking_reward_schedule_hour">Hour</string>
<string name="staking_reward_schedule_month">Month</string>
<string name="staking_reward_schedule_week">Week</string>
<string name="staking_rewards">Rewards</string>
<string name="staking_stake_locked">Stake locked</string>
<string name="staking_stake_more">Stake more</string>
<string name="staking_title_stake">Stake %s</string>
<string name="staking_title_unstake">Unstake %s</string>
<string name="staking_unlocked_locked">Unlock locked</string>
<string name="staking_unstaked">Unstaked</string>
<string name="staking_unstaked_footer">Check unstaked to claim your assets</string>
<string name="staking_unstaking">Unstaking</string>
<string name="staking_validator">Validator</string>
<string name="staking_validators">Validators</string>
<string name="staking_vote">Vote</string>
<string name="staking_vote_locked">Vote locked</string>
<string name="staking_withdraw">Withdraw</string>

View file

@ -32,7 +32,7 @@ internal object CoinsResponseConverter : Converter<CoinsData, List<Token>> {
Token.Network(
networkId = network.networkId,
standardType = getNetworkStandardType(blockchain).name,
name = blockchain.fullName,
name = blockchain.getNetworkName(),
address = network.contractAddress,
iconUrl = getIconUrl(network.networkId, value.imageHost),
decimalCount = network.decimalCount?.toInt(),

View file

@ -24,7 +24,7 @@ internal fun getNetwork(
return Network(
id = Network.ID(blockchain.id),
backendId = blockchain.toNetworkId(),
name = blockchain.fullName,
name = blockchain.getNetworkName(),
isTestnet = blockchain.isTestnet(),
derivationPath = getNetworkDerivationPath(blockchain, extraDerivationPath, derivationStyleProvider),
currencySymbol = blockchain.currency,

View file

@ -105,6 +105,7 @@ class ResponseCryptoCurrenciesFactory {
Blockchain.BaseTestnet,
Blockchain.Telos,
Blockchain.Cronos,
Blockchain.TON,
Blockchain.Cyber,
-> this.fullName
else -> responseToken.name

View file

@ -14,7 +14,6 @@ import com.tangem.feature.swap.domain.api.SwapRepository
import com.tangem.feature.swap.domain.models.domain.LeastTokenInfo
import com.tangem.lib.crypto.BlockchainUtils
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import com.tangem.utils.coroutines.runCatching
import com.tangem.utils.isNullOrZero
import kotlinx.coroutines.flow.*
import java.math.BigDecimal
@ -86,57 +85,49 @@ class GetCurrencyWarningsUseCase(
currencyStatus: CryptoCurrencyStatus,
): Flow<CryptoCurrencyWarning?> {
val currency = currencyStatus.currency
val cryptoStatuses = operations.getCurrenciesStatusesSync()
val cryptoCurrencyStatuses = operations.getCurrenciesStatusesSync().getOrNull() ?: emptyList()
val promoBanner = promoRepository.getOkxPromoBanner()
val pairs = swapRepository.getPairsOnly(
LeastTokenInfo(
contractAddress = (currency as? CryptoCurrency.Token)?.contractAddress ?: "0",
network = currency.network.backendId,
),
cryptoCurrencyStatuses.map { it.currency },
).pairs
return combine(
showSwapPromoTokenUseCase().conflate(),
flowOf(marketCryptoCurrencyRepository.isExchangeable(userWalletId, currency)).conflate(),
) { shouldShowSwapPromo, isExchangeable ->
promoBanner ?: return@combine null
val showPromo = promoBanner.isActive && shouldShowSwapPromo
if (showPromo && isExchangeable && currencyStatus.value !is CryptoCurrencyStatus.Unreachable) {
cryptoStatuses.fold(
ifLeft = { null },
ifRight = { cryptoCurrencyStatuses ->
val pairs = runCatching(dispatchers.io) {
swapRepository.getPairsOnly(
LeastTokenInfo(
contractAddress = (currency as? CryptoCurrency.Token)?.contractAddress ?: "0",
network = currency.network.backendId,
),
cryptoCurrencyStatuses.map { it.currency },
)
}.getOrNull()?.pairs ?: emptyList()
val filteredCurrencies = cryptoCurrencyStatuses.filterNot {
it.currency.id == currency.id
val showPromoBannerActive = promoBanner.isActive && shouldShowSwapPromo
if (showPromoBannerActive && isExchangeable && currencyStatus.value !is CryptoCurrencyStatus.Unreachable) {
val filteredCurrencies = cryptoCurrencyStatuses.filterNot {
it.currency.id == currency.id
}
val currencyPairs = pairs.filter {
it.from.network == currency.network.backendId ||
it.to.network == currency.network.backendId
}
val showPromoForPair = currencyPairs.any { pair ->
val availablePair = if (currencyStatus.value.amount.isNullOrZero()) {
filteredCurrencies.filterNot { it.value.amount.isNullOrZero() }
} else {
filteredCurrencies
}
availablePair
.any {
it.currency.network.backendId == pair.to.network ||
it.currency.network.backendId == pair.from.network
}
val currencyPairs = pairs.filter {
it.from.network == currency.network.backendId ||
it.to.network == currency.network.backendId
}
val showPromo = currencyPairs.any { pair ->
val availablePair = if (currencyStatus.value.amount.isNullOrZero()) {
filteredCurrencies.filterNot { it.value.amount.isNullOrZero() }
} else {
filteredCurrencies
}
availablePair
.any {
it.currency.network.backendId == pair.to.network ||
it.currency.network.backendId == pair.from.network
}
}
if (showPromo) {
CryptoCurrencyWarning.SwapPromo(
startDateTime = promoBanner.bannerState.timeline.start,
endDateTime = promoBanner.bannerState.timeline.end,
)
} else {
null
}
},
)
}
if (showPromoForPair) {
CryptoCurrencyWarning.SwapPromo(
startDateTime = promoBanner.bannerState.timeline.start,
endDateTime = promoBanner.bannerState.timeline.end,
)
} else {
null
}
} else {
null
}

View file

@ -39,7 +39,7 @@ internal fun FeeBlock(feeState: SendStates.FeeState, isClickDisabled: Boolean, o
) {
Text(
text = stringResource(R.string.common_network_fee_title),
style = TangemTheme.typography.subtitle2,
style = TangemTheme.typography.subtitle1,
color = TangemTheme.colors.text.secondary,
)

View file

@ -58,7 +58,7 @@ internal class SetInitialDataStateTransformer(
override fun transform(prevState: StakingUiState): StakingUiState {
return prevState.copy(
title = TextReference.Res(
R.string.staking_initial_info_title,
R.string.staking_title_stake,
wrappedList(cryptoCurrencyStatusProvider().currency.name),
),
clickIntents = clickIntents,

View file

@ -1911,7 +1911,7 @@ internal class SwapInteractorImpl @Inject constructor(
} else {
SwapFeeState.NotEnough(
feeCurrency = fromTokenStatus.currency,
currencyName = fromTokenStatus.currency.network.name,
currencyName = fromTokenStatus.currency.name,
currencySymbol = fromTokenStatus.currency.symbol,
)
}

View file

@ -28,6 +28,7 @@ import com.tangem.feature.swap.presentation.R
fun SwapSuccessScreen(state: SwapSuccessStateHolder, onBack: () -> Unit) {
Scaffold(
modifier = Modifier.systemBarsPadding(),
backgroundColor = TangemTheme.colors.background.tertiary,
content = { padding ->
SwapSuccessScreenContent(padding = padding, state = state)
},

View file

@ -219,7 +219,6 @@ internal class TokenDetailsSwapTransactionsStateConverter(
isSending = isSending,
isSendingDone = isSendingDone,
isRefunded = isRefunded,
hasFailed = hasFailed,
),
)
}
@ -302,8 +301,8 @@ internal class TokenDetailsSwapTransactionsStateConverter(
)
}
private fun sendStep(isSending: Boolean, isSendingDone: Boolean, isRefunded: Boolean, hasFailed: Boolean) = when {
hasFailed || isRefunded -> ExchangeStatusState(
private fun sendStep(isSending: Boolean, isSendingDone: Boolean, isRefunded: Boolean) = when {
isRefunded -> ExchangeStatusState(
status = ExchangeStatus.Refunded,
text = TextReference.Res(R.string.express_exchange_status_refunded),
isActive = false,

View file

@ -3,8 +3,8 @@ package com.tangem.feature.tokendetails.presentation.tokendetails.ui.components
import android.content.res.Configuration
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.material.Text
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
@ -73,17 +73,22 @@ private fun NetworkInfoText(currency: TokenInfoBlockState.Currency) {
horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing4),
) {
val state = extractNetwork(tokenCurrency = currency)
Text(
text = state.normalText,
style = TangemTheme.typography.caption2,
color = TangemTheme.colors.text.tertiary,
)
if (state.normalText.isNotBlank()) {
Text(
text = state.normalText,
style = TangemTheme.typography.caption2,
color = TangemTheme.colors.text.tertiary,
)
}
Icon(
modifier = Modifier.size(TangemTheme.dimens.size16),
painter = painterResource(id = currency.networkIcon),
tint = Color.Unspecified,
contentDescription = null,
)
Text(
text = state.boldText,
style = TangemTheme.typography.caption1,
@ -94,7 +99,7 @@ private fun NetworkInfoText(currency: TokenInfoBlockState.Currency) {
}
}
private const val SEPARATOR = " %image% "
private const val SEPARATOR = "%image%"
@Composable
private fun extractNetwork(tokenCurrency: TokenInfoBlockState.Currency.Token): ExtractedTokenNetworkText {
@ -105,20 +110,20 @@ private fun extractNetwork(tokenCurrency: TokenInfoBlockState.Currency.Token): E
tokenCurrency.standardName,
tokenCurrency.networkName,
),
).split(SEPARATOR)
)
} else {
stringResource(
id = R.string.token_details_token_type_subtitle_no_standard,
formatArgs = arrayOf(
tokenCurrency.networkName,
),
).split(SEPARATOR)
)
}
return remember(splitString) {
ExtractedTokenNetworkText(
normalText = splitString.firstOrNull().orEmpty(),
boldText = splitString.getOrNull(1).orEmpty(),
normalText = splitString.substringBefore(delimiter = SEPARATOR, missingDelimiterValue = "").trim(),
boldText = splitString.substringAfterLast(delimiter = SEPARATOR).trim(),
)
}
}
@ -130,6 +135,7 @@ private data class ExtractedTokenNetworkText(
@Preview
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
@Preview(locale = "ja")
@Composable
private fun Preview_TokenInfoBlock(
@PreviewParameter(TokenInfoStateProvider::class)

View file

@ -35,10 +35,11 @@ internal class WalletPushPermissionClickIntentsImplementor @Inject constructor(
}
override fun onNeverAskPushPermission(isUserDismissed: Boolean) {
if (!isUserDismissedDialog) return
isUserDismissedDialog = isUserDismissed
if (isUserDismissedDialog != isUserDismissed) return
viewModelScope.launch {
PushNotificationAnalyticEvents.ButtonCancel(AnalyticsParam.ScreensSources.Main)
analyticsEventHandler.send(
PushNotificationAnalyticEvents.ButtonCancel(AnalyticsParam.ScreensSources.Main),
)
neverRequestPermissionUseCase(PUSH_PERMISSION)
}
}

View file

@ -88,7 +88,7 @@ markdown = "0.7.2"
# endregion Other libraries
# region Tangem
tangemBlockchainSdk = "develop-729"
tangemBlockchainSdk = "develop-733"
#tangemBlockchainSdk = "0.0.1" # Keep it! - used for local builds
tangemCardSdk = "develop-375"
#tangemCardSdk = "0.0.1" # Keep it! - used for local builds ^