Updated on 2026-08-14

This commit is contained in:
Tangem 2025-09-18 14:18:39 +04:00
parent 4193e5777e
commit 3306749ae5
11 changed files with 108 additions and 101 deletions

View file

@ -341,16 +341,18 @@ private class AppCurrencySelectorStateProvider : CollectionPreviewParameterProvi
.mapIndexed { index, s -> Currency(index.toString(), s) }
.toPersistentList()
add(AppCurrencySelectorState.Loading(onBackClick = {}))
add(AppCurrencySelectorState.Default(
this + AppCurrencySelectorState.Loading(onBackClick = {})
this + AppCurrencySelectorState.Default(
selectedId = "0",
items = items,
scrollToSelected = consumedEvent(),
onCurrencyClick = {},
onBackClick = {},
onTopBarActionClick = {},
))
add(AppCurrencySelectorState.Search(
)
this + AppCurrencySelectorState.Search(
selectedId = "0",
items = items,
scrollToSelected = consumedEvent(),
@ -358,7 +360,7 @@ private class AppCurrencySelectorStateProvider : CollectionPreviewParameterProvi
onBackClick = {},
onSearchInputChange = {},
onTopBarActionClick = {},
))
)
},
)
// endregion Preview

View file

@ -15,8 +15,8 @@ import androidx.compose.ui.platform.LocalDensity
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.res.TangemThemePreview
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreview
import com.tangem.domain.apptheme.model.AppThemeMode
import com.tangem.tap.features.details.ui.appsettings.AppSettingsScreenState.Item
import com.tangem.tap.features.details.ui.appsettings.components.*
@ -103,10 +103,10 @@ private class AppSettingsScreenStateProvider : CollectionPreviewParameterProvide
itemsFactory.createSelectThemeModeButton(AppThemeMode.DEFAULT, {}),
)
add(AppSettingsScreenState.Content(
this + AppSettingsScreenState.Content(
items = items,
dialog = null,
))
)
},
)
// endregion Preview

View file

@ -14,8 +14,8 @@ 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.extensions.resolveReference
import com.tangem.core.ui.res.TangemThemePreview
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreview
import com.tangem.tap.features.details.ui.appsettings.AppSettingsItemsFactory
import com.tangem.tap.features.details.ui.appsettings.AppSettingsScreenState.Item
@ -64,10 +64,10 @@ private class ButtonItemProvider : CollectionPreviewParameterProvider<Item.Butto
collection = buildList {
val itemsFactory = AppSettingsItemsFactory()
add(itemsFactory.createSelectAppCurrencyButton(
this + itemsFactory.createSelectAppCurrencyButton(
currentAppCurrencyName = "US Dollar",
onClick = { /* no-op */ },
))
)
},
)
// endregion Preview

View file

@ -16,8 +16,8 @@ import androidx.compose.ui.unit.dp
import com.tangem.core.ui.components.SpacerH4
import com.tangem.core.ui.components.SpacerW16
import com.tangem.core.ui.extensions.resolveReference
import com.tangem.core.ui.res.TangemThemePreview
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreview
import com.tangem.tap.features.details.ui.appsettings.AppSettingsItemsFactory
import com.tangem.tap.features.details.ui.appsettings.AppSettingsScreenState.Item
@ -71,9 +71,7 @@ private class CardItemProvider : CollectionPreviewParameterProvider<Item.Card>(
collection = buildList {
val itemsFactory = AppSettingsItemsFactory()
add(itemsFactory.createEnrollBiometricsCard(
onClick = { /* no-op */ },
))
this + itemsFactory.createEnrollBiometricsCard(onClick = { /* no-op */ })
},
)
// endregion Preview

View file

@ -17,8 +17,8 @@ import com.tangem.core.ui.components.SpacerH4
import com.tangem.core.ui.components.SpacerW32
import com.tangem.core.ui.components.TangemSwitch
import com.tangem.core.ui.extensions.resolveReference
import com.tangem.core.ui.res.TangemThemePreview
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreview
import com.tangem.tap.features.details.ui.appsettings.AppSettingsItemsFactory
import com.tangem.tap.features.details.ui.appsettings.AppSettingsScreenState.Item
@ -85,26 +85,29 @@ private class SwitchItemProvider : CollectionPreviewParameterProvider<Item.Switc
collection = buildList {
val itemsFactory = AppSettingsItemsFactory()
add(itemsFactory.createSaveAccessCodeSwitch(
this + itemsFactory.createSaveAccessCodeSwitch(
isChecked = true,
isEnabled = true,
onCheckedChange = { /* no-op */ },
))
add(itemsFactory.createSaveAccessCodeSwitch(
)
this + itemsFactory.createSaveAccessCodeSwitch(
isChecked = false,
isEnabled = true,
onCheckedChange = { /* no-op */ },
))
add(itemsFactory.createSaveAccessCodeSwitch(
)
this + itemsFactory.createSaveAccessCodeSwitch(
isChecked = true,
isEnabled = false,
onCheckedChange = { /* no-op */ },
))
add(itemsFactory.createSaveAccessCodeSwitch(
)
this + itemsFactory.createSaveAccessCodeSwitch(
isChecked = false,
isEnabled = false,
onCheckedChange = { /* no-op */ },
))
)
},
)
// endregion Preview

View file

@ -32,6 +32,7 @@ import com.tangem.tap.store
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import com.tangem.utils.coroutines.JobHolder
import com.tangem.utils.coroutines.saveIn
import com.tangem.utils.extensions.addIf
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.flow.*
@ -100,74 +101,57 @@ internal class AppSettingsModel @Inject constructor(
private fun buildItems(state: AppSettingsState): ImmutableList<AppSettingsScreenState.Item> {
val items = buildList<AppSettingsScreenState.Item> {
if (state.needEnrollBiometrics) {
add(
itemsFactory.createEnrollBiometricsCard(
onClick = ::enrollBiometrics,
),
)
}
addIf(
condition = state.needEnrollBiometrics,
element = itemsFactory.createEnrollBiometricsCard(onClick = ::enrollBiometrics),
)
add(
itemsFactory.createSelectAppCurrencyButton(
currentAppCurrencyName = state.selectedAppCurrency.name,
onClick = ::showAppCurrencySelector,
),
this + itemsFactory.createSelectAppCurrencyButton(
currentAppCurrencyName = state.selectedAppCurrency.name,
onClick = ::showAppCurrencySelector,
)
if (hotWalletFeatureToggles.isHotWalletEnabled) {
val canUseBiometrics = !state.needEnrollBiometrics && !state.isInProgress
add(
itemsFactory.createUseBiometricsSwitch(
isChecked = state.useBiometricAuthentication,
isEnabled = canUseBiometrics,
onCheckedChange = ::onBiometricAuthenticationToggled,
),
this + itemsFactory.createUseBiometricsSwitch(
isChecked = state.useBiometricAuthentication,
isEnabled = canUseBiometrics,
onCheckedChange = ::onBiometricAuthenticationToggled,
)
add(
itemsFactory.createRequireAccessCodeSwitch(
isChecked = state.requireAccessCode,
isEnabled = canUseBiometrics && state.useBiometricAuthentication,
onCheckedChange = ::onRequireAccessCodeToggled,
),
this + itemsFactory.createRequireAccessCodeSwitch(
isChecked = state.requireAccessCode,
isEnabled = canUseBiometrics && state.useBiometricAuthentication,
onCheckedChange = ::onRequireAccessCodeToggled,
)
} else {
if (state.isBiometricsAvailable) {
val canUseBiometrics = !state.needEnrollBiometrics && !state.isInProgress
add(
itemsFactory.createSaveWalletsSwitch(
isChecked = state.saveWallets,
isEnabled = canUseBiometrics,
onCheckedChange = ::onSaveWalletsToggled,
),
this + itemsFactory.createSaveWalletsSwitch(
isChecked = state.saveWallets,
isEnabled = canUseBiometrics,
onCheckedChange = ::onSaveWalletsToggled,
)
add(
itemsFactory.createSaveAccessCodeSwitch(
isChecked = state.saveAccessCodes,
isEnabled = canUseBiometrics,
onCheckedChange = ::onSaveAccessCodesToggled,
),
this + itemsFactory.createSaveAccessCodeSwitch(
isChecked = state.saveAccessCodes,
isEnabled = canUseBiometrics,
onCheckedChange = ::onSaveAccessCodesToggled,
)
}
}
add(
itemsFactory.createFlipToHideBalanceSwitch(
isChecked = state.isHidingEnabled,
isEnabled = true,
onCheckedChange = ::onFlipToHideBalanceToggled,
),
this + itemsFactory.createFlipToHideBalanceSwitch(
isChecked = state.isHidingEnabled,
isEnabled = true,
onCheckedChange = ::onFlipToHideBalanceToggled,
)
add(
itemsFactory.createSelectThemeModeButton(
currentThemeMode = state.selectedThemeMode,
onClick = { showThemeModeSelector(state.selectedThemeMode) },
),
this + itemsFactory.createSelectThemeModeButton(
currentThemeMode = state.selectedThemeMode,
onClick = { showThemeModeSelector(state.selectedThemeMode) },
)
}

View file

@ -12,9 +12,9 @@ import com.tangem.core.decompose.model.Model
import com.tangem.core.decompose.model.ParamsContainer
import com.tangem.domain.card.CardTypesResolver
import com.tangem.domain.card.ScanCardProcessor
import com.tangem.domain.card.repository.CardSdkConfigRepository
import com.tangem.domain.card.common.util.cardTypesResolver
import com.tangem.domain.card.common.util.getBackupCardsCount
import com.tangem.domain.card.repository.CardSdkConfigRepository
import com.tangem.domain.models.scan.CardDTO
import com.tangem.domain.models.scan.ScanResponse
import com.tangem.domain.models.wallet.requireColdWallet
@ -34,6 +34,7 @@ import com.tangem.tap.features.details.ui.cardsettings.domain.CardSettingsIntera
import com.tangem.tap.features.details.ui.common.utils.*
import com.tangem.tap.store
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import com.tangem.utils.extensions.addIf
import com.tangem.wallet.R
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.launch
@ -89,8 +90,7 @@ internal class CardSettingsModel @Inject constructor(
.getOrElse { error("User wallet $userWalletId not found") }
.requireColdWallet()
cardSdkConfigRepository.isBiometricsRequestPolicy =
userWallet.scanResponse.card.isAccessCodeSet &&
cardSdkConfigRepository.isBiometricsRequestPolicy = userWallet.scanResponse.card.isAccessCodeSet &&
settingsRepository.shouldSaveAccessCodes()
}
}
@ -135,36 +135,37 @@ internal class CardSettingsModel @Inject constructor(
)
val isResetCardAllowed = isResetToFactoryAllowedByCard(card, cardTypesResolver)
val cardDetails = buildList<CardInfo> {
val cardDetails: List<CardInfo> = buildList {
add(CardInfo.CardId(cardId))
add(CardInfo.Issuer(card.issuer.name))
if (!cardTypesResolver.isTangemTwins()) {
add(CardInfo.SignedHashes(card.signedHashesCount().toString()))
}
addIf(
condition = !cardTypesResolver.isTangemTwins(),
element = CardInfo.SignedHashes(card.signedHashesCount().toString()),
)
add(
CardInfo.SecurityMode(
currentSecurityOption,
securityOption = currentSecurityOption,
clickable = allowedSecurityOptions.size > 1,
),
)
if (card.backupStatus?.isActive == true && card.isAccessCodeSet) {
add(CardInfo.ChangeAccessCode)
}
addIf(
condition = card.backupStatus?.isActive == true && card.isAccessCodeSet,
element = CardInfo.ChangeAccessCode,
)
if (isAccessCodeRecoveryAllowed(cardTypesResolver)) {
add(CardInfo.AccessCodeRecovery(isAccessCodeRecoveryEnabled(cardTypesResolver, card)))
}
addIf(
condition = isAccessCodeRecoveryAllowed(cardTypesResolver),
element = CardInfo.AccessCodeRecovery(isAccessCodeRecoveryEnabled(cardTypesResolver, card)),
)
if (isResetCardAllowed) {
add(
CardInfo.ResetToFactorySettings(
description = getResetToFactoryDescription(
isActiveBackupStatus = card.backupStatus?.isActive == true,
typesResolver = cardTypesResolver,
),
addIf(isResetCardAllowed) {
CardInfo.ResetToFactorySettings(
description = getResetToFactoryDescription(
isActiveBackupStatus = card.backupStatus?.isActive == true,
typesResolver = cardTypesResolver,
),
)
}

View file

@ -20,7 +20,22 @@ fun <T> Collection<T>.copy(): Collection<T> {
return this.map { it }
}
inline fun <T> List<T>.indexOfFirstOrNull(predicate: (T) -> Boolean): Int? {
val index = indexOfFirst(predicate)
return if (index == -1) null else index
/**
* Adds an element to the mutable list if the specified condition is true.
*
* @param condition The condition to evaluate.
* @param create A lambda function that creates the element to be added.
*/
inline fun <T> MutableCollection<T>.addIf(condition: Boolean, create: () -> T) {
addIf(condition = condition, element = create())
}
/**
* Adds an element to the mutable list if the specified condition is true.
*
* @param condition The condition to evaluate.
* @param element The element to be added.
*/
fun <T> MutableCollection<T>.addIf(condition: Boolean, element: T) {
if (condition) this.add(element)
}

View file

@ -72,4 +72,9 @@ fun <T> List<T>.filterIf(condition: Boolean, predicate: (T) -> Boolean): List<T>
} else {
this
}
}
inline fun <T> List<T>.indexOfFirstOrNull(predicate: (T) -> Boolean): Int? {
val index = indexOfFirst(predicate)
return if (index == -1) null else index
}

View file

@ -33,6 +33,7 @@ import com.tangem.feature.wallet.impl.R
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletNotification
import com.tangem.lib.crypto.BlockchainUtils.isBitcoin
import com.tangem.utils.coroutines.combine6
import com.tangem.utils.extensions.addIf
import com.tangem.utils.extensions.isPositive
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.toImmutableList
@ -356,10 +357,6 @@ internal class GetMultiWalletWarningsFactory @Inject constructor(
)
}
private fun MutableList<WalletNotification>.addIf(element: WalletNotification, condition: Boolean) {
if (condition) add(element = element)
}
private companion object {
const val MAX_REMAINING_SIGNATURES_COUNT = 10
}

View file

@ -15,6 +15,7 @@ import com.tangem.domain.wallets.usecase.GetWalletsUseCase
import com.tangem.domain.wallets.usecase.IsNeedToBackupUseCase
import com.tangem.feature.wallet.child.wallet.model.intents.WalletClickIntents
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletNotification
import com.tangem.utils.extensions.addIf
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.flow.*
@ -204,14 +205,15 @@ internal class GetSingleWalletWarningsFactory @Inject constructor(
}
private fun MutableList<WalletNotification>.addIf(element: WalletNotification, condition: Boolean) {
if (condition) {
add(element = element)
addIf(condition) {
if (element is WalletNotification.Critical ||
element is WalletNotification.Warning ||
element is WalletNotification.NoteMigration
) {
readyForRateAppNotification = false
}
element
}
}