From 32a94880874570d7c23232269e36ad4224b6c926 Mon Sep 17 00:00:00 2001 From: Tangem Date: Wed, 18 Sep 2024 18:34:59 +0300 Subject: [PATCH] Updated on 2026-08-14 --- .../amplitude/AmplitudeAnalyticsHandler.kt | 14 ++++++---- core/res/src/main/res/values-de/strings.xml | 2 +- core/res/src/main/res/values-es/strings.xml | 1 + core/res/src/main/res/values-fr/strings.xml | 1 + core/res/src/main/res/values-ja/strings.xml | 5 +++- core/res/src/main/res/values-ru/strings.xml | 11 +++++--- .../src/main/res/values-uk-rUA/strings.xml | 1 + core/res/src/main/res/values/strings.xml | 10 ++++--- .../components/inputrow/InputRowImageBase.kt | 6 +++-- .../components/inputrow/InputRowImageInfo.kt | 3 +++ .../inputrow/InputRowImageSelector.kt | 3 +++ .../inputrow/inner/InputRowAsyncImage.kt | 10 +++++-- .../res/drawable/ic_staking_filled_18.xml | 9 +++++++ .../AddStakingNotificationsTransformer.kt | 8 +++--- .../SetConfirmationStateLoadingTransformer.kt | 8 +++--- .../SetInitialDataStateTransformer.kt | 7 +---- .../ui/StakingClaimRewardsValidatorContent.kt | 1 + .../ui/StakingInitialInfoContent.kt | 4 +-- .../ui/StakingValidatorListContent.kt | 6 ++--- .../ui/ValidatorImagePlaceholder.kt | 25 ++++++++++++++++++ .../presentation/ui/block/ValidatorBlock.kt | 2 ++ .../TokenDetailsLoadedBalanceConverter.kt | 3 +-- .../factory/TokenStakingStateConverter.kt | 3 +-- .../state/utils/RewardScheduleUtils.kt | 26 ------------------- .../presentation/wallet/ui/WalletScreen.kt | 16 ++++++++++-- gradle/dependencies.toml | 2 +- 26 files changed, 113 insertions(+), 74 deletions(-) create mode 100644 core/ui/src/main/res/drawable/ic_staking_filled_18.xml create mode 100644 features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/ValidatorImagePlaceholder.kt delete mode 100644 features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/utils/RewardScheduleUtils.kt diff --git a/app/src/main/java/com/tangem/tap/common/analytics/handlers/amplitude/AmplitudeAnalyticsHandler.kt b/app/src/main/java/com/tangem/tap/common/analytics/handlers/amplitude/AmplitudeAnalyticsHandler.kt index 5eed564c97..2aa36c5413 100644 --- a/app/src/main/java/com/tangem/tap/common/analytics/handlers/amplitude/AmplitudeAnalyticsHandler.kt +++ b/app/src/main/java/com/tangem/tap/common/analytics/handlers/amplitude/AmplitudeAnalyticsHandler.kt @@ -18,10 +18,14 @@ class AmplitudeAnalyticsHandler( } class Builder : AnalyticsHandlerBuilder { - override fun build(data: AnalyticsHandlerBuilder.Data): AnalyticsHandler? = when { - !data.isDebug -> AmplitudeClient(data.application, data.config.amplitudeApiKey) - data.isDebug && data.logConfig.amplitude -> AmplitudeLogClient(data.jsonConverter) - else -> null - }?.let { AmplitudeAnalyticsHandler(it) } + override fun build(data: AnalyticsHandlerBuilder.Data): AnalyticsHandler { + return AmplitudeAnalyticsHandler( + client = if (data.logConfig.amplitude) { + AmplitudeLogClient(data.jsonConverter) + } else { + AmplitudeClient(data.application, data.config.amplitudeApiKey) + }, + ) + } } } \ No newline at end of file diff --git a/core/res/src/main/res/values-de/strings.xml b/core/res/src/main/res/values-de/strings.xml index c130e68816..a72160333d 100644 --- a/core/res/src/main/res/values-de/strings.xml +++ b/core/res/src/main/res/values-de/strings.xml @@ -383,6 +383,7 @@ Webseite Kaufdruck Die Differenz zwischen Käufer- und Verkäufervolumen + Kaufdruck Umlaufmenge Die Gesamtzahl der Coins, die für den Handel verfügbar sind und auf dem Markt zirkulieren Erfahrene Käufer @@ -707,7 +708,6 @@ Block Tag Täglich - Jeder %1$s Epoche Ära Stunde diff --git a/core/res/src/main/res/values-es/strings.xml b/core/res/src/main/res/values-es/strings.xml index 3c8fb3e199..0bfcf8de3d 100644 --- a/core/res/src/main/res/values-es/strings.xml +++ b/core/res/src/main/res/values-es/strings.xml @@ -382,6 +382,7 @@ Sitio web Presión de compra La diferencia entre el volumen de compradores y el volumen de vendedores + Presión de compra Suministro circulante El número total de monedas que están disponibles para el comercio y que circulan en el mercado. Compradores experimentados diff --git a/core/res/src/main/res/values-fr/strings.xml b/core/res/src/main/res/values-fr/strings.xml index d2745aa359..0d3cb6b2bc 100644 --- a/core/res/src/main/res/values-fr/strings.xml +++ b/core/res/src/main/res/values-fr/strings.xml @@ -382,6 +382,7 @@ Site web Pression d\'achat La différence entre le volume des acheteurs et le volume des vendeurs + Pression d\'achat Approvisionnement en circulation Le nombre total de pièces disponibles pour le trading et en circulation sur le marché Acheteurs expérimentés diff --git a/core/res/src/main/res/values-ja/strings.xml b/core/res/src/main/res/values-ja/strings.xml index 1a848e9582..cff94ccc70 100644 --- a/core/res/src/main/res/values-ja/strings.xml +++ b/core/res/src/main/res/values-ja/strings.xml @@ -353,6 +353,7 @@ データを読み込めません… データなし クイックアクション + マーケットから探す 結果 時価総額10万ドル以下のトークンを見る トークンを表示 @@ -379,6 +380,7 @@ ウェブサイト 買い圧力 買い手と売り手の取引量の差 + 買い圧力 循環供給量 取引可能で市場に流通しているコインの総数 経験豊富な買い手 @@ -697,7 +699,6 @@ ブロック 毎日 - %1$s毎 エポック 時代 @@ -857,6 +858,8 @@ アクティベーションに失敗しました BNBネットワーク開発者によると、BEP-2規格のサポートは2024年6月に終了します。この規格の資産を失わないために、BEP-20規格に変換してください。BNBスマートチェーンネットワークへ移行するには、Tangemのスワップサービスをご利用ください。 BNBビーコンチェーンは閉鎖されます。 + ネットワーク手数料をカバーするために%1$sを入金してください + ネットワーク手数料をカバーする資金が不足しています もっと良くなるはず 気に入った はい、わかりました! diff --git a/core/res/src/main/res/values-ru/strings.xml b/core/res/src/main/res/values-ru/strings.xml index b64757fd46..fe50c2b14d 100644 --- a/core/res/src/main/res/values-ru/strings.xml +++ b/core/res/src/main/res/values-ru/strings.xml @@ -38,7 +38,7 @@ Слишком много попыток Вы отключили биометрическую аутентификацию на вашем телефоне и не сможете сохранять кошельки в приложении. Для сохранения кошельков, пожалуйста, включите функцию биометрической аутентификации в настройках телефона. Начать резервное копирование - С помощью банковской карты или банковского аккаунта + Используйте банковскую карту или другие методы оплаты %d карта %d карты @@ -276,7 +276,7 @@ Токены не найдены. Пожалуйста, попробуйте другой запрос ID: %s ID транзакции скопирован - С другой валютой в вашем кошельке + Конвертируйте одну из ваших валют в другую Информация ниже не является обязательной. Вы можете стереть её, если хотите. Расскажите, каких функций вам не хватает, и мы постараемся вам помочь. Скажите, пожалуйста, какая у вас карта? @@ -352,6 +352,7 @@ Мой портфель Рынок Чтобы создать адреса для выбранных сетей, отсканируйте вашу карту Tangem кошелька + Потяните вверх или коснитесь поисковой строки, чтобы добавить токен Данные раздела получены из следующих сетей: %s Невозможно загрузить данные Нет данных @@ -386,6 +387,7 @@ Веб-сайт Покуп. предпоч. Разница между объемом покупателей и продавцов + Покуп. предпоч. Циркулир. предл. Общее количество монет, доступных для торговли и находящихся в обращении на рынке Опытные трейдеры @@ -524,7 +526,7 @@ Доступ к камере запрещен %1$s (%2$s) в сети %3$s Отправляйте только %s на этот адрес. Использование другой сети может привести к утрате средств. - Покажи QR-код или поделись своим адресом + Переводите средства с другого кошелька или биржи Участвовать Не удалось загрузить информацию по реферальной программе. Пожалуйста, попробуйте позже. Не удалось загрузить информацию по реферальной программе. Код ошибки: %s. Пожалуйста, попробуйте позже. @@ -654,6 +656,7 @@ Это приведет к удалению кошелька из приложения. Сам кошелек можно добавить снова. Имя Сумма для стейкинга должна быть не менее %s + Согласно правилам сети, сумма стейкинга будет округлена до %1$sTRX. Забрать средства Стейкинг аккаунт — это специальный счет, на котором хранятся застейканные токены SOL. Он создается при делегировании ваших токенов валидатору для участия в подтверждении транзакций и получении наград. За создание стейкинг аккаунта взимается небольшая комиссия, которая возвращается после завершения стейкинга. Процентная ставка @@ -699,7 +702,7 @@ Блок День Каждый день - Каждые ~%1$s сек + Каждую минуту Эпоха Эра Час diff --git a/core/res/src/main/res/values-uk-rUA/strings.xml b/core/res/src/main/res/values-uk-rUA/strings.xml index 9e4b55bc64..c032f68459 100644 --- a/core/res/src/main/res/values-uk-rUA/strings.xml +++ b/core/res/src/main/res/values-uk-rUA/strings.xml @@ -391,6 +391,7 @@ Веб-сайт Давлення покупця Різниця між обсягом покупців та обсягом продавців + Давлення покупця Циркуляційний запас Загальна кількість монет, які доступні для торгівлі та перебувають в обігу на ринку Досвідчені покупці diff --git a/core/res/src/main/res/values/strings.xml b/core/res/src/main/res/values/strings.xml index b3ac1d05be..e95c0bc2b7 100644 --- a/core/res/src/main/res/values/strings.xml +++ b/core/res/src/main/res/values/strings.xml @@ -39,7 +39,7 @@ Too many attempts You have disabled biometric authentication on your phone and will not be able to save wallets in the app. To save wallets, please enable the biometric authentication function in your phone settings. Start backup process - With your bank card or bank account + Use a bank card or other payment methods %d card %d cards @@ -275,7 +275,7 @@ No tokens found. Please try another request ID: %s Transaction ID copied - With another currency in your wallet + Convert one of your currencies to another The following information is optional. You can erase it if you don\'t want to share it. Tell us what functions you are missing, and we will try to help you. Please tell us what card do you have @@ -384,6 +384,7 @@ Website Buy pressure The difference between buyers volume and sellers volume + Buy pressure Circulating supply The total number of coins that are available for trading and are circulating in the market Experienced buyers @@ -518,7 +519,7 @@ Camera access denied %1$s (%2$s) on %3$s network Send only %s to this address. Sending any other currency will result in its irreversible loss. - Show a QR-code or share your address + Transfer funds from another wallet or exchange Participate Failed to load the information about the referral program. Please try again later. Failed to load the information about the referral program. Error code: %s. Please try again later. @@ -678,6 +679,7 @@ Migrate Native staking Earned rewards will be sent to your wallet and available for use immediately + Stake securely and start earning your rewards Stake securely and start earning daily rewards Stake securely and start earning hourly rewards Stake securely and start earning monthly rewards @@ -706,7 +708,7 @@ Block Day Each day - Each ~%1$ssec + Each minute Epoch Era Hour diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/inputrow/InputRowImageBase.kt b/core/ui/src/main/java/com/tangem/core/ui/components/inputrow/InputRowImageBase.kt index 0991dcdf5a..6db1972160 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/components/inputrow/InputRowImageBase.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/components/inputrow/InputRowImageBase.kt @@ -39,6 +39,7 @@ import com.tangem.core.ui.res.TangemThemePreview * @param captionColor caption text color * @param isGrayscaleImage whether to display grayscale image * @param iconEndRes icon to end of row + * @param onImageError composable to show if image loading failed * @param extraContent extra content */ @Composable @@ -53,6 +54,7 @@ internal fun InputRowImageBase( iconTint: Color = TangemTheme.colors.icon.informative, isGrayscaleImage: Boolean = false, iconEndRes: Int? = null, + onImageError: (@Composable () -> Unit)? = null, extraContent: (@Composable RowScope.() -> Unit)? = null, ) { Row( @@ -63,13 +65,13 @@ internal fun InputRowImageBase( InputRowAsyncImage( imageUrl = imageUrl, isGrayscale = isGrayscaleImage, + onImageError = onImageError, modifier = Modifier .size(TangemTheme.dimens.spacing36) .clip(TangemTheme.shapes.roundedCornersXLarge), ) SpacerW12() - } - if (iconRes != null) { + } else if (iconRes != null) { Box( contentAlignment = Alignment.Center, modifier = Modifier diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/inputrow/InputRowImageInfo.kt b/core/ui/src/main/java/com/tangem/core/ui/components/inputrow/InputRowImageInfo.kt index 19bb005a00..2905e007b7 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/components/inputrow/InputRowImageInfo.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/components/inputrow/InputRowImageInfo.kt @@ -35,6 +35,7 @@ import com.tangem.core.ui.res.TangemThemePreview * @param captionColor caption text color * @param isGrayscaleImage whether to display grayscale image * @param iconEndRes icon to end of row + * @param onImageError composable to show if image loading failed */ @Suppress("LongParameterList") @Composable @@ -52,6 +53,7 @@ fun InputRowImageInfo( iconTint: Color = TangemTheme.colors.icon.informative, isGrayscaleImage: Boolean = false, @DrawableRes iconEndRes: Int? = null, + onImageError: (@Composable () -> Unit)? = null, ) { Column( verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing6), @@ -75,6 +77,7 @@ fun InputRowImageInfo( captionColor = captionColor, isGrayscaleImage = isGrayscaleImage, iconEndRes = iconEndRes, + onImageError = onImageError, ) { Column( verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing2), diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/inputrow/InputRowImageSelector.kt b/core/ui/src/main/java/com/tangem/core/ui/components/inputrow/InputRowImageSelector.kt index 6fcc6ef997..287edc1197 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/components/inputrow/InputRowImageSelector.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/components/inputrow/InputRowImageSelector.kt @@ -41,6 +41,7 @@ import java.math.BigDecimal * @param captionColor caption text color * @param isSelected true if selected * @param selectorContent selector content + * @param onImageError composable to show if image loading failed */ @Composable fun InputRowImageSelector( @@ -52,6 +53,7 @@ fun InputRowImageSelector( subtitleColor: Color = TangemTheme.colors.text.primary1, captionColor: Color = TangemTheme.colors.text.tertiary, isSelected: Boolean = false, + onImageError: (@Composable () -> Unit)? = null, selectorContent: @Composable ((isSelected: Boolean, isEnabled: Boolean, onSelect: () -> Unit) -> Unit), ) { InputRowImageBase( @@ -60,6 +62,7 @@ fun InputRowImageSelector( imageUrl = imageUrl, subtitleColor = subtitleColor, captionColor = captionColor, + onImageError = onImageError, modifier = modifier .clickable( onClick = onSelect, diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/inputrow/inner/InputRowAsyncImage.kt b/core/ui/src/main/java/com/tangem/core/ui/components/inputrow/inner/InputRowAsyncImage.kt index b85e91ba30..3b46eeffc5 100644 --- a/core/ui/src/main/java/com/tangem/core/ui/components/inputrow/inner/InputRowAsyncImage.kt +++ b/core/ui/src/main/java/com/tangem/core/ui/components/inputrow/inner/InputRowAsyncImage.kt @@ -18,9 +18,15 @@ import com.tangem.core.ui.utils.getGreyScaleColorFilter * @param imageUrl url of the image * @param modifier modifier * @param isGrayscale whether to apply grayscale filter + * @param onImageError composable to show if image loading failed */ @Composable -internal fun InputRowAsyncImage(imageUrl: String, modifier: Modifier = Modifier, isGrayscale: Boolean = false) { +internal fun InputRowAsyncImage( + imageUrl: String, + modifier: Modifier = Modifier, + isGrayscale: Boolean = false, + onImageError: (@Composable () -> Unit)? = null, +) { val (alpha, colorFilter) = getGreyScaleColorFilter(isGrayscale = isGrayscale) SubcomposeAsyncImage( modifier = modifier, @@ -33,7 +39,7 @@ internal fun InputRowAsyncImage(imageUrl: String, modifier: Modifier = Modifier, .build(), loading = { LoadingIcon() }, error = { - Box( + onImageError?.invoke() ?: Box( modifier = Modifier .background( color = TangemTheme.colors.background.tertiary, diff --git a/core/ui/src/main/res/drawable/ic_staking_filled_18.xml b/core/ui/src/main/res/drawable/ic_staking_filled_18.xml new file mode 100644 index 0000000000..e6741b6156 --- /dev/null +++ b/core/ui/src/main/res/drawable/ic_staking_filled_18.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/AddStakingNotificationsTransformer.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/AddStakingNotificationsTransformer.kt index f4f4da10b4..181d37a8a2 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/AddStakingNotificationsTransformer.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/AddStakingNotificationsTransformer.kt @@ -73,6 +73,7 @@ internal class AddStakingNotificationsTransformer( isSubtractAvailable = isSubtractAvailable, reduceAmountBy = reduceAmountBy, ) + val minimumRequirement = yield.args.enter.args[Yield.Args.ArgType.AMOUNT]?.minimum.orZero() val sendingAmount = if (isEnterAction) { checkAndCalculateSubtractedAmount( isAmountSubtractAvailable = isSubtractAvailable, @@ -84,7 +85,7 @@ internal class AddStakingNotificationsTransformer( } else { // No amount is taken from account balance on exit or pending actions BigDecimal.ZERO - } + }.max(minimumRequirement) val notifications = buildList { // errors @@ -106,7 +107,7 @@ internal class AddStakingNotificationsTransformer( amountState = amountState, feeState = feeState, sendingAmount = sendingAmount, - isFeeCoverage = isFeeCoverage && isEnterAction, + isFeeCoverage = isFeeCoverage && isEnterAction && !sendingAmount.equals(minimumRequirement), ) addInfoNotifications(prevState) @@ -223,11 +224,10 @@ internal class AddStakingNotificationsTransformer( cryptoCurrencyStatus: CryptoCurrencyStatus, onClick: (CryptoCurrency) -> Unit, ) { - val minimumRequirement = yield.args.enter.args[Yield.Args.ArgType.AMOUNT]?.minimum val balance = cryptoCurrencyStatus.value.amount ?: BigDecimal.ZERO if (!isSubtractionAvailable) return - val showNotification = sendingAmount + feeAmount > balance - minimumRequirement.orZero() + val showNotification = sendingAmount + feeAmount > balance if (showNotification) { val notification = if (actionType == StakingActionCommonType.ENTER) { NotificationUM.Error.TotalExceedsBalance diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetConfirmationStateLoadingTransformer.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetConfirmationStateLoadingTransformer.kt index bd88fa6ffc..27d5d30086 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetConfirmationStateLoadingTransformer.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetConfirmationStateLoadingTransformer.kt @@ -35,7 +35,7 @@ internal class SetConfirmationStateLoadingTransformer( availableValidators = yield.validators, ), notifications = persistentListOf(), - footerText = getFooter(prevState), + footerText = getFooter(prevState, chosenValidator), transactionDoneState = TransactionDoneState.Empty, pendingAction = possibleConfirmationState?.pendingAction, pendingActions = possibleConfirmationState?.pendingActions, @@ -45,14 +45,12 @@ internal class SetConfirmationStateLoadingTransformer( ) } - private fun getFooter(state: StakingUiState): TextReference { + private fun getFooter(state: StakingUiState, validator: Yield.Validator): TextReference { val amountState = state.amountState as? AmountState.Data - val confirmationState = state.confirmationState as? StakingStates.ConfirmationState.Data - val validatorState = confirmationState?.validatorState as? ValidatorState.Content val isEnterAction = state.actionType == StakingActionCommonType.ENTER - val apr = validatorState?.chosenValidator?.apr.orZero() + val apr = validator.apr.orZero() val amountDecimal = amountState?.amountTextField?.fiatAmount?.value val potentialReward = amountDecimal?.multiply(apr) diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetInitialDataStateTransformer.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetInitialDataStateTransformer.kt index 9ed92bf14b..517cbba094 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetInitialDataStateTransformer.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/state/transformers/SetInitialDataStateTransformer.kt @@ -258,10 +258,7 @@ internal class SetInitialDataStateTransformer( Yield.Metadata.RewardSchedule.BLOCK -> { val networkId = cryptoCurrencyStatusProvider().currency.network.id.value when { - isCosmos(networkId) -> resourceReference( - R.string.staking_reward_schedule_each_sec, - wrappedList(COSMOS_BLOCK_TIME), - ) + isCosmos(networkId) -> resourceReference(R.string.staking_reward_schedule_each_minute) else -> resourceReference(R.string.staking_reward_schedule_each_day) } } @@ -278,8 +275,6 @@ internal class SetInitialDataStateTransformer( private companion object { val EQUALITY_THRESHOLD = BigDecimal(1E-10) - const val COSMOS_BLOCK_TIME = "20" // 20 seconds - val rewardClaimingResources = mapOf( Yield.Metadata.RewardClaiming.MANUAL to R.string.staking_reward_claiming_manual, Yield.Metadata.RewardClaiming.AUTO to R.string.staking_reward_claiming_auto, diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/StakingClaimRewardsValidatorContent.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/StakingClaimRewardsValidatorContent.kt index cbcb806d97..fecd9f9cb6 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/StakingClaimRewardsValidatorContent.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/StakingClaimRewardsValidatorContent.kt @@ -52,6 +52,7 @@ internal fun StakingClaimRewardsValidatorContent( infoTitle = item.fiatAmount, infoSubtitle = item.cryptoAmount, imageUrl = item.validator?.image.orEmpty(), + onImageError = { ValidatorImagePlaceholder() }, modifier = modifier .roundedShapeItemDecoration(index, state.rewards.lastIndex, false) .background(TangemTheme.colors.background.action) diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/StakingInitialInfoContent.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/StakingInitialInfoContent.kt index 6fa945af4f..679dd0675d 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/StakingInitialInfoContent.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/StakingInitialInfoContent.kt @@ -57,7 +57,6 @@ import com.tangem.features.staking.impl.presentation.state.previewdata.InitialSt import com.tangem.features.staking.impl.presentation.state.stub.StakingClickIntentsStub import com.tangem.features.staking.impl.presentation.viewmodel.StakingClickIntents import com.tangem.utils.StringsSigns.DOT -import com.tangem.utils.StringsSigns.PLUS import com.tangem.utils.extensions.orZero private const val BANNER_BLOCK_KEY = "BannerBlock" @@ -231,8 +230,6 @@ private fun StakingRewardBlock( val (text, textColor) = when (rewardBlockType) { RewardBlockType.Rewards -> { annotatedReference { - append(PLUS) - appendSpace() append(rewardFiat.orMaskWithStars(isBalanceHidden)) appendSpace() append(DOT) @@ -282,6 +279,7 @@ private fun ActiveStakingBlock( imageUrl = balance.getImage(), iconRes = icon, iconTint = iconTint, + onImageError = { ValidatorImagePlaceholder() }, modifier = modifier .background(TangemTheme.colors.background.action) .clickable( diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/StakingValidatorListContent.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/StakingValidatorListContent.kt index 9f8db40d8e..c86ebb7e95 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/StakingValidatorListContent.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/StakingValidatorListContent.kt @@ -3,10 +3,7 @@ package com.tangem.features.staking.impl.presentation.ui import android.content.res.Configuration import androidx.compose.animation.AnimatedVisibility import androidx.compose.foundation.background -import androidx.compose.foundation.layout.PaddingValues -import androidx.compose.foundation.layout.WindowInsets -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.systemBars +import androidx.compose.foundation.layout.* import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.material3.Icon import androidx.compose.runtime.Composable @@ -95,6 +92,7 @@ internal fun StakingValidatorListContent( ) } }, + onImageError = { ValidatorImagePlaceholder() }, ) } } diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/ValidatorImagePlaceholder.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/ValidatorImagePlaceholder.kt new file mode 100644 index 0000000000..d935c0e9ff --- /dev/null +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/ValidatorImagePlaceholder.kt @@ -0,0 +1,25 @@ +package com.tangem.features.staking.impl.presentation.ui + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.material3.Icon +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.graphics.vector.rememberVectorPainter +import androidx.compose.ui.res.vectorResource +import com.tangem.core.ui.res.TangemTheme +import com.tangem.features.staking.impl.R + +@Composable +internal fun ValidatorImagePlaceholder() { + Icon( + painter = rememberVectorPainter(ImageVector.vectorResource(R.drawable.ic_staking_filled_18)), + contentDescription = null, + tint = TangemTheme.colors.icon.inactive, + modifier = Modifier + .background(TangemTheme.colors.icon.primary1, CircleShape) + .padding(TangemTheme.dimens.size9), + ) +} \ No newline at end of file diff --git a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/block/ValidatorBlock.kt b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/block/ValidatorBlock.kt index be7909007e..e895963463 100644 --- a/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/block/ValidatorBlock.kt +++ b/features/staking/impl/src/main/java/com/tangem/features/staking/impl/presentation/ui/block/ValidatorBlock.kt @@ -16,6 +16,7 @@ import com.tangem.core.ui.res.TangemTheme import com.tangem.core.ui.utils.BigDecimalFormatter import com.tangem.features.staking.impl.R import com.tangem.features.staking.impl.presentation.state.ValidatorState +import com.tangem.features.staking.impl.presentation.ui.ValidatorImagePlaceholder import com.tangem.utils.extensions.orZero @Composable @@ -45,6 +46,7 @@ internal fun ValidatorBlock(validatorState: ValidatorState, onClick: () -> Unit) ) }, imageUrl = validatorState.chosenValidator.image.orEmpty(), + onImageError = { ValidatorImagePlaceholder() }, ) } } diff --git a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsLoadedBalanceConverter.kt b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsLoadedBalanceConverter.kt index 190a186493..dafdd53e8c 100644 --- a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsLoadedBalanceConverter.kt +++ b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenDetailsLoadedBalanceConverter.kt @@ -21,7 +21,6 @@ import com.tangem.feature.tokendetails.presentation.tokendetails.state.* import com.tangem.feature.tokendetails.presentation.tokendetails.state.components.TokenDetailsNotification import com.tangem.feature.tokendetails.presentation.tokendetails.state.factory.txhistory.TokenDetailsTxHistoryTransactionStateConverter import com.tangem.feature.tokendetails.presentation.tokendetails.state.utils.getBalance -import com.tangem.feature.tokendetails.presentation.tokendetails.state.utils.getStringResourceId import com.tangem.feature.tokendetails.presentation.tokendetails.viewmodels.TokenDetailsClickIntents import com.tangem.features.staking.api.featuretoggles.StakingFeatureToggles import com.tangem.features.tokendetails.impl.R @@ -204,7 +203,7 @@ internal class TokenDetailsLoadedBalanceConverter( formatArgs = wrappedList(apr), ), subtitleText = resourceReference( - id = stakingEntryInfo.rewardSchedule.getStringResourceId(), + id = R.string.staking_notification_earn_rewards_text, formatArgs = wrappedList(stakingEntryInfo.tokenSymbol), ), iconState = iconState, diff --git a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenStakingStateConverter.kt b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenStakingStateConverter.kt index b12e12eb53..14bd84bf23 100644 --- a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenStakingStateConverter.kt +++ b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/factory/TokenStakingStateConverter.kt @@ -8,7 +8,6 @@ import com.tangem.domain.staking.model.StakingEntryInfo import com.tangem.domain.staking.model.stakekit.StakingError import com.tangem.feature.tokendetails.presentation.tokendetails.state.StakingBlockUM import com.tangem.feature.tokendetails.presentation.tokendetails.state.TokenDetailsState -import com.tangem.feature.tokendetails.presentation.tokendetails.state.utils.getStringResourceId import com.tangem.feature.tokendetails.presentation.tokendetails.viewmodels.TokenDetailsClickIntents import com.tangem.features.tokendetails.impl.R import com.tangem.utils.Provider @@ -39,7 +38,7 @@ internal class TokenStakingStateConverter( formatArgs = wrappedList(apr), ), subtitleText = resourceReference( - id = stakingEntryInfo.rewardSchedule.getStringResourceId(), + id = R.string.staking_notification_earn_rewards_text, formatArgs = wrappedList(stakingEntryInfo.tokenSymbol), ), iconState = iconState, diff --git a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/utils/RewardScheduleUtils.kt b/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/utils/RewardScheduleUtils.kt deleted file mode 100644 index 1219166e7b..0000000000 --- a/features/tokendetails/impl/src/main/kotlin/com/tangem/feature/tokendetails/presentation/tokendetails/state/utils/RewardScheduleUtils.kt +++ /dev/null @@ -1,26 +0,0 @@ -package com.tangem.feature.tokendetails.presentation.tokendetails.state.utils - -import com.tangem.domain.staking.model.stakekit.Yield -import com.tangem.features.tokendetails.impl.R - -internal fun Yield.Metadata.RewardSchedule.getStringResourceId(): Int { - return when (this) { - Yield.Metadata.RewardSchedule.BLOCK, - Yield.Metadata.RewardSchedule.DAY, - Yield.Metadata.RewardSchedule.ERA, - Yield.Metadata.RewardSchedule.EPOCH, - -> R.string.staking_notification_earn_rewards_text_daily - - Yield.Metadata.RewardSchedule.HOUR, - -> R.string.staking_notification_earn_rewards_text_hourly - - Yield.Metadata.RewardSchedule.WEEK, - -> R.string.staking_notification_earn_rewards_text_weekly - - Yield.Metadata.RewardSchedule.MONTH, - -> R.string.staking_notification_earn_rewards_text_monthly - - else - -> R.string.staking_notification_earn_rewards_text_daily - } -} \ No newline at end of file diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/WalletScreen.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/WalletScreen.kt index a42d33d598..d8b674e7df 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/WalletScreen.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/WalletScreen.kt @@ -24,6 +24,7 @@ import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.drawBehind +import androidx.compose.ui.focus.onFocusChanged import androidx.compose.ui.geometry.* import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Path @@ -386,11 +387,13 @@ private inline fun BaseScaffoldWithMarkets( LocalMainBottomSheetColor provides remember { mutableStateOf(backgroundPrimary) }, ) { val backgroundColor = LocalMainBottomSheetColor.current + var isSearchFieldFocused by remember { mutableStateOf(false) } BottomSheetStateEffects( bottomSheetState = bottomSheetState, alertConfig = alertConfig, onBottomSheetStateChange = onBottomSheetStateChange, + isSearchFieldFocused = isSearchFieldFocused, ) TangemBottomSheetScaffold( @@ -422,7 +425,14 @@ private inline fun BaseScaffoldWithMarkets( modifier = Modifier.sizeIn(maxHeight = maxHeight - statusBarHeight), ) { Hand(Modifier.drawBehind { drawRect(backgroundColor.value) }) - bottomSheetContent() + Box( + modifier = Modifier + .onFocusChanged { + isSearchFieldFocused = it.isFocused + }, + ) { + bottomSheetContent() + } } }, content = { paddingValues -> @@ -463,6 +473,7 @@ private inline fun BaseScaffoldWithMarkets( state.showMarketsOnboarding, onDismissRequest = { coroutineScope.launch { bottomSheetState.partialExpand() } + state.onDismissMarketsOnboarding() }, ) @@ -640,6 +651,7 @@ private fun BottomSheetStateEffects( bottomSheetState: TangemSheetState, alertConfig: WalletAlertState?, onBottomSheetStateChange: (BottomSheetState) -> Unit, + isSearchFieldFocused: Boolean, ) { val systemUiController = rememberSystemUiController() val navigationBarColor = TangemTheme.colors.background.primary @@ -688,7 +700,7 @@ private fun BottomSheetStateEffects( val isKeyboardVisible by rememberIsKeyboardVisible() LaunchedEffect(isKeyboardVisible) { - if (isKeyboardVisible && alertConfig == null) { + if (isKeyboardVisible && alertConfig == null && isSearchFieldFocused) { bottomSheetState.expand() } } diff --git a/gradle/dependencies.toml b/gradle/dependencies.toml index cb4e3722a1..7e7f4a8b81 100644 --- a/gradle/dependencies.toml +++ b/gradle/dependencies.toml @@ -89,7 +89,7 @@ markdownComposeView = "0.5.4" # endregion Other libraries # region Tangem -tangemBlockchainSdk = "release-app_5.15-778" +tangemBlockchainSdk = "release-app_5.15-780" #tangemBlockchainSdk = "0.0.1" # Keep it! - used for local builds tangemCardSdk = "release-app_5.15-382" #tangemCardSdk = "0.0.1" # Keep it! - used for local builds ^