Updated on 2026-08-14
This commit is contained in:
commit
2d0a910594
32 changed files with 519 additions and 190 deletions
|
|
@ -48,9 +48,9 @@ import kotlin.coroutines.suspendCoroutine
|
|||
|
||||
class TangemSdkManager(private val tangemSdk: TangemSdk, private val context: Context) {
|
||||
val canUseBiometry: Boolean
|
||||
get() = tangemSdk.biometricManager.canAuthenticate || canEnrollBiometrics
|
||||
get() = tangemSdk.biometricManager.canAuthenticate || needEnrollBiometrics
|
||||
|
||||
val canEnrollBiometrics: Boolean
|
||||
val needEnrollBiometrics: Boolean
|
||||
get() = tangemSdk.biometricManager.canEnrollBiometrics
|
||||
|
||||
val biometricManager: BiometricManager
|
||||
|
|
|
|||
|
|
@ -55,10 +55,14 @@ sealed class DetailsAction : Action {
|
|||
) : AppSettings()
|
||||
}
|
||||
|
||||
object EnrollBiometrics : AppSettings() {
|
||||
object Enroll : AppSettings()
|
||||
object Cancel : AppSettings()
|
||||
}
|
||||
data class CheckBiometricsStatus(
|
||||
val awaitStatusChange: Boolean,
|
||||
) : AppSettings()
|
||||
|
||||
object EnrollBiometrics : AppSettings()
|
||||
data class BiometricsStatusChanged(
|
||||
val needEnrollBiometrics: Boolean,
|
||||
) : AppSettings()
|
||||
}
|
||||
|
||||
data class ChangeAppCurrency(val fiatCurrency: FiatCurrency) : DetailsAction()
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ import com.tangem.tap.userWalletsListManager
|
|||
import com.tangem.tap.walletStoresManager
|
||||
import com.tangem.wallet.R
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.rekotlin.Action
|
||||
|
|
@ -194,18 +195,39 @@ class DetailsMiddleware {
|
|||
fun handle(state: DetailsState, action: DetailsAction.AppSettings) {
|
||||
when (action) {
|
||||
is DetailsAction.AppSettings.SwitchPrivacySetting -> {
|
||||
if (tangemSdkManager.canEnrollBiometrics) {
|
||||
store.dispatch(DetailsAction.AppSettings.EnrollBiometrics)
|
||||
}
|
||||
when (action.setting) {
|
||||
PrivacySetting.SaveWallets -> toggleSaveWallets(state, enable = action.enable)
|
||||
PrivacySetting.SaveAccessCode -> toggleSaveAccessCodes(state, enable = action.enable)
|
||||
}
|
||||
}
|
||||
is DetailsAction.AppSettings.SwitchPrivacySetting.Success -> Unit
|
||||
is DetailsAction.AppSettings.EnrollBiometrics -> Unit
|
||||
is DetailsAction.AppSettings.EnrollBiometrics.Enroll -> enrollBiometrics()
|
||||
is DetailsAction.AppSettings.EnrollBiometrics.Cancel -> Unit
|
||||
is DetailsAction.AppSettings.CheckBiometricsStatus -> {
|
||||
checkBiometricsStatus(action.awaitStatusChange, state)
|
||||
}
|
||||
is DetailsAction.AppSettings.EnrollBiometrics -> {
|
||||
enrollBiometrics()
|
||||
}
|
||||
is DetailsAction.AppSettings.SwitchPrivacySetting.Success,
|
||||
is DetailsAction.AppSettings.BiometricsStatusChanged,
|
||||
-> Unit
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param awaitStatusChange If true then start a new coroutine and check the biometric status every 100
|
||||
* milliseconds until it changes
|
||||
* */
|
||||
private fun checkBiometricsStatus(awaitStatusChange: Boolean, state: DetailsState) {
|
||||
scope.launch {
|
||||
if (awaitStatusChange) {
|
||||
while (state.needEnrollBiometrics == tangemSdkManager.needEnrollBiometrics) {
|
||||
delay(timeMillis = 100)
|
||||
}
|
||||
}
|
||||
store.dispatchOnMain(
|
||||
DetailsAction.AppSettings.BiometricsStatusChanged(
|
||||
needEnrollBiometrics = tangemSdkManager.needEnrollBiometrics,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -157,15 +157,17 @@ private fun handlePrivacyAction(
|
|||
state: DetailsState,
|
||||
): DetailsState {
|
||||
return when (action) {
|
||||
is DetailsAction.AppSettings.SwitchPrivacySetting -> state
|
||||
is DetailsAction.AppSettings.SwitchPrivacySetting.Success -> when (action.setting) {
|
||||
PrivacySetting.SaveWallets -> state.copy(saveWallets = action.enable)
|
||||
PrivacySetting.SaveAccessCode -> state.copy(saveAccessCodes = action.enable)
|
||||
}
|
||||
is DetailsAction.AppSettings.EnrollBiometrics -> state.copy(needEnrollBiometrics = true)
|
||||
is DetailsAction.AppSettings.EnrollBiometrics.Enroll,
|
||||
is DetailsAction.AppSettings.EnrollBiometrics.Cancel,
|
||||
-> state.copy(needEnrollBiometrics = false)
|
||||
is DetailsAction.AppSettings.BiometricsStatusChanged -> state.copy(
|
||||
needEnrollBiometrics = action.needEnrollBiometrics,
|
||||
)
|
||||
is DetailsAction.AppSettings.SwitchPrivacySetting,
|
||||
is DetailsAction.AppSettings.EnrollBiometrics,
|
||||
is DetailsAction.AppSettings.CheckBiometricsStatus,
|
||||
-> state
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,11 +9,12 @@ import androidx.compose.runtime.mutableStateOf
|
|||
import androidx.compose.ui.platform.ComposeView
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.transition.TransitionInflater
|
||||
import com.google.accompanist.appcompattheme.AppCompatTheme
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.tap.common.redux.navigation.NavigationAction
|
||||
import com.tangem.tap.features.details.redux.DetailsAction
|
||||
import com.tangem.tap.features.details.redux.DetailsState
|
||||
import com.tangem.tap.store
|
||||
import com.tangem.wallet.R
|
||||
import org.rekotlin.StoreSubscriber
|
||||
|
||||
class AppSettingsFragment : Fragment(), StoreSubscriber<DetailsState> {
|
||||
|
|
@ -24,8 +25,9 @@ class AppSettingsFragment : Fragment(), StoreSubscriber<DetailsState> {
|
|||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
val inflater = TransitionInflater.from(requireContext())
|
||||
enterTransition = inflater.inflateTransition(android.R.transition.fade)
|
||||
exitTransition = inflater.inflateTransition(android.R.transition.fade)
|
||||
enterTransition = inflater.inflateTransition(R.transition.fade)
|
||||
exitTransition = inflater.inflateTransition(R.transition.fade)
|
||||
viewModel.checkBiometricsStatus()
|
||||
}
|
||||
|
||||
override fun onCreateView(
|
||||
|
|
@ -36,7 +38,7 @@ class AppSettingsFragment : Fragment(), StoreSubscriber<DetailsState> {
|
|||
return ComposeView(requireContext()).apply {
|
||||
setContent {
|
||||
isTransitionGroup = true
|
||||
AppCompatTheme {
|
||||
TangemTheme {
|
||||
AppSettingsScreen(
|
||||
state = screenState.value,
|
||||
onBackPressed = {
|
||||
|
|
@ -58,6 +60,11 @@ class AppSettingsFragment : Fragment(), StoreSubscriber<DetailsState> {
|
|||
}
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
viewModel.refreshBiometricsStatus()
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
super.onStop()
|
||||
store.unsubscribe(this)
|
||||
|
|
|
|||
|
|
@ -1,24 +1,31 @@
|
|||
package com.tangem.tap.features.details.ui.appsettings
|
||||
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.shape.CornerSize
|
||||
import androidx.compose.material.AlertDialog
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.material.TextButton
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberUpdatedState
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.colorResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import com.tangem.core.ui.components.dialogs.EnrollBiometricsDialogContent
|
||||
import com.tangem.core.ui.models.EnrollBiometricsDialog
|
||||
import com.tangem.tap.common.compose.TangemTypography
|
||||
import com.tangem.core.ui.components.SpacerH24
|
||||
import com.tangem.core.ui.components.SpacerH32
|
||||
import com.tangem.core.ui.components.SpacerH4
|
||||
import com.tangem.core.ui.components.SpacerW32
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.tap.features.details.redux.PrivacySetting
|
||||
import com.tangem.tap.features.details.ui.appsettings.components.EnrollBiometricsCard
|
||||
import com.tangem.tap.features.details.ui.appsettings.components.SettingsAlertDialog
|
||||
import com.tangem.tap.features.details.ui.common.SettingsScreensScaffold
|
||||
import com.tangem.tap.features.details.ui.common.TangemSwitch
|
||||
import com.tangem.wallet.R
|
||||
|
|
@ -51,47 +58,43 @@ private fun AppSettings(
|
|||
element = it,
|
||||
onDialogStateChange = onDialogStateChange,
|
||||
onSettingToggled = state.onSettingToggled,
|
||||
modifier = modifier,
|
||||
)
|
||||
}
|
||||
|
||||
EnrollBiometricsDialog(dialog = state.enrollBiometricsDialog)
|
||||
|
||||
Column(
|
||||
modifier = modifier
|
||||
.fillMaxSize(),
|
||||
) {
|
||||
if (state.showEnrollBiometricsCard) {
|
||||
EnrollBiometricsCard(
|
||||
modifier = Modifier
|
||||
.padding(horizontal = TangemTheme.dimens.spacing8)
|
||||
.fillMaxWidth(),
|
||||
onClick = state.onEnrollBiometrics,
|
||||
)
|
||||
SpacerH24()
|
||||
}
|
||||
|
||||
AppSettingsElement(
|
||||
state = state,
|
||||
setting = PrivacySetting.SaveWallets,
|
||||
onDialogStateChange = onDialogStateChange,
|
||||
modifier = modifier,
|
||||
)
|
||||
Spacer(modifier = Modifier.size(32.dp))
|
||||
SpacerH32()
|
||||
AppSettingsElement(
|
||||
state = state,
|
||||
setting = PrivacySetting.SaveAccessCode,
|
||||
onDialogStateChange = onDialogStateChange,
|
||||
modifier = modifier,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun EnrollBiometricsDialog(
|
||||
modifier: Modifier = Modifier,
|
||||
dialog: EnrollBiometricsDialog?,
|
||||
) {
|
||||
if (dialog == null) return
|
||||
EnrollBiometricsDialogContent(modifier, dialog)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun AppSettingsElement(
|
||||
modifier: Modifier = Modifier,
|
||||
state: AppSettingsScreenState,
|
||||
setting: PrivacySetting,
|
||||
onDialogStateChange: (PrivacySetting?) -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
val titleRes = when (setting) {
|
||||
PrivacySetting.SaveWallets -> R.string.app_settings_saved_wallet
|
||||
|
|
@ -103,48 +106,63 @@ private fun AppSettingsElement(
|
|||
}
|
||||
val checked = state.settings[setting] ?: false
|
||||
|
||||
val titleTextColor by rememberUpdatedState(
|
||||
newValue = if (state.isTogglesEnabled) {
|
||||
TangemTheme.colors.text.primary1
|
||||
} else {
|
||||
TangemTheme.colors.text.secondary
|
||||
},
|
||||
)
|
||||
val descriptionTextColor by rememberUpdatedState(
|
||||
newValue = if (state.isTogglesEnabled) {
|
||||
TangemTheme.colors.text.secondary
|
||||
} else {
|
||||
TangemTheme.colors.text.tertiary
|
||||
},
|
||||
)
|
||||
|
||||
Row(
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
.padding(start = 20.dp),
|
||||
.padding(horizontal = TangemTheme.dimens.spacing20),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.SpaceBetween,
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier.weight(weight = .9f),
|
||||
verticalArrangement = Arrangement.Center,
|
||||
modifier = modifier
|
||||
.weight(0.6f)
|
||||
.padding(end = 4.dp),
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(id = titleRes),
|
||||
style = TangemTypography.subtitle1,
|
||||
color = colorResource(id = R.color.text_primary_1),
|
||||
style = TangemTheme.typography.subtitle1,
|
||||
color = titleTextColor,
|
||||
)
|
||||
Spacer(modifier = Modifier.size(4.dp))
|
||||
SpacerH4()
|
||||
Text(
|
||||
text = stringResource(id = subtitleRes),
|
||||
style = TangemTypography.body2,
|
||||
color = colorResource(id = R.color.text_secondary),
|
||||
style = TangemTheme.typography.body2,
|
||||
color = descriptionTextColor,
|
||||
)
|
||||
}
|
||||
SpacerW32()
|
||||
TangemSwitch(
|
||||
checked = checked,
|
||||
onCheckedChange = {
|
||||
enabled = state.isTogglesEnabled,
|
||||
onCheckedChange = { isChecked ->
|
||||
onCheckedChange(
|
||||
element = setting,
|
||||
enabled = it,
|
||||
enabled = isChecked,
|
||||
onSettingToggled = state.onSettingToggled,
|
||||
onDialogStateChange = onDialogStateChange,
|
||||
)
|
||||
},
|
||||
modifier = modifier
|
||||
.padding(20.dp),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun onCheckedChange(
|
||||
element: PrivacySetting, enabled: Boolean,
|
||||
element: PrivacySetting,
|
||||
enabled: Boolean,
|
||||
onSettingToggled: (PrivacySetting, Boolean) -> Unit,
|
||||
onDialogStateChange: (PrivacySetting?) -> Unit,
|
||||
) {
|
||||
|
|
@ -152,82 +170,88 @@ private fun onCheckedChange(
|
|||
if (!enabled) {
|
||||
onDialogStateChange(element)
|
||||
} else {
|
||||
onSettingToggled(element, enabled)
|
||||
onSettingToggled(element, true)
|
||||
}
|
||||
}
|
||||
|
||||
// region Preview
|
||||
@Composable
|
||||
private fun SettingsAlertDialog(
|
||||
element: PrivacySetting,
|
||||
onDialogStateChange: (PrivacySetting?) -> Unit,
|
||||
onSettingToggled: (PrivacySetting, Boolean) -> Unit,
|
||||
private fun AppSettingsScreenSample(
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
val text = when (element) {
|
||||
PrivacySetting.SaveWallets -> R.string.app_settings_off_saved_wallet_alert_message
|
||||
PrivacySetting.SaveAccessCode -> R.string.app_settings_off_saved_access_code_alert_message
|
||||
Column(
|
||||
modifier = modifier
|
||||
.background(TangemTheme.colors.background.primary),
|
||||
) {
|
||||
AppSettingsScreen(
|
||||
state = AppSettingsScreenState(
|
||||
settings = mapOf(
|
||||
PrivacySetting.SaveWallets to true,
|
||||
PrivacySetting.SaveAccessCode to false,
|
||||
),
|
||||
showEnrollBiometricsCard = false,
|
||||
isTogglesEnabled = true,
|
||||
onSettingToggled = { _, _ -> },
|
||||
onEnrollBiometrics = {},
|
||||
),
|
||||
onBackPressed = { },
|
||||
)
|
||||
}
|
||||
AlertDialog(
|
||||
onDismissRequest = { onDialogStateChange(null) },
|
||||
confirmButton = {
|
||||
TextButton(
|
||||
onClick = {
|
||||
onDialogStateChange(null)
|
||||
},
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(id = R.string.common_cancel),
|
||||
color = colorResource(id = R.color.text_secondary),
|
||||
fontSize = 14.sp,
|
||||
fontWeight = FontWeight.Medium,
|
||||
)
|
||||
}
|
||||
},
|
||||
dismissButton = {
|
||||
TextButton(
|
||||
onClick = {
|
||||
onDialogStateChange(null)
|
||||
onSettingToggled(element, false)
|
||||
},
|
||||
modifier = modifier.padding(bottom = 14.dp),
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(id = R.string.common_delete),
|
||||
color = colorResource(id = R.color.text_warning),
|
||||
fontSize = 14.sp,
|
||||
fontWeight = FontWeight.Medium,
|
||||
)
|
||||
}
|
||||
},
|
||||
title = {
|
||||
Text(
|
||||
text = stringResource(id = R.string.common_attention),
|
||||
color = colorResource(id = R.color.text_primary_1),
|
||||
)
|
||||
},
|
||||
text = {
|
||||
Text(
|
||||
text = stringResource(id = text),
|
||||
color = colorResource(id = R.color.text_secondary),
|
||||
)
|
||||
},
|
||||
shape = MaterialTheme.shapes.medium.copy(all = CornerSize(size = 28.dp)),
|
||||
modifier = modifier.padding(vertical = 34.dp, horizontal = 24.dp),
|
||||
)
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Preview(showBackground = true, widthDp = 360)
|
||||
@Composable
|
||||
fun AppSettingsScreenPreview() {
|
||||
AppSettingsScreen(
|
||||
state = AppSettingsScreenState(
|
||||
settings = mapOf(
|
||||
PrivacySetting.SaveWallets to true,
|
||||
PrivacySetting.SaveAccessCode to false,
|
||||
private fun AppSettingsScreenPreview_Light() {
|
||||
TangemTheme {
|
||||
AppSettingsScreenSample()
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(showBackground = true, widthDp = 360)
|
||||
@Composable
|
||||
private fun AppSettingsScreenPreview_Dark() {
|
||||
TangemTheme(isDark = true) {
|
||||
AppSettingsScreenSample()
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun AppSettingsScreen_EnrollBiometrics_Sample(
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
Column(
|
||||
modifier = modifier
|
||||
.background(TangemTheme.colors.background.primary),
|
||||
) {
|
||||
AppSettingsScreen(
|
||||
state = AppSettingsScreenState(
|
||||
settings = mapOf(
|
||||
PrivacySetting.SaveWallets to true,
|
||||
PrivacySetting.SaveAccessCode to false,
|
||||
),
|
||||
showEnrollBiometricsCard = true,
|
||||
isTogglesEnabled = false,
|
||||
onSettingToggled = { _, _ -> },
|
||||
onEnrollBiometrics = {},
|
||||
),
|
||||
onSettingToggled = { _, _ -> },
|
||||
enrollBiometricsDialog = null,
|
||||
),
|
||||
onBackPressed = { },
|
||||
)
|
||||
}
|
||||
onBackPressed = { },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(showBackground = true, widthDp = 360)
|
||||
@Composable
|
||||
private fun AppSettingsScreen_EnrollBiometrics_Preview_Light() {
|
||||
TangemTheme {
|
||||
AppSettingsScreen_EnrollBiometrics_Sample()
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(showBackground = true, widthDp = 360)
|
||||
@Composable
|
||||
private fun AppSettingsScreen_EnrollBiometrics_Preview_Dark() {
|
||||
TangemTheme(isDark = true) {
|
||||
AppSettingsScreen_EnrollBiometrics_Sample()
|
||||
}
|
||||
}
|
||||
// endregion Preview
|
||||
|
|
@ -1,10 +1,11 @@
|
|||
package com.tangem.tap.features.details.ui.appsettings
|
||||
|
||||
import com.tangem.core.ui.models.EnrollBiometricsDialog
|
||||
import com.tangem.tap.features.details.redux.PrivacySetting
|
||||
|
||||
data class AppSettingsScreenState(
|
||||
val settings: Map<PrivacySetting, Boolean>,
|
||||
val enrollBiometricsDialog: EnrollBiometricsDialog?,
|
||||
val onSettingToggled: (PrivacySetting, Boolean) -> Unit,
|
||||
val settings: Map<PrivacySetting, Boolean> = emptyMap(),
|
||||
val showEnrollBiometricsCard: Boolean = false,
|
||||
val isTogglesEnabled: Boolean = true,
|
||||
val onSettingToggled: (PrivacySetting, Boolean) -> Unit = { _, _ -> /* no-op */ },
|
||||
val onEnrollBiometrics: () -> Unit = { /* no-op */ },
|
||||
)
|
||||
|
|
@ -1,6 +1,5 @@
|
|||
package com.tangem.tap.features.details.ui.appsettings
|
||||
|
||||
import com.tangem.core.ui.models.EnrollBiometricsDialog
|
||||
import com.tangem.tap.common.extensions.dispatchOnMain
|
||||
import com.tangem.tap.common.redux.AppState
|
||||
import com.tangem.tap.features.details.redux.DetailsAction
|
||||
|
|
@ -20,8 +19,14 @@ class AppSettingsViewModel(private val store: Store<AppState>) {
|
|||
PrivacySetting.SaveWallets to state.saveWallets,
|
||||
PrivacySetting.SaveAccessCode to state.saveAccessCodes,
|
||||
),
|
||||
enrollBiometricsDialog = if (state.needEnrollBiometrics) createEnrollBiometricsDialog() else null,
|
||||
onSettingToggled = { privacySetting, enabled -> onSettingsToggled(privacySetting, enabled) },
|
||||
showEnrollBiometricsCard = state.needEnrollBiometrics,
|
||||
isTogglesEnabled = !state.needEnrollBiometrics,
|
||||
onSettingToggled = { privacySetting, enabled ->
|
||||
onSettingsToggled(privacySetting, enabled)
|
||||
},
|
||||
onEnrollBiometrics = {
|
||||
store.dispatchOnMain(DetailsAction.AppSettings.EnrollBiometrics)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -29,12 +34,11 @@ class AppSettingsViewModel(private val store: Store<AppState>) {
|
|||
store.dispatch(DetailsAction.AppSettings.SwitchPrivacySetting(enable = enable, setting = setting))
|
||||
}
|
||||
|
||||
private fun createEnrollBiometricsDialog() = EnrollBiometricsDialog(
|
||||
onCancel = {
|
||||
store.dispatchOnMain(DetailsAction.AppSettings.EnrollBiometrics.Cancel)
|
||||
},
|
||||
onEnroll = {
|
||||
store.dispatchOnMain(DetailsAction.AppSettings.EnrollBiometrics.Enroll)
|
||||
},
|
||||
)
|
||||
fun checkBiometricsStatus() {
|
||||
store.dispatch(DetailsAction.AppSettings.CheckBiometricsStatus(awaitStatusChange = false))
|
||||
}
|
||||
|
||||
fun refreshBiometricsStatus() {
|
||||
store.dispatch(DetailsAction.AppSettings.CheckBiometricsStatus(awaitStatusChange = true))
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
package com.tangem.tap.features.details.ui.appsettings.components
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material.ExperimentalMaterialApi
|
||||
import androidx.compose.material.Icon
|
||||
import androidx.compose.material.Surface
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
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.res.TangemTheme
|
||||
import com.tangem.wallet.R
|
||||
|
||||
@OptIn(ExperimentalMaterialApi::class)
|
||||
@Composable
|
||||
internal fun EnrollBiometricsCard(
|
||||
modifier: Modifier = Modifier,
|
||||
onClick: () -> Unit,
|
||||
) {
|
||||
Surface(
|
||||
modifier = modifier,
|
||||
color = TangemTheme.colors.background.primary,
|
||||
shape = TangemTheme.shapes.roundedCornersLarge,
|
||||
onClick = onClick,
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier.padding(all = 16.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.SpaceEvenly,
|
||||
) {
|
||||
Icon(
|
||||
painter = painterResource(id = R.drawable.ic_alert_circle_24),
|
||||
tint = TangemTheme.colors.icon.attention,
|
||||
contentDescription = null,
|
||||
)
|
||||
SpacerW16()
|
||||
Column {
|
||||
Text(
|
||||
text = stringResource(id = R.string.app_settings_enable_biometrics_title),
|
||||
style = TangemTheme.typography.subtitle1,
|
||||
color = TangemTheme.colors.text.primary1,
|
||||
)
|
||||
SpacerH4()
|
||||
Text(
|
||||
text = stringResource(id = R.string.app_settings_enable_biometrics_description),
|
||||
style = TangemTheme.typography.body2,
|
||||
color = TangemTheme.colors.text.secondary,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// region Preview
|
||||
@Composable
|
||||
private fun EnrollBiometricsCardSample(
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
Column(
|
||||
modifier = modifier
|
||||
.background(TangemTheme.colors.background.secondary),
|
||||
) {
|
||||
EnrollBiometricsCard(onClick = {})
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(showBackground = true, widthDp = 360)
|
||||
@Composable
|
||||
private fun EnrollBiometricsCardPreview_Light() {
|
||||
TangemTheme {
|
||||
EnrollBiometricsCardSample()
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(showBackground = true, widthDp = 360)
|
||||
@Composable
|
||||
private fun EnrollBiometricsCardPreview_Dark() {
|
||||
TangemTheme(isDark = true) {
|
||||
EnrollBiometricsCardSample()
|
||||
}
|
||||
}
|
||||
// endregion Preview
|
||||
|
|
@ -0,0 +1,101 @@
|
|||
package com.tangem.tap.features.details.ui.appsettings.components
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material.AlertDialog
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import com.tangem.core.ui.components.TextButton
|
||||
import com.tangem.core.ui.components.WarningTextButton
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.tap.features.details.redux.PrivacySetting
|
||||
import com.tangem.wallet.R
|
||||
|
||||
@Composable
|
||||
internal fun SettingsAlertDialog(
|
||||
element: PrivacySetting,
|
||||
onDialogStateChange: (PrivacySetting?) -> Unit,
|
||||
onSettingToggled: (PrivacySetting, Boolean) -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
val text = when (element) {
|
||||
PrivacySetting.SaveWallets -> R.string.app_settings_off_saved_wallet_alert_message
|
||||
PrivacySetting.SaveAccessCode -> R.string.app_settings_off_saved_access_code_alert_message
|
||||
}
|
||||
|
||||
AlertDialog(
|
||||
onDismissRequest = { onDialogStateChange(null) },
|
||||
confirmButton = {
|
||||
TextButton(
|
||||
modifier = Modifier.padding(bottom = TangemTheme.dimens.spacing12),
|
||||
text = stringResource(id = R.string.common_cancel),
|
||||
onClick = {
|
||||
onDialogStateChange(null)
|
||||
},
|
||||
)
|
||||
},
|
||||
dismissButton = {
|
||||
WarningTextButton(
|
||||
text = stringResource(id = R.string.common_delete),
|
||||
onClick = {
|
||||
onDialogStateChange(null)
|
||||
onSettingToggled(element, false)
|
||||
},
|
||||
)
|
||||
},
|
||||
title = {
|
||||
Text(
|
||||
text = stringResource(id = R.string.common_attention),
|
||||
color = TangemTheme.colors.text.primary1,
|
||||
style = TangemTheme.typography.h2,
|
||||
)
|
||||
},
|
||||
text = {
|
||||
Text(
|
||||
text = stringResource(id = text),
|
||||
color = TangemTheme.colors.text.secondary,
|
||||
style = TangemTheme.typography.body2,
|
||||
)
|
||||
},
|
||||
shape = TangemTheme.shapes.roundedCornersLarge,
|
||||
modifier = modifier,
|
||||
)
|
||||
}
|
||||
|
||||
// region Preview
|
||||
@Composable
|
||||
private fun SettingsAlertDialogSample(
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
Column(
|
||||
modifier = modifier
|
||||
.background(TangemTheme.colors.background.primary),
|
||||
) {
|
||||
SettingsAlertDialog(
|
||||
element = PrivacySetting.SaveAccessCode,
|
||||
onDialogStateChange = {},
|
||||
onSettingToggled = { _, _ -> },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(showBackground = true, widthDp = 360)
|
||||
@Composable
|
||||
private fun SettingsAlertDialogPreview_Light() {
|
||||
TangemTheme {
|
||||
SettingsAlertDialogSample()
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(showBackground = true, widthDp = 360)
|
||||
@Composable
|
||||
private fun SettingsAlertDialogPreview_Dark() {
|
||||
TangemTheme(isDark = true) {
|
||||
SettingsAlertDialogSample()
|
||||
}
|
||||
}
|
||||
// endregion Preview
|
||||
|
|
@ -9,7 +9,7 @@ import androidx.compose.runtime.mutableStateOf
|
|||
import androidx.compose.ui.platform.ComposeView
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.transition.TransitionInflater
|
||||
import com.google.accompanist.appcompattheme.AppCompatTheme
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.tap.common.redux.navigation.NavigationAction
|
||||
import com.tangem.tap.features.details.redux.DetailsAction
|
||||
import com.tangem.tap.features.details.redux.DetailsState
|
||||
|
|
@ -39,7 +39,7 @@ class CardSettingsFragment : Fragment(), StoreSubscriber<DetailsState> {
|
|||
return ComposeView(requireContext()).apply {
|
||||
setContent {
|
||||
isTransitionGroup = true
|
||||
AppCompatTheme {
|
||||
TangemTheme {
|
||||
CardSettingsScreen(
|
||||
state = screenState.value,
|
||||
onBackPressed = {
|
||||
|
|
|
|||
|
|
@ -15,6 +15,8 @@ import androidx.compose.foundation.rememberScrollState
|
|||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.rememberUpdatedState
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.rotate
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
|
|
@ -23,6 +25,7 @@ import androidx.compose.ui.res.painterResource
|
|||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.tap.common.compose.TangemTypography
|
||||
import com.tangem.tap.features.details.ui.common.DetailsMainButton
|
||||
import com.tangem.tap.features.details.ui.common.SettingsScreensScaffold
|
||||
|
|
@ -34,14 +37,22 @@ fun CardSettingsScreen(
|
|||
onBackPressed: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
val needReadCard = state.cardDetails == null
|
||||
val backgroundColor by rememberUpdatedState(
|
||||
newValue = if (needReadCard) TangemTheme.colors.background.primary
|
||||
else TangemTheme.colors.background.secondary,
|
||||
)
|
||||
|
||||
SettingsScreensScaffold(
|
||||
content =
|
||||
if (state.cardDetails == null) {
|
||||
{ CardSettingsReadCard(state.onScanCardClick, modifier = modifier) }
|
||||
} else {
|
||||
{ CardSettings(state = state, modifier = modifier) }
|
||||
content = {
|
||||
if (needReadCard) {
|
||||
CardSettingsReadCard(state.onScanCardClick, modifier = modifier)
|
||||
} else {
|
||||
CardSettings(state = state, modifier = modifier)
|
||||
}
|
||||
},
|
||||
titleRes = R.string.card_settings_title,
|
||||
backgroundColor = backgroundColor,
|
||||
onBackClick = onBackPressed,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,18 +25,19 @@ import androidx.compose.ui.res.colorResource
|
|||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.tap.common.compose.TangemTypography
|
||||
import com.tangem.wallet.R
|
||||
|
||||
@Composable
|
||||
fun SettingsScreensScaffold(
|
||||
modifier: Modifier = Modifier,
|
||||
content: @Composable () -> Unit,
|
||||
background: @Composable (() -> Unit)? = null,
|
||||
fab: @Composable (() -> Unit)? = null,
|
||||
backgroundColor: Color = colorResource(id = R.color.background_primary),
|
||||
backgroundColor: Color = TangemTheme.colors.background.secondary,
|
||||
titleRes: Int? = null,
|
||||
onBackClick: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
BackHandler(true, onBackClick)
|
||||
|
||||
|
|
@ -58,9 +59,13 @@ fun SettingsScreensScaffold(
|
|||
Column(modifier = modifier.fillMaxWidth()) {
|
||||
Text(
|
||||
text = stringResource(id = titleRes),
|
||||
modifier = modifier.padding(start = 20.dp, end = 20.dp, bottom = 52.dp),
|
||||
style = TangemTypography.headline1,
|
||||
color = colorResource(id = R.color.text_primary_1),
|
||||
modifier = modifier.padding(
|
||||
start = TangemTheme.dimens.spacing20,
|
||||
end = TangemTheme.dimens.spacing20,
|
||||
bottom = TangemTheme.dimens.spacing54,
|
||||
),
|
||||
style = TangemTheme.typography.h1,
|
||||
color = TangemTheme.colors.text.primary1,
|
||||
)
|
||||
content()
|
||||
}
|
||||
|
|
@ -86,18 +91,20 @@ fun ScreenTitle(
|
|||
|
||||
@Composable
|
||||
fun EmptyTopBarWithNavigation(
|
||||
onBackClick: () -> Unit,
|
||||
backgroundColor: Color = colorResource(id = R.color.background_primary),
|
||||
modifier: Modifier = Modifier,
|
||||
onBackClick: () -> Unit,
|
||||
backgroundColor: Color = TangemTheme.colors.background.primary,
|
||||
) {
|
||||
TopAppBar(
|
||||
modifier = modifier,
|
||||
title = { },
|
||||
navigationIcon =
|
||||
{
|
||||
IconButton(onClick = onBackClick) {
|
||||
Icon(
|
||||
painterResource(id = R.drawable.ic_back), "",
|
||||
tint = colorResource(id = R.color.icon_primary_1),
|
||||
painter = painterResource(id = R.drawable.ic_back),
|
||||
contentDescription = null,
|
||||
tint = TangemTheme.colors.icon.primary1,
|
||||
)
|
||||
}
|
||||
},
|
||||
|
|
@ -108,10 +115,10 @@ fun EmptyTopBarWithNavigation(
|
|||
|
||||
@Composable
|
||||
fun DetailsMainButton(
|
||||
modifier: Modifier = Modifier,
|
||||
title: String,
|
||||
enabled: Boolean = true,
|
||||
onClick: (() -> Unit),
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
Button(
|
||||
onClick = onClick,
|
||||
|
|
|
|||
|
|
@ -33,10 +33,11 @@ import com.tangem.wallet.R
|
|||
@Composable
|
||||
fun TangemSwitch(
|
||||
modifier: Modifier = Modifier,
|
||||
enabledColor: Color = colorResource(id = R.color.control_checked),
|
||||
disabledColor: Color = colorResource(id = R.color.icon_informative),
|
||||
checkedColor: Color = colorResource(id = R.color.control_checked),
|
||||
uncheckedColor: Color = colorResource(id = R.color.icon_informative),
|
||||
size: Dp = 48.dp,
|
||||
checked: Boolean = false,
|
||||
enabled: Boolean = true,
|
||||
onCheckedChange: (Boolean) -> Unit,
|
||||
) {
|
||||
val transition = updateTransition(checked, label = "SwitchState")
|
||||
|
|
@ -45,8 +46,8 @@ fun TangemSwitch(
|
|||
tween(durationMillis = 200, easing = FastOutLinearInEasing)
|
||||
},
|
||||
label = "",
|
||||
) { enabled ->
|
||||
if (enabled) enabledColor else disabledColor
|
||||
) { isChecked ->
|
||||
if (isChecked) checkedColor else uncheckedColor
|
||||
}
|
||||
val interactionSource = remember { MutableInteractionSource() }
|
||||
|
||||
|
|
@ -55,6 +56,7 @@ fun TangemSwitch(
|
|||
.clickable(
|
||||
interactionSource = interactionSource,
|
||||
indication = null,
|
||||
enabled = enabled,
|
||||
) {
|
||||
onCheckedChange(!checked)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import androidx.compose.runtime.mutableStateOf
|
|||
import androidx.compose.ui.platform.ComposeView
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.transition.TransitionInflater
|
||||
import com.google.accompanist.appcompattheme.AppCompatTheme
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.tap.common.analytics.Analytics
|
||||
import com.tangem.tap.common.analytics.events.Settings
|
||||
import com.tangem.tap.common.redux.navigation.NavigationAction
|
||||
|
|
@ -40,7 +40,7 @@ class DetailsFragment : Fragment(), StoreSubscriber<DetailsState> {
|
|||
return ComposeView(requireContext()).apply {
|
||||
setContent {
|
||||
isTransitionGroup = true
|
||||
AppCompatTheme {
|
||||
TangemTheme {
|
||||
DetailsScreen(
|
||||
state = detailsScreenState.value,
|
||||
onBackPressed = { store.dispatch(NavigationAction.PopBackTo()) },
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import androidx.compose.runtime.mutableStateOf
|
|||
import androidx.compose.ui.platform.ComposeView
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.transition.TransitionInflater
|
||||
import com.google.accompanist.appcompattheme.AppCompatTheme
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.tap.common.redux.navigation.NavigationAction
|
||||
import com.tangem.tap.features.details.redux.DetailsState
|
||||
import com.tangem.tap.store
|
||||
|
|
@ -38,7 +38,7 @@ class ResetCardFragment : Fragment(), StoreSubscriber<DetailsState> {
|
|||
return ComposeView(requireContext()).apply {
|
||||
setContent {
|
||||
isTransitionGroup = true
|
||||
AppCompatTheme {
|
||||
TangemTheme {
|
||||
ResetCardScreen(
|
||||
state = screenState.value,
|
||||
onBackPressed = { store.dispatch(NavigationAction.PopBackTo()) },
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import androidx.compose.runtime.mutableStateOf
|
|||
import androidx.compose.ui.platform.ComposeView
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.transition.TransitionInflater
|
||||
import com.google.accompanist.appcompattheme.AppCompatTheme
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.tap.common.redux.navigation.NavigationAction
|
||||
import com.tangem.tap.features.details.redux.DetailsState
|
||||
import com.tangem.tap.store
|
||||
|
|
@ -38,7 +38,7 @@ class SecurityModeFragment : Fragment(), StoreSubscriber<DetailsState> {
|
|||
return ComposeView(requireContext()).apply {
|
||||
setContent {
|
||||
isTransitionGroup = true
|
||||
AppCompatTheme {
|
||||
TangemTheme {
|
||||
SecurityModeScreen(
|
||||
state = screenState.value,
|
||||
onBackPressed = { store.dispatch(NavigationAction.PopBackTo()) },
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import androidx.compose.runtime.mutableStateOf
|
|||
import androidx.compose.ui.platform.ComposeView
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.transition.TransitionInflater
|
||||
import com.google.accompanist.appcompattheme.AppCompatTheme
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.tap.common.redux.navigation.NavigationAction
|
||||
import com.tangem.tap.features.details.redux.walletconnect.WalletConnectAction
|
||||
import com.tangem.tap.features.details.redux.walletconnect.WalletConnectState
|
||||
|
|
@ -36,7 +36,7 @@ class WalletConnectFragment : Fragment(), StoreSubscriber<WalletConnectState> {
|
|||
return ComposeView(requireContext()).apply {
|
||||
setContent {
|
||||
isTransitionGroup = true
|
||||
AppCompatTheme {
|
||||
TangemTheme {
|
||||
WalletConnectScreen(
|
||||
state = screenState.value,
|
||||
onBackPressed = {
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ internal class SaveWalletMiddleware {
|
|||
}
|
||||
|
||||
private fun saveWalletIfBiometricsEnrolled(state: SaveWalletState) {
|
||||
if (tangemSdkManager.canEnrollBiometrics) {
|
||||
if (tangemSdkManager.needEnrollBiometrics) {
|
||||
store.dispatchOnMain(SaveWalletAction.EnrollBiometrics)
|
||||
} else {
|
||||
saveWallet(state)
|
||||
|
|
|
|||
|
|
@ -16,12 +16,12 @@ import androidx.compose.runtime.rememberUpdatedState
|
|||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.fragment.app.viewModels
|
||||
import com.tangem.core.ui.components.dialogs.EnrollBiometricsDialogContent
|
||||
import com.tangem.core.ui.fragments.ComposeBottomSheetFragment
|
||||
import com.tangem.core.ui.models.EnrollBiometricsDialog
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.tap.features.details.ui.cardsettings.resolveReference
|
||||
import com.tangem.tap.features.saveWallet.ui.components.EnrollBiometricsDialogContent
|
||||
import com.tangem.tap.features.saveWallet.ui.components.SaveWalletScreenContent
|
||||
import com.tangem.tap.features.saveWallet.ui.models.EnrollBiometricsDialog
|
||||
|
||||
internal class SaveWalletBottomSheetFragment : ComposeBottomSheetFragment<SaveWalletScreenState>() {
|
||||
override val expandedHeightFraction: Float = .98f
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
package com.tangem.tap.features.saveWallet.ui
|
||||
|
||||
import androidx.compose.runtime.Immutable
|
||||
import com.tangem.core.ui.models.EnrollBiometricsDialog
|
||||
import com.tangem.tap.features.details.ui.cardsettings.TextReference
|
||||
import com.tangem.tap.features.saveWallet.ui.models.EnrollBiometricsDialog
|
||||
|
||||
@Immutable
|
||||
internal data class SaveWalletScreenState(
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
package com.tangem.tap.features.saveWallet.ui
|
||||
|
||||
import androidx.lifecycle.ViewModel
|
||||
import com.tangem.core.ui.models.EnrollBiometricsDialog
|
||||
import com.tangem.tap.common.extensions.dispatchOnMain
|
||||
import com.tangem.tap.features.details.ui.cardsettings.TextReference
|
||||
import com.tangem.tap.features.saveWallet.redux.SaveWalletAction
|
||||
import com.tangem.tap.features.saveWallet.redux.SaveWalletState
|
||||
import com.tangem.tap.features.saveWallet.ui.models.EnrollBiometricsDialog
|
||||
import com.tangem.tap.store
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
package com.tangem.core.ui.components.dialogs
|
||||
package com.tangem.tap.features.saveWallet.ui.components
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
|
|
@ -17,8 +17,8 @@ import com.tangem.core.ui.components.SpacerH16
|
|||
import com.tangem.core.ui.components.SpacerH24
|
||||
import com.tangem.core.ui.components.SpacerW8
|
||||
import com.tangem.core.ui.components.TextButton
|
||||
import com.tangem.core.ui.models.EnrollBiometricsDialog
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.tap.features.saveWallet.ui.models.EnrollBiometricsDialog
|
||||
|
||||
@Composable
|
||||
fun EnrollBiometricsDialogContent(
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package com.tangem.core.ui.models
|
||||
package com.tangem.tap.features.saveWallet.ui.models
|
||||
|
||||
import androidx.compose.runtime.Immutable
|
||||
|
||||
|
|
@ -227,4 +227,6 @@
|
|||
<string name="user_wallet_list_editing_count">%d selected</string>
|
||||
<string name="common_biometric_authentication">biometric authentication</string>
|
||||
<string name="common_biometrics">biometrics</string>
|
||||
<string name="app_settings_enable_biometrics_title">Enable biometric authentication</string>
|
||||
<string name="app_settings_enable_biometrics_description">Go to settings to enable biometric authentication in the Tangem App</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -227,4 +227,6 @@
|
|||
<string name="user_wallet_list_editing_count">%d selected</string>
|
||||
<string name="common_biometric_authentication">biometric authentication</string>
|
||||
<string name="common_biometrics">biometrics</string>
|
||||
<string name="app_settings_enable_biometrics_title">Enable biometric authentication</string>
|
||||
<string name="app_settings_enable_biometrics_description">Go to settings to enable biometric authentication in the Tangem App</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -227,4 +227,6 @@
|
|||
<string name="user_wallet_list_editing_count">%d selected</string>
|
||||
<string name="common_biometric_authentication">biometric authentication</string>
|
||||
<string name="common_biometrics">biometrics</string>
|
||||
<string name="app_settings_enable_biometrics_title">Enable biometric authentication</string>
|
||||
<string name="app_settings_enable_biometrics_description">Go to settings to enable biometric authentication in the Tangem App</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -227,4 +227,6 @@
|
|||
<string name="user_wallet_list_editing_count">%d выбрано</string>
|
||||
<string name="common_biometric_authentication">биометрическую аутентификацию</string>
|
||||
<string name="common_biometrics">биометрией</string>
|
||||
<string name="app_settings_enable_biometrics_title">Включите биометрическую аутентификацию</string>
|
||||
<string name="app_settings_enable_biometrics_description">Перейдите в настройки, чтобы включить биометрическую аутентификацию в приложении Tangem App</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -227,4 +227,6 @@
|
|||
<string name="user_wallet_list_editing_count">%d selected</string>
|
||||
<string name="common_biometric_authentication">biometric authentication</string>
|
||||
<string name="common_biometrics">biometrics</string>
|
||||
<string name="app_settings_enable_biometrics_title">Enable biometric authentication</string>
|
||||
<string name="app_settings_enable_biometrics_description">Go to settings to enable biometric authentication in the Tangem App</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ fun TextButton(
|
|||
onClick = onClick,
|
||||
enabled = enabled,
|
||||
showProgress = false,
|
||||
colors = TangemButtonsDefaults.textButtonColors,
|
||||
colors = TangemButtonsDefaults.defaultTextButtonColors,
|
||||
size = TangemButtonSize.Text,
|
||||
)
|
||||
}
|
||||
|
|
@ -77,7 +77,26 @@ fun TextButtonIconLeft(
|
|||
onClick = onClick,
|
||||
enabled = enabled,
|
||||
showProgress = false,
|
||||
colors = TangemButtonsDefaults.textButtonColors,
|
||||
colors = TangemButtonsDefaults.defaultTextButtonColors,
|
||||
size = TangemButtonSize.Text,
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun WarningTextButton(
|
||||
modifier: Modifier = Modifier,
|
||||
text: String,
|
||||
enabled: Boolean = true,
|
||||
onClick: () -> Unit,
|
||||
) {
|
||||
TangemButton(
|
||||
modifier = modifier,
|
||||
text = text,
|
||||
icon = TangemButtonIcon.None,
|
||||
onClick = onClick,
|
||||
enabled = enabled,
|
||||
showProgress = false,
|
||||
colors = TangemButtonsDefaults.warningTextButtonColors,
|
||||
size = TangemButtonSize.Text,
|
||||
)
|
||||
}
|
||||
|
|
@ -325,7 +344,7 @@ private fun TangemButtonSize.toShape(): Shape = when (this) {
|
|||
TangemButtonSize.Text -> TangemTheme.shapes.roundedCornersSmall
|
||||
}
|
||||
|
||||
private object TangemButtonsDefaults {
|
||||
object TangemButtonsDefaults {
|
||||
val elevation: ButtonElevation
|
||||
@Composable get() = ButtonDefaults
|
||||
.elevation(
|
||||
|
|
@ -349,17 +368,25 @@ private object TangemButtonsDefaults {
|
|||
disabledContentColor = TangemTheme.colors.text.disabled,
|
||||
)
|
||||
|
||||
val textButtonColors: ButtonColors
|
||||
val defaultTextButtonColors: ButtonColors
|
||||
@Composable get() = TangemButtonColors(
|
||||
backgroundColor = Color.Transparent,
|
||||
contentColor = TangemTheme.colors.text.secondary,
|
||||
disabledBackgroundColor = Color.Transparent,
|
||||
disabledContentColor = TangemTheme.colors.text.disabled,
|
||||
)
|
||||
|
||||
val warningTextButtonColors: ButtonColors
|
||||
@Composable get() = TangemButtonColors(
|
||||
backgroundColor = Color.Transparent,
|
||||
contentColor = TangemTheme.colors.text.warning,
|
||||
disabledBackgroundColor = Color.Transparent,
|
||||
disabledContentColor = TangemTheme.colors.text.disabled,
|
||||
)
|
||||
}
|
||||
|
||||
@Immutable
|
||||
private class TangemButtonColors(
|
||||
private open class TangemButtonColors(
|
||||
private val backgroundColor: Color,
|
||||
private val contentColor: Color,
|
||||
private val disabledBackgroundColor: Color,
|
||||
|
|
@ -561,6 +588,11 @@ private fun TextButtonSample(
|
|||
enabled = false,
|
||||
onClick = { /* no-op */ },
|
||||
)
|
||||
Divider(modifier = Modifier.padding(vertical = TangemTheme.dimens.spacing8))
|
||||
WarningTextButton(
|
||||
text = "Delete",
|
||||
onClick = { /* no-op */ },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@ data class TangemDimens internal constructor(
|
|||
val spacing12: Dp = 12.dp,
|
||||
val spacing14: Dp = 14.dp,
|
||||
val spacing16: Dp = 16.dp,
|
||||
val spacing20: Dp = 20.dp,
|
||||
val spacing24: Dp = 24.dp,
|
||||
val spacing32: Dp = 32.dp,
|
||||
val spacing34: Dp = 34.dp,
|
||||
|
|
|
|||
9
core/ui/src/main/res/drawable/ic_alert_circle_24.xml
Normal file
9
core/ui/src/main/res/drawable/ic_alert_circle_24.xml
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="#000000"
|
||||
android:pathData="M13,13H11V7H13M13,17H11V15H13M12,2C10.687,2 9.386,2.259 8.173,2.761C6.96,3.264 5.858,4 4.929,4.929C3.054,6.804 2,9.348 2,12C2,14.652 3.054,17.196 4.929,19.071C5.858,20 6.96,20.736 8.173,21.239C9.386,21.741 10.687,22 12,22C14.652,22 17.196,20.946 19.071,19.071C20.946,17.196 22,14.652 22,12C22,10.687 21.741,9.386 21.239,8.173C20.736,6.96 20,5.858 19.071,4.929C18.142,4 17.04,3.264 15.827,2.761C14.614,2.259 13.313,2 12,2Z" />
|
||||
</vector>
|
||||
Loading…
Add table
Add a link
Reference in a new issue