diff --git a/app/src/main/java/com/tangem/tap/features/walletSelector/ui/components/WallectSelectorScreenContent.kt b/app/src/main/java/com/tangem/tap/features/walletSelector/ui/components/WallectSelectorScreenContent.kt
index 472a4322ec..0993a1c9ea 100644
--- a/app/src/main/java/com/tangem/tap/features/walletSelector/ui/components/WallectSelectorScreenContent.kt
+++ b/app/src/main/java/com/tangem/tap/features/walletSelector/ui/components/WallectSelectorScreenContent.kt
@@ -177,7 +177,7 @@ private fun Footer(
PrimaryButton(
modifier = Modifier.fillMaxWidth(),
text = stringResource(
- id = R.string.user_wallet_list_unlock_all,
+ id = R.string.user_wallet_list_unlock_all_with,
stringResource(id = R.string.common_biometrics),
),
showProgress = showUnlockProgress,
diff --git a/core/res/src/main/res/values-ru/strings.xml b/core/res/src/main/res/values-ru/strings.xml
index aca1c4e67a..510b31b595 100644
--- a/core/res/src/main/res/values-ru/strings.xml
+++ b/core/res/src/main/res/values-ru/strings.xml
@@ -71,6 +71,7 @@
биометрическую аутентификацию
биометрией
Купить
+ Купить %1$s
Вы не предоставили доступ к камере, пожалуйста, измените настройки конфиденциальности.
Отмена
Закрыть
@@ -192,6 +193,7 @@
Приложите карту
Внутренняя ошибка: не удается найти менеджер кошельков
Вы обновили данные биометрии, отсканируйте свою карту для входа
+ Чтобы начать отслеживать свои криптоактивы и транзакции, добавьте токены
Вы успешно прошли все уроки и теперь можете получить 1INCH токены
- Пройдите 3 урока и получите %d 1INCH токен на свой кошелек
@@ -215,6 +217,8 @@
- Вам надо сгенерировать адреса для %d новых сетей, используя вашу карту
Некоторые адреса отсутствуют
+ Добавить
+ Изменить
Невозможно покрыть %1$s комиссию
Вам необходимо установить единый код доступа для защиты всех ваших карт
Защита
@@ -325,6 +329,8 @@
- за %d кошельков
Получите ^^%1$s^^ на ваш адрес в сети %2$s %3$s ^^спустя 30 дней^^ за каждый кошелек, который купит ваш друг
+ Получите
+ на ваш адрес в сети %1$s%2$s за каждый кошелек, который купит ваш друг
Вы
Получит
при покупке кошелька на сайте tangem.com
@@ -491,10 +497,11 @@
Переименование кошелька
Одновалютные
Мои кошельки
- Разблокировать все с %s
+ Разблокировать все
+ Разблокировать все с %s
История транзакций
Сеть недоступна
- Блокчейн недоступен. Попробуй позже.
+ Блокчейн недоступен. Попробуйте позже.
Баланс загружается…
Отсканируйте карту
Транзакция подтверждается…
@@ -577,5 +584,5 @@
Войти с %s
Сканировать карту
Используйте %s или отсканируйте карту для входа в приложение
- С возвращением!
+ C возвращением!
diff --git a/core/res/src/main/res/values-zh-rTW/strings.xml b/core/res/src/main/res/values-zh-rTW/strings.xml
index dbc98ef5f5..545a1272b2 100644
--- a/core/res/src/main/res/values-zh-rTW/strings.xml
+++ b/core/res/src/main/res/values-zh-rTW/strings.xml
@@ -38,6 +38,7 @@
允許您使用此卡重置此錢包中其他卡上的訪問密碼
禁用重置此卡或此錢包中其他卡上的訪問密碼的功能
恢復訪問密碼
+ 重置
您確定要這麼做嗎?
更改訪問密碼
訪問密碼將僅在此卡上更改
@@ -258,6 +259,8 @@
無法加載有關推薦計劃的消息。請稍後再試
無法加載有關推薦計劃的消息。原因:%s。請稍後再試
您的朋友買
+ 會得到
+ 對於你的朋友在你的 %1$s 網絡地址%2$s上購買的每個錢包
你
得到
%s 折扣
@@ -277,7 +280,6 @@
我了解執行此操作後,我將無法再訪問當前錢包
恢復原廠設置將從所選卡中完全刪除錢包。您將無法恢復當前錢包或使用卡恢復訪問密碼
恢復原廠設置將從所選卡中完全刪除錢包並將其從應用程序中刪除。您將無法恢復當前錢包
- 您有其他國家的銀行卡或銀聯卡嗎?
目前不接受俄羅斯銀行卡
登錄應用程序並在不掃描卡片的情況下檢查您的資產
訪問應用程序
@@ -402,7 +404,7 @@
重新命名錢包
單一幣種
我的錢包
- 用 %s 解鎖全部
+ 用 %s 解鎖全部
交易記錄
網路無法使用
區塊鍊無法使用。稍後再試
diff --git a/core/res/src/main/res/values/strings.xml b/core/res/src/main/res/values/strings.xml
index e869ddb5a2..660803875f 100644
--- a/core/res/src/main/res/values/strings.xml
+++ b/core/res/src/main/res/values/strings.xml
@@ -69,6 +69,7 @@
biometric authentication
biometrics
Buy
+ Buy %1$s
You have not given access to your camera, please adjust your privacy settings
Cancel
Close
@@ -134,7 +135,10 @@
Required field
Decimal number must be a valid integer, no higher than %d
Custom derivation
+ E. g. m/00\'/0000\'/0\'/0/0
+ Enter custom derivation
Decimals
+ Derivation Path
Default
BIP44 coin type
The derivation path you\'ve entered is not valid
@@ -142,6 +146,8 @@
Name
Not selected
Network
+ Token network
+ You can manually add a token that is not natively supported by Tangem
E.g. USDC
Token symbol
This token/network has already been added to your list
@@ -193,7 +199,7 @@
Tap the card
Internal error: wallet manager not found
You have updated biometrics, scan your card to enter
- To begin tracking your crypto assets and transactions, add tokens.
+ To begin tracking your crypto assets and transactions, add tokens
You have completed all of the lessons, and are now eligible to receive your 1INCH tokens
- Complete three lessons and receive %d 1INCH token to your wallet
@@ -213,6 +219,29 @@
- You need to generate addresses for %d new networks using your card
Some addresses are missing
+ Add
+ Custom
+ Edit
+ Blockchain the cryptocurrency was initially created
+ Native network
+ Using non-native networks for tokens enables cross-blockchain interoperability, allowing assets to be utilized in diverse decentralized applications and smart contracts across platforms. However, this often involves a custodian or smart contract to hold the original asset securely, introducing centralization and counterparty risk.
+ Not original or primary blockchain the token is hosted
+ Non-native networks
+ Blockchain the cryptocurrency was initially created
+ Networks
+ Choose networks
+ Wallet
+ Couldn’t find this token, you can add it manually
+ %d of %#@total_wallets@
+
+ - %d wallet
+ - %d wallets
+
+ e.g. BTC I trust, hodl I must
+ Coin market cap
+ The selected token is currently unavailable for actions within the crypto wallet. But worry not, you can express your interest by upvoting it.
+ Upvote
+ Choose wallet
Unable to cover %1$s fee
You have to set up a single access code to protect all your wallets
Protect
@@ -322,6 +351,8 @@
- for %d wallets
Will get ^^%1$s^^ for each wallet bought by your friend on your %2$s network address %3$s ^^30 days after^^ that
+ Will get
+ for each wallet bought by your friend on your %1$s network address%2$s
You
Will get a
when buying a wallet on tangem.com
@@ -484,7 +515,8 @@
Rename Wallet
Single-currency
My Wallets
- Unlock all with %s
+ Unlock all
+ Unlock all with %s
Transaction history
Network is unreachable
Blockchain is unreachable. Try later
@@ -549,6 +581,7 @@
Tangem
Can be better
Learn more
+ Love it!
Ok, Got it!
Really cool!
%1$s network has a concept of Existential Deposit. If your account drops below %2$s it will be deactivated and any remaining funds will be destroyed.
@@ -559,7 +592,11 @@
How do you like Tangem?
One question
This card has signed transactions in the past
+ Network currently is unreachable. Please try again later.
+ Some networks currently are unreachable. Please try again later.
This is a Testnet card. Don\'t accept it as a payment. This card must only be used for testing and development purposes.
+ Note top up
+ Some networks are unreachable
Discard
You have an interrupted backup. Do you want to resume?
Yes, resume
diff --git a/core/ui/src/main/java/com/tangem/core/ui/components/notifications/Notification.kt b/core/ui/src/main/java/com/tangem/core/ui/components/notifications/Notification.kt
index 213f8f90e8..6e569c56bb 100644
--- a/core/ui/src/main/java/com/tangem/core/ui/components/notifications/Notification.kt
+++ b/core/ui/src/main/java/com/tangem/core/ui/components/notifications/Notification.kt
@@ -1,9 +1,7 @@
package com.tangem.core.ui.components.notifications
import androidx.annotation.DrawableRes
-import androidx.compose.animation.AnimatedContent
import androidx.compose.animation.AnimatedVisibility
-import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.foundation.Image
import androidx.compose.foundation.LocalIndication
import androidx.compose.foundation.clickable
@@ -25,9 +23,7 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider
import com.tangem.core.ui.R
-import com.tangem.core.ui.components.PrimaryButton
-import com.tangem.core.ui.components.PrimaryButtonIconEnd
-import com.tangem.core.ui.components.SecondaryButton
+import com.tangem.core.ui.components.*
import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.extensions.resolveReference
import com.tangem.core.ui.res.TangemTheme
@@ -46,7 +42,7 @@ import com.tangem.core.ui.components.notifications.NotificationConfig.ButtonsSta
*/
@Composable
fun Notification(config: NotificationConfig, modifier: Modifier = Modifier, iconTint: Color? = null) {
- BaseContainer(buttonsState = config.buttonsState, modifier = modifier) {
+ BaseContainer(buttonsState = config.buttonsState, onClick = config.onClick, modifier = modifier) {
Column(
modifier = Modifier.padding(all = TangemTheme.dimens.spacing12),
verticalArrangement = Arrangement.spacedBy(space = TangemTheme.dimens.spacing12),
@@ -56,6 +52,7 @@ fun Notification(config: NotificationConfig, modifier: Modifier = Modifier, icon
iconTint = iconTint,
title = config.title,
subtitle = config.subtitle,
+ isClickableComponent = config.onClick != null,
)
Buttons(state = config.buttonsState)
@@ -71,11 +68,12 @@ fun Notification(config: NotificationConfig, modifier: Modifier = Modifier, icon
@Composable
private fun BaseContainer(
buttonsState: NotificationConfig.ButtonsState?,
+ onClick: (() -> Unit)?,
modifier: Modifier = Modifier,
content: @Composable BoxScope.() -> Unit,
) {
val containerColor by rememberUpdatedState(
- newValue = if (buttonsState != null) {
+ newValue = if (buttonsState != null || onClick != null) {
TangemTheme.colors.background.primary
} else {
TangemTheme.colors.button.disabled
@@ -83,9 +81,11 @@ private fun BaseContainer(
)
Surface(
+ onClick = onClick ?: {},
modifier = modifier
.defaultMinSize(minHeight = TangemTheme.dimens.size62)
.fillMaxWidth(),
+ enabled = onClick != null,
shape = TangemTheme.shapes.roundedCornersXMedium,
color = containerColor,
) {
@@ -94,15 +94,36 @@ private fun BaseContainer(
}
@Composable
-private fun MainContent(iconResId: Int, iconTint: Color?, title: TextReference, subtitle: TextReference) {
- Row(horizontalArrangement = Arrangement.spacedBy(space = TangemTheme.dimens.spacing10)) {
+private fun MainContent(
+ iconResId: Int,
+ iconTint: Color?,
+ title: TextReference,
+ subtitle: TextReference,
+ isClickableComponent: Boolean,
+) {
+ Row {
Icon(
iconResId = iconResId,
tint = iconTint,
modifier = Modifier.align(alignment = Alignment.CenterVertically),
)
+ SpacerW(width = TangemTheme.dimens.spacing10)
+
TextsBlock(title = title, subtitle = subtitle)
+
+ if (isClickableComponent) {
+ SpacerWMax()
+
+ Icon(
+ painter = painterResource(id = R.drawable.ic_chevron_right_24),
+ contentDescription = null,
+ modifier = Modifier
+ .size(size = TangemTheme.dimens.size20)
+ .align(alignment = Alignment.CenterVertically),
+ tint = TangemTheme.colors.icon.informative,
+ )
+ }
}
}
@@ -130,7 +151,7 @@ private fun TextsBlock(title: TextReference, subtitle: TextReference) {
Text(
text = title.resolveReference(),
color = TangemTheme.colors.text.primary1,
- style = TangemTheme.typography.body2,
+ style = TangemTheme.typography.button,
)
Text(
@@ -141,16 +162,13 @@ private fun TextsBlock(title: TextReference, subtitle: TextReference) {
}
}
-@OptIn(ExperimentalAnimationApi::class)
@Composable
private fun Buttons(state: NotificationButtonsState?) {
- AnimatedContent(targetState = state, label = "Update the buttons content") { animatedState ->
- when (animatedState) {
- is NotificationButtonsState.SecondaryButtonConfig -> SingleSecondaryButton(config = animatedState)
- is NotificationButtonsState.PrimaryButtonConfig -> SinglePrimaryButton(config = animatedState)
- is NotificationButtonsState.PairButtonsConfig -> PairButtons(config = animatedState)
- null -> Unit
- }
+ when (state) {
+ is NotificationButtonsState.SecondaryButtonConfig -> SingleSecondaryButton(config = state)
+ is NotificationButtonsState.PrimaryButtonConfig -> SinglePrimaryButton(config = state)
+ is NotificationButtonsState.PairButtonsConfig -> PairButtons(config = state)
+ null -> Unit
}
}
@@ -266,6 +284,12 @@ private class NotificationConfigProvider : CollectionPreviewParameterProvider Unit)? = null,
val onCloseClick: (() -> Unit)? = null,
) {
diff --git a/core/ui/src/main/java/com/tangem/core/ui/extensions/TextReference.kt b/core/ui/src/main/java/com/tangem/core/ui/extensions/TextReference.kt
index d90718dcb8..d44b32ecdf 100644
--- a/core/ui/src/main/java/com/tangem/core/ui/extensions/TextReference.kt
+++ b/core/ui/src/main/java/com/tangem/core/ui/extensions/TextReference.kt
@@ -109,7 +109,13 @@ fun combinedReference(refs: WrappedList): TextReference {
@ReadOnlyComposable
fun TextReference.resolveReference(): String {
return when (this) {
- is TextReference.Res -> stringResource(id, *formatArgs.toTypedArray())
+ is TextReference.Res -> {
+ val args = formatArgs
+ .map { if (it is TextReference) it.resolveReference() else it }
+ .toTypedArray()
+
+ stringResource(id = id, *args)
+ }
is TextReference.PluralRes -> pluralStringResource(id, count, *formatArgs.toTypedArray())
is TextReference.Str -> value
is TextReference.Combined -> {
@@ -125,7 +131,13 @@ fun TextReference.resolveReference(): String {
/** Resolve [TextReference] as [String] using [resources] (non-composable context) */
fun TextReference.resolveReference(resources: Resources): String {
return when (this) {
- is TextReference.Res -> resources.getString(id, *formatArgs.toTypedArray())
+ is TextReference.Res -> {
+ val args = formatArgs
+ .map { if (it is TextReference) it.resolveReference(resources) else it }
+ .toTypedArray()
+
+ resources.getString(id, *args)
+ }
is TextReference.PluralRes -> resources.getQuantityString(id, count, *formatArgs.toTypedArray())
is TextReference.Str -> value
is TextReference.Combined -> {
diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/common/WalletPreviewData.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/common/WalletPreviewData.kt
index 27df264a07..4b51515ef3 100644
--- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/common/WalletPreviewData.kt
+++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/common/WalletPreviewData.kt
@@ -381,10 +381,9 @@ internal object WalletPreviewData {
onRefresh = {},
),
notifications = persistentListOf(
- WalletNotification.UnreachableNetworks,
- WalletNotification.LikeTangemApp(onClick = {}),
- WalletNotification.BackupCard(onClick = {}),
- WalletNotification.ScanCard(onClick = {}),
+ WalletNotification.Critical.DevCard,
+ WalletNotification.MissingAddresses(missingAddressesCount = 0, onGenerateClick = {}),
+ WalletNotification.Warning.NetworksUnreachable,
),
bottomSheetConfig = bottomSheet,
tokenActionsBottomSheet = actionsBottomSheet,
@@ -402,7 +401,7 @@ internal object WalletPreviewData {
isRefreshing = false,
onRefresh = {},
),
- notifications = persistentListOf(WalletNotification.LikeTangemApp(onClick = {})),
+ notifications = persistentListOf(WalletNotification.Warning.NetworksUnreachable),
buttons = manageButtons,
bottomSheetConfig = bottomSheet,
marketPriceBlockState = MarketPriceBlockState.Content(
diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/components/WalletBottomSheetConfig.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/components/WalletBottomSheetConfig.kt
index 7b4abe968d..44d45cf615 100644
--- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/components/WalletBottomSheetConfig.kt
+++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/components/WalletBottomSheetConfig.kt
@@ -4,7 +4,8 @@ import androidx.annotation.DrawableRes
import androidx.compose.ui.graphics.Color
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfigContent
import com.tangem.core.ui.extensions.TextReference
-import com.tangem.core.ui.extensions.WrappedList
+import com.tangem.core.ui.extensions.resourceReference
+import com.tangem.core.ui.extensions.wrappedList
import com.tangem.core.ui.res.TangemColorPalette
import com.tangem.feature.wallet.impl.R
@@ -13,7 +14,6 @@ import com.tangem.feature.wallet.impl.R
*
[REDACTED_AUTHOR]
*/
-// TODO: Finalize notification strings [REDACTED_JIRA]
sealed class WalletBottomSheetConfig(
open val title: TextReference,
open val subtitle: TextReference,
@@ -29,61 +29,24 @@ sealed class WalletBottomSheetConfig(
@DrawableRes val iconResId: Int? = null,
)
- data class UnlockWallets(
- val onUnlockClick: () -> Unit,
- val onScanClick: () -> Unit,
- ) : WalletBottomSheetConfig(
- title = TextReference.Str(value = "Unlock needed"),
- subtitle = TextReference.Str(
- value = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor " +
- "incididunt ut labore et dolore magna aliqua.",
+ data class UnlockWallets(val onUnlockClick: () -> Unit, val onScanClick: () -> Unit) : WalletBottomSheetConfig(
+ title = resourceReference(id = R.string.common_unlock_needed),
+ subtitle = resourceReference(
+ id = R.string.unlock_wallet_description_full,
+ formatArgs = wrappedList(
+ resourceReference(R.string.common_biometrics),
+ ),
),
iconResId = R.drawable.ic_locked_24,
tint = TangemColorPalette.Black,
- primaryButtonConfig = ButtonConfig(text = TextReference.Str(value = "Unlock"), onClick = onUnlockClick),
+ primaryButtonConfig = ButtonConfig(
+ text = resourceReference(id = R.string.user_wallet_list_unlock_all),
+ onClick = onUnlockClick,
+ ),
secondaryButtonConfig = ButtonConfig(
- text = TextReference.Str(value = "Scan card"),
+ text = resourceReference(id = R.string.welcome_unlock_card),
onClick = onScanClick,
iconResId = R.drawable.ic_tangem_24,
),
)
-
- data class LikeTangemApp(
- val onRateTheAppClick: () -> Unit,
- val onShareClick: () -> Unit,
- ) : WalletBottomSheetConfig(
- title = TextReference.Str(value = "Like Tangem App?"),
- subtitle = TextReference.Str(value = "How was your experience with our app? Let us know:"),
- iconResId = R.drawable.ic_star_24,
- tint = TangemColorPalette.Tangerine,
- primaryButtonConfig = ButtonConfig(
- text = TextReference.Str(value = "Rate the app"),
- onClick = onRateTheAppClick,
- ),
- secondaryButtonConfig = ButtonConfig(
- text = TextReference.Str(value = "Share feedback"),
- onClick = onShareClick,
- ),
- )
-
- data class CriticalWarningAlreadySignedHashes(
- val onOkClick: () -> Unit,
- val onCancelClick: () -> Unit,
- ) : WalletBottomSheetConfig(
- title = TextReference.Res(
- id = R.string.warning_important_security_info,
- formatArgs = WrappedList(listOf("\u26A0")),
- ),
- subtitle = TextReference.Res(id = R.string.alert_signed_hashes_message),
- iconResId = R.drawable.img_attention_20,
- tint = null,
- primaryButtonConfig = ButtonConfig(
- text = TextReference.Res(id = R.string.common_ok),
- onClick = onOkClick,
- ),
- secondaryButtonConfig = ButtonConfig(
- text = TextReference.Res(id = R.string.common_cancel),
- onClick = onCancelClick,
- ),
- )
}
\ No newline at end of file
diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/components/WalletNotification.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/components/WalletNotification.kt
index e5e9221005..c38b2b3bfa 100644
--- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/components/WalletNotification.kt
+++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/components/WalletNotification.kt
@@ -2,8 +2,7 @@ package com.tangem.feature.wallet.presentation.wallet.state.components
import androidx.compose.runtime.Immutable
import com.tangem.core.ui.components.notifications.NotificationConfig
-import com.tangem.core.ui.extensions.TextReference
-import com.tangem.core.ui.extensions.WrappedList
+import com.tangem.core.ui.extensions.*
import com.tangem.feature.wallet.impl.R
/**
@@ -13,157 +12,144 @@ import com.tangem.feature.wallet.impl.R
*
[REDACTED_AUTHOR]
*/
-// TODO: Finalize notification strings [REDACTED_JIRA]
@Immutable
-sealed class WalletNotification(open val config: NotificationConfig) {
+sealed class WalletNotification(val config: NotificationConfig) {
- /** Clickable notification */
- sealed interface Clickable {
+ sealed class Critical(title: TextReference, subtitle: TextReference) : WalletNotification(
+ config = NotificationConfig(
+ title = title,
+ subtitle = subtitle,
+ iconResId = R.drawable.ic_alert_circle_24,
+ ),
+ ) {
- /** Lambda be invoked when notification is clicked */
- val onClick: () -> Unit
+ object DevCard : Critical(
+ title = resourceReference(id = R.string.common_warning),
+ subtitle = resourceReference(id = R.string.alert_developer_card),
+ )
+
+ object DemoCard : Critical(
+ title = resourceReference(id = R.string.common_warning),
+ subtitle = resourceReference(id = R.string.alert_demo_message),
+ )
+
+ object TestNetCard : Critical(
+ title = resourceReference(id = R.string.common_warning),
+ subtitle = resourceReference(id = R.string.warning_testnet_card_message),
+ )
+
+ object FailedCardValidation : Critical(
+ title = resourceReference(id = R.string.warning_failed_to_verify_card_title),
+ subtitle = resourceReference(id = R.string.warning_failed_to_verify_card_message),
+ )
+
+ data class LowSignatures(val count: Int) : Critical(
+ title = resourceReference(id = R.string.common_warning),
+ subtitle = resourceReference(
+ id = R.string.warning_low_signatures_format,
+ formatArgs = wrappedList(count),
+ ),
+ )
}
- /** "Development card" notification */
- object DevCard : WalletNotification(
+ sealed class Warning(
+ title: TextReference,
+ subtitle: TextReference,
+ buttonsState: NotificationConfig.ButtonsState? = null,
+ onClick: (() -> Unit)? = null,
+ ) : WalletNotification(
config = NotificationConfig(
- title = TextReference.Res(id = R.string.common_warning),
- subtitle = TextReference.Res(id = R.string.alert_developer_card),
- iconResId = R.drawable.ic_alert_circle_24,
+ title = title,
+ subtitle = subtitle,
+ iconResId = R.drawable.img_attention_20,
+ buttonsState = buttonsState,
+ onClick = onClick,
),
- )
+ ) {
- /** "Test card" notification */
- object TestCard : WalletNotification(
- config = NotificationConfig(
- title = TextReference.Res(id = R.string.common_warning),
- subtitle = TextReference.Res(id = R.string.warning_testnet_card_message),
- iconResId = R.drawable.ic_alert_circle_24,
- ),
- )
+ data class MissingBackup(val onStartBackupClick: () -> Unit) : Warning(
+ title = resourceReference(id = R.string.main_no_backup_warning_title),
+ subtitle = resourceReference(id = R.string.main_no_backup_warning_subtitle),
+ buttonsState = NotificationConfig.ButtonsState.SecondaryButtonConfig(
+ text = resourceReference(id = R.string.button_start_backup_process),
+ onClick = onStartBackupClick,
+ ),
+ )
- /** "Demo card" notification */
- object DemoCard : WalletNotification(
- config = NotificationConfig(
- title = TextReference.Res(id = R.string.common_warning),
- subtitle = TextReference.Res(id = R.string.alert_demo_message),
- iconResId = R.drawable.ic_alert_circle_24,
- ),
- )
+ object NetworksUnreachable : Warning(
+ title = resourceReference(id = R.string.wallet_balance_blockchain_unreachable),
+ subtitle = resourceReference(id = R.string.warning_subtitle_network_unreachable),
+ )
- /** "Card verification failed" notification */
- object CardVerificationFailed : WalletNotification(
- config = NotificationConfig(
- title = TextReference.Res(id = R.string.warning_failed_to_verify_card_title),
- subtitle = TextReference.Res(id = R.string.warning_failed_to_verify_card_message),
- iconResId = R.drawable.ic_alert_circle_24,
- ),
- )
+ object SomeNetworksUnreachable : Warning(
+ title = resourceReference(id = R.string.warning_title_some_networks_unreachable),
+ subtitle = resourceReference(id = R.string.warning_subtitle_some_networks_unreachable),
+ )
- /**
- * "Remaining signatures left" notification
- *
- * @param count number of remaining signatures
- */
- class RemainingSignaturesLeft(count: Int) : WalletNotification(
+ data class TopUpNote(val errorMessage: String) : Warning(
+ title = resourceReference(id = R.string.warning_title_note_top_up),
+ subtitle = stringReference(value = errorMessage),
+ )
+
+ object NumberOfSignedHashesIncorrect : Warning(
+ title = resourceReference(id = R.string.common_warning),
+ subtitle = resourceReference(id = R.string.alert_card_signed_transactions),
+ )
+
+ data class MultiWalletSignedHashesIncorrect(val onClick: () -> Unit) : Warning(
+ title = resourceReference(id = R.string.common_warning),
+ subtitle = resourceReference(id = R.string.warning_signed_tx_previously),
+ onClick = onClick,
+ )
+ }
+
+ data class MissingAddresses(val missingAddressesCount: Int, val onGenerateClick: () -> Unit) : WalletNotification(
config = NotificationConfig(
- title = TextReference.Res(id = R.string.common_warning),
- subtitle = TextReference.Res(
- id = R.string.warning_low_signatures_format,
- formatArgs = WrappedList(data = listOf(count)),
+ title = resourceReference(id = R.string.main_warning_missing_derivation_title),
+ subtitle = pluralReference(
+ id = R.plurals.main_warning_missing_derivation_description,
+ count = missingAddressesCount,
+ formatArgs = wrappedList(missingAddressesCount),
),
iconResId = R.drawable.ic_alert_circle_24,
- ),
- )
-
- /**
- * "Already topped up and signed hashes" warning notification
- *
- * @property onClick lambda be invoked when notification's close button is clicked
- */
- data class WarningAlreadySignedHashes(override val onClick: () -> Unit) : Clickable, WalletNotification(
- config = NotificationConfig(
- title = TextReference.Res(id = R.string.common_warning),
- subtitle = TextReference.Res(id = R.string.alert_card_signed_transactions),
- iconResId = R.drawable.img_attention_20,
- onCloseClick = onClick,
- ),
- )
-
- /**
- * "Already signed hashes" critical warning notification
- *
- * @property onClick lambda be invoked when notification is clicked
- */
- data class CriticalWarningAlreadySignedHashes(override val onClick: () -> Unit) : Clickable, WalletNotification(
- config = NotificationConfig(
- title = TextReference.Res(
- id = R.string.warning_important_security_info,
- formatArgs = WrappedList(listOf("\u26A0")),
+ buttonsState = NotificationConfig.ButtonsState.PrimaryButtonConfig(
+ text = resourceReference(id = R.string.common_generate_addresses),
+ iconResId = R.drawable.ic_tangem_24,
+ onClick = onGenerateClick,
),
- subtitle = TextReference.Res(id = R.string.warning_signed_tx_previously),
- iconResId = R.drawable.img_attention_20,
),
)
- /**
- * "Backup the card" notification
- *
- * @property onClick lambda be invoked when notification is clicked
- */
- data class BackupCard(override val onClick: () -> Unit) : Clickable, WalletNotification(
+ data class UnlockWallets(val onClick: () -> Unit) : WalletNotification(
config = NotificationConfig(
- title = TextReference.Str(value = "Backup your card"),
- subtitle = TextReference.Str(value = ""),
- iconResId = R.drawable.img_attention_20,
- ),
- )
-
- /** "Unreachable networks" notification */
- object UnreachableNetworks : WalletNotification(
- config = NotificationConfig(
- title = TextReference.Str(value = "Some networks are unreachable"),
- subtitle = TextReference.Str(value = ""),
- iconResId = R.drawable.img_attention_20,
- ),
- )
-
- /**
- * "Like Tangem App" notification
- *
- * @property onClick lambda be invoked when notification is clicked
- */
- data class LikeTangemApp(override val onClick: () -> Unit) : Clickable, WalletNotification(
- config = NotificationConfig(
- title = TextReference.Str(value = "Like Tangem App?"),
- subtitle = TextReference.Str(value = ""),
- iconResId = R.drawable.ic_star_24,
- ),
- )
-
- /**
- * "Scan the card" notification
- *
- * @property onClick lambda be invoked when notification is clicked
- */
- data class ScanCard(override val onClick: () -> Unit) : Clickable, WalletNotification(
- config = NotificationConfig(
- title = TextReference.Str(value = "Scan your card to continue"),
- subtitle = TextReference.Str(value = ""),
- iconResId = R.drawable.ic_tangem_24,
- ),
- )
-
- /**
- * "Unlock wallets" notification
- *
- * @property onClick lambda be invoked when notification is clicked
- */
- data class UnlockWallets(override val onClick: () -> Unit) : Clickable, WalletNotification(
- config = NotificationConfig(
- title = TextReference.Str(value = "Unlock needed"),
- subtitle = TextReference.Str(value = ""),
+ title = resourceReference(id = R.string.common_unlock_needed),
+ subtitle = resourceReference(
+ id = R.string.unlock_wallet_description_short,
+ formatArgs = wrappedList(
+ resourceReference(R.string.common_biometrics),
+ ),
+ ),
iconResId = R.drawable.ic_locked_24,
+ onClick = onClick,
+ ),
+ )
+
+ data class RateApp(
+ val onPositiveClick: () -> Unit,
+ val onNegativeClick: () -> Unit,
+ val onCloseClick: () -> Unit,
+ ) : WalletNotification(
+ config = NotificationConfig(
+ title = resourceReference(id = R.string.warning_rate_app_title),
+ subtitle = resourceReference(id = R.string.warning_rate_app_message),
+ iconResId = R.drawable.ic_star_24,
+ buttonsState = NotificationConfig.ButtonsState.PairButtonsConfig(
+ primaryText = resourceReference(id = R.string.warning_button_love_it),
+ onPrimaryClick = onPositiveClick,
+ secondaryText = resourceReference(id = R.string.warning_button_can_be_better),
+ onSecondaryClick = onNegativeClick,
+ ),
+ onCloseClick = onCloseClick,
),
)
}
\ No newline at end of file
diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/components/common/WalletNotifications.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/components/common/WalletNotifications.kt
index 730832731b..22c20dcfc7 100644
--- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/components/common/WalletNotifications.kt
+++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/ui/components/common/WalletNotifications.kt
@@ -5,6 +5,7 @@ import androidx.compose.foundation.lazy.LazyListScope
import androidx.compose.foundation.lazy.items
import androidx.compose.ui.Modifier
import com.tangem.core.ui.components.notifications.Notification
+import com.tangem.core.ui.res.TangemTheme
import com.tangem.feature.wallet.presentation.wallet.state.components.WalletNotification
import kotlinx.collections.immutable.ImmutableList
@@ -20,8 +21,20 @@ import kotlinx.collections.immutable.ImmutableList
internal fun LazyListScope.notifications(configs: ImmutableList, modifier: Modifier = Modifier) {
items(
items = configs,
- key = { it.config.title.hashCode() },
+ key = { it::class.java },
contentType = { it.config::class.java },
- itemContent = { Notification(config = it.config, modifier = modifier.animateItemPlacement()) },
+ itemContent = {
+ Notification(
+ config = it.config,
+ modifier = modifier.animateItemPlacement(),
+ iconTint = when (it) {
+ is WalletNotification.Critical -> TangemTheme.colors.icon.warning
+ is WalletNotification.MissingAddresses -> TangemTheme.colors.icon.accent
+ is WalletNotification.RateApp -> TangemTheme.colors.icon.attention
+ is WalletNotification.UnlockWallets -> TangemTheme.colors.icon.primary1
+ is WalletNotification.Warning -> null
+ },
+ )
+ },
)
}
\ No newline at end of file
diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/WalletClickIntents.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/WalletClickIntents.kt
index b5267bd065..e0da1fe275 100644
--- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/WalletClickIntents.kt
+++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/WalletClickIntents.kt
@@ -9,9 +9,7 @@ internal interface WalletClickIntents {
fun onBackClick()
- fun onScanCardClick()
-
- fun onScanCardNotificationClick()
+ fun onGenerateMissedAddressesClick()
fun onScanToUnlockWalletClick()
@@ -19,16 +17,12 @@ internal interface WalletClickIntents {
fun onBackupCardClick()
- fun onCriticalWarningAlreadySignedHashesClick()
-
- fun onCloseWarningAlreadySignedHashesClick()
+ fun onMultiWalletSignedHashesNotificationClick()
fun onLikeTangemAppClick()
fun onRateTheAppClick()
- fun onShareClick()
-
fun onWalletChange(index: Int)
fun onRefreshSwipe()
diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/WalletNotificationsListFactory.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/WalletNotificationsListFactory.kt
index 1d981cf79a..e6a3d1a22c 100644
--- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/WalletNotificationsListFactory.kt
+++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/WalletNotificationsListFactory.kt
@@ -1,9 +1,10 @@
package com.tangem.feature.wallet.presentation.wallet.viewmodels
+import com.tangem.domain.card.GetCardWasScannedUseCase
import com.tangem.domain.common.CardTypesResolver
+import com.tangem.domain.demo.IsDemoCardUseCase
+import com.tangem.domain.settings.IsUserAlreadyRateAppUseCase
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
-import com.tangem.domain.tokens.model.NetworkGroup
-import com.tangem.domain.tokens.model.TokenList
import com.tangem.feature.wallet.presentation.wallet.state.components.WalletNotification
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.toImmutableList
@@ -13,126 +14,166 @@ import kotlinx.coroutines.flow.flow
/**
* Wallet notifications list factory
*
- * @property wasCardScannedCallback callback that check if card was scanned
- * @property isUserAlreadyRateAppCallback callback that check if card is user already rate app
- * @property isDemoCardCallback callback that check if card is demo
- * @property clickIntents screen click intents
+ * @property isDemoCardUseCase use case that check if card is demo
+ * @property isUserAlreadyRateAppUseCase use case that check if card is user already rate app
+ * @property getCardWasScannedUseCase use case that check if card was scanned
+ * @property clickIntents screen click intents
*
[REDACTED_AUTHOR]
*/
internal class WalletNotificationsListFactory(
- private val wasCardScannedCallback: suspend (String) -> Boolean,
- private val isUserAlreadyRateAppCallback: suspend () -> Boolean,
- private val isDemoCardCallback: (String) -> Boolean,
+ private val isDemoCardUseCase: IsDemoCardUseCase,
+ private val isUserAlreadyRateAppUseCase: IsUserAlreadyRateAppUseCase,
+ private val getCardWasScannedUseCase: GetCardWasScannedUseCase,
private val clickIntents: WalletClickIntents,
) {
- fun create(cardTypesResolver: CardTypesResolver, tokenList: TokenList?): Flow> {
- // TODO: [REDACTED_JIRA] order
+ fun create(
+ cardTypesResolver: CardTypesResolver,
+ cryptoCurrencyList: List,
+ ): Flow> {
return flow {
emit(
buildList {
- if (cardTypesResolver.isTestCard()) {
- add(element = WalletNotification.TestCard)
- return@buildList
- }
+ addCriticalNotifications(cardTypesResolver)
- addRemainingSignaturesLeftNotifications(cardTypesResolver)
+ addMissingAddressesNotification(cryptoCurrencyList)
- val isDemo = isDemoCardCallback(cardTypesResolver.getCardId())
- if (!cardTypesResolver.isReleaseFirmwareType()) {
- add(element = WalletNotification.DevCard)
- } else {
- addReleaseSpecialNotifications(cardTypesResolver = cardTypesResolver, isDemo = isDemo)
- }
+ addRateTheAppNotification()
- if (isDemo) {
- add(element = WalletNotification.DemoCard)
- }
-
- if (hasUnreachableNetworks(tokenList)) {
- add(element = WalletNotification.UnreachableNetworks)
- }
-
- if (!cardTypesResolver.isBackupForbidden() && !cardTypesResolver.hasBackup()) {
- add(element = WalletNotification.BackupCard(onClick = clickIntents::onBackupCardClick))
- }
-
- if (tokenList != null && tokenList.hasMissedDerivations()) {
- add(element = WalletNotification.ScanCard(onClick = clickIntents::onScanCardNotificationClick))
- }
-
- if (isUserAlreadyRateAppCallback()) {
- add(element = WalletNotification.LikeTangemApp(onClick = clickIntents::onLikeTangemAppClick))
- }
- }.toImmutableList(),
+ addWarningNotifications(cardTypesResolver, cryptoCurrencyList)
+ }
+ .toImmutableList(),
)
}
}
- private fun MutableList.addRemainingSignaturesLeftNotifications(
- cardTypesResolver: CardTypesResolver,
- ) {
- val remainingSignatures = cardTypesResolver.getRemainingSignatures()
- if (remainingSignatures != null && remainingSignatures <= MAX_REMAINING_SIGNATURES_COUNT) {
- add(element = WalletNotification.RemainingSignaturesLeft(remainingSignatures))
+ private fun MutableList.addCriticalNotifications(cardTypesResolver: CardTypesResolver) {
+ addIf(
+ element = WalletNotification.Critical.DevCard,
+ condition = !cardTypesResolver.isReleaseFirmwareType(),
+ )
+
+ addIf(
+ element = WalletNotification.Critical.DemoCard,
+ condition = isDemoCardUseCase(cardId = cardTypesResolver.getCardId()),
+ )
+
+ addIf(
+ element = WalletNotification.Critical.TestNetCard,
+ condition = cardTypesResolver.isTestCard(),
+ )
+
+ addIf(
+ element = WalletNotification.Critical.FailedCardValidation,
+ condition = cardTypesResolver.isReleaseFirmwareType() && cardTypesResolver.isAttestationFailed(),
+ )
+
+ cardTypesResolver.getRemainingSignatures()?.let { remainingSignatures ->
+ addIf(
+ element = WalletNotification.Critical.LowSignatures(count = remainingSignatures),
+ condition = remainingSignatures <= MAX_REMAINING_SIGNATURES_COUNT,
+ )
}
}
- private suspend fun MutableList.addReleaseSpecialNotifications(
- cardTypesResolver: CardTypesResolver,
- isDemo: Boolean,
+ private fun MutableList.addMissingAddressesNotification(
+ cryptoCurrencyList: List,
) {
- if (!wasCardScannedCallback(cardTypesResolver.getCardId()) && cardTypesResolver.isMultiwalletAllowed() &&
- !isDemo
- ) {
- if (cardTypesResolver.isBackupForbidden() && cardTypesResolver.hasWalletSignedHashes()) {
- add(
- element = WalletNotification.CriticalWarningAlreadySignedHashes(
- onClick = clickIntents::onCriticalWarningAlreadySignedHashesClick,
- ),
+ val missedAddressesCount = cryptoCurrencyList.getMissedAddressesCount()
+
+ addIf(
+ element = WalletNotification.MissingAddresses(
+ missingAddressesCount = missedAddressesCount,
+ onGenerateClick = clickIntents::onGenerateMissedAddressesClick,
+ ),
+ condition = missedAddressesCount > 0,
+ )
+ }
+
+ private fun List.getMissedAddressesCount(): Int {
+ return filterIsInstance().count()
+ }
+
+ // TODO: [REDACTED_JIRA]
+ private suspend fun MutableList.addRateTheAppNotification() {
+ addIf(
+ element = WalletNotification.RateApp(
+ onPositiveClick = {},
+ onNegativeClick = {},
+ onCloseClick = {},
+ ),
+ condition = isUserAlreadyRateAppUseCase(),
+ )
+ }
+
+ private suspend fun MutableList.addWarningNotifications(
+ cardTypesResolver: CardTypesResolver,
+ cryptoCurrencyList: List,
+ ) {
+ addIf(
+ element = WalletNotification.Warning.MissingBackup(
+ onStartBackupClick = clickIntents::onBackupCardClick,
+ ),
+ condition = !cardTypesResolver.isBackupForbidden() && !cardTypesResolver.hasBackup(),
+ )
+
+ val isDemo = isDemoCardUseCase(cardId = cardTypesResolver.getCardId())
+ if (cardTypesResolver.isMultiwalletAllowed()) {
+ addIf(
+ element = WalletNotification.Warning.SomeNetworksUnreachable,
+ condition = cryptoCurrencyList.hasUnreachableNetworks(),
+ )
+
+ if (cardTypesResolver.isBackupForbidden()) {
+ addIf(
+ element = WalletNotification.Warning.NumberOfSignedHashesIncorrect,
+ condition = checkSignedHashes(cardTypesResolver = cardTypesResolver, isDemo = isDemo),
)
- } else if (cardTypesResolver.hasWalletSignedHashes()) {
- add(
- element = WalletNotification.WarningAlreadySignedHashes(
- onClick = clickIntents::onCloseWarningAlreadySignedHashesClick,
+ } else {
+ addIf(
+ element = WalletNotification.Warning.MultiWalletSignedHashesIncorrect(
+ onClick = clickIntents::onMultiWalletSignedHashesNotificationClick,
),
+ condition = checkSignedHashes(cardTypesResolver = cardTypesResolver, isDemo = isDemo),
)
}
- }
+ } else {
+ addIf(
+ element = WalletNotification.Warning.NetworksUnreachable,
+ condition = cryptoCurrencyList.hasUnreachableNetworks(),
+ )
- if (cardTypesResolver.isAttestationFailed()) {
- add(element = WalletNotification.CardVerificationFailed)
+ // TODO: [REDACTED_JIRA]
+ addIf(
+ element = WalletNotification.Warning.TopUpNote(
+ errorMessage = "To activate card top up it with at least 1 XLM",
+ ),
+ condition = cryptoCurrencyList.hasNoAccountStatus(),
+ )
+
+ addIf(
+ element = WalletNotification.Warning.NumberOfSignedHashesIncorrect,
+ condition = checkSignedHashes(cardTypesResolver, isDemo),
+ )
}
}
- private fun hasUnreachableNetworks(tokenList: TokenList?): Boolean {
- return when (tokenList) {
- is TokenList.GroupedByNetwork -> {
- tokenList.groups
- .flatMap(NetworkGroup::currencies)
- .map(CryptoCurrencyStatus::value)
- .any { it is CryptoCurrencyStatus.Unreachable }
- }
- is TokenList.Ungrouped -> {
- tokenList.currencies
- .map(CryptoCurrencyStatus::value)
- .any { it is CryptoCurrencyStatus.Unreachable }
- }
- is TokenList.NotInitialized,
- null,
- -> false
- }
+ private fun MutableList.addIf(element: WalletNotification, condition: Boolean) {
+ if (condition) add(element = element)
}
- private fun TokenList.hasMissedDerivations(): Boolean {
- val statuses = when (this) {
- is TokenList.GroupedByNetwork -> groups.flatMap(NetworkGroup::currencies).map(CryptoCurrencyStatus::value)
- is TokenList.Ungrouped -> currencies.map(CryptoCurrencyStatus::value)
- TokenList.NotInitialized -> emptyList()
- }
+ private fun List.hasUnreachableNetworks(): Boolean {
+ return any { it is CryptoCurrencyStatus.Unreachable }
+ }
- return statuses.any { it is CryptoCurrencyStatus.MissedDerivation }
+ private fun List.hasNoAccountStatus(): Boolean {
+ return any { it is CryptoCurrencyStatus.NoAccount }
+ }
+
+ private suspend fun checkSignedHashes(cardTypesResolver: CardTypesResolver, isDemo: Boolean): Boolean {
+ return cardTypesResolver.isReleaseFirmwareType() && cardTypesResolver.hasWalletSignedHashes() &&
+ !isDemo && !getCardWasScannedUseCase(cardId = cardTypesResolver.getCardId())
}
private companion object {
diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/WalletViewModel.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/WalletViewModel.kt
index e8ed3975b2..6e932219ae 100644
--- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/WalletViewModel.kt
+++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/WalletViewModel.kt
@@ -11,7 +11,6 @@ import com.tangem.core.navigation.AppScreen
import com.tangem.core.ui.components.bottomsheets.tokenreceive.AddressModel
import com.tangem.core.ui.components.bottomsheets.tokenreceive.TokenReceiveBottomSheetConfig
import com.tangem.core.ui.components.marketprice.MarketPriceBlockState
-import com.tangem.core.ui.extensions.TextReference
import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
import com.tangem.domain.appcurrency.model.AppCurrency
import com.tangem.domain.balancehiding.IsBalanceHiddenUseCase
@@ -25,6 +24,7 @@ import com.tangem.domain.settings.*
import com.tangem.domain.tokens.*
import com.tangem.domain.tokens.legacy.TradeCryptoAction
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
+import com.tangem.domain.tokens.model.NetworkGroup
import com.tangem.domain.tokens.model.TokenList
import com.tangem.domain.tokens.models.CryptoCurrency
import com.tangem.domain.tokens.models.Network
@@ -32,7 +32,6 @@ import com.tangem.domain.txhistory.usecase.GetTxHistoryItemsCountUseCase
import com.tangem.domain.txhistory.usecase.GetTxHistoryItemsUseCase
import com.tangem.domain.userwallets.UserWalletBuilder
import com.tangem.domain.walletmanager.WalletManagersFacade
-import com.tangem.domain.wallets.models.SaveWalletError
import com.tangem.domain.wallets.models.UserWallet
import com.tangem.domain.wallets.models.UserWalletId
import com.tangem.domain.wallets.usecase.*
@@ -41,7 +40,6 @@ import com.tangem.feature.wallet.presentation.router.InnerWalletRouter
import com.tangem.feature.wallet.presentation.wallet.analytics.PortfolioEvent
import com.tangem.feature.wallet.presentation.wallet.analytics.WalletScreenAnalyticsEvent
import com.tangem.feature.wallet.presentation.wallet.state.*
-import com.tangem.feature.wallet.presentation.wallet.state.components.WalletBottomSheetConfig
import com.tangem.feature.wallet.presentation.wallet.state.components.WalletCardState
import com.tangem.feature.wallet.presentation.wallet.state.components.WalletTokensListState
import com.tangem.feature.wallet.presentation.wallet.state.factory.WalletStateFactory
@@ -80,9 +78,6 @@ internal class WalletViewModel @Inject constructor(
private val getPrimaryCurrencyStatusUpdatesUseCase: GetPrimaryCurrencyStatusUpdatesUseCase,
private val fetchCurrencyStatusUseCase: FetchCurrencyStatusUseCase,
private val getNetworkCoinStatusUseCase: GetNetworkCoinStatusUseCase,
- private val getCardWasScannedUseCase: GetCardWasScannedUseCase,
- private val isUserAlreadyRateAppUseCase: IsUserAlreadyRateAppUseCase,
- private val isDemoCardUseCase: IsDemoCardUseCase,
private val scanCardProcessor: ScanCardProcessor,
private val txHistoryItemsCountUseCase: GetTxHistoryItemsCountUseCase,
private val txHistoryItemsUseCase: GetTxHistoryItemsUseCase,
@@ -99,6 +94,9 @@ internal class WalletViewModel @Inject constructor(
private val reduxStateHolder: ReduxStateHolder,
private val dispatchers: CoroutineDispatcherProvider,
private val analyticsEventsHandler: AnalyticsEventHandler,
+ getCardWasScannedUseCase: GetCardWasScannedUseCase,
+ isUserAlreadyRateAppUseCase: IsUserAlreadyRateAppUseCase,
+ isDemoCardUseCase: IsDemoCardUseCase,
// endregion Parameters
) : ViewModel(), DefaultLifecycleObserver, WalletClickIntents {
@@ -109,9 +107,9 @@ internal class WalletViewModel @Inject constructor(
private var isBalanceHidden = true
private val notificationsListFactory = WalletNotificationsListFactory(
- wasCardScannedCallback = getCardWasScannedUseCase::invoke,
- isUserAlreadyRateAppCallback = isUserAlreadyRateAppUseCase::invoke,
- isDemoCardCallback = isDemoCardUseCase::invoke,
+ getCardWasScannedUseCase = getCardWasScannedUseCase,
+ isUserAlreadyRateAppUseCase = isUserAlreadyRateAppUseCase,
+ isDemoCardUseCase = isDemoCardUseCase,
clickIntents = this,
)
@@ -254,58 +252,9 @@ internal class WalletViewModel @Inject constructor(
}
}
- override fun onScanCardClick() {
+ override fun onGenerateMissedAddressesClick() {
analyticsEventsHandler.send(WalletScreenAnalyticsEvent.NoticeScanYourCardTapped)
- viewModelScope.launch(dispatchers.io) {
- scanCardProcessor.scan()
- .doOnSuccess {
- // If card's public key is null then user wallet will be null
- val userWallet = UserWalletBuilder(scanResponse = it).build()
-
- if (userWallet != null) {
- saveWalletUseCase(userWallet = userWallet, canOverride = false)
- .onLeft { saveWalletError ->
- showErrorIfWalletNotSaved(
- error = saveWalletError,
- scannedWalletId = userWallet.walletId,
- )
- }
- }
- }
- }
- }
-
- private fun showErrorIfWalletNotSaved(error: SaveWalletError, scannedWalletId: UserWalletId) {
- when (error) {
- is SaveWalletError.DataError -> Unit
- is SaveWalletError.WalletAlreadySaved -> {
- viewModelScope.launch(dispatchers.main) {
- val alreadySavedWalletIndex = (uiState as? WalletState.ContentState)?.walletsListConfig
- ?.wallets?.indexOfFirst { it.id == scannedWalletId }
-
- if (alreadySavedWalletIndex != null && alreadySavedWalletIndex != -1) {
- uiState = stateFactory.getStateAndTriggerEvent(
- state = uiState,
- event = WalletEvent.ChangeWallet(index = alreadySavedWalletIndex),
- setUiState = { uiState = it },
- )
-
- // Delay between events
- delay(timeMillis = 500L)
- }
-
- uiState = stateFactory.getStateAndTriggerEvent(
- state = uiState,
- event = WalletEvent.ShowError(text = TextReference.Res(error.messageId)),
- setUiState = { uiState = it },
- )
- }
- }
- }
- }
-
- override fun onScanCardNotificationClick() {
scanToUpdateSelectedWallet(
onSuccessSave = {
// Reload currencies with missed derivation
@@ -361,33 +310,15 @@ internal class WalletViewModel @Inject constructor(
router.openOnboardingScreen()
}
- override fun onCriticalWarningAlreadySignedHashesClick() {
- uiState = stateFactory.getStateWithOpenWalletBottomSheet(
- content = WalletBottomSheetConfig.CriticalWarningAlreadySignedHashes(
- onOkClick = {},
- onCancelClick = {},
- ),
- )
- }
-
- override fun onCloseWarningAlreadySignedHashesClick() {
+ override fun onMultiWalletSignedHashesNotificationClick() {
// TODO: [REDACTED_JIRA]
}
override fun onLikeTangemAppClick() {
- uiState = stateFactory.getStateWithOpenWalletBottomSheet(
- content = WalletBottomSheetConfig.LikeTangemApp(
- onRateTheAppClick = ::onRateTheAppClick,
- onShareClick = ::onShareClick,
- ),
- )
- }
-
- override fun onRateTheAppClick() {
// TODO: [REDACTED_JIRA]
}
- override fun onShareClick() {
+ override fun onRateTheAppClick() {
// TODO: [REDACTED_JIRA]
}
@@ -772,7 +703,19 @@ internal class WalletViewModel @Inject constructor(
private fun updateNotifications(index: Int, tokenList: TokenList? = null) {
notificationsListFactory.create(
cardTypesResolver = getCardTypeResolver(index = index),
- tokenList = tokenList,
+ cryptoCurrencyList = if (tokenList != null) {
+ when (tokenList) {
+ is TokenList.GroupedByNetwork -> {
+ tokenList.groups
+ .flatMap(NetworkGroup::currencies)
+ .map(CryptoCurrencyStatus::value)
+ }
+ is TokenList.Ungrouped -> tokenList.currencies.map(CryptoCurrencyStatus::value)
+ is TokenList.NotInitialized -> emptyList()
+ }
+ } else {
+ listOfNotNull(singleWalletCryptoCurrencyStatus?.value)
+ },
)
.distinctUntilChanged()
.onEach { uiState = stateFactory.getStateByNotifications(notifications = it) }