From af3f8c6c25068189f7412f85d649d793529de8a5 Mon Sep 17 00:00:00 2001 From: Tangem Date: Thu, 4 Aug 2022 18:03:14 +0400 Subject: [PATCH] Updated on 2026-08-14 --- .../com/tangem/tap/common/DialogManager.kt | 14 -- .../tap/common/extensions/Navigation.kt | 3 +- .../features/details/redux/DetailsAction.kt | 5 +- .../details/redux/DetailsMiddleware.kt | 15 +- .../features/details/redux/DetailsReducer.kt | 7 +- .../features/details/redux/DetailsState.kt | 15 +- .../ui/appsettings/AppSettingsFragment.kt | 70 +++++- .../ui/appsettings/AppSettingsScreen.kt | 229 +++++++++++++++++- .../ui/appsettings/AppSettingsScreenState.kt | 10 + .../ui/appsettings/AppSettingsViewModel.kt | 27 +++ .../details/ui/common/TangemSwitch.kt | 87 +++++++ app/src/main/res/values-de/strings.xml | 1 + app/src/main/res/values-fr/strings.xml | 1 + app/src/main/res/values-it/strings.xml | 1 + app/src/main/res/values-ru/strings.xml | 1 + app/src/main/res/values/strings.xml | 1 + 16 files changed, 436 insertions(+), 51 deletions(-) create mode 100644 app/src/main/java/com/tangem/tap/features/details/ui/appsettings/AppSettingsScreenState.kt create mode 100644 app/src/main/java/com/tangem/tap/features/details/ui/appsettings/AppSettingsViewModel.kt create mode 100644 app/src/main/java/com/tangem/tap/features/details/ui/common/TangemSwitch.kt diff --git a/app/src/main/java/com/tangem/tap/common/DialogManager.kt b/app/src/main/java/com/tangem/tap/common/DialogManager.kt index eeb216951d..6329729b5d 100644 --- a/app/src/main/java/com/tangem/tap/common/DialogManager.kt +++ b/app/src/main/java/com/tangem/tap/common/DialogManager.kt @@ -6,8 +6,6 @@ import com.tangem.tap.common.redux.AppDialog import com.tangem.tap.common.redux.global.GlobalState import com.tangem.tap.common.ui.SimpleAlertDialog import com.tangem.tap.common.ui.SimpleCancelableAlertDialog -import com.tangem.tap.features.details.redux.DetailsDialog -import com.tangem.tap.features.details.redux.PrivacySetting import com.tangem.tap.features.details.redux.walletconnect.WalletConnectDialog import com.tangem.tap.features.details.ui.walletconnect.dialogs.ApproveWcSessionDialog import com.tangem.tap.features.details.ui.walletconnect.dialogs.BnbTransactionDialog @@ -150,18 +148,6 @@ class DialogManager : StoreSubscriber { ) is WalletDialog.RussianCardholdersWarningDialog -> RussianCardholdersWarningBottomSheetDialog(context) - is DetailsDialog.ConfirmDisablingSaving -> { - val messageRes = when (state.dialog.setting) { - PrivacySetting.SAVE_CARDS -> R.string.app_settings_off_saved_wallet_alert_message - PrivacySetting.SAVE_ACCESS_CODE -> R.string.app_settings_off_saved_access_code_alert_message - } - SimpleCancelableAlertDialog.create( - titleRes = R.string.common_warning, - messageRes = messageRes, - context = context, - primaryButtonAction = state.dialog.onOk - ) - } else -> null } dialog?.show() diff --git a/app/src/main/java/com/tangem/tap/common/extensions/Navigation.kt b/app/src/main/java/com/tangem/tap/common/extensions/Navigation.kt index f5feed18d7..a9504e668a 100644 --- a/app/src/main/java/com/tangem/tap/common/extensions/Navigation.kt +++ b/app/src/main/java/com/tangem/tap/common/extensions/Navigation.kt @@ -7,6 +7,7 @@ import androidx.fragment.app.FragmentManager import com.tangem.common.extensions.VoidCallback import com.tangem.tap.common.redux.navigation.AppScreen import com.tangem.tap.common.redux.navigation.FragmentShareTransition +import com.tangem.tap.features.details.ui.appsettings.AppSettingsFragment import com.tangem.tap.features.details.ui.cardsettings.CardSettingsFragment import com.tangem.tap.features.details.ui.details.DetailsFragment import com.tangem.tap.features.details.ui.resetcard.ResetCardFragment @@ -95,7 +96,7 @@ private fun fragmentFactory(screen: AppScreen): Fragment { AppScreen.Details -> DetailsFragment() AppScreen.DetailsSecurity -> SecurityModeFragment() AppScreen.CardSettings -> CardSettingsFragment() - AppScreen.AppSettings -> CardSettingsFragment() + AppScreen.AppSettings -> AppSettingsFragment() AppScreen.ResetToFactory -> ResetCardFragment() AppScreen.Disclaimer -> DisclaimerFragment() AppScreen.AddTokens -> AddTokensFragment() diff --git a/app/src/main/java/com/tangem/tap/features/details/redux/DetailsAction.kt b/app/src/main/java/com/tangem/tap/features/details/redux/DetailsAction.kt index 3ad36caa55..9cb5cfe537 100644 --- a/app/src/main/java/com/tangem/tap/features/details/redux/DetailsAction.kt +++ b/app/src/main/java/com/tangem/tap/features/details/redux/DetailsAction.kt @@ -44,10 +44,7 @@ sealed class DetailsAction : Action { } sealed class AppSettings : DetailsAction() { - data class SwitchPrivacySetting(val allow: Boolean, val setting: PrivacySetting) : - AppSettings() - - data class ConfirmSwitchingSetting(val allow: Boolean, val setting: PrivacySetting) : + data class SwitchPrivacySetting(val enable: Boolean, val setting: PrivacySetting) : AppSettings() } diff --git a/app/src/main/java/com/tangem/tap/features/details/redux/DetailsMiddleware.kt b/app/src/main/java/com/tangem/tap/features/details/redux/DetailsMiddleware.kt index 8cae2e026b..537668094f 100644 --- a/app/src/main/java/com/tangem/tap/features/details/redux/DetailsMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/details/redux/DetailsMiddleware.kt @@ -5,7 +5,6 @@ import com.tangem.common.core.TangemSdkError import com.tangem.domain.common.isTangemTwins import com.tangem.tap.common.analytics.Analytics import com.tangem.tap.common.analytics.AnalyticsParam -import com.tangem.tap.common.extensions.dispatchDialogShow import com.tangem.tap.common.extensions.dispatchNotification import com.tangem.tap.common.extensions.dispatchOnMain import com.tangem.tap.common.redux.AppState @@ -188,20 +187,8 @@ class DetailsMiddleware { class ManagePrivacyMiddleware { fun handle(action: DetailsAction.AppSettings) { when (action) { - is DetailsAction.AppSettings.ConfirmSwitchingSetting -> { -// TODO() - } is DetailsAction.AppSettings.SwitchPrivacySetting -> { - if (action.allow) { - store.dispatch( - DetailsAction.AppSettings.ConfirmSwitchingSetting( - action.allow, - action.setting, - ), - ) - } else { - store.dispatchDialogShow(DetailsDialog.ConfirmDisablingSaving(action.setting)) - } +// TODO() } } } diff --git a/app/src/main/java/com/tangem/tap/features/details/redux/DetailsReducer.kt b/app/src/main/java/com/tangem/tap/features/details/redux/DetailsReducer.kt index 99024b0c20..a85b15b857 100644 --- a/app/src/main/java/com/tangem/tap/features/details/redux/DetailsReducer.kt +++ b/app/src/main/java/com/tangem/tap/features/details/redux/DetailsReducer.kt @@ -149,13 +149,12 @@ private fun handlePrivacyAction( action: DetailsAction.AppSettings, state: DetailsState, ): DetailsState { return when (action) { - is DetailsAction.AppSettings.ConfirmSwitchingSetting -> { + is DetailsAction.AppSettings.SwitchPrivacySetting -> { when (action.setting) { - PrivacySetting.SAVE_CARDS -> state.copy(saveCards = action.allow) - PrivacySetting.SAVE_ACCESS_CODE -> state.copy(savePasswords = action.allow) + PrivacySetting.SaveWallets -> state.copy(saveWallets = action.enable) + PrivacySetting.SaveAccessCode -> state.copy(saveAccessCodes = action.enable) } } - is DetailsAction.AppSettings.SwitchPrivacySetting -> state } } diff --git a/app/src/main/java/com/tangem/tap/features/details/redux/DetailsState.kt b/app/src/main/java/com/tangem/tap/features/details/redux/DetailsState.kt index cf0b3852e5..8e02856097 100644 --- a/app/src/main/java/com/tangem/tap/features/details/redux/DetailsState.kt +++ b/app/src/main/java/com/tangem/tap/features/details/redux/DetailsState.kt @@ -6,7 +6,6 @@ import com.tangem.common.card.Card import com.tangem.domain.common.ScanResponse import com.tangem.tap.common.entities.Button import com.tangem.tap.common.entities.FiatCurrency -import com.tangem.tap.common.redux.StateDialog import com.tangem.tap.features.onboarding.products.twins.redux.TwinCardsState import com.tangem.tap.store import org.rekotlin.StateType @@ -21,8 +20,8 @@ data class DetailsState( val privacyPolicyUrl: String? = null, val createBackupAllowed: Boolean = false, val appCurrency: FiatCurrency = FiatCurrency.Default, - val saveCards: Boolean = true, - val savePasswords: Boolean = true + val saveWallets: Boolean = true, + val saveAccessCodes: Boolean = true, ) : StateType { // if you do not delegate - the application crashes on startup, @@ -58,14 +57,6 @@ data class ManageSecurityState( enum class SecurityOption { LongTap, PassCode, AccessCode } - -sealed interface DetailsDialog : StateDialog { - data class ConfirmDisablingSaving(val setting: PrivacySetting) : DetailsDialog { - val onOk: () -> Unit = - { store.dispatch(DetailsAction.AppSettings.ConfirmSwitchingSetting(false, setting)) } - } -} - enum class PrivacySetting { - SAVE_CARDS, SAVE_ACCESS_CODE + SaveWallets, SaveAccessCode } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/details/ui/appsettings/AppSettingsFragment.kt b/app/src/main/java/com/tangem/tap/features/details/ui/appsettings/AppSettingsFragment.kt index 048b390954..bea7b87171 100644 --- a/app/src/main/java/com/tangem/tap/features/details/ui/appsettings/AppSettingsFragment.kt +++ b/app/src/main/java/com/tangem/tap/features/details/ui/appsettings/AppSettingsFragment.kt @@ -1,3 +1,71 @@ package com.tangem.tap.features.details.ui.appsettings -class AppSettingsFragment \ No newline at end of file +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.compose.runtime.MutableState +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.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 { + private val viewModel = AppSettingsViewModel(store) + private var screenState: MutableState = + mutableStateOf(viewModel.updateState(store.state.detailsState)) + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + val inflater = TransitionInflater.from(requireContext()) + enterTransition = inflater.inflateTransition(R.transition.slide_right) + exitTransition = inflater.inflateTransition(R.transition.fade) + } + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle?, + ): View { + return ComposeView(requireContext()).apply { + setContent { + isTransitionGroup = true + AppCompatTheme { + AppSettingsScreen( + state = screenState.value, + onBackPressed = { + store.dispatch(DetailsAction.ResetCardSettingsData) + store.dispatch(NavigationAction.PopBackTo()) + }, + ) + } + } + } + } + + override fun onStart() { + super.onStart() + store.subscribe(this) { state -> + state.skipRepeats { oldState, newState -> + oldState.detailsState == newState.detailsState + }.select { it.detailsState } + } + } + + override fun onStop() { + super.onStop() + store.unsubscribe(this) + } + + override fun newState(state: DetailsState) { + if (activity == null || view == null) return + screenState.value = viewModel.updateState(state) + } +} diff --git a/app/src/main/java/com/tangem/tap/features/details/ui/appsettings/AppSettingsScreen.kt b/app/src/main/java/com/tangem/tap/features/details/ui/appsettings/AppSettingsScreen.kt index 060c8cc343..71f13c39b4 100644 --- a/app/src/main/java/com/tangem/tap/features/details/ui/appsettings/AppSettingsScreen.kt +++ b/app/src/main/java/com/tangem/tap/features/details/ui/appsettings/AppSettingsScreen.kt @@ -1,9 +1,236 @@ package com.tangem.tap.features.details.ui.appsettings +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.shape.CornerSize +import androidx.compose.material.AlertDialog +import androidx.compose.material.MaterialTheme +import androidx.compose.material.Switch +import androidx.compose.material.SwitchDefaults +import androidx.compose.material.Text +import androidx.compose.material.TextButton import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +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.tap.common.compose.TangemTypography +import com.tangem.tap.features.details.redux.PrivacySetting +import com.tangem.tap.features.details.ui.common.SettingsScreensScaffold +import com.tangem.wallet.R @Composable fun AppSettingsScreen( - + state: AppSettingsScreenState, + onBackPressed: () -> Unit, + modifier: Modifier = Modifier, ) { + SettingsScreensScaffold( + content = { + AppSettings(state = state, modifier = modifier) + }, + titleRes = R.string.app_settings_title, + onBackClick = onBackPressed, + ) +} + +@Composable +fun AppSettings( + state: AppSettingsScreenState, + modifier: Modifier = Modifier, +) { + var dialogType by remember { mutableStateOf(null) } + val onDialogStateChange: (PrivacySetting?) -> Unit = { dialogType = it } + + dialogType?.let { + SettingsAlertDialog( + element = it, + onDialogStateChange = onDialogStateChange, + onSettingToggled = state.onSettingToggled, + modifier = modifier, + ) + } + + Column( + modifier = modifier + .fillMaxSize(), + ) { + AppSettingsElement( + state = state, setting = PrivacySetting.SaveWallets, + onDialogStateChange = onDialogStateChange, + modifier = modifier, + ) + Spacer(modifier = Modifier.size(32.dp)) + AppSettingsElement( + state = state, setting = PrivacySetting.SaveAccessCode, + onDialogStateChange = onDialogStateChange, + modifier = modifier, + ) + } +} + +@Composable +fun AppSettingsElement( + state: AppSettingsScreenState, + setting: PrivacySetting, + onDialogStateChange: (PrivacySetting?) -> Unit, + modifier: Modifier = Modifier, +) { + val titleRes = when (setting) { + PrivacySetting.SaveWallets -> R.string.app_settings_saved_wallet + PrivacySetting.SaveAccessCode -> R.string.app_settings_saved_access_codes + } + val subtitleRes = when (setting) { + PrivacySetting.SaveWallets -> R.string.app_settings_saved_wallet_footer + PrivacySetting.SaveAccessCode -> R.string.app_settings_saved_access_codes_footer + } + val checked = state.settings[setting] ?: false + + Row( + modifier = modifier + .fillMaxWidth() + .padding(start = 20.dp), + // .clickable { state.onSettingToggled(element, !checked) }, + verticalAlignment = Alignment.CenterVertically, + ) { + Column( + 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), + ) + Spacer(modifier = Modifier.size(4.dp)) + Text( + text = stringResource(id = subtitleRes), + style = TangemTypography.body2, + color = colorResource(id = R.color.text_secondary), + ) + } + Switch( + checked = checked, + onCheckedChange = { + onCheckedChange( + element = setting, + enabled = it, + onSettingToggled = state.onSettingToggled, + onDialogStateChange = onDialogStateChange, + ) + }, + colors = SwitchDefaults.colors( + checkedThumbColor = colorResource(id = R.color.control_key), + uncheckedThumbColor = colorResource(id = R.color.control_key), + checkedTrackColor = colorResource(id = R.color.control_checked), + uncheckedTrackColor = colorResource(id = R.color.icon_informative), + ), + modifier = modifier + .padding(start = 20.dp, end = 20.dp), + ) + } +} + +fun onCheckedChange( + element: PrivacySetting, enabled: Boolean, + onSettingToggled: (PrivacySetting, Boolean) -> Unit, + onDialogStateChange: (PrivacySetting?) -> Unit, +) { + //Show warning if user wants to disable the switch + if (!enabled) { + onDialogStateChange(element) + } else { + onSettingToggled(element, enabled) + } +} + +@Composable +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( + 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 +@Composable +fun AppSettingsScreenPreview() { + AppSettingsScreen( + state = AppSettingsScreenState( + settings = mapOf( + PrivacySetting.SaveWallets to true, + PrivacySetting.SaveAccessCode to false, + ), + onSettingToggled = { _, _ -> }, + ), + onBackPressed = { }, + ) } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/details/ui/appsettings/AppSettingsScreenState.kt b/app/src/main/java/com/tangem/tap/features/details/ui/appsettings/AppSettingsScreenState.kt new file mode 100644 index 0000000000..043423b3d3 --- /dev/null +++ b/app/src/main/java/com/tangem/tap/features/details/ui/appsettings/AppSettingsScreenState.kt @@ -0,0 +1,10 @@ +package com.tangem.tap.features.details.ui.appsettings + +import com.tangem.tap.features.details.redux.PrivacySetting + +data class AppSettingsScreenState( + val settings: Map, + val onSettingToggled: (PrivacySetting, Boolean) -> Unit, +) + + diff --git a/app/src/main/java/com/tangem/tap/features/details/ui/appsettings/AppSettingsViewModel.kt b/app/src/main/java/com/tangem/tap/features/details/ui/appsettings/AppSettingsViewModel.kt new file mode 100644 index 0000000000..65dd12eaeb --- /dev/null +++ b/app/src/main/java/com/tangem/tap/features/details/ui/appsettings/AppSettingsViewModel.kt @@ -0,0 +1,27 @@ +package com.tangem.tap.features.details.ui.appsettings + +import com.tangem.tap.common.redux.AppState +import com.tangem.tap.features.details.redux.DetailsAction +import com.tangem.tap.features.details.redux.DetailsState +import com.tangem.tap.features.details.redux.PrivacySetting +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import org.rekotlin.Store + +class AppSettingsViewModel(private val store: Store) { + private val _uiState = MutableStateFlow(updateState(store.state.detailsState)) + val uiState: StateFlow = _uiState + fun updateState(state: DetailsState): AppSettingsScreenState { + return AppSettingsScreenState( + settings = mapOf( + PrivacySetting.SaveWallets to state.saveWallets, + PrivacySetting.SaveAccessCode to state.saveAccessCodes, + ), + onSettingToggled = { privacySetting, enabled -> onSettingsToggled(privacySetting, enabled) }, + ) + } + + private fun onSettingsToggled(setting: PrivacySetting, enable: Boolean) { + store.dispatch(DetailsAction.AppSettings.SwitchPrivacySetting(enable = enable, setting = setting)) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/details/ui/common/TangemSwitch.kt b/app/src/main/java/com/tangem/tap/features/details/ui/common/TangemSwitch.kt new file mode 100644 index 0000000000..02b698421a --- /dev/null +++ b/app/src/main/java/com/tangem/tap/features/details/ui/common/TangemSwitch.kt @@ -0,0 +1,87 @@ +package com.tangem.tap.features.details.ui.common + +import androidx.compose.animation.core.animateFloatAsState +import androidx.compose.foundation.Canvas +import androidx.compose.foundation.gestures.detectTapGestures +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.size +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.geometry.CornerRadius +import androidx.compose.ui.geometry.Offset +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.drawscope.Fill +import androidx.compose.ui.input.pointer.pointerInput +import androidx.compose.ui.platform.LocalDensity +import androidx.compose.ui.res.colorResource +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.dp +import com.tangem.wallet.R + +@Composable +fun TangemSwitch( + checked: Boolean, + onCheckedChange: (Boolean) -> Unit, + modifier: Modifier = Modifier, + width: Dp = 48.dp, + height: Dp = 24.dp, + checkedTrackColor: Color = colorResource(id = R.color.control_checked), + uncheckedTrackColor: Color = colorResource(id = R.color.icon_informative), + selectorColor: Color = colorResource(id = R.color.background_secondary), + gapBetweenThumbAndTrackEdge: Dp = 3.dp, +) { + val thumbRadius = (height / 2) - gapBetweenThumbAndTrackEdge + val animatePosition = animateFloatAsState( + targetValue = if (checked) + with(LocalDensity.current) { (width - thumbRadius - gapBetweenThumbAndTrackEdge).toPx() } + else + with(LocalDensity.current) { (thumbRadius + gapBetweenThumbAndTrackEdge).toPx() }, + ) + + Canvas( + modifier = modifier + .size(width = width, height = height) + .pointerInput(Unit) { + detectTapGestures( + onTap = { + onCheckedChange(checked) + }, + ) + }, + ) { + drawRoundRect( + color = if (checked) checkedTrackColor else uncheckedTrackColor, + cornerRadius = CornerRadius(x = 35.dp.toPx(), y = 35.dp.toPx()), + style = Fill, + ) + + drawCircle( + color = selectorColor, + radius = thumbRadius.toPx(), + center = Offset( + x = animatePosition.value, + y = size.height / 2, + ), + ) + } + + Spacer(modifier = Modifier.height(18.dp)) +} + +@Preview +@Composable +fun TangemSwitchPreview() { + Column( + modifier = Modifier.fillMaxSize(), + verticalArrangement = Arrangement.Center, + horizontalAlignment = Alignment.CenterHorizontally, + ) { + TangemSwitch(true, {}) + } +} \ No newline at end of file diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 99c83c09c5..cf8a46c64c 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -6,6 +6,7 @@ Erledigt Abbrechen Akzeptieren + Entfernen Der Kamerazugriff wurde verweigert Sie haben keinen Zugang zur Kamera erteilt, bitte passen Sie Ihre Datenschutzeinstellungen an diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 17a6a3cce0..d39650f3b7 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -7,6 +7,7 @@ Exécuté Annuler J\'accepte + Supprimer L\'accès à la caméra est refusé Vous n\'avez pas octroyé l\'accès à votre caméra, veuillez modifier vos paramètres de confidentialité diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 4d699600d3..7eba948ed7 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -6,6 +6,7 @@ Riprova Fatto Annulla + Rimuovere Accesso alla videocamera negato Non hai fornito l\'accesso alla tua videocamera, modifica le tue impostazioni sulla privacy Impostazioni diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 9b6b5d5725..db78a57ae5 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -7,6 +7,7 @@ Готово Отмена Принять + Удалить %s Доступ к камере запрещен Вы не предоставили доступ к своей камере, измените настройки конфиденциальности diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 60d0c22f1d..2c1ebffd92 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -8,6 +8,7 @@ Done Cancel Accept + Delete %s Camera access denied