Updated on 2026-08-14
This commit is contained in:
parent
30a7d0dcec
commit
0c5d018677
16 changed files with 195 additions and 12 deletions
|
|
@ -25,7 +25,7 @@ import dagger.hilt.InstallIn
|
|||
import dagger.hilt.components.SingletonComponent
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Suppress("TooManyFunctions")
|
||||
@Suppress("TooManyFunctions", "LargeClass")
|
||||
@Module
|
||||
@InstallIn(SingletonComponent::class)
|
||||
internal object WalletsDomainModule {
|
||||
|
|
@ -352,4 +352,24 @@ internal object WalletsDomainModule {
|
|||
walletsRepository = walletsRepository,
|
||||
)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun providesIsUpgradeWalletNotificationEnabledUseCase(
|
||||
walletsRepository: WalletsRepository,
|
||||
): IsUpgradeWalletNotificationEnabledUseCase {
|
||||
return IsUpgradeWalletNotificationEnabledUseCase(
|
||||
walletsRepository = walletsRepository,
|
||||
)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun providesDismissUpgradeWalletNotificationUseCase(
|
||||
walletsRepository: WalletsRepository,
|
||||
): DismissUpgradeWalletNotificationUseCase {
|
||||
return DismissUpgradeWalletNotificationUseCase(
|
||||
walletsRepository = walletsRepository,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -27,7 +27,6 @@ import androidx.compose.ui.tooling.preview.Preview
|
|||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.tangem.core.ui.R
|
||||
import com.tangem.core.ui.components.*
|
||||
import com.tangem.core.ui.components.buttons.common.TangemButtonSize
|
||||
|
|
@ -64,7 +63,6 @@ fun Notification(
|
|||
NotificationConfig.IconTint.Accent -> TangemTheme.colors.icon.accent
|
||||
NotificationConfig.IconTint.Attention -> TangemTheme.colors.icon.attention
|
||||
},
|
||||
iconSize: Dp = 20.dp,
|
||||
isEnabled: Boolean = true,
|
||||
) {
|
||||
NotificationBaseContainer(
|
||||
|
|
@ -78,7 +76,7 @@ fun Notification(
|
|||
MainContent(
|
||||
iconResId = config.iconResId,
|
||||
iconTint = iconTint,
|
||||
iconSize = iconSize,
|
||||
iconSize = config.iconSize,
|
||||
title = config.title,
|
||||
titleColor = titleColor,
|
||||
subtitle = config.subtitle,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
package com.tangem.core.ui.components.notifications
|
||||
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
|
||||
/**
|
||||
|
|
@ -26,6 +28,7 @@ data class NotificationConfig(
|
|||
val onCloseClick: (() -> Unit)? = null,
|
||||
val showArrowIcon: Boolean = onClick != null,
|
||||
val iconTint: IconTint = IconTint.Unspecified,
|
||||
val iconSize: Dp = 20.dp,
|
||||
) {
|
||||
|
||||
sealed class ButtonsState {
|
||||
|
|
|
|||
22
core/ui/src/main/res/drawable/ic_hardware_backup_36.xml
Normal file
22
core/ui/src/main/res/drawable/ic_hardware_backup_36.xml
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="36dp"
|
||||
android:height="36dp"
|
||||
android:viewportWidth="36"
|
||||
android:viewportHeight="36">
|
||||
<group>
|
||||
<clip-path
|
||||
android:pathData="M0,0h36v36h-36z"/>
|
||||
<path
|
||||
android:pathData="M18,18m-18,0a18,18 0,1 1,36 0a18,18 0,1 1,-36 0"
|
||||
android:fillColor="#EBEBEB"/>
|
||||
<path
|
||||
android:pathData="M21.682,9.25H14.318C13.156,9.25 12.576,9.25 12.132,9.476C11.742,9.675 11.424,9.992 11.226,10.382C11,10.826 11,11.406 11,12.568V13.8H25V12.568C25,11.406 25,10.826 24.774,10.382C24.575,9.992 24.258,9.674 23.868,9.476C23.424,9.25 22.844,9.25 21.682,9.25Z"
|
||||
android:fillColor="#1E1E1E"/>
|
||||
<path
|
||||
android:pathData="M20.333,17.65H25V23.432C25,24.594 25,25.174 24.773,25.618C24.574,26.008 24.258,26.326 23.868,26.524C23.423,26.75 22.843,26.75 21.681,26.75H20.334L20.333,17.65Z"
|
||||
android:fillColor="#1E1E1E"/>
|
||||
<path
|
||||
android:pathData="M11,17.65H15.666V26.75H14.318C13.157,26.75 12.576,26.75 12.132,26.524C11.742,26.326 11.425,26.008 11.226,25.618C11,25.174 11,24.594 11,23.432V17.65Z"
|
||||
android:fillColor="#1E1E1E"/>
|
||||
</group>
|
||||
</vector>
|
||||
|
|
@ -31,6 +31,7 @@ import com.tangem.utils.coroutines.runCatching
|
|||
import kotlinx.coroutines.flow.*
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import kotlin.collections.mutableSetOf
|
||||
|
||||
typealias SeedPhraseNotificationsStatuses = Map<UserWalletId, SeedPhraseNotificationsStatus>
|
||||
|
||||
|
|
@ -44,6 +45,9 @@ internal class DefaultWalletsRepository(
|
|||
private val authProvider: AuthProvider,
|
||||
) : WalletsRepository {
|
||||
|
||||
private val upgradeWalletNotificationDisabled: MutableStateFlow<Set<UserWalletId>> =
|
||||
MutableStateFlow(mutableSetOf<UserWalletId>())
|
||||
|
||||
override suspend fun shouldSaveUserWalletsSync(): Boolean {
|
||||
return appPreferencesStore.getSyncOrDefault(key = PreferencesKeys.SAVE_USER_WALLETS_KEY, default = false)
|
||||
}
|
||||
|
|
@ -327,6 +331,16 @@ internal class DefaultWalletsRepository(
|
|||
}
|
||||
}
|
||||
|
||||
override fun isUpgradeWalletNotificationEnabled(userWalletId: UserWalletId): Flow<Boolean> {
|
||||
return upgradeWalletNotificationDisabled.map {
|
||||
it.contains(userWalletId)
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun dismissUpgradeWalletNotification(userWalletId: UserWalletId) {
|
||||
upgradeWalletNotificationDisabled.update { it.plus(userWalletId) }
|
||||
}
|
||||
|
||||
override suspend fun setWalletName(walletId: String, walletName: String) = withContext(dispatchers.io) {
|
||||
tangemTechApi.updateWallet(
|
||||
walletId = walletId,
|
||||
|
|
|
|||
|
|
@ -57,6 +57,10 @@ interface WalletsRepository {
|
|||
|
||||
suspend fun setNotificationsEnabled(userWalletId: UserWalletId, isEnabled: Boolean)
|
||||
|
||||
fun isUpgradeWalletNotificationEnabled(userWalletId: UserWalletId): Flow<Boolean>
|
||||
|
||||
suspend fun dismissUpgradeWalletNotification(userWalletId: UserWalletId)
|
||||
|
||||
@Throws
|
||||
suspend fun setWalletName(walletId: String, walletName: String)
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,12 @@
|
|||
package com.tangem.domain.wallets.usecase
|
||||
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.wallets.repository.WalletsRepository
|
||||
|
||||
class DismissUpgradeWalletNotificationUseCase(
|
||||
private val walletsRepository: WalletsRepository,
|
||||
) {
|
||||
suspend operator fun invoke(userWalletId: UserWalletId) {
|
||||
walletsRepository.dismissUpgradeWalletNotification(userWalletId)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
package com.tangem.domain.wallets.usecase
|
||||
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.wallets.repository.WalletsRepository
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
class IsUpgradeWalletNotificationEnabledUseCase(
|
||||
private val walletsRepository: WalletsRepository,
|
||||
) {
|
||||
operator fun invoke(userWalletId: UserWalletId): Flow<Boolean> {
|
||||
return walletsRepository.isUpgradeWalletNotificationEnabled(userWalletId)
|
||||
}
|
||||
}
|
||||
|
|
@ -45,6 +45,9 @@ internal class PreviewWalletSettingsComponent : WalletSettingsComponent {
|
|||
onNotificationsDescriptionClick = {},
|
||||
isNotificationsPermissionGranted = false,
|
||||
onAccessCodeClick = {},
|
||||
walletUpgradeDismissed = false,
|
||||
onUpgradeWalletClick = {},
|
||||
onDismissUpgradeWalletClick = {},
|
||||
),
|
||||
requestPushNotificationsPermission = false,
|
||||
onPushNotificationPermissionGranted = {},
|
||||
|
|
|
|||
|
|
@ -43,4 +43,12 @@ internal sealed class WalletSettingsItemUM {
|
|||
val title: TextReference,
|
||||
val description: TextReference,
|
||||
) : WalletSettingsItemUM()
|
||||
|
||||
data class UpgradeWallet(
|
||||
override val id: String,
|
||||
val title: TextReference,
|
||||
val description: TextReference,
|
||||
val onClick: () -> Unit,
|
||||
val onDismissClick: () -> Unit,
|
||||
) : WalletSettingsItemUM()
|
||||
}
|
||||
|
|
@ -10,4 +10,5 @@ internal data class WalletSettingsUM(
|
|||
val requestPushNotificationsPermission: Boolean = false,
|
||||
val onPushNotificationPermissionGranted: (Boolean) -> Unit,
|
||||
val isWalletBackedUp: Boolean = true,
|
||||
val walletUpgradeDismissed: Boolean = false,
|
||||
)
|
||||
|
|
@ -56,7 +56,7 @@ import kotlinx.coroutines.launch
|
|||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
@Suppress("LongParameterList")
|
||||
@Suppress("LongParameterList", "LargeClass")
|
||||
@ModelScoped
|
||||
internal class WalletSettingsModel @Inject constructor(
|
||||
getWalletUseCase: GetUserWalletUseCase,
|
||||
|
|
@ -80,6 +80,8 @@ internal class WalletSettingsModel @Inject constructor(
|
|||
private val permissionsRepository: PermissionRepository,
|
||||
private val notificationsRepository: NotificationsRepository,
|
||||
private val getIsHuaweiDeviceWithoutGoogleServicesUseCase: GetIsHuaweiDeviceWithoutGoogleServicesUseCase,
|
||||
private val isUpgradeWalletNotificationEnabledUseCase: IsUpgradeWalletNotificationEnabledUseCase,
|
||||
private val dismissUpgradeWalletNotificationUseCase: DismissUpgradeWalletNotificationUseCase,
|
||||
) : Model() {
|
||||
|
||||
val params: WalletSettingsComponent.Params = paramsContainer.require()
|
||||
|
|
@ -93,6 +95,7 @@ internal class WalletSettingsModel @Inject constructor(
|
|||
requestPushNotificationsPermission = false,
|
||||
onPushNotificationPermissionGranted = ::onPushNotificationPermissionGranted,
|
||||
isWalletBackedUp = true,
|
||||
walletUpgradeDismissed = false,
|
||||
),
|
||||
)
|
||||
|
||||
|
|
@ -120,7 +123,8 @@ internal class WalletSettingsModel @Inject constructor(
|
|||
getWalletUseCase.invokeFlow(params.userWalletId).distinctUntilChanged(),
|
||||
getWalletNFTEnabledUseCase.invoke(params.userWalletId),
|
||||
getWalletNotificationsEnabledUseCase(params.userWalletId),
|
||||
) { maybeWallet, nftEnabled, notificationsEnabled ->
|
||||
isUpgradeWalletNotificationEnabledUseCase(params.userWalletId),
|
||||
) { maybeWallet, nftEnabled, notificationsEnabled, isUpgradeNotificationEnabled ->
|
||||
val wallet = maybeWallet.getOrNull() ?: return@combine
|
||||
val isRenameWalletAvailable = getShouldSaveUserWalletsSyncUseCase()
|
||||
val isWalletBackedUp = when (wallet) {
|
||||
|
|
@ -139,6 +143,7 @@ internal class WalletSettingsModel @Inject constructor(
|
|||
isNotificationsEnabled = notificationsEnabled,
|
||||
isNotificationsFeatureEnabled = isNeedShowNotifications,
|
||||
isNotificationsPermissionGranted = isNotificationsPermissionGranted(),
|
||||
isUpgradeNotificationEnabled = isUpgradeNotificationEnabled,
|
||||
),
|
||||
isWalletBackedUp = isWalletBackedUp,
|
||||
)
|
||||
|
|
@ -165,6 +170,7 @@ internal class WalletSettingsModel @Inject constructor(
|
|||
isNotificationsFeatureEnabled: Boolean,
|
||||
isNotificationsEnabled: Boolean,
|
||||
isNotificationsPermissionGranted: Boolean,
|
||||
isUpgradeNotificationEnabled: Boolean,
|
||||
): PersistentList<WalletSettingsItemUM> {
|
||||
val isMultiCurrency = when (userWallet) {
|
||||
is UserWallet.Cold -> userWallet.isMultiCurrency
|
||||
|
|
@ -215,6 +221,9 @@ internal class WalletSettingsModel @Inject constructor(
|
|||
onCheckedNotificationsChanged = ::onCheckedNotificationsChange,
|
||||
onNotificationsDescriptionClick = ::onNotificationsDescriptionClick,
|
||||
onAccessCodeClick = ::onAccessCodeClick,
|
||||
walletUpgradeDismissed = isUpgradeNotificationEnabled,
|
||||
onUpgradeWalletClick = ::onUpgradeWalletClick,
|
||||
onDismissUpgradeWalletClick = ::onDismissUpgradeWalletClick,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -367,4 +376,14 @@ internal class WalletSettingsModel @Inject constructor(
|
|||
router.push(AppRoute.UpdateAccessCode(params.userWalletId))
|
||||
}
|
||||
}
|
||||
|
||||
private fun onUpgradeWalletClick() {
|
||||
// TODO [REDACTED_TASK_KEY]
|
||||
}
|
||||
|
||||
private fun onDismissUpgradeWalletClick() {
|
||||
modelScope.launch {
|
||||
dismissUpgradeWalletNotificationUseCase.invoke(params.userWalletId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -25,6 +25,7 @@ import com.tangem.core.ui.components.items.DescriptionItem
|
|||
import com.tangem.core.ui.components.notifications.Notification
|
||||
import com.tangem.core.ui.components.notifications.NotificationConfig
|
||||
import com.tangem.core.ui.extensions.resolveReference
|
||||
import com.tangem.core.ui.extensions.stringReference
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
|
|
@ -116,6 +117,10 @@ private fun Content(state: WalletSettingsUM, modifier: Modifier = Modifier) {
|
|||
modifier = itemModifier,
|
||||
model = item,
|
||||
)
|
||||
is WalletSettingsItemUM.UpgradeWallet -> UpgradeWalletBlock(
|
||||
modifier = itemModifier,
|
||||
model = item,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -225,6 +230,21 @@ private fun SwitchBlock(model: WalletSettingsItemUM.WithSwitch, modifier: Modifi
|
|||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun UpgradeWalletBlock(model: WalletSettingsItemUM.UpgradeWallet, modifier: Modifier = Modifier) {
|
||||
Notification(
|
||||
config = NotificationConfig(
|
||||
title = model.title,
|
||||
subtitle = model.description,
|
||||
iconResId = R.drawable.ic_hardware_backup_36,
|
||||
iconSize = 36.dp,
|
||||
onClick = model.onClick,
|
||||
onCloseClick = model.onDismissClick,
|
||||
),
|
||||
modifier = modifier,
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun NotificationAlertBlock(model: WalletSettingsItemUM.NotificationPermission, modifier: Modifier = Modifier) {
|
||||
Notification(
|
||||
|
|
@ -266,4 +286,21 @@ private fun Preview_WalletSettingsScreen() {
|
|||
PreviewWalletSettingsComponent().Content(modifier = Modifier.fillMaxSize())
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
@Preview(showBackground = true, widthDp = 360)
|
||||
@Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
private fun Preview_WalletSettingsScreen1() {
|
||||
TangemThemePreview {
|
||||
UpgradeWalletBlock(
|
||||
model = WalletSettingsItemUM.UpgradeWallet(
|
||||
id = "upgrade_wallet",
|
||||
title = stringReference("Upgrade wallet with a hardware backup"),
|
||||
description = stringReference("Keep your crypto safe with Tangem’s best-in-class hardware wallet."),
|
||||
onClick = {},
|
||||
onDismissClick = {},
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
// endregion Preview
|
||||
|
|
@ -47,8 +47,19 @@ internal class ItemsBuilder @Inject constructor(
|
|||
onLinkMoreCardsClick: () -> Unit,
|
||||
onReferralClick: () -> Unit,
|
||||
onAccessCodeClick: () -> Unit,
|
||||
walletUpgradeDismissed: Boolean,
|
||||
onUpgradeWalletClick: () -> Unit,
|
||||
onDismissUpgradeWalletClick: () -> Unit,
|
||||
): PersistentList<WalletSettingsItemUM> = persistentListOf<WalletSettingsItemUM>()
|
||||
.add(buildNameItem(userWalletName, isRenameWalletAvailable, renameWallet))
|
||||
.addAll(
|
||||
buildUpgradeWalletItem(
|
||||
userWallet = userWallet,
|
||||
walletUpgradeDismissed = walletUpgradeDismissed,
|
||||
onUpgradeWalletClick = onUpgradeWalletClick,
|
||||
onDismissUpgradeWalletClick = onDismissUpgradeWalletClick,
|
||||
),
|
||||
)
|
||||
.addAll(buildAccessCodeItem(userWallet, onAccessCodeClick))
|
||||
.add(
|
||||
buildCardItem(
|
||||
|
|
@ -124,6 +135,28 @@ internal class ItemsBuilder @Inject constructor(
|
|||
onCheckedChange = onCheckedNFTChange,
|
||||
)
|
||||
|
||||
private fun buildUpgradeWalletItem(
|
||||
userWallet: UserWallet,
|
||||
walletUpgradeDismissed: Boolean,
|
||||
onUpgradeWalletClick: () -> Unit,
|
||||
onDismissUpgradeWalletClick: () -> Unit,
|
||||
): List<WalletSettingsItemUM> = when (userWallet) {
|
||||
is UserWallet.Cold -> emptyList()
|
||||
is UserWallet.Hot -> if (!walletUpgradeDismissed) {
|
||||
listOf(
|
||||
WalletSettingsItemUM.UpgradeWallet(
|
||||
id = "upgrade_wallet",
|
||||
title = resourceReference(id = R.string.hw_upgrade_to_cold_banner_title),
|
||||
description = resourceReference(id = R.string.hw_upgrade_to_cold_banner_description),
|
||||
onClick = onUpgradeWalletClick,
|
||||
onDismissClick = onDismissUpgradeWalletClick,
|
||||
),
|
||||
)
|
||||
} else {
|
||||
emptyList()
|
||||
}
|
||||
}
|
||||
|
||||
private fun buildNotificationsPermissionItem() = WalletSettingsItemUM.NotificationPermission(
|
||||
id = "notifications_permission",
|
||||
title = resourceReference(id = R.string.transaction_notifications_warning_title),
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package com.tangem.feature.wallet.presentation.wallet.state.model
|
||||
|
||||
import androidx.compose.runtime.Immutable
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.tangem.core.ui.components.notifications.NotificationConfig
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
import com.tangem.core.ui.extensions.pluralReference
|
||||
|
|
@ -282,6 +283,7 @@ sealed class WalletNotification(val config: NotificationConfig) {
|
|||
text = resourceReference(R.string.notification_referral_promo_button),
|
||||
onClick = onClick,
|
||||
),
|
||||
iconSize = 54.dp,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
@ -3,7 +3,6 @@ package com.tangem.feature.wallet.presentation.wallet.ui.components.common
|
|||
import androidx.compose.foundation.lazy.LazyListScope
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.tangem.core.ui.components.notifications.NoteMigrationNotification
|
||||
import com.tangem.core.ui.components.notifications.Notification
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
|
|
@ -39,11 +38,6 @@ internal fun LazyListScope.notifications(configs: ImmutableList<WalletNotificati
|
|||
Notification(
|
||||
config = it.config,
|
||||
modifier = modifier.animateItem(fadeInSpec = null, fadeOutSpec = null),
|
||||
iconSize = if (it is WalletNotification.ReferralPromo) {
|
||||
54.dp
|
||||
} else {
|
||||
20.dp
|
||||
},
|
||||
iconTint = when (it) {
|
||||
is WalletNotification.Critical -> TangemTheme.colors.icon.warning
|
||||
is WalletNotification.Informational -> TangemTheme.colors.icon.accent
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue