Updated on 2026-08-14
This commit is contained in:
commit
fbb99bcda0
317 changed files with 3800 additions and 2894 deletions
|
|
@ -18,13 +18,13 @@ import androidx.compose.ui.Alignment
|
|||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.testTag
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import com.tangem.core.ui.components.appbar.TangemTopAppBar
|
||||
import com.tangem.core.ui.components.appbar.models.TopAppBarButtonUM
|
||||
import com.tangem.core.ui.components.block.BlockItem
|
||||
import com.tangem.core.ui.components.snackbar.TangemSnackbarHost
|
||||
import com.tangem.core.ui.decompose.ComposableContentComponent
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.core.ui.res.LocalSnackbarHostState
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
|
|
@ -86,7 +86,7 @@ private fun Content(
|
|||
item {
|
||||
Text(
|
||||
modifier = Modifier.padding(horizontal = TangemTheme.dimens.spacing16),
|
||||
text = stringResource(R.string.details_title),
|
||||
text = stringResourceSafe(R.string.details_title),
|
||||
style = TangemTheme.typography.h1,
|
||||
color = TangemTheme.colors.text.primary1,
|
||||
)
|
||||
|
|
@ -127,7 +127,9 @@ private fun Block(
|
|||
horizontalAlignment = Alignment.Start,
|
||||
verticalArrangement = Arrangement.Top,
|
||||
) {
|
||||
val itemModifier = Modifier.fillMaxWidth().testTag(TestTags.DETAILS_SCREEN_ITEM)
|
||||
val itemModifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.testTag(TestTags.DETAILS_SCREEN_ITEM)
|
||||
|
||||
when (model) {
|
||||
is DetailsItemUM.Basic -> {
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ 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 com.tangem.core.ui.components.block.BlockCard
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.core.ui.res.TangemColorPalette
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.features.details.impl.R
|
||||
|
|
@ -37,12 +37,12 @@ internal fun WalletConnectBlock(onClick: () -> Unit, modifier: Modifier = Modifi
|
|||
verticalArrangement = Arrangement.SpaceAround,
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(id = R.string.wallet_connect_title),
|
||||
text = stringResourceSafe(id = R.string.wallet_connect_title),
|
||||
style = TangemTheme.typography.subtitle1,
|
||||
color = TangemTheme.colors.text.primary1,
|
||||
)
|
||||
Text(
|
||||
text = stringResource(id = R.string.wallet_connect_subtitle),
|
||||
text = stringResourceSafe(id = R.string.wallet_connect_subtitle),
|
||||
style = TangemTheme.typography.body2,
|
||||
color = TangemTheme.colors.text.secondary,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
package com.tangem.features.details.utils
|
||||
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import arrow.core.Either
|
||||
import arrow.core.raise.Raise
|
||||
import arrow.core.raise.ensureNotNull
|
||||
|
|
@ -13,10 +12,7 @@ import com.tangem.core.decompose.navigation.Router
|
|||
import com.tangem.core.decompose.navigation.popTo
|
||||
import com.tangem.core.decompose.ui.UiMessageSender
|
||||
import com.tangem.core.ui.components.SimpleOkDialog
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
import com.tangem.core.ui.extensions.isNullOrEmpty
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.extensions.stringReference
|
||||
import com.tangem.core.ui.extensions.*
|
||||
import com.tangem.core.ui.message.ContentMessage
|
||||
import com.tangem.core.ui.message.SnackbarMessage
|
||||
import com.tangem.domain.card.ScanCardProcessor
|
||||
|
|
@ -107,7 +103,7 @@ internal class UserWalletSaver @Inject constructor(
|
|||
messageSender.send(
|
||||
message = ContentMessage { onDismiss ->
|
||||
SimpleOkDialog(
|
||||
message = stringResource(id = R.string.user_wallet_list_error_wallet_already_saved),
|
||||
message = stringResourceSafe(id = R.string.user_wallet_list_error_wallet_already_saved),
|
||||
onDismissDialog = onDismiss,
|
||||
)
|
||||
},
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@ import androidx.compose.ui.Alignment
|
|||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalDensity
|
||||
import androidx.compose.ui.platform.testTag
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import com.google.accompanist.permissions.ExperimentalPermissionsApi
|
||||
import com.google.accompanist.permissions.isGranted
|
||||
|
|
@ -31,6 +30,7 @@ import com.tangem.core.ui.components.appbar.TangemTopAppBar
|
|||
import com.tangem.core.ui.components.appbar.models.TopAppBarButtonUM
|
||||
import com.tangem.core.ui.components.buttons.common.TangemButtonColors
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.core.ui.res.TangemColorPalette
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
|
|
@ -153,7 +153,7 @@ private fun BoxScope.DisclaimerButton(onAccept: (Boolean) -> Unit) {
|
|||
rememberPermissionState(permission = permission).status.isGranted
|
||||
} ?: true
|
||||
PrimaryButton(
|
||||
text = stringResource(id = R.string.common_accept),
|
||||
text = stringResourceSafe(id = R.string.common_accept),
|
||||
onClick = { onAccept(!isPermissionGranted) },
|
||||
colors = TangemButtonColors(
|
||||
backgroundColor = TangemColorPalette.Light4,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
package com.tangem.features.managetokens.model
|
||||
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import arrow.core.getOrElse
|
||||
import com.tangem.core.analytics.api.AnalyticsEventHandler
|
||||
import com.tangem.core.decompose.di.ComponentScoped
|
||||
|
|
@ -10,6 +9,7 @@ import com.tangem.core.decompose.ui.UiMessageSender
|
|||
import com.tangem.core.ui.components.SimpleOkDialog
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.extensions.stringReference
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.core.ui.message.ContentMessage
|
||||
import com.tangem.domain.card.DerivePublicKeysUseCase
|
||||
import com.tangem.domain.card.HasMissedDerivationsUseCase
|
||||
|
|
@ -231,7 +231,7 @@ internal class CustomTokenFormModel @Inject constructor(
|
|||
private fun showErrorDialog() {
|
||||
val dialog = ContentMessage { onDismiss ->
|
||||
SimpleOkDialog(
|
||||
message = stringResource(R.string.common_unknown_error),
|
||||
message = stringResourceSafe(R.string.common_unknown_error),
|
||||
onDismissDialog = onDismiss,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@ import androidx.compose.ui.Modifier
|
|||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.focus.onFocusChanged
|
||||
import androidx.compose.ui.platform.LocalDensity
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||
|
|
@ -33,6 +32,7 @@ import com.tangem.core.ui.components.keyboardAsState
|
|||
import com.tangem.core.ui.components.notifications.Notification
|
||||
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
|
||||
import com.tangem.features.managetokens.component.preview.PreviewCustomTokenFormComponent
|
||||
|
|
@ -89,7 +89,7 @@ internal fun CustomTokenFormContent(model: CustomTokenFormUM, modifier: Modifier
|
|||
.align(Alignment.BottomCenter)
|
||||
.padding(bottom = TangemTheme.dimens.spacing16 + bottomBarHeight)
|
||||
.fillMaxWidth(),
|
||||
text = stringResource(id = R.string.custom_token_add_token),
|
||||
text = stringResourceSafe(id = R.string.custom_token_add_token),
|
||||
colors = TangemButtonsDefaults.primaryButtonColors,
|
||||
enabled = model.canAddToken,
|
||||
showProgress = model.isValidating,
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@ import androidx.compose.ui.draw.clip
|
|||
import androidx.compose.ui.graphics.RectangleShape
|
||||
import androidx.compose.ui.platform.LocalDensity
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||
|
|
@ -28,6 +27,7 @@ import com.tangem.core.ui.components.currency.icon.CurrencyIconState
|
|||
import com.tangem.core.ui.components.rows.ChainRow
|
||||
import com.tangem.core.ui.components.rows.model.ChainRowUM
|
||||
import com.tangem.core.ui.extensions.resolveReference
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.domain.tokens.model.Network
|
||||
|
|
@ -137,7 +137,7 @@ private fun Header(header: CustomTokenSelectorUM.HeaderUM, modifier: Modifier =
|
|||
modifier = Modifier
|
||||
.padding(top = TangemTheme.dimens.spacing12)
|
||||
.padding(horizontal = TangemTheme.dimens.spacing12),
|
||||
text = stringResource(R.string.add_custom_token_choose_network),
|
||||
text = stringResourceSafe(R.string.add_custom_token_choose_network),
|
||||
style = TangemTheme.typography.subtitle2,
|
||||
color = TangemTheme.colors.text.tertiary,
|
||||
)
|
||||
|
|
@ -189,13 +189,14 @@ private fun CustomDerivationButton(
|
|||
verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing8),
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(id = R.string.custom_token_custom_derivation),
|
||||
text = stringResourceSafe(id = R.string.custom_token_custom_derivation),
|
||||
style = TangemTheme.typography.caption2,
|
||||
color = TangemTheme.colors.text.secondary,
|
||||
)
|
||||
Text(
|
||||
modifier = Modifier.padding(bottom = TangemTheme.dimens.spacing12),
|
||||
text = enteredDerivationPath ?: stringResource(id = R.string.custom_token_custom_derivation_title),
|
||||
text = enteredDerivationPath
|
||||
?: stringResourceSafe(id = R.string.custom_token_custom_derivation_title),
|
||||
style = TangemTheme.typography.body2,
|
||||
color = TangemTheme.colors.text.primary1,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@ import androidx.compose.ui.draw.rotate
|
|||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||
import androidx.compose.ui.platform.LocalDensity
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||
|
|
@ -55,6 +54,7 @@ import com.tangem.core.ui.components.snackbar.TangemSnackbarHost
|
|||
import com.tangem.core.ui.event.EventEffect
|
||||
import com.tangem.core.ui.extensions.resolveReference
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.core.ui.haptic.TangemHapticEffect
|
||||
import com.tangem.core.ui.res.LocalHapticManager
|
||||
import com.tangem.core.ui.res.LocalSnackbarHostState
|
||||
|
|
@ -165,7 +165,7 @@ private fun SaveChangesButton(
|
|||
label = "save_button_visibility",
|
||||
) {
|
||||
TangemButton(
|
||||
text = stringResource(id = R.string.common_save),
|
||||
text = stringResourceSafe(id = R.string.common_save),
|
||||
icon = if (showIcon) {
|
||||
TangemButtonIconPosition.End(R.drawable.ic_tangem_24)
|
||||
} else {
|
||||
|
|
@ -277,7 +277,7 @@ private fun SearchNothingFoundText(modifier: Modifier = Modifier) {
|
|||
contentAlignment = Alignment.Center,
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(R.string.markets_search_token_no_result_title),
|
||||
text = stringResourceSafe(R.string.markets_search_token_no_result_title),
|
||||
style = TangemTheme.typography.caption1,
|
||||
color = TangemTheme.colors.text.tertiary,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ import androidx.compose.runtime.Composable
|
|||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider
|
||||
|
|
@ -20,6 +19,7 @@ import com.tangem.core.ui.components.SecondaryButton
|
|||
import com.tangem.core.ui.components.fields.SearchBar
|
||||
import com.tangem.core.ui.components.snackbar.TangemSnackbarHost
|
||||
import com.tangem.core.ui.event.EventEffect
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.core.ui.res.LocalSnackbarHostState
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
|
|
@ -102,7 +102,7 @@ private fun FloatingActionButton(config: OnboardingManageTokensUM.ActionButtonCo
|
|||
is OnboardingManageTokensUM.ActionButtonConfig.Continue -> ContinueButton(config = config, modifier = modifier)
|
||||
is OnboardingManageTokensUM.ActionButtonConfig.Later -> SecondaryButton(
|
||||
modifier = modifier,
|
||||
text = stringResource(id = R.string.common_later),
|
||||
text = stringResourceSafe(id = R.string.common_later),
|
||||
showProgress = config.showProgress,
|
||||
onClick = config.onClick,
|
||||
)
|
||||
|
|
@ -117,7 +117,7 @@ private fun ContinueButton(
|
|||
if (config.showTangemIcon) {
|
||||
PrimaryButtonIconEnd(
|
||||
modifier = modifier,
|
||||
text = stringResource(id = R.string.common_continue),
|
||||
text = stringResourceSafe(id = R.string.common_continue),
|
||||
iconResId = R.drawable.ic_tangem_24,
|
||||
showProgress = config.showProgress,
|
||||
onClick = config.onClick,
|
||||
|
|
@ -125,7 +125,7 @@ private fun ContinueButton(
|
|||
} else {
|
||||
PrimaryButton(
|
||||
modifier = modifier,
|
||||
text = stringResource(id = R.string.common_continue),
|
||||
text = stringResourceSafe(id = R.string.common_continue),
|
||||
showProgress = config.showProgress,
|
||||
onClick = config.onClick,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@ import androidx.compose.foundation.layout.fillMaxWidth
|
|||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.features.managetokens.impl.R
|
||||
|
||||
|
|
@ -13,7 +13,7 @@ import com.tangem.features.managetokens.impl.R
|
|||
internal fun AddCustomTokenDescription(modifier: Modifier = Modifier) {
|
||||
Text(
|
||||
modifier = modifier.fillMaxWidth(fraction = 0.7f),
|
||||
text = stringResource(id = R.string.custom_token_subtitle),
|
||||
text = stringResourceSafe(id = R.string.custom_token_subtitle),
|
||||
style = TangemTheme.typography.caption2,
|
||||
color = TangemTheme.colors.text.secondary,
|
||||
textAlign = TextAlign.Center,
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
package com.tangem.features.managetokens.ui.dialog
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import com.tangem.core.ui.components.BasicDialog
|
||||
import com.tangem.core.ui.components.DialogButtonUM
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
import com.tangem.core.ui.extensions.resolveReference
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.features.managetokens.impl.R
|
||||
|
||||
@Composable
|
||||
|
|
@ -14,7 +14,7 @@ internal fun CurrencyUnsupportedDialog(title: TextReference, message: TextRefere
|
|||
title = title.resolveReference(),
|
||||
message = message.resolveReference(),
|
||||
confirmButton = DialogButtonUM(
|
||||
title = stringResource(R.string.common_ok),
|
||||
title = stringResourceSafe(R.string.common_ok),
|
||||
onClick = onDismiss,
|
||||
),
|
||||
onDismissDialog = onDismiss,
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ import android.content.res.Configuration
|
|||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.rememberUpdatedState
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||
|
|
@ -12,6 +11,7 @@ import com.tangem.core.ui.components.AdditionalTextInputDialogUM
|
|||
import com.tangem.core.ui.components.DialogButtonUM
|
||||
import com.tangem.core.ui.components.TextInputDialog
|
||||
import com.tangem.core.ui.extensions.resolveReference
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.features.managetokens.component.CustomTokenDerivationInputComponent
|
||||
import com.tangem.features.managetokens.component.preview.PreviewCustomTokenDerivationInputComponent
|
||||
|
|
@ -23,21 +23,21 @@ internal fun CustomDerivationInputDialog(model: CustomDerivationInputUM, onDismi
|
|||
val value by rememberUpdatedState(newValue = model.value)
|
||||
|
||||
TextInputDialog(
|
||||
title = stringResource(id = R.string.custom_token_custom_derivation_title),
|
||||
title = stringResourceSafe(id = R.string.custom_token_custom_derivation_title),
|
||||
fieldValue = value,
|
||||
confirmButton = DialogButtonUM(
|
||||
title = stringResource(id = R.string.common_ok),
|
||||
title = stringResourceSafe(id = R.string.common_ok),
|
||||
enabled = model.isConfirmEnabled,
|
||||
onClick = model.onConfirm,
|
||||
),
|
||||
dismissButton = DialogButtonUM(
|
||||
title = stringResource(id = R.string.common_cancel),
|
||||
title = stringResourceSafe(id = R.string.common_cancel),
|
||||
onClick = onDismiss,
|
||||
),
|
||||
onDismissDialog = onDismiss,
|
||||
onValueChange = model.updateValue,
|
||||
textFieldParams = AdditionalTextInputDialogUM(
|
||||
label = model.error?.resolveReference() ?: stringResource(id = R.string.custom_token_derivation_path),
|
||||
label = model.error?.resolveReference() ?: stringResourceSafe(id = R.string.custom_token_derivation_path),
|
||||
isError = model.error != null,
|
||||
),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
package com.tangem.features.managetokens.ui.dialog
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import com.tangem.core.ui.components.BasicDialog
|
||||
import com.tangem.core.ui.components.DialogButtonUM
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.domain.managetokens.model.ManagedCryptoCurrency
|
||||
import com.tangem.domain.tokens.model.Network
|
||||
import com.tangem.features.managetokens.impl.R
|
||||
|
|
@ -11,18 +11,18 @@ import com.tangem.features.managetokens.impl.R
|
|||
@Composable
|
||||
internal fun HasLinkedTokensWarning(currency: ManagedCryptoCurrency, network: Network, onDismiss: () -> Unit) {
|
||||
BasicDialog(
|
||||
title = stringResource(
|
||||
title = stringResourceSafe(
|
||||
R.string.token_details_unable_hide_alert_title,
|
||||
currency.name,
|
||||
),
|
||||
message = stringResource(
|
||||
message = stringResourceSafe(
|
||||
R.string.token_details_unable_hide_alert_message,
|
||||
currency.name,
|
||||
currency.symbol,
|
||||
network.name,
|
||||
),
|
||||
confirmButton = DialogButtonUM(
|
||||
title = stringResource(R.string.common_ok),
|
||||
title = stringResourceSafe(R.string.common_ok),
|
||||
onClick = onDismiss,
|
||||
),
|
||||
onDismissDialog = onDismiss,
|
||||
|
|
|
|||
|
|
@ -1,27 +1,27 @@
|
|||
package com.tangem.features.managetokens.ui.dialog
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import com.tangem.core.ui.components.BasicDialog
|
||||
import com.tangem.core.ui.components.DialogButtonUM
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.domain.managetokens.model.ManagedCryptoCurrency
|
||||
import com.tangem.features.managetokens.impl.R
|
||||
|
||||
@Composable
|
||||
internal fun HideTokenWarning(currency: ManagedCryptoCurrency, onConfirm: () -> Unit, onDismiss: () -> Unit) {
|
||||
BasicDialog(
|
||||
title = stringResource(
|
||||
title = stringResourceSafe(
|
||||
R.string.token_details_hide_alert_title,
|
||||
currency.name,
|
||||
),
|
||||
message = stringResource(R.string.token_details_hide_alert_message),
|
||||
message = stringResourceSafe(R.string.token_details_hide_alert_message),
|
||||
confirmButton = DialogButtonUM(
|
||||
title = stringResource(R.string.token_details_hide_alert_hide),
|
||||
title = stringResourceSafe(R.string.token_details_hide_alert_hide),
|
||||
warning = true,
|
||||
onClick = onConfirm,
|
||||
),
|
||||
dismissButton = DialogButtonUM(
|
||||
title = stringResource(R.string.common_cancel),
|
||||
title = stringResourceSafe(R.string.common_cancel),
|
||||
onClick = onDismiss,
|
||||
),
|
||||
onDismissDialog = onDismiss,
|
||||
|
|
|
|||
|
|
@ -152,7 +152,7 @@ internal class ManageTokensUiManager(
|
|||
|
||||
private fun copyContractAddress(source: ManagedCryptoCurrency.SourceNetwork) {
|
||||
if (source is ManagedCryptoCurrency.SourceNetwork.Default) {
|
||||
clipboardManager.setText(text = source.contractAddress)
|
||||
clipboardManager.setText(text = source.contractAddress, isSensitive = false)
|
||||
showSnackbarMessage(resourceReference(R.string.contract_address_copied_message))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ import androidx.compose.foundation.layout.fillMaxWidth
|
|||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.SpanStyle
|
||||
import androidx.compose.ui.text.buildAnnotatedString
|
||||
import androidx.compose.ui.text.withStyle
|
||||
|
|
@ -15,6 +14,7 @@ import com.tangem.core.ui.components.TextShimmer
|
|||
import com.tangem.core.ui.extensions.TextReference
|
||||
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
|
||||
import com.tangem.core.ui.utils.PreviewShimmerContainer
|
||||
|
|
@ -34,7 +34,12 @@ internal fun Description(
|
|||
append(description.resolveReference())
|
||||
}
|
||||
withStyle(SpanStyle(color = TangemTheme.colors.text.accent)) {
|
||||
append(" " + stringResource(R.string.common_read_more).replace(' ', StringsSigns.NON_BREAKING_SPACE))
|
||||
append(
|
||||
" " + stringResourceSafe(R.string.common_read_more).replace(
|
||||
' ',
|
||||
StringsSigns.NON_BREAKING_SPACE,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ import androidx.compose.runtime.Composable
|
|||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalDensity
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
|
|
@ -27,10 +26,7 @@ import com.tangem.core.ui.components.buttons.SmallButtonConfig
|
|||
import com.tangem.core.ui.components.currency.icon.CurrencyIconState
|
||||
import com.tangem.core.ui.components.token.TokenItem
|
||||
import com.tangem.core.ui.components.token.state.TokenItemState
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
import com.tangem.core.ui.extensions.resolveReference
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.extensions.stringReference
|
||||
import com.tangem.core.ui.extensions.*
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.features.markets.details.impl.ui.state.ExchangesBottomSheetContent
|
||||
|
|
@ -92,7 +88,7 @@ internal fun ExchangesBottomSheet(config: TangemBottomSheetConfig) {
|
|||
@Composable
|
||||
private fun Title(@StringRes textResId: Int, onBackClick: () -> Unit) {
|
||||
TangemTopAppBar(
|
||||
title = stringResource(id = textResId),
|
||||
title = stringResourceSafe(id = textResId),
|
||||
startButton = TopAppBarButtonUM.Back(onBackClicked = onBackClick),
|
||||
)
|
||||
}
|
||||
|
|
@ -128,7 +124,7 @@ private fun Error(content: ExchangesBottomSheetContent.Error, modifier: Modifier
|
|||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(id = content.message),
|
||||
text = stringResourceSafe(id = content.message),
|
||||
color = TangemTheme.colors.text.tertiary,
|
||||
textAlign = TextAlign.Center,
|
||||
style = TangemTheme.typography.caption1,
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ import androidx.compose.foundation.layout.*
|
|||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
|
@ -16,6 +15,7 @@ import com.tangem.core.ui.components.block.information.InformationBlock
|
|||
import com.tangem.core.ui.components.buttons.chip.Chip
|
||||
import com.tangem.core.ui.components.inputrow.inner.DividerContainer
|
||||
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
|
||||
import com.tangem.core.ui.utils.PreviewShimmerContainer
|
||||
|
|
@ -31,7 +31,7 @@ internal fun LinksBlock(state: LinksUM, modifier: Modifier = Modifier) {
|
|||
contentHorizontalPadding = 0.dp,
|
||||
title = {
|
||||
Text(
|
||||
text = stringResource(id = R.string.markets_token_details_links),
|
||||
text = stringResourceSafe(id = R.string.markets_token_details_links),
|
||||
style = TangemTheme.typography.subtitle2,
|
||||
color = TangemTheme.colors.text.tertiary,
|
||||
maxLines = 1,
|
||||
|
|
@ -41,22 +41,22 @@ internal fun LinksBlock(state: LinksUM, modifier: Modifier = Modifier) {
|
|||
content = {
|
||||
Column {
|
||||
SubBlock(
|
||||
title = stringResource(id = R.string.markets_token_details_official_links),
|
||||
title = stringResourceSafe(id = R.string.markets_token_details_official_links),
|
||||
links = state.officialLinks,
|
||||
onLinkClick = state.onLinkClick,
|
||||
)
|
||||
SubBlock(
|
||||
title = stringResource(id = R.string.markets_token_details_social),
|
||||
title = stringResourceSafe(id = R.string.markets_token_details_social),
|
||||
links = state.social,
|
||||
onLinkClick = state.onLinkClick,
|
||||
)
|
||||
SubBlock(
|
||||
title = stringResource(id = R.string.markets_token_details_repository),
|
||||
title = stringResourceSafe(id = R.string.markets_token_details_repository),
|
||||
links = state.repository,
|
||||
onLinkClick = state.onLinkClick,
|
||||
)
|
||||
SubBlock(
|
||||
title = stringResource(id = R.string.markets_token_details_blockchain_site),
|
||||
title = stringResourceSafe(id = R.string.markets_token_details_blockchain_site),
|
||||
links = state.blockchainSite,
|
||||
onLinkClick = state.onLinkClick,
|
||||
lastBlock = true,
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
package com.tangem.features.markets.details.impl.ui.components
|
||||
|
||||
import android.content.res.Configuration
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import com.tangem.core.ui.components.TextButton
|
||||
|
|
@ -14,6 +15,7 @@ import com.tangem.core.ui.components.block.information.GridItems
|
|||
import com.tangem.core.ui.components.block.information.InformationBlock
|
||||
import com.tangem.core.ui.components.buttons.common.TangemButtonsDefaults
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.core.ui.utils.PreviewShimmerContainer
|
||||
|
|
@ -33,7 +35,7 @@ internal fun MetricsBlock(state: MetricsUM, modifier: Modifier = Modifier) {
|
|||
modifier = modifier,
|
||||
title = {
|
||||
Text(
|
||||
text = stringResource(id = R.string.markets_token_details_metrics),
|
||||
text = stringResourceSafe(id = R.string.markets_token_details_metrics),
|
||||
style = TangemTheme.typography.subtitle2,
|
||||
color = TangemTheme.colors.text.tertiary,
|
||||
maxLines = 1,
|
||||
|
|
|
|||
|
|
@ -2,14 +2,12 @@ package com.tangem.features.markets.details.impl.ui.components
|
|||
|
||||
import android.content.res.Configuration
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.material3.LinearProgressIndicator
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.StrokeCap
|
||||
import androidx.compose.ui.platform.LocalDensity
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
|
|
@ -21,13 +19,14 @@ import com.tangem.core.ui.components.block.information.InformationBlock
|
|||
import com.tangem.core.ui.components.buttons.segmentedbutton.SegmentedButtons
|
||||
import com.tangem.core.ui.components.progressbar.LinearProgressIndicator
|
||||
import com.tangem.core.ui.extensions.resolveReference
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.core.ui.res.TangemAnimations
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.core.ui.utils.PreviewShimmerContainer
|
||||
import com.tangem.domain.markets.PriceChangeInterval
|
||||
import com.tangem.features.markets.details.impl.ui.state.PricePerformanceUM
|
||||
import com.tangem.features.markets.details.impl.ui.getText
|
||||
import com.tangem.features.markets.details.impl.ui.state.PricePerformanceUM
|
||||
import com.tangem.features.markets.impl.R
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
|
||||
|
|
@ -39,7 +38,7 @@ internal fun PricePerformanceBlock(state: PricePerformanceUM, modifier: Modifier
|
|||
modifier = modifier,
|
||||
title = {
|
||||
Text(
|
||||
text = stringResource(id = R.string.markets_token_details_price_performance),
|
||||
text = stringResourceSafe(id = R.string.markets_token_details_price_performance),
|
||||
style = TangemTheme.typography.subtitle2,
|
||||
color = TangemTheme.colors.text.tertiary,
|
||||
maxLines = 1,
|
||||
|
|
@ -106,13 +105,13 @@ private fun Content(state: PricePerformanceUM.Value, modifier: Modifier = Modifi
|
|||
horizontalArrangement = Arrangement.SpaceBetween,
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(R.string.markets_token_details_low),
|
||||
text = stringResourceSafe(R.string.markets_token_details_low),
|
||||
style = TangemTheme.typography.caption2,
|
||||
color = TangemTheme.colors.text.tertiary,
|
||||
)
|
||||
SpacerW8()
|
||||
Text(
|
||||
text = stringResource(R.string.markets_token_details_high),
|
||||
text = stringResourceSafe(R.string.markets_token_details_high),
|
||||
style = TangemTheme.typography.caption2,
|
||||
color = TangemTheme.colors.text.tertiary,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -130,7 +130,7 @@ internal class TokenActionsHandler @AssistedInject constructor(
|
|||
.toImmutableList()
|
||||
val defaultAddress = addresses.firstOrNull()?.value ?: return
|
||||
|
||||
clipboardManager.setText(text = defaultAddress)
|
||||
clipboardManager.setText(text = defaultAddress, isSensitive = true)
|
||||
uiMessageSender.send(SnackbarMessage(resourceReference(R.string.wallet_notification_address_copied)))
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@ import androidx.compose.ui.Modifier
|
|||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.layout.onGloballyPositioned
|
||||
import androidx.compose.ui.platform.LocalDensity
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.res.vectorResource
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
|
|
@ -37,6 +36,7 @@ import com.tangem.core.ui.components.currency.icon.CoinIcon
|
|||
import com.tangem.core.ui.components.rows.ArrowRow
|
||||
import com.tangem.core.ui.components.rows.BlockchainRow
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.core.ui.haptic.TangemHapticEffect
|
||||
import com.tangem.core.ui.res.LocalHapticManager
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
|
|
@ -154,7 +154,7 @@ private fun ContinueButton(
|
|||
)
|
||||
.navigationBarsPadding()
|
||||
.fillMaxWidth(),
|
||||
text = stringResource(R.string.common_continue),
|
||||
text = stringResourceSafe(R.string.common_continue),
|
||||
icon = if (enabled && isTangemIconVisible) {
|
||||
TangemButtonIconPosition.End(R.drawable.ic_tangem_24)
|
||||
} else {
|
||||
|
|
@ -178,7 +178,7 @@ private fun NetworkSelection(state: SelectNetworkUM, modifier: Modifier = Modifi
|
|||
modifier = modifier,
|
||||
title = {
|
||||
Text(
|
||||
text = stringResource(R.string.markets_select_network),
|
||||
text = stringResourceSafe(R.string.markets_select_network),
|
||||
style = TangemTheme.typography.subtitle2,
|
||||
color = TangemTheme.colors.text.tertiary,
|
||||
)
|
||||
|
|
@ -279,7 +279,7 @@ private fun ScanWalletWarning(modifier: Modifier = Modifier) {
|
|||
contentDescription = null,
|
||||
)
|
||||
Text(
|
||||
text = stringResource(R.string.markets_generate_addresses_notification),
|
||||
text = stringResourceSafe(R.string.markets_generate_addresses_notification),
|
||||
style = TangemTheme.typography.caption2,
|
||||
color = TangemTheme.colors.text.tertiary,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ import androidx.compose.runtime.Composable
|
|||
import androidx.compose.runtime.key
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import androidx.compose.ui.util.fastForEachIndexed
|
||||
|
|
@ -24,6 +23,7 @@ import com.tangem.core.ui.components.buttons.SecondarySmallButton
|
|||
import com.tangem.core.ui.components.buttons.SmallButtonConfig
|
||||
import com.tangem.core.ui.components.buttons.common.TangemButtonIconPosition
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.features.markets.impl.R
|
||||
|
|
@ -68,7 +68,7 @@ internal fun MyPortfolio(state: MyPortfolioUM, modifier: Modifier = Modifier) {
|
|||
@Composable
|
||||
private fun Title() {
|
||||
Text(
|
||||
text = stringResource(R.string.markets_common_my_portfolio),
|
||||
text = stringResourceSafe(R.string.markets_common_my_portfolio),
|
||||
style = TangemTheme.typography.subtitle2,
|
||||
color = TangemTheme.colors.text.tertiary,
|
||||
)
|
||||
|
|
@ -150,7 +150,7 @@ fun UnavailableAssetForWallet(modifier: Modifier = Modifier) {
|
|||
private fun UnavailableContent(@StringRes textId: Int, modifier: Modifier = Modifier) {
|
||||
Text(
|
||||
modifier = modifier,
|
||||
text = stringResource(textId),
|
||||
text = stringResourceSafe(textId),
|
||||
style = TangemTheme.typography.body2,
|
||||
color = TangemTheme.colors.text.tertiary,
|
||||
)
|
||||
|
|
@ -163,14 +163,14 @@ private fun AddFirstTokenContent(state: MyPortfolioUM.AddFirstToken, modifier: M
|
|||
verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing12),
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(R.string.markets_add_to_my_portfolio_description),
|
||||
text = stringResourceSafe(R.string.markets_add_to_my_portfolio_description),
|
||||
style = TangemTheme.typography.body2,
|
||||
color = TangemTheme.colors.text.tertiary,
|
||||
)
|
||||
|
||||
PrimaryButton(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
text = stringResource(R.string.markets_add_to_portfolio_button),
|
||||
text = stringResourceSafe(R.string.markets_add_to_portfolio_button),
|
||||
onClick = state.onAddClick,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
package com.tangem.features.markets.portfolio.impl.ui
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import com.tangem.core.ui.components.BasicDialog
|
||||
import com.tangem.core.ui.components.DialogButtonUM
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
import com.tangem.core.ui.extensions.resolveReference
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.features.markets.impl.R
|
||||
|
||||
@Composable
|
||||
|
|
@ -19,7 +19,7 @@ internal fun WarningDialog(
|
|||
title = title.resolveReference(),
|
||||
message = message.resolveReference(),
|
||||
confirmButton = DialogButtonUM(
|
||||
title = stringResource(R.string.common_ok),
|
||||
title = stringResourceSafe(R.string.common_ok),
|
||||
onClick = onDismiss,
|
||||
),
|
||||
onDismissDialog = onDismiss,
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ import androidx.compose.runtime.Composable
|
|||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.res.vectorResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import com.tangem.common.ui.charts.MarketChartMini
|
||||
|
|
@ -21,6 +20,7 @@ import com.tangem.core.ui.components.TextShimmer
|
|||
import com.tangem.core.ui.components.block.BlockCard
|
||||
import com.tangem.core.ui.components.marketprice.PriceChangeInPercent
|
||||
import com.tangem.core.ui.components.marketprice.PriceChangeType
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.features.markets.details.impl.model.formatter.toChartType
|
||||
|
|
@ -75,7 +75,7 @@ private fun LeftSide(
|
|||
verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing4),
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(id = R.string.wallet_marketplace_block_title, symbol),
|
||||
text = stringResourceSafe(id = R.string.wallet_marketplace_block_title, symbol),
|
||||
color = TangemTheme.colors.text.tertiary,
|
||||
style = TangemTheme.typography.subtitle2,
|
||||
)
|
||||
|
|
@ -99,7 +99,7 @@ private fun LeftSide(
|
|||
)
|
||||
Text(
|
||||
modifier = Modifier.alignByBaseline(),
|
||||
text = stringResource(id = R.string.wallet_marketprice_block_update_time),
|
||||
text = stringResourceSafe(id = R.string.wallet_marketprice_block_update_time),
|
||||
style = TangemTheme.typography.body2,
|
||||
color = TangemTheme.colors.text.tertiary,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ import androidx.compose.ui.layout.onGloballyPositioned
|
|||
import androidx.compose.ui.platform.LocalDensity
|
||||
import androidx.compose.ui.platform.LocalFocusManager
|
||||
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
|
@ -33,6 +32,7 @@ import com.tangem.core.ui.components.keyboardAsState
|
|||
import com.tangem.core.ui.event.consumedEvent
|
||||
import com.tangem.core.ui.extensions.resolveReference
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.core.ui.res.LocalMainBottomSheetColor
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
|
|
@ -149,9 +149,9 @@ private fun Title(isInSearchMode: Boolean, modifier: Modifier = Modifier) {
|
|||
Text(
|
||||
modifier = modifier,
|
||||
text = if (isInSearchMode) {
|
||||
stringResource(id = R.string.markets_search_result_title)
|
||||
stringResourceSafe(id = R.string.markets_search_result_title)
|
||||
} else {
|
||||
stringResource(id = R.string.markets_common_title)
|
||||
stringResourceSafe(id = R.string.markets_common_title)
|
||||
},
|
||||
style = TangemTheme.typography.h3,
|
||||
color = TangemTheme.colors.text.primary1,
|
||||
|
|
|
|||
|
|
@ -10,12 +10,12 @@ import androidx.compose.runtime.*
|
|||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalDensity
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import com.tangem.core.ui.components.buttons.SecondarySmallButton
|
||||
import com.tangem.core.ui.components.buttons.SmallButtonConfig
|
||||
import com.tangem.core.ui.components.list.InfiniteListHandler
|
||||
import com.tangem.core.ui.event.EventEffect
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.features.markets.impl.R
|
||||
import com.tangem.features.markets.tokenlist.impl.ui.state.ListUM
|
||||
|
|
@ -160,7 +160,7 @@ private fun ShowTokensUnder100kItem(onShowTokensClick: () -> Unit, modifier: Mod
|
|||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(R.string.markets_search_see_tokens_under_100k),
|
||||
text = stringResourceSafe(R.string.markets_search_see_tokens_under_100k),
|
||||
style = TangemTheme.typography.caption1,
|
||||
color = TangemTheme.colors.text.tertiary,
|
||||
)
|
||||
|
|
@ -180,7 +180,7 @@ private fun SearchNothingFoundText(modifier: Modifier = Modifier) {
|
|||
contentAlignment = Alignment.Center,
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(R.string.markets_search_token_no_result_title),
|
||||
text = stringResourceSafe(R.string.markets_search_token_no_result_title),
|
||||
style = TangemTheme.typography.caption1,
|
||||
color = TangemTheme.colors.text.tertiary,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -7,11 +7,11 @@ import androidx.compose.material3.Text
|
|||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import com.tangem.core.ui.components.buttons.SecondarySmallButton
|
||||
import com.tangem.core.ui.components.buttons.SmallButtonConfig
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.features.markets.impl.R
|
||||
|
|
@ -24,7 +24,7 @@ internal fun UnableToLoadData(onRetryClick: () -> Unit, modifier: Modifier = Mod
|
|||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(R.string.markets_loading_error_title),
|
||||
text = stringResourceSafe(R.string.markets_loading_error_title),
|
||||
style = TangemTheme.typography.caption1,
|
||||
color = TangemTheme.colors.text.tertiary,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@ import androidx.compose.ui.Alignment
|
|||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.res.vectorResource
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.airbnb.lottie.compose.LottieAnimation
|
||||
|
|
@ -17,6 +17,7 @@ import com.airbnb.lottie.compose.LottieCompositionSpec
|
|||
import com.airbnb.lottie.compose.animateLottieCompositionAsState
|
||||
import com.airbnb.lottie.compose.rememberLottieComposition
|
||||
import com.tangem.core.ui.components.*
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.features.onboarding.v2.impl.R
|
||||
|
|
@ -49,16 +50,17 @@ internal fun OnboardingDone(onContinueClick: () -> Unit, modifier: Modifier = Mo
|
|||
SpacerH32()
|
||||
Text(
|
||||
modifier = Modifier.padding(horizontal = 32.dp),
|
||||
text = stringResource(R.string.onboarding_done_header),
|
||||
text = stringResourceSafe(R.string.onboarding_done_header),
|
||||
style = TangemTheme.typography.h2,
|
||||
color = TangemTheme.colors.text.primary1,
|
||||
)
|
||||
SpacerH12()
|
||||
Text(
|
||||
modifier = Modifier.padding(horizontal = 32.dp),
|
||||
text = stringResource(R.string.onboarding_subtitle_success_tangem_wallet_onboarding),
|
||||
text = stringResourceSafe(R.string.onboarding_subtitle_success_tangem_wallet_onboarding),
|
||||
style = TangemTheme.typography.body1,
|
||||
color = TangemTheme.colors.text.secondary,
|
||||
textAlign = TextAlign.Center,
|
||||
)
|
||||
SpacerH(72.dp)
|
||||
}
|
||||
|
|
@ -69,7 +71,7 @@ internal fun OnboardingDone(onContinueClick: () -> Unit, modifier: Modifier = Mo
|
|||
.padding(horizontal = 16.dp)
|
||||
.padding(bottom = 16.dp)
|
||||
.navigationBarsPadding(),
|
||||
text = stringResource(R.string.onboarding_button_continue_wallet),
|
||||
text = stringResourceSafe(R.string.onboarding_button_continue_wallet),
|
||||
onClick = onContinueClick,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ import com.tangem.features.onboarding.v2.multiwallet.impl.child.backup.MultiWall
|
|||
import com.tangem.features.onboarding.v2.multiwallet.impl.child.chooseoption.Wallet1ChooseOptionComponent
|
||||
import com.tangem.features.onboarding.v2.multiwallet.impl.child.createwallet.MultiWalletCreateWalletComponent
|
||||
import com.tangem.features.onboarding.v2.multiwallet.impl.child.finalize.MultiWalletFinalizeComponent
|
||||
import com.tangem.features.onboarding.v2.multiwallet.impl.child.scanprimary.Wallet1ScanPrimaryComponent
|
||||
import com.tangem.features.onboarding.v2.multiwallet.impl.child.seedphrase.MultiWalletSeedPhraseComponent
|
||||
import com.tangem.features.onboarding.v2.multiwallet.impl.model.OnboardingMultiWalletModel
|
||||
import com.tangem.features.onboarding.v2.multiwallet.impl.model.OnboardingMultiWalletState
|
||||
|
|
@ -59,6 +60,7 @@ internal class DefaultOnboardingMultiWalletComponent @AssistedInject constructor
|
|||
CreateWallet -> WalletArtworksState.Folded
|
||||
ChooseBackupOption -> WalletArtworksState.Fan
|
||||
SeedPhrase -> WalletArtworksState.Folded
|
||||
ScanPrimary -> WalletArtworksState.Folded
|
||||
AddBackupDevice -> WalletArtworksState.Unfold(WalletArtworksState.Unfold.Step.First)
|
||||
Finalize -> WalletArtworksState.Stack()
|
||||
Done -> error("Done state should not be used as starting state")
|
||||
|
|
@ -93,11 +95,14 @@ internal class DefaultOnboardingMultiWalletComponent @AssistedInject constructor
|
|||
)
|
||||
|
||||
val backButtonClickFlow = MutableSharedFlow<Unit>()
|
||||
|
||||
override val innerNavigation: InnerNavigation = object : InnerNavigation {
|
||||
override val state = innerNavigationStateFlow
|
||||
|
||||
override fun pop(onComplete: (Boolean) -> Unit) {
|
||||
if (childStack.active.configuration == SeedPhrase) {
|
||||
val config = childStack.active.configuration
|
||||
|
||||
if (config == SeedPhrase || config == Finalize) {
|
||||
componentScope.launch { backButtonClickFlow.emit(Unit) }
|
||||
} else {
|
||||
model.onBack()
|
||||
|
|
@ -152,6 +157,11 @@ internal class DefaultOnboardingMultiWalletComponent @AssistedInject constructor
|
|||
backButtonClickFlow = backButtonClickFlow,
|
||||
onBack = { stackNavigation.pop() },
|
||||
)
|
||||
ScanPrimary -> Wallet1ScanPrimaryComponent(
|
||||
context = childContext,
|
||||
params = childParams,
|
||||
onDone = { handleNavigationEvent(AddBackupDevice) },
|
||||
)
|
||||
AddBackupDevice -> MultiWalletBackupComponent(
|
||||
context = childContext,
|
||||
params = childParams,
|
||||
|
|
@ -160,6 +170,8 @@ internal class DefaultOnboardingMultiWalletComponent @AssistedInject constructor
|
|||
Finalize -> MultiWalletFinalizeComponent(
|
||||
context = childContext,
|
||||
params = childParams,
|
||||
backButtonClickFlow = backButtonClickFlow,
|
||||
onBack = { model.onBack() },
|
||||
onEvent = ::handleFinalizeComponentEvent,
|
||||
)
|
||||
Done -> error("Unexpected Done state")
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package com.tangem.features.onboarding.v2.multiwallet.impl.child.accesscode.model
|
||||
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.ui.text.input.TextFieldValue
|
||||
import com.tangem.core.analytics.api.AnalyticsEventHandler
|
||||
import com.tangem.core.decompose.di.ComponentScoped
|
||||
|
|
@ -20,6 +21,7 @@ import javax.inject.Inject
|
|||
|
||||
private const val MINIMUM_ACCESS_CODE_LENGTH = 4
|
||||
|
||||
@Stable
|
||||
@ComponentScoped
|
||||
internal class MultiWalletAccessCodeModel @Inject constructor(
|
||||
paramsContainer: ParamsContainer,
|
||||
|
|
|
|||
|
|
@ -4,12 +4,12 @@ import androidx.compose.animation.AnimatedContent
|
|||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.tangem.core.ui.components.PrimaryButton
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheet
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfigContent
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.core.ui.res.TangemAnimations
|
||||
import com.tangem.features.onboarding.v2.impl.R
|
||||
import com.tangem.features.onboarding.v2.multiwallet.impl.child.accesscode.ui.state.MultiWalletAccessCodeUM
|
||||
|
|
@ -65,9 +65,9 @@ private fun Content(state: MultiWalletAccessCodeUM, modifier: Modifier = Modifie
|
|||
.padding(start = 16.dp, end = 16.dp, bottom = 16.dp)
|
||||
.imePadding(),
|
||||
text = if (state.step == ConfirmAccessCode) {
|
||||
stringResource(R.string.common_confirm)
|
||||
stringResourceSafe(R.string.common_confirm)
|
||||
} else {
|
||||
stringResource(R.string.common_continue)
|
||||
stringResourceSafe(R.string.common_continue)
|
||||
},
|
||||
onClick = state.onContinue,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,9 @@
|
|||
package com.tangem.features.onboarding.v2.multiwallet.impl.child.accesscode.ui
|
||||
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
|
|
@ -9,12 +12,12 @@ import androidx.compose.ui.Alignment
|
|||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.focus.FocusRequester
|
||||
import androidx.compose.ui.focus.focusRequester
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.input.PasswordVisualTransformation
|
||||
import androidx.compose.ui.text.input.VisualTransformation
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.tangem.core.ui.components.OutlineTextFieldWithIcon
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.features.onboarding.v2.impl.R
|
||||
|
|
@ -35,17 +38,17 @@ internal fun MultiWalletAccessCodeEnter(
|
|||
) {
|
||||
Text(
|
||||
text = if (reEnterAccessCodeState) {
|
||||
stringResource(R.string.onboarding_access_code_repeat_code_title)
|
||||
stringResourceSafe(R.string.onboarding_access_code_repeat_code_title)
|
||||
} else {
|
||||
stringResource(R.string.onboarding_access_code_intro_title)
|
||||
stringResourceSafe(R.string.onboarding_access_code_intro_title)
|
||||
},
|
||||
style = TangemTheme.typography.subtitle1,
|
||||
)
|
||||
Text(
|
||||
text = if (reEnterAccessCodeState) {
|
||||
stringResource(R.string.onboarding_access_code_repeat_code_hint)
|
||||
stringResourceSafe(R.string.onboarding_access_code_repeat_code_hint)
|
||||
} else {
|
||||
stringResource(R.string.onboarding_access_code_hint)
|
||||
stringResourceSafe(R.string.onboarding_access_code_hint)
|
||||
},
|
||||
style = TangemTheme.typography.body1,
|
||||
)
|
||||
|
|
@ -73,7 +76,7 @@ internal fun MultiWalletAccessCodeEnter(
|
|||
} else {
|
||||
state.onAccessCodeFirstChange
|
||||
},
|
||||
label = stringResource(id = R.string.onboarding_wallet_info_title_third),
|
||||
label = stringResourceSafe(id = R.string.onboarding_wallet_info_title_third),
|
||||
isError = state.codesNotMatchError || state.atLeast4CharError,
|
||||
visualTransformation = if (state.accessCodeHidden) {
|
||||
PasswordVisualTransformation()
|
||||
|
|
@ -82,9 +85,9 @@ internal fun MultiWalletAccessCodeEnter(
|
|||
},
|
||||
caption = when {
|
||||
state.codesNotMatchError && reEnterAccessCodeState ->
|
||||
stringResource(R.string.onboarding_access_codes_doesnt_match)
|
||||
stringResourceSafe(R.string.onboarding_access_codes_doesnt_match)
|
||||
state.atLeast4CharError && !reEnterAccessCodeState ->
|
||||
stringResource(R.string.onboarding_access_code_too_short)
|
||||
stringResourceSafe(R.string.onboarding_access_code_too_short)
|
||||
else -> null
|
||||
},
|
||||
)
|
||||
|
|
|
|||
|
|
@ -8,12 +8,12 @@ import androidx.compose.runtime.Composable
|
|||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.res.vectorResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.tangem.core.ui.components.SpacerH
|
||||
import com.tangem.core.ui.components.SpacerW
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.features.onboarding.v2.impl.R
|
||||
|
|
@ -26,7 +26,7 @@ internal fun MultiWalletAccessCodeIntro(modifier: Modifier = Modifier) {
|
|||
verticalArrangement = Arrangement.spacedBy(12.dp),
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(R.string.onboarding_access_code_intro_title),
|
||||
text = stringResourceSafe(R.string.onboarding_access_code_intro_title),
|
||||
style = TangemTheme.typography.h2,
|
||||
)
|
||||
Icon(
|
||||
|
|
@ -41,18 +41,18 @@ internal fun MultiWalletAccessCodeIntro(modifier: Modifier = Modifier) {
|
|||
verticalArrangement = Arrangement.spacedBy(24.dp),
|
||||
) {
|
||||
DescriptionItem(
|
||||
title = stringResource(R.string.onboarding_access_code_feature_1_title),
|
||||
body = stringResource(R.string.onboarding_access_code_feature_1_description),
|
||||
title = stringResourceSafe(R.string.onboarding_access_code_feature_1_title),
|
||||
body = stringResourceSafe(R.string.onboarding_access_code_feature_1_description),
|
||||
iconRes = R.drawable.ic_feature_1,
|
||||
)
|
||||
DescriptionItem(
|
||||
title = stringResource(R.string.onboarding_access_code_feature_2_title),
|
||||
body = stringResource(R.string.onboarding_access_code_feature_2_description),
|
||||
title = stringResourceSafe(R.string.onboarding_access_code_feature_2_title),
|
||||
body = stringResourceSafe(R.string.onboarding_access_code_feature_2_description),
|
||||
iconRes = R.drawable.ic_feature_2,
|
||||
)
|
||||
DescriptionItem(
|
||||
title = stringResource(R.string.onboarding_access_code_feature_3_title),
|
||||
body = stringResource(R.string.onboarding_access_code_feature_3_description),
|
||||
title = stringResourceSafe(R.string.onboarding_access_code_feature_3_title),
|
||||
body = stringResourceSafe(R.string.onboarding_access_code_feature_3_description),
|
||||
iconRes = R.drawable.ic_feature_3,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@ import com.tangem.core.decompose.context.AppComponentContext
|
|||
import com.tangem.core.decompose.model.getOrCreateModel
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.features.onboarding.v2.impl.R
|
||||
import com.tangem.features.onboarding.v2.multiwallet.impl.child.MultiWalletChildParams
|
||||
import com.tangem.features.onboarding.v2.multiwallet.impl.child.MultiWalletChildComponent
|
||||
import com.tangem.features.onboarding.v2.multiwallet.impl.child.MultiWalletChildParams
|
||||
import com.tangem.features.onboarding.v2.multiwallet.impl.child.backup.model.MultiWalletBackupModel
|
||||
import com.tangem.features.onboarding.v2.multiwallet.impl.child.backup.ui.MultiWalletBackup
|
||||
import kotlinx.coroutines.flow.update
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package com.tangem.features.onboarding.v2.multiwallet.impl.child.backup.model
|
||||
|
||||
import androidx.compose.runtime.Stable
|
||||
import com.google.firebase.crashlytics.FirebaseCrashlytics
|
||||
import com.tangem.common.CompletionResult
|
||||
import com.tangem.common.core.TangemSdkError
|
||||
|
|
@ -28,6 +29,7 @@ import kotlinx.coroutines.flow.update
|
|||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
||||
@Stable
|
||||
@ComponentScoped
|
||||
class MultiWalletBackupModel @Inject constructor(
|
||||
paramsContainer: ParamsContainer,
|
||||
|
|
@ -82,15 +84,16 @@ class MultiWalletBackupModel @Inject constructor(
|
|||
}
|
||||
|
||||
private fun startBackupWallet() {
|
||||
if (state.value.numberOfBackupCards == 0) {
|
||||
if (state.value.numberOfBackupCards == 0 && scanResponse.primaryCard != null) {
|
||||
backupService.discardSavedBackup()
|
||||
}
|
||||
val primaryCard = scanResponse.primaryCard
|
||||
|
||||
val primaryCard = scanResponse.primaryCard
|
||||
if (primaryCard != null) {
|
||||
backupService.setPrimaryCard(primaryCard)
|
||||
addBackupCardWithService()
|
||||
}
|
||||
|
||||
addBackupCardWithService()
|
||||
}
|
||||
|
||||
private fun setNumberOfBackupCards(number: Int) {
|
||||
|
|
|
|||
|
|
@ -1,17 +1,22 @@
|
|||
package com.tangem.features.onboarding.v2.multiwallet.impl.child.backup.ui
|
||||
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.tangem.core.ui.components.*
|
||||
import com.tangem.core.ui.components.BasicDialog
|
||||
import com.tangem.core.ui.components.DialogButtonUM
|
||||
import com.tangem.core.ui.components.PrimaryButton
|
||||
import com.tangem.core.ui.components.SecondaryButtonIconEnd
|
||||
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
|
||||
import com.tangem.features.onboarding.v2.impl.R
|
||||
|
|
@ -55,7 +60,8 @@ private fun ColumnScope.Content(state: MultiWalletBackupUM) {
|
|||
Column(
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(start = 32.dp, end = 32.dp, bottom = 74.dp)
|
||||
.verticalScroll(rememberScrollState())
|
||||
.padding(start = 32.dp, end = 32.dp, bottom = 16.dp)
|
||||
.weight(1f),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
|
|
@ -83,7 +89,7 @@ private fun ColumnScope.Content(state: MultiWalletBackupUM) {
|
|||
iconResId = R.drawable.ic_tangem_24,
|
||||
enabled = state.addBackupButtonEnabled,
|
||||
showProgress = state.addBackupButtonLoading,
|
||||
text = stringResource(R.string.onboarding_button_add_backup_card),
|
||||
text = stringResourceSafe(R.string.onboarding_button_add_backup_card),
|
||||
onClick = state.onAddBackupClick,
|
||||
)
|
||||
|
||||
|
|
@ -91,7 +97,7 @@ private fun ColumnScope.Content(state: MultiWalletBackupUM) {
|
|||
modifier = Modifier
|
||||
.padding(start = 16.dp, end = 16.dp, bottom = 16.dp)
|
||||
.fillMaxWidth(),
|
||||
text = stringResource(R.string.onboarding_button_finalize_backup),
|
||||
text = stringResourceSafe(R.string.onboarding_button_finalize_backup),
|
||||
enabled = state.finalizeButtonEnabled,
|
||||
onClick = state.onFinalizeButtonClick,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ class Wallet1ChooseOptionComponent(
|
|||
}
|
||||
|
||||
params.parentParams.titleProvider.changeTitle(
|
||||
text = resourceReference(R.string.onboarding_create_wallet_header),
|
||||
text = resourceReference(R.string.onboarding_getting_started),
|
||||
)
|
||||
|
||||
componentScope.launch {
|
||||
|
|
@ -45,6 +45,7 @@ class Wallet1ChooseOptionComponent(
|
|||
@Composable
|
||||
override fun Content(modifier: Modifier) {
|
||||
Wallet1ChooseOption(
|
||||
canSkipBackup = model.canSkipBackup,
|
||||
onBackupClick = {
|
||||
onNextStep(OnboardingMultiWalletState.Step.AddBackupDevice)
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,10 +1,12 @@
|
|||
package com.tangem.features.onboarding.v2.multiwallet.impl.child.chooseoption.model
|
||||
|
||||
import androidx.compose.runtime.Stable
|
||||
import com.tangem.core.analytics.api.AnalyticsEventHandler
|
||||
import com.tangem.core.decompose.di.ComponentScoped
|
||||
import com.tangem.core.decompose.model.Model
|
||||
import com.tangem.core.decompose.model.ParamsContainer
|
||||
import com.tangem.domain.card.repository.CardRepository
|
||||
import com.tangem.domain.common.TapWorkarounds.canSkipBackup
|
||||
import com.tangem.domain.models.scan.ScanResponse
|
||||
import com.tangem.domain.wallets.builder.UserWalletBuilder
|
||||
import com.tangem.domain.wallets.models.UserWallet
|
||||
|
|
@ -18,6 +20,7 @@ import kotlinx.coroutines.flow.update
|
|||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
||||
@Stable
|
||||
@ComponentScoped
|
||||
internal class Wallet1ChooseOptionModel @Inject constructor(
|
||||
override val dispatchers: CoroutineDispatcherProvider,
|
||||
|
|
@ -36,6 +39,8 @@ internal class Wallet1ChooseOptionModel @Inject constructor(
|
|||
analyticsHandler.send(OnboardingEvent.Backup.ScreenOpened)
|
||||
}
|
||||
|
||||
val canSkipBackup = params.multiWalletState.value.currentScanResponse.card.canSkipBackup
|
||||
|
||||
fun onSkipClick() {
|
||||
if (skipClicked) return
|
||||
skipClicked = true
|
||||
|
|
|
|||
|
|
@ -1,20 +1,29 @@
|
|||
package com.tangem.features.onboarding.v2.multiwallet.impl.child.chooseoption.ui
|
||||
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.tangem.core.ui.components.PrimaryButtonIconEnd
|
||||
import com.tangem.core.ui.components.PrimaryButton
|
||||
import com.tangem.core.ui.components.SecondaryButton
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.features.onboarding.v2.impl.R
|
||||
|
||||
@Composable
|
||||
fun Wallet1ChooseOption(onSkipClick: () -> Unit, onBackupClick: () -> Unit, modifier: Modifier = Modifier) {
|
||||
fun Wallet1ChooseOption(
|
||||
canSkipBackup: Boolean,
|
||||
onSkipClick: () -> Unit,
|
||||
onBackupClick: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
Column(
|
||||
modifier = modifier
|
||||
.fillMaxSize()
|
||||
|
|
@ -26,12 +35,13 @@ fun Wallet1ChooseOption(onSkipClick: () -> Unit, onBackupClick: () -> Unit, modi
|
|||
Column(
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(start = 32.dp, end = 32.dp, bottom = 24.dp)
|
||||
.verticalScroll(rememberScrollState())
|
||||
.padding(start = 32.dp, end = 32.dp, bottom = 16.dp)
|
||||
.weight(1f),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(R.string.onboarding_create_wallet_header),
|
||||
text = stringResourceSafe(R.string.onboarding_wallet_info_title_first),
|
||||
style = TangemTheme.typography.h2,
|
||||
color = TangemTheme.colors.text.primary1,
|
||||
textAlign = TextAlign.Center,
|
||||
|
|
@ -39,7 +49,7 @@ fun Wallet1ChooseOption(onSkipClick: () -> Unit, onBackupClick: () -> Unit, modi
|
|||
)
|
||||
|
||||
Text(
|
||||
text = stringResource(R.string.onboarding_create_wallet_body),
|
||||
text = stringResourceSafe(R.string.onboarding_wallet_info_subtitle_first),
|
||||
style = TangemTheme.typography.body1,
|
||||
color = TangemTheme.colors.text.secondary,
|
||||
textAlign = TextAlign.Center,
|
||||
|
|
@ -47,21 +57,35 @@ fun Wallet1ChooseOption(onSkipClick: () -> Unit, onBackupClick: () -> Unit, modi
|
|||
)
|
||||
}
|
||||
|
||||
PrimaryButtonIconEnd(
|
||||
PrimaryButton(
|
||||
modifier = Modifier
|
||||
.padding(start = 16.dp, end = 16.dp, bottom = 12.dp)
|
||||
.fillMaxWidth(),
|
||||
iconResId = R.drawable.ic_tangem_24,
|
||||
text = stringResource(R.string.onboarding_button_backup_now),
|
||||
text = stringResourceSafe(R.string.onboarding_button_backup_now),
|
||||
onClick = onBackupClick,
|
||||
)
|
||||
|
||||
SecondaryButton(
|
||||
modifier = Modifier
|
||||
.padding(start = 16.dp, end = 16.dp, bottom = 16.dp)
|
||||
.fillMaxWidth(),
|
||||
text = stringResource(R.string.onboarding_button_skip_backup),
|
||||
onClick = onSkipClick,
|
||||
if (canSkipBackup) {
|
||||
SecondaryButton(
|
||||
modifier = Modifier
|
||||
.padding(start = 16.dp, end = 16.dp, bottom = 16.dp)
|
||||
.fillMaxWidth(),
|
||||
text = stringResourceSafe(R.string.onboarding_button_skip_backup),
|
||||
onClick = onSkipClick,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(showBackground = true)
|
||||
@Composable
|
||||
private fun Preview() {
|
||||
TangemThemePreview {
|
||||
Wallet1ChooseOption(
|
||||
canSkipBackup = true,
|
||||
onSkipClick = {},
|
||||
onBackupClick = {},
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -4,6 +4,7 @@ import androidx.compose.runtime.Composable
|
|||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.arkivanov.essenty.lifecycle.doOnStart
|
||||
import com.tangem.core.decompose.context.AppComponentContext
|
||||
import com.tangem.core.decompose.model.getOrCreateModel
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
|
|
@ -25,17 +26,19 @@ internal class MultiWalletCreateWalletComponent(
|
|||
private val model: MultiWalletCreateWalletModel = getOrCreateModel(params)
|
||||
|
||||
init {
|
||||
params.innerNavigation.update {
|
||||
it.copy(
|
||||
stackSize = 2,
|
||||
stackMaxSize = 8,
|
||||
lifecycle.doOnStart {
|
||||
params.innerNavigation.update {
|
||||
it.copy(
|
||||
stackSize = 2,
|
||||
stackMaxSize = 8,
|
||||
)
|
||||
}
|
||||
|
||||
params.parentParams.titleProvider.changeTitle(
|
||||
text = resourceReference(R.string.onboarding_create_wallet_header),
|
||||
)
|
||||
}
|
||||
|
||||
params.parentParams.titleProvider.changeTitle(
|
||||
text = resourceReference(R.string.onboarding_create_wallet_header),
|
||||
)
|
||||
|
||||
componentScope.launch {
|
||||
model.onDone.collect(onNextStep)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package com.tangem.features.onboarding.v2.multiwallet.impl.child.createwallet.model
|
||||
|
||||
import androidx.compose.runtime.Stable
|
||||
import com.tangem.common.CompletionResult
|
||||
import com.tangem.common.core.TangemSdkError
|
||||
import com.tangem.core.analytics.api.AnalyticsEventHandler
|
||||
|
|
@ -11,12 +12,17 @@ import com.tangem.domain.card.repository.CardRepository
|
|||
import com.tangem.domain.feedback.GetCardInfoUseCase
|
||||
import com.tangem.domain.feedback.SendFeedbackEmailUseCase
|
||||
import com.tangem.domain.feedback.models.FeedbackEmailType
|
||||
import com.tangem.domain.models.scan.ScanResponse
|
||||
import com.tangem.domain.wallets.builder.UserWalletBuilder
|
||||
import com.tangem.domain.wallets.models.UserWallet
|
||||
import com.tangem.domain.wallets.usecase.GenerateWalletNameUseCase
|
||||
import com.tangem.domain.wallets.usecase.SaveWalletUseCase
|
||||
import com.tangem.features.onboarding.v2.impl.R
|
||||
import com.tangem.features.onboarding.v2.multiwallet.impl.analytics.OnboardingEvent
|
||||
import com.tangem.features.onboarding.v2.multiwallet.impl.child.MultiWalletChildParams
|
||||
import com.tangem.features.onboarding.v2.multiwallet.impl.child.createwallet.ui.state.MultiWalletCreateWalletUM
|
||||
import com.tangem.features.onboarding.v2.multiwallet.impl.common.ui.resetCardDialog
|
||||
import com.tangem.features.onboarding.v2.multiwallet.impl.model.OnboardingMultiWalletState
|
||||
import com.tangem.features.onboarding.v2.multiwallet.impl.model.OnboardingMultiWalletState.Step
|
||||
import com.tangem.sdk.api.TangemSdkManager
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
|
|
@ -27,6 +33,7 @@ import kotlinx.coroutines.launch
|
|||
import javax.inject.Inject
|
||||
|
||||
@Suppress("LongParameterList")
|
||||
@Stable
|
||||
@ComponentScoped
|
||||
internal class MultiWalletCreateWalletModel @Inject constructor(
|
||||
paramsContainer: ParamsContainer,
|
||||
|
|
@ -36,6 +43,8 @@ internal class MultiWalletCreateWalletModel @Inject constructor(
|
|||
private val getCardInfoUseCase: GetCardInfoUseCase,
|
||||
private val cardRepository: CardRepository,
|
||||
private val analyticsHandler: AnalyticsEventHandler,
|
||||
private val generateWalletNameUseCase: GenerateWalletNameUseCase,
|
||||
private val saveWalletUseCase: SaveWalletUseCase,
|
||||
) : Model() {
|
||||
|
||||
private val params = paramsContainer.require<MultiWalletChildParams>()
|
||||
|
|
@ -61,7 +70,7 @@ internal class MultiWalletCreateWalletModel @Inject constructor(
|
|||
showOtherOptionsButton = params.parentParams.withSeedPhraseFlow,
|
||||
onOtherOptionsClick = {
|
||||
modelScope.launch {
|
||||
onDone.emit(OnboardingMultiWalletState.Step.SeedPhrase)
|
||||
onDone.emit(Step.SeedPhrase)
|
||||
}
|
||||
},
|
||||
dialog = null,
|
||||
|
|
@ -69,7 +78,7 @@ internal class MultiWalletCreateWalletModel @Inject constructor(
|
|||
)
|
||||
|
||||
val uiState: StateFlow<MultiWalletCreateWalletUM> = _uiState
|
||||
val onDone = MutableSharedFlow<OnboardingMultiWalletState.Step>()
|
||||
val onDone = MutableSharedFlow<Step>()
|
||||
|
||||
init {
|
||||
analyticsHandler.send(OnboardingEvent.CreateWallet.ScreenOpened)
|
||||
|
|
@ -96,13 +105,14 @@ internal class MultiWalletCreateWalletModel @Inject constructor(
|
|||
|
||||
cardRepository.startCardActivation(cardId = result.data.card.cardId)
|
||||
|
||||
if (params.parentParams.withSeedPhraseFlow) {
|
||||
onDone.emit(OnboardingMultiWalletState.Step.AddBackupDevice)
|
||||
} else {
|
||||
onDone.emit(OnboardingMultiWalletState.Step.ChooseBackupOption)
|
||||
}
|
||||
|
||||
analyticsHandler.send(OnboardingEvent.CreateWallet.WalletCreatedSuccessfully())
|
||||
|
||||
val cardDoesNotSupportBackup = result.data.card.settings.isBackupAllowed.not()
|
||||
when {
|
||||
cardDoesNotSupportBackup -> createWalletAndNavigateBackWithDone()
|
||||
params.parentParams.withSeedPhraseFlow -> onDone.emit(Step.AddBackupDevice)
|
||||
else -> onDone.emit(Step.ChooseBackupOption)
|
||||
}
|
||||
}
|
||||
|
||||
is CompletionResult.Failure -> {
|
||||
|
|
@ -115,6 +125,32 @@ internal class MultiWalletCreateWalletModel @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private fun createWalletAndNavigateBackWithDone() {
|
||||
modelScope.launch {
|
||||
val scanResponse = params.multiWalletState.value.currentScanResponse
|
||||
|
||||
val userWallet = createUserWallet(scanResponse)
|
||||
saveWalletUseCase(userWallet, canOverride = true)
|
||||
.onRight {
|
||||
cardRepository.finishCardActivation(scanResponse.card.cardId)
|
||||
|
||||
// save user wallet for manage tokens screen
|
||||
params.multiWalletState.update {
|
||||
it.copy(resultUserWallet = userWallet)
|
||||
}
|
||||
|
||||
onDone.emit(Step.Done)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun createUserWallet(scanResponse: ScanResponse): UserWallet {
|
||||
return requireNotNull(
|
||||
value = UserWalletBuilder(scanResponse, generateWalletNameUseCase).build(),
|
||||
lazyMessage = { "User wallet not created" },
|
||||
)
|
||||
}
|
||||
|
||||
private fun handleActivationError() {
|
||||
_uiState.update { state ->
|
||||
state.copy(
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
package com.tangem.features.onboarding.v2.multiwallet.impl.child.createwallet.ui
|
||||
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
|
@ -15,6 +16,7 @@ import com.tangem.core.ui.components.PrimaryButtonIconEnd
|
|||
import com.tangem.core.ui.components.SecondaryButton
|
||||
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
|
||||
import com.tangem.features.onboarding.v2.impl.R
|
||||
|
|
@ -48,7 +50,8 @@ internal fun MultiWalletCreateWallet(state: MultiWalletCreateWalletUM, modifier:
|
|||
Column(
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(start = 32.dp, end = 32.dp, bottom = 24.dp)
|
||||
.verticalScroll(rememberScrollState())
|
||||
.padding(start = 32.dp, end = 32.dp, bottom = 16.dp)
|
||||
.weight(1f),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
|
|
@ -74,7 +77,7 @@ internal fun MultiWalletCreateWallet(state: MultiWalletCreateWalletUM, modifier:
|
|||
.padding(start = 16.dp, end = 16.dp, bottom = 12.dp)
|
||||
.fillMaxWidth(),
|
||||
iconResId = R.drawable.ic_tangem_24,
|
||||
text = stringResource(R.string.onboarding_create_wallet_button_create_wallet),
|
||||
text = stringResourceSafe(R.string.onboarding_create_wallet_button_create_wallet),
|
||||
onClick = state.onCreateWalletClick,
|
||||
)
|
||||
|
||||
|
|
@ -83,7 +86,7 @@ internal fun MultiWalletCreateWallet(state: MultiWalletCreateWalletUM, modifier:
|
|||
modifier = Modifier
|
||||
.padding(start = 16.dp, end = 16.dp, bottom = 16.dp)
|
||||
.fillMaxWidth(),
|
||||
text = stringResource(R.string.onboarding_create_wallet_options_button_options),
|
||||
text = stringResourceSafe(R.string.onboarding_create_wallet_options_button_options),
|
||||
onClick = state.onOtherOptionsClick,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package com.tangem.features.onboarding.v2.multiwallet.impl.child.finalize
|
||||
|
||||
import androidx.activity.compose.BackHandler
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Modifier
|
||||
|
|
@ -12,6 +13,7 @@ import com.tangem.features.onboarding.v2.multiwallet.impl.child.MultiWalletChild
|
|||
import com.tangem.features.onboarding.v2.multiwallet.impl.child.MultiWalletChildParams
|
||||
import com.tangem.features.onboarding.v2.multiwallet.impl.child.finalize.model.MultiWalletFinalizeModel
|
||||
import com.tangem.features.onboarding.v2.multiwallet.impl.child.finalize.ui.MultiWalletFinalize
|
||||
import kotlinx.coroutines.flow.SharedFlow
|
||||
import kotlinx.coroutines.flow.update
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
|
|
@ -19,6 +21,8 @@ import kotlinx.coroutines.launch
|
|||
internal class MultiWalletFinalizeComponent(
|
||||
context: AppComponentContext,
|
||||
params: MultiWalletChildParams,
|
||||
backButtonClickFlow: SharedFlow<Unit>,
|
||||
onBack: () -> Unit,
|
||||
onEvent: (Event) -> Unit,
|
||||
) : AppComponentContext by context, MultiWalletChildComponent {
|
||||
|
||||
|
|
@ -40,12 +44,21 @@ internal class MultiWalletFinalizeComponent(
|
|||
onEvent(it)
|
||||
}
|
||||
}
|
||||
|
||||
componentScope.launch {
|
||||
backButtonClickFlow.collect { model.onBack() }
|
||||
}
|
||||
componentScope.launch {
|
||||
model.onBackFlow.collect { onBack() }
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
override fun Content(modifier: Modifier) {
|
||||
val state by model.uiState.collectAsStateWithLifecycle()
|
||||
|
||||
BackHandler { model.onBack() }
|
||||
|
||||
MultiWalletFinalize(
|
||||
state = state,
|
||||
modifier = modifier,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package com.tangem.features.onboarding.v2.multiwallet.impl.child.finalize.model
|
||||
|
||||
import androidx.compose.runtime.Stable
|
||||
import com.tangem.common.CompletionResult
|
||||
import com.tangem.common.core.TangemSdkError
|
||||
import com.tangem.core.decompose.di.ComponentScoped
|
||||
|
|
@ -29,14 +30,12 @@ import com.tangem.sdk.api.BackupServiceHolder
|
|||
import com.tangem.sdk.api.TangemSdkManager
|
||||
import com.tangem.utils.StringsSigns
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
import kotlinx.coroutines.flow.update
|
||||
import kotlinx.coroutines.flow.*
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
||||
@Suppress("LongParameterList")
|
||||
@Stable
|
||||
@ComponentScoped
|
||||
internal class MultiWalletFinalizeModel @Inject constructor(
|
||||
paramsContainer: ParamsContainer,
|
||||
|
|
@ -59,6 +58,7 @@ internal class MultiWalletFinalizeModel @Inject constructor(
|
|||
|
||||
private var walletHasBackupError = false
|
||||
val uiState = _uiState.asStateFlow()
|
||||
val onBackFlow = MutableSharedFlow<Unit>()
|
||||
|
||||
val onEvent = MutableSharedFlow<MultiWalletFinalizeComponent.Event>()
|
||||
|
||||
|
|
@ -72,6 +72,12 @@ internal class MultiWalletFinalizeModel @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
fun onBack() {
|
||||
if (uiState.value.scanPrimary) {
|
||||
modelScope.launch { onBackFlow.emit(Unit) }
|
||||
}
|
||||
}
|
||||
|
||||
private fun getInitialState(): MultiWalletFinalizeUM {
|
||||
val backupService = backupServiceHolder.backupService.get() ?: return MultiWalletFinalizeUM()
|
||||
val initialStep = getInitialStep()
|
||||
|
|
@ -193,18 +199,24 @@ internal class MultiWalletFinalizeModel @Inject constructor(
|
|||
private fun finishBackup() {
|
||||
modelScope.launch {
|
||||
val scanResponse = params.multiWalletState.value.currentScanResponse
|
||||
val userWallet = createUserWallet(scanResponse)
|
||||
|
||||
when (params.parentParams.mode) {
|
||||
val userWalletCreated = createUserWallet(scanResponse)
|
||||
|
||||
val userWallet = when (params.parentParams.mode) {
|
||||
OnboardingMultiWalletComponent.Mode.Onboarding -> {
|
||||
userWalletsListManager.save(
|
||||
userWallet = userWallet.copy(
|
||||
userWallet = userWalletCreated.copy(
|
||||
scanResponse = scanResponse.updateScanResponseAfterBackup(),
|
||||
),
|
||||
canOverride = true,
|
||||
)
|
||||
userWalletCreated
|
||||
}
|
||||
OnboardingMultiWalletComponent.Mode.AddBackup -> {
|
||||
val userWallet = userWalletsListManager.userWallets.first()
|
||||
.firstOrNull { it.scanResponse.primaryCard?.cardId == scanResponse.primaryCard?.cardId }
|
||||
?: userWalletCreated
|
||||
|
||||
userWalletsListManager.update(
|
||||
userWalletId = userWallet.walletId,
|
||||
update = { wallet ->
|
||||
|
|
@ -213,6 +225,8 @@ internal class MultiWalletFinalizeModel @Inject constructor(
|
|||
)
|
||||
},
|
||||
)
|
||||
|
||||
userWallet
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,15 +1,17 @@
|
|||
package com.tangem.features.onboarding.v2.multiwallet.impl.child.finalize.ui
|
||||
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.tangem.core.ui.components.PrimaryButtonIconEnd
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.features.onboarding.v2.impl.R
|
||||
|
|
@ -27,13 +29,14 @@ internal fun MultiWalletFinalize(state: MultiWalletFinalizeUM, modifier: Modifie
|
|||
Column(
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(start = 32.dp, end = 32.dp, bottom = 74.dp)
|
||||
.padding(start = 32.dp, end = 32.dp, bottom = 16.dp)
|
||||
.verticalScroll(rememberScrollState())
|
||||
.weight(1f),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
Text(
|
||||
modifier = Modifier.padding(top = 16.dp),
|
||||
text = stringResource(
|
||||
text = stringResourceSafe(
|
||||
when {
|
||||
state.scanPrimary && state.isRing -> R.string.common_origin_ring
|
||||
state.scanPrimary && state.isRing.not() -> R.string.common_origin_card
|
||||
|
|
@ -49,9 +52,9 @@ internal fun MultiWalletFinalize(state: MultiWalletFinalizeUM, modifier: Modifie
|
|||
Text(
|
||||
modifier = Modifier.padding(top = 12.dp),
|
||||
text = if (state.isRing) {
|
||||
stringResource(R.string.onboarding_subtitle_scan_ring)
|
||||
stringResourceSafe(R.string.onboarding_subtitle_scan_ring)
|
||||
} else {
|
||||
stringResource(
|
||||
stringResourceSafe(
|
||||
R.string.onboarding_subtitle_scan_backup_card_format,
|
||||
state.cardNumber,
|
||||
)
|
||||
|
|
@ -66,7 +69,7 @@ internal fun MultiWalletFinalize(state: MultiWalletFinalizeUM, modifier: Modifie
|
|||
modifier = Modifier
|
||||
.padding(start = 16.dp, end = 16.dp, bottom = 16.dp)
|
||||
.fillMaxWidth(),
|
||||
text = stringResource(
|
||||
text = stringResourceSafe(
|
||||
if (state.isRing) R.string.onboarding_button_backup_ring else R.string.onboarding_button_backup_origin,
|
||||
),
|
||||
iconResId = R.drawable.ic_tangem_24,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,46 @@
|
|||
package com.tangem.features.onboarding.v2.multiwallet.impl.child.scanprimary
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import com.tangem.core.decompose.context.AppComponentContext
|
||||
import com.tangem.core.decompose.model.getOrCreateModel
|
||||
import com.tangem.core.ui.decompose.ComposableContentComponent
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.features.onboarding.v2.impl.R
|
||||
import com.tangem.features.onboarding.v2.multiwallet.impl.child.MultiWalletChildParams
|
||||
import com.tangem.features.onboarding.v2.multiwallet.impl.child.scanprimary.model.Wallet1ScanPrimaryModel
|
||||
import com.tangem.features.onboarding.v2.multiwallet.impl.child.scanprimary.ui.Wallet1ScanPrimary
|
||||
import kotlinx.coroutines.flow.update
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
internal class Wallet1ScanPrimaryComponent(
|
||||
context: AppComponentContext,
|
||||
params: MultiWalletChildParams,
|
||||
onDone: () -> Unit,
|
||||
) : AppComponentContext by context, ComposableContentComponent {
|
||||
|
||||
private val model: Wallet1ScanPrimaryModel = getOrCreateModel(params)
|
||||
|
||||
init {
|
||||
params.innerNavigation.update {
|
||||
it.copy(
|
||||
stackSize = 4,
|
||||
stackMaxSize = 8,
|
||||
)
|
||||
}
|
||||
|
||||
params.parentParams.titleProvider.changeTitle(
|
||||
text = resourceReference(R.string.onboarding_navbar_title_creating_backup),
|
||||
)
|
||||
|
||||
componentScope.launch { model.onDone.collect { onDone() } }
|
||||
}
|
||||
|
||||
@Composable
|
||||
override fun Content(modifier: Modifier) {
|
||||
Wallet1ScanPrimary(
|
||||
isRing = model.isRing,
|
||||
onScanPrimaryClick = model::onScanPrimaryClick,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
package com.tangem.features.onboarding.v2.multiwallet.impl.child.scanprimary.model
|
||||
|
||||
import androidx.compose.runtime.Stable
|
||||
import com.tangem.common.CompletionResult
|
||||
import com.tangem.core.decompose.di.ComponentScoped
|
||||
import com.tangem.core.decompose.model.Model
|
||||
import com.tangem.core.decompose.model.ParamsContainer
|
||||
import com.tangem.domain.common.util.cardTypesResolver
|
||||
import com.tangem.features.onboarding.v2.impl.R
|
||||
import com.tangem.features.onboarding.v2.multiwallet.impl.child.MultiWalletChildParams
|
||||
import com.tangem.sdk.api.BackupServiceHolder
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
||||
@Stable
|
||||
@ComponentScoped
|
||||
internal class Wallet1ScanPrimaryModel @Inject constructor(
|
||||
paramsContainer: ParamsContainer,
|
||||
override val dispatchers: CoroutineDispatcherProvider,
|
||||
private val backupServiceHolder: BackupServiceHolder,
|
||||
) : Model() {
|
||||
|
||||
private val params = paramsContainer.require<MultiWalletChildParams>()
|
||||
private val scanResponse = params.multiWalletState.value.currentScanResponse
|
||||
|
||||
val isRing = scanResponse.cardTypesResolver.isRing()
|
||||
val onDone = MutableSharedFlow<Unit>()
|
||||
|
||||
fun onScanPrimaryClick() {
|
||||
val backupService = backupServiceHolder.backupService.get() ?: return
|
||||
val iconScanRes = R.drawable.img_hand_scan_ring.takeIf { isRing }
|
||||
backupService.readPrimaryCard(iconScanRes = iconScanRes, cardId = scanResponse.card.cardId) { result ->
|
||||
when (result) {
|
||||
is CompletionResult.Success -> {
|
||||
modelScope.launch { onDone.emit(Unit) }
|
||||
}
|
||||
is CompletionResult.Failure -> Unit
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
package com.tangem.features.onboarding.v2.multiwallet.impl.child.scanprimary.ui
|
||||
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.tangem.core.ui.components.PrimaryButtonIconEnd
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.features.onboarding.v2.impl.R
|
||||
|
||||
@Composable
|
||||
internal fun Wallet1ScanPrimary(isRing: Boolean, onScanPrimaryClick: () -> Unit, modifier: Modifier = Modifier) {
|
||||
Column(
|
||||
modifier = modifier
|
||||
.fillMaxSize()
|
||||
.navigationBarsPadding(),
|
||||
verticalArrangement = Arrangement.Bottom,
|
||||
) {
|
||||
Column(
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(start = 32.dp, end = 32.dp, bottom = 16.dp)
|
||||
.verticalScroll(rememberScrollState())
|
||||
.weight(1f),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
Text(
|
||||
modifier = Modifier.padding(top = 16.dp),
|
||||
text = stringResourceSafe(R.string.onboarding_title_scan_origin_card),
|
||||
color = TangemTheme.colors.text.primary1,
|
||||
textAlign = TextAlign.Center,
|
||||
style = TangemTheme.typography.h2,
|
||||
)
|
||||
|
||||
Text(
|
||||
modifier = Modifier.padding(top = 12.dp),
|
||||
text = stringResourceSafe(R.string.onboarding_subtitle_scan_primary),
|
||||
color = TangemTheme.colors.text.secondary,
|
||||
textAlign = TextAlign.Center,
|
||||
style = TangemTheme.typography.body1,
|
||||
)
|
||||
}
|
||||
|
||||
PrimaryButtonIconEnd(
|
||||
modifier = Modifier
|
||||
.padding(start = 16.dp, end = 16.dp, bottom = 16.dp)
|
||||
.fillMaxWidth(),
|
||||
text = stringResourceSafe(
|
||||
if (isRing) R.string.onboarding_button_backup_ring else R.string.onboarding_button_backup_origin,
|
||||
),
|
||||
iconResId = R.drawable.ic_tangem_24,
|
||||
onClick = onScanPrimaryClick,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
private fun Preview() {
|
||||
TangemThemePreview {
|
||||
Wallet1ScanPrimary(
|
||||
isRing = true,
|
||||
onScanPrimaryClick = {},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
package com.tangem.features.onboarding.v2.multiwallet.impl.child.seedphrase.model
|
||||
|
||||
import androidx.compose.runtime.Stable
|
||||
import com.tangem.common.CompletionResult
|
||||
import com.tangem.common.core.TangemSdkError
|
||||
import com.tangem.core.analytics.api.AnalyticsEventHandler
|
||||
|
|
@ -33,6 +34,7 @@ import javax.inject.Inject
|
|||
// | DON'T FIXME !!! MODIFY WITH CAUTION !!! |
|
||||
// =============================================
|
||||
@Suppress("LongParameterList")
|
||||
@Stable
|
||||
@ComponentScoped
|
||||
internal class MultiWalletSeedPhraseModel @Inject constructor(
|
||||
paramsContainer: ParamsContainer,
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import android.net.Uri
|
|||
import com.tangem.utils.SupportedLanguages
|
||||
import java.util.Locale
|
||||
|
||||
// TODO: [REDACTED_JIRA]
|
||||
internal fun seedPhraseLearnMoreUrl(): String {
|
||||
val language = Locale.getDefault().language
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package com.tangem.features.onboarding.v2.multiwallet.impl.child.seedphrase.ui
|
||||
|
||||
import androidx.compose.animation.*
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.lazy.LazyRow
|
||||
|
|
@ -14,7 +15,6 @@ import androidx.compose.runtime.remember
|
|||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.SpanStyle
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
|
|
@ -55,49 +55,52 @@ internal fun MultiWalletSeedPhraseImport(state: MultiWalletSeedPhraseUM.Import,
|
|||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.verticalScroll(rememberScrollState()),
|
||||
.imePadding(),
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(id = R.string.onboarding_seed_import_message),
|
||||
style = TangemTheme.typography.body1,
|
||||
color = TangemTheme.colors.text.secondary,
|
||||
textAlign = TextAlign.Center,
|
||||
modifier = Modifier
|
||||
.padding(start = 36.dp, end = 36.dp, top = 24.dp, bottom = 16.dp)
|
||||
.fillMaxWidth(),
|
||||
)
|
||||
|
||||
PhraseBlock(
|
||||
state = state,
|
||||
modifier = Modifier.padding(horizontal = 16.dp),
|
||||
)
|
||||
|
||||
OutlineTextFieldWithIcon(
|
||||
modifier = modifier
|
||||
.padding(horizontal = 16.dp)
|
||||
.fillMaxWidth(),
|
||||
value = state.passPhrase,
|
||||
onValueChange = state.passPhraseChange,
|
||||
iconResId = R.drawable.ic_information_24,
|
||||
iconColor = TangemTheme.colors.icon.informative,
|
||||
label = stringResource(id = R.string.common_passphrase),
|
||||
placeholder = stringResource(id = R.string.send_optional_field),
|
||||
onIconClick = state.onPassphraseInfoClick,
|
||||
)
|
||||
|
||||
Box(Modifier.weight(1f)) {
|
||||
PrimaryButtonIconEnd(
|
||||
Column(
|
||||
Modifier
|
||||
.verticalScroll(rememberScrollState())
|
||||
.weight(1f),
|
||||
) {
|
||||
Text(
|
||||
text = stringResourceSafe(id = R.string.onboarding_seed_import_message),
|
||||
style = TangemTheme.typography.body1,
|
||||
color = TangemTheme.colors.text.secondary,
|
||||
textAlign = TextAlign.Center,
|
||||
modifier = Modifier
|
||||
.align(Alignment.BottomStart)
|
||||
.padding(16.dp)
|
||||
.padding(start = 36.dp, end = 36.dp, top = 24.dp, bottom = 16.dp)
|
||||
.fillMaxWidth(),
|
||||
text = stringResource(id = R.string.common_import),
|
||||
iconResId = R.drawable.ic_tangem_24,
|
||||
enabled = state.createWalletEnabled,
|
||||
showProgress = state.createWalletProgress,
|
||||
onClick = state.createWalletClick,
|
||||
)
|
||||
|
||||
PhraseBlock(
|
||||
state = state,
|
||||
modifier = Modifier.padding(horizontal = 16.dp),
|
||||
)
|
||||
|
||||
OutlineTextFieldWithIcon(
|
||||
modifier = modifier
|
||||
.padding(horizontal = 16.dp)
|
||||
.fillMaxWidth(),
|
||||
value = state.passPhrase,
|
||||
onValueChange = state.passPhraseChange,
|
||||
iconResId = R.drawable.ic_information_24,
|
||||
iconColor = TangemTheme.colors.icon.informative,
|
||||
label = stringResourceSafe(id = R.string.common_passphrase),
|
||||
placeholder = stringResourceSafe(id = R.string.send_optional_field),
|
||||
onIconClick = state.onPassphraseInfoClick,
|
||||
)
|
||||
}
|
||||
|
||||
PrimaryButtonIconEnd(
|
||||
modifier = Modifier
|
||||
.padding(16.dp)
|
||||
.fillMaxWidth(),
|
||||
text = stringResourceSafe(id = R.string.common_import),
|
||||
iconResId = R.drawable.ic_tangem_24,
|
||||
enabled = state.createWalletEnabled,
|
||||
showProgress = state.createWalletProgress,
|
||||
onClick = state.createWalletClick,
|
||||
)
|
||||
}
|
||||
|
||||
val keyboard by keyboardAsState()
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ import androidx.compose.ui.Alignment
|
|||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.res.vectorResource
|
||||
import androidx.compose.ui.text.style.LineBreak
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
|
|
@ -19,6 +18,7 @@ import androidx.compose.ui.unit.dp
|
|||
import com.tangem.core.ui.components.SecondaryButton
|
||||
import com.tangem.core.ui.components.SpacerH32
|
||||
import com.tangem.core.ui.components.SpacerW8
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.features.onboarding.v2.impl.R
|
||||
|
|
@ -51,7 +51,7 @@ internal fun MultiWalletSeedPhraseStart(state: MultiWalletSeedPhraseUM.Start, mo
|
|||
Text(
|
||||
modifier = Modifier
|
||||
.padding(horizontal = TangemTheme.dimens.size12, vertical = TangemTheme.dimens.size4),
|
||||
text = stringResource(id = R.string.onboarding_seed_phrase_intro_legacy),
|
||||
text = stringResourceSafe(id = R.string.onboarding_seed_phrase_intro_legacy),
|
||||
color = TangemTheme.colors.text.warning,
|
||||
style = TangemTheme.typography.body1,
|
||||
)
|
||||
|
|
@ -71,12 +71,12 @@ private fun BodyContent(state: MultiWalletSeedPhraseUM.Start, modifier: Modifier
|
|||
verticalArrangement = Arrangement.spacedBy(16.dp),
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(id = R.string.onboarding_seed_intro_title),
|
||||
text = stringResourceSafe(id = R.string.onboarding_seed_intro_title),
|
||||
style = TangemTheme.typography.h2,
|
||||
color = TangemTheme.colors.text.primary1,
|
||||
)
|
||||
Text(
|
||||
text = stringResource(id = R.string.onboarding_seed_intro_message),
|
||||
text = stringResourceSafe(id = R.string.onboarding_seed_intro_message),
|
||||
style = TangemTheme.typography.body1
|
||||
.copy(lineBreak = LineBreak.Paragraph),
|
||||
color = TangemTheme.colors.text.secondary,
|
||||
|
|
@ -119,7 +119,7 @@ private fun ReadMoreBlock(state: MultiWalletSeedPhraseUM.Start, modifier: Modifi
|
|||
Text(
|
||||
modifier = Modifier.align(Alignment.CenterVertically),
|
||||
style = TangemTheme.typography.button,
|
||||
text = stringResource(id = R.string.onboarding_seed_button_read_more),
|
||||
text = stringResourceSafe(id = R.string.onboarding_seed_button_read_more),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -135,13 +135,13 @@ private fun Buttons(state: MultiWalletSeedPhraseUM.Start, modifier: Modifier = M
|
|||
) {
|
||||
SecondaryButton(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
text = stringResource(id = R.string.onboarding_seed_intro_button_generate),
|
||||
text = stringResourceSafe(id = R.string.onboarding_seed_intro_button_generate),
|
||||
onClick = state.onGenerateSeedPhraseClicked,
|
||||
)
|
||||
SecondaryButton(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth(),
|
||||
text = stringResource(id = R.string.onboarding_seed_intro_button_import),
|
||||
text = stringResourceSafe(id = R.string.onboarding_seed_intro_button_import),
|
||||
onClick = state.onImportSeedPhraseClicked,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,14 +8,14 @@ import androidx.compose.runtime.Composable
|
|||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalLayoutDirection
|
||||
import androidx.compose.ui.res.pluralStringResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.LayoutDirection
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.tangem.core.ui.components.PrimaryButton
|
||||
import com.tangem.core.ui.components.buttons.segmentedbutton.SegmentedButtons
|
||||
import com.tangem.core.ui.extensions.pluralStringResourceSafe
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.features.onboarding.v2.impl.R
|
||||
|
|
@ -31,26 +31,32 @@ internal fun MultiWalletSeedPhraseWords(
|
|||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
Column(modifier.fillMaxSize()) {
|
||||
SegmentSeedBlock(
|
||||
modifier = Modifier.padding(vertical = 20.dp),
|
||||
state = state,
|
||||
)
|
||||
|
||||
TitleBlock(state)
|
||||
|
||||
SeedPhraseGridBlock(
|
||||
mnemonicGridItems = state.words,
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
.fillMaxWidth()
|
||||
.padding(top = 20.dp, bottom = 32.dp),
|
||||
)
|
||||
.verticalScroll(rememberScrollState())
|
||||
.imePadding()
|
||||
.weight(1f),
|
||||
) {
|
||||
SegmentSeedBlock(
|
||||
modifier = Modifier.padding(vertical = 20.dp),
|
||||
state = state,
|
||||
)
|
||||
|
||||
TitleBlock(state)
|
||||
|
||||
SeedPhraseGridBlock(
|
||||
mnemonicGridItems = state.words,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(top = 20.dp, bottom = 32.dp),
|
||||
)
|
||||
}
|
||||
|
||||
PrimaryButton(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(start = 16.dp, end = 16.dp, bottom = 16.dp),
|
||||
text = stringResource(id = R.string.common_continue),
|
||||
text = stringResourceSafe(id = R.string.common_continue),
|
||||
onClick = state.onContinueClick,
|
||||
)
|
||||
}
|
||||
|
|
@ -70,7 +76,7 @@ private fun SegmentSeedBlock(state: MultiWalletSeedPhraseUM.GenerateSeedPhrase,
|
|||
},
|
||||
) {
|
||||
Text(
|
||||
text = pluralStringResource(
|
||||
text = pluralStringResourceSafe(
|
||||
id = R.plurals.onboarding_seed_generate_words_count,
|
||||
count = if (it == 0) 12 else 24,
|
||||
if (it == 0) 12 else 24,
|
||||
|
|
@ -95,14 +101,14 @@ private fun TitleBlock(state: MultiWalletSeedPhraseUM.GenerateSeedPhrase, modifi
|
|||
verticalArrangement = Arrangement.spacedBy(16.dp),
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(id = R.string.onboarding_seed_generate_title),
|
||||
text = stringResourceSafe(id = R.string.onboarding_seed_generate_title),
|
||||
style = TangemTheme.typography.h2,
|
||||
color = TangemTheme.colors.text.primary1,
|
||||
textAlign = TextAlign.Center,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
)
|
||||
Text(
|
||||
text = pluralStringResource(
|
||||
text = pluralStringResourceSafe(
|
||||
id = R.plurals.onboarding_seed_generate_message_words_count,
|
||||
count = if (state.words24OptionSelected.not()) 12 else 24,
|
||||
if (state.words24OptionSelected.not()) 12 else 24,
|
||||
|
|
@ -118,8 +124,7 @@ private fun TitleBlock(state: MultiWalletSeedPhraseUM.GenerateSeedPhrase, modifi
|
|||
@Composable
|
||||
private fun SeedPhraseGridBlock(mnemonicGridItems: ImmutableList<MnemonicGridItem>, modifier: Modifier = Modifier) {
|
||||
VerticalGrid(
|
||||
modifier = modifier
|
||||
.verticalScroll(rememberScrollState()),
|
||||
modifier = modifier,
|
||||
items = mnemonicGridItems,
|
||||
) { item ->
|
||||
Row(
|
||||
|
|
|
|||
|
|
@ -5,9 +5,7 @@ import androidx.compose.foundation.rememberScrollState
|
|||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.input.TextFieldValue
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
|
|
@ -18,6 +16,7 @@ import com.tangem.core.ui.components.DialogButtonUM
|
|||
import com.tangem.core.ui.components.OutlineTextField
|
||||
import com.tangem.core.ui.components.PrimaryButtonIconEnd
|
||||
import com.tangem.core.ui.extensions.resolveReference
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.features.onboarding.v2.multiwallet.impl.child.seedphrase.ui.state.MultiWalletSeedPhraseUM
|
||||
|
|
@ -48,48 +47,50 @@ internal fun MultiWalletSeedPhraseWordsCheck(
|
|||
Column(
|
||||
modifier = modifier
|
||||
.fillMaxSize()
|
||||
.verticalScroll(rememberScrollState()),
|
||||
.imePadding(),
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(R.string.onboarding_seed_user_validation_title),
|
||||
style = TangemTheme.typography.h2,
|
||||
color = TangemTheme.colors.text.primary1,
|
||||
textAlign = TextAlign.Center,
|
||||
modifier = Modifier
|
||||
.padding(top = 48.dp, start = 36.dp, end = 36.dp, bottom = 16.dp)
|
||||
.fillMaxWidth(),
|
||||
)
|
||||
Text(
|
||||
text = stringResource(R.string.onboarding_seed_user_validation_message),
|
||||
style = TangemTheme.typography.body1,
|
||||
color = TangemTheme.colors.text.secondary,
|
||||
textAlign = TextAlign.Center,
|
||||
modifier = Modifier
|
||||
.padding(horizontal = 36.dp)
|
||||
.fillMaxWidth(),
|
||||
)
|
||||
|
||||
Fields(
|
||||
state = state,
|
||||
modifier = Modifier
|
||||
.padding(vertical = 30.dp, horizontal = 16.dp),
|
||||
)
|
||||
|
||||
Box(
|
||||
Modifier.weight(1f),
|
||||
Column(
|
||||
Modifier
|
||||
.verticalScroll(rememberScrollState())
|
||||
.weight(1f),
|
||||
) {
|
||||
PrimaryButtonIconEnd(
|
||||
Text(
|
||||
text = stringResourceSafe(R.string.onboarding_seed_user_validation_title),
|
||||
style = TangemTheme.typography.h2,
|
||||
color = TangemTheme.colors.text.primary1,
|
||||
textAlign = TextAlign.Center,
|
||||
modifier = Modifier
|
||||
.align(Alignment.BottomStart)
|
||||
.padding(16.dp)
|
||||
.padding(top = 48.dp, start = 36.dp, end = 36.dp, bottom = 16.dp)
|
||||
.fillMaxWidth(),
|
||||
text = stringResource(id = R.string.onboarding_create_wallet_button_create_wallet),
|
||||
iconResId = R.drawable.ic_tangem_24,
|
||||
enabled = state.createWalletButtonEnabled,
|
||||
showProgress = state.createWalletButtonProgress,
|
||||
onClick = state.onCreateWalletButtonClick,
|
||||
)
|
||||
Text(
|
||||
text = stringResourceSafe(R.string.onboarding_seed_user_validation_message),
|
||||
style = TangemTheme.typography.body1,
|
||||
color = TangemTheme.colors.text.secondary,
|
||||
textAlign = TextAlign.Center,
|
||||
modifier = Modifier
|
||||
.padding(horizontal = 36.dp)
|
||||
.fillMaxWidth(),
|
||||
)
|
||||
|
||||
Fields(
|
||||
state = state,
|
||||
modifier = Modifier
|
||||
.padding(vertical = 30.dp, horizontal = 16.dp),
|
||||
)
|
||||
}
|
||||
|
||||
PrimaryButtonIconEnd(
|
||||
modifier = Modifier
|
||||
.padding(16.dp)
|
||||
.imePadding()
|
||||
.fillMaxWidth(),
|
||||
text = stringResourceSafe(id = R.string.onboarding_create_wallet_button_create_wallet),
|
||||
iconResId = R.drawable.ic_tangem_24,
|
||||
enabled = state.createWalletButtonEnabled,
|
||||
showProgress = state.createWalletButtonProgress,
|
||||
onClick = state.onCreateWalletButtonClick,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11,13 +11,13 @@ 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.text.style.TextAlign
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import com.tangem.core.ui.components.PrimaryButton
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheet
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfigContent
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.features.onboarding.v2.impl.R
|
||||
|
|
@ -50,7 +50,7 @@ fun PassphraseInfoBottomSheetContent(onDismiss: () -> Unit) {
|
|||
)
|
||||
|
||||
Text(
|
||||
text = stringResource(id = R.string.common_passphrase),
|
||||
text = stringResourceSafe(id = R.string.common_passphrase),
|
||||
modifier = Modifier
|
||||
.padding(top = TangemTheme.dimens.size40)
|
||||
.align(Alignment.CenterHorizontally),
|
||||
|
|
@ -59,7 +59,7 @@ fun PassphraseInfoBottomSheetContent(onDismiss: () -> Unit) {
|
|||
)
|
||||
|
||||
Text(
|
||||
text = stringResource(id = R.string.onboarding_bottom_sheet_passphrase_description),
|
||||
text = stringResourceSafe(id = R.string.onboarding_bottom_sheet_passphrase_description),
|
||||
modifier = Modifier
|
||||
.padding(top = TangemTheme.dimens.size16)
|
||||
.padding(horizontal = TangemTheme.dimens.size24)
|
||||
|
|
@ -75,7 +75,7 @@ fun PassphraseInfoBottomSheetContent(onDismiss: () -> Unit) {
|
|||
.padding(top = TangemTheme.dimens.size40)
|
||||
.padding(bottom = TangemTheme.dimens.size32)
|
||||
.fillMaxWidth(),
|
||||
text = stringResource(id = R.string.common_ok),
|
||||
text = stringResourceSafe(id = R.string.common_ok),
|
||||
onClick = onDismiss,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import com.tangem.features.onboarding.v2.multiwallet.impl.child.backup.model.Mul
|
|||
import com.tangem.features.onboarding.v2.multiwallet.impl.child.chooseoption.model.Wallet1ChooseOptionModel
|
||||
import com.tangem.features.onboarding.v2.multiwallet.impl.child.createwallet.model.MultiWalletCreateWalletModel
|
||||
import com.tangem.features.onboarding.v2.multiwallet.impl.child.finalize.model.MultiWalletFinalizeModel
|
||||
import com.tangem.features.onboarding.v2.multiwallet.impl.child.scanprimary.model.Wallet1ScanPrimaryModel
|
||||
import com.tangem.features.onboarding.v2.multiwallet.impl.child.seedphrase.model.MultiWalletSeedPhraseModel
|
||||
import com.tangem.features.onboarding.v2.multiwallet.impl.model.OnboardingMultiWalletModel
|
||||
import dagger.Binds
|
||||
|
|
@ -66,4 +67,9 @@ internal interface ModelModule {
|
|||
@IntoMap
|
||||
@ClassKey(Wallet1ChooseOptionModel::class)
|
||||
fun provideModel7(model: Wallet1ChooseOptionModel): Model
|
||||
|
||||
@Binds
|
||||
@IntoMap
|
||||
@ClassKey(Wallet1ScanPrimaryModel::class)
|
||||
fun provideModel8(model: Wallet1ScanPrimaryModel): Model
|
||||
}
|
||||
|
|
@ -103,11 +103,19 @@ internal class OnboardingMultiWalletModel @Inject constructor(
|
|||
}
|
||||
|
||||
private fun getInitialStep(): OnboardingMultiWalletState.Step {
|
||||
val card = params.scanResponse.card
|
||||
val scanResponse = params.scanResponse
|
||||
val card = scanResponse.card
|
||||
val backupService = backupServiceHolder.backupService.get()!!
|
||||
|
||||
return when {
|
||||
// interrupted backup
|
||||
backupService.hasIncompletedBackup -> OnboardingMultiWalletState.Step.Finalize
|
||||
|
||||
// Add backup button
|
||||
// Wallet1 without backup and userwallet's scanResponse doesn't contain primary card.
|
||||
card.wallets.isNotEmpty() && card.backupStatus == CardDTO.BackupStatus.NoBackup &&
|
||||
scanResponse.primaryCard == null -> OnboardingMultiWalletState.Step.ScanPrimary
|
||||
|
||||
card.wallets.isNotEmpty() && card.backupStatus == CardDTO.BackupStatus.NoBackup ->
|
||||
OnboardingMultiWalletState.Step.AddBackupDevice
|
||||
card.wallets.isNotEmpty() && card.backupStatus?.isActive == true ->
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@ data class OnboardingMultiWalletState(
|
|||
|
||||
/**
|
||||
* Wallet1
|
||||
* ScanPrimary -> |
|
||||
* |
|
||||
* CreateWallet -> ChooseBackupOption -> AddBackupDevice -> Finalize -> [Done]
|
||||
* |
|
||||
* -> [Done]
|
||||
|
|
@ -27,7 +29,7 @@ data class OnboardingMultiWalletState(
|
|||
* -> AddBackupDevice -> Finalize -> [Done]
|
||||
*/
|
||||
enum class Step {
|
||||
CreateWallet, ChooseBackupOption, SeedPhrase, AddBackupDevice, Finalize, Done
|
||||
CreateWallet, ChooseBackupOption, SeedPhrase, ScanPrimary, AddBackupDevice, Finalize, Done
|
||||
}
|
||||
|
||||
@JvmInline
|
||||
|
|
|
|||
|
|
@ -7,7 +7,9 @@ import com.tangem.features.onboarding.v2.impl.R
|
|||
fun screenTitleByStep(step: OnboardingMultiWalletState.Step): TextReference = when (step) {
|
||||
OnboardingMultiWalletState.Step.CreateWallet ->
|
||||
resourceReference(R.string.onboarding_create_wallet_header)
|
||||
OnboardingMultiWalletState.Step.AddBackupDevice ->
|
||||
OnboardingMultiWalletState.Step.ScanPrimary,
|
||||
OnboardingMultiWalletState.Step.AddBackupDevice,
|
||||
->
|
||||
resourceReference(R.string.onboarding_navbar_title_creating_backup)
|
||||
OnboardingMultiWalletState.Step.Finalize ->
|
||||
resourceReference(R.string.onboarding_button_finalize_backup)
|
||||
|
|
|
|||
|
|
@ -49,9 +49,9 @@ internal fun OnboardingMultiWallet(
|
|||
url2 = state.artwork2Url,
|
||||
url3 = state.artwork3Url,
|
||||
modifier = Modifier
|
||||
.weight(.56f)
|
||||
.padding(horizontal = 34.dp)
|
||||
.padding(top = 20.dp)
|
||||
.weight(.4f)
|
||||
.fillMaxWidth(),
|
||||
state = artworksState,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ import kotlinx.coroutines.flow.StateFlow
|
|||
import kotlinx.coroutines.launch
|
||||
|
||||
@Suppress("UnusedPrivateMember")
|
||||
class DefaultOnboardingVisaComponent @AssistedInject constructor(
|
||||
internal class DefaultOnboardingVisaComponent @AssistedInject constructor(
|
||||
@Assisted appComponentContext: AppComponentContext,
|
||||
@Assisted private val params: OnboardingVisaComponent.Params,
|
||||
) : OnboardingVisaComponent, AppComponentContext by appComponentContext {
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import com.tangem.core.ui.decompose.ComposableContentComponent
|
|||
import com.tangem.features.onboarding.v2.visa.impl.child.accesscode.model.OnboardingVisaAccessCodeModel
|
||||
import kotlinx.coroutines.flow.SharedFlow
|
||||
|
||||
class OnboardingVisaAccessCodeComponent(
|
||||
internal class OnboardingVisaAccessCodeComponent(
|
||||
appComponentContext: AppComponentContext,
|
||||
private val params: Params,
|
||||
) : ComposableContentComponent, AppComponentContext by appComponentContext {
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import javax.inject.Inject
|
|||
|
||||
@Stable
|
||||
@ComponentScoped
|
||||
class OnboardingVisaAccessCodeModel @Inject constructor(
|
||||
internal class OnboardingVisaAccessCodeModel @Inject constructor(
|
||||
override val dispatchers: CoroutineDispatcherProvider,
|
||||
private val paramsContainer: ParamsContainer,
|
||||
) : Model() {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,167 @@
|
|||
package com.tangem.features.onboarding.v2.visa.impl.child.accesscode.ui
|
||||
|
||||
import androidx.compose.animation.AnimatedContent
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.focus.FocusRequester
|
||||
import androidx.compose.ui.focus.focusRequester
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.input.PasswordVisualTransformation
|
||||
import androidx.compose.ui.text.input.VisualTransformation
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.tangem.common.ui.navigationButtons.NavigationButton
|
||||
import com.tangem.common.ui.navigationButtons.NavigationPrimaryButton
|
||||
import com.tangem.core.ui.components.OutlineTextFieldWithIcon
|
||||
import com.tangem.core.ui.components.SpacerH
|
||||
import com.tangem.core.ui.components.SpacerH16
|
||||
import com.tangem.core.ui.components.SpacerH32
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.res.TangemAnimations
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.features.onboarding.v2.impl.R
|
||||
import com.tangem.features.onboarding.v2.visa.impl.child.accesscode.ui.state.OnboardingVisaAccessCodeUM
|
||||
import kotlinx.coroutines.delay
|
||||
|
||||
@Composable
|
||||
internal fun OnboardingVisaAccessCode(state: OnboardingVisaAccessCodeUM, modifier: Modifier = Modifier) {
|
||||
Column(
|
||||
modifier
|
||||
.fillMaxSize()
|
||||
.navigationBarsPadding(),
|
||||
) {
|
||||
AnimatedContent(
|
||||
modifier = Modifier
|
||||
.padding(top = 48.dp)
|
||||
.weight(1f),
|
||||
targetState = state.step,
|
||||
transitionSpec = TangemAnimations.AnimatedContent
|
||||
.slide { initial, target -> initial.ordinal < target.ordinal },
|
||||
) { step ->
|
||||
Content(
|
||||
state = state,
|
||||
reEnterAccessCodeState = step == OnboardingVisaAccessCodeUM.Step.ReEnter,
|
||||
)
|
||||
}
|
||||
|
||||
SpacerH(20.dp)
|
||||
|
||||
NavigationPrimaryButton(
|
||||
modifier = Modifier
|
||||
.padding(start = 16.dp, end = 16.dp, bottom = 16.dp)
|
||||
.imePadding(),
|
||||
primaryButton = NavigationButton(
|
||||
textReference = when (state.step) {
|
||||
OnboardingVisaAccessCodeUM.Step.Enter -> resourceReference(R.string.common_continue)
|
||||
OnboardingVisaAccessCodeUM.Step.ReEnter ->
|
||||
resourceReference(R.string.onboarding_create_wallet_button_create_wallet)
|
||||
},
|
||||
onClick = state.onContinue,
|
||||
iconRes = R.drawable.ic_tangem_24,
|
||||
isIconVisible = state.step == OnboardingVisaAccessCodeUM.Step.ReEnter,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("LongMethod")
|
||||
@Composable
|
||||
private fun Content(
|
||||
state: OnboardingVisaAccessCodeUM,
|
||||
reEnterAccessCodeState: Boolean,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
Column(
|
||||
modifier = modifier,
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
Text(
|
||||
modifier = Modifier
|
||||
.padding(horizontal = 32.dp),
|
||||
text = if (reEnterAccessCodeState) {
|
||||
"Re-enter your access code" // TODO
|
||||
} else {
|
||||
"Create access code" // TODO
|
||||
},
|
||||
style = TangemTheme.typography.h2,
|
||||
color = TangemTheme.colors.text.primary1,
|
||||
textAlign = TextAlign.Center,
|
||||
)
|
||||
|
||||
SpacerH16()
|
||||
|
||||
// TODO
|
||||
Text(
|
||||
modifier = Modifier
|
||||
.padding(horizontal = 32.dp),
|
||||
text = "The access code will be used manage your payment account and protect it from unauthorized access",
|
||||
style = TangemTheme.typography.body1,
|
||||
color = TangemTheme.colors.text.secondary,
|
||||
textAlign = TextAlign.Center,
|
||||
)
|
||||
|
||||
SpacerH32()
|
||||
|
||||
val focusRequester = remember { FocusRequester() }
|
||||
|
||||
OutlineTextFieldWithIcon(
|
||||
modifier = modifier
|
||||
.padding(horizontal = 16.dp)
|
||||
.focusRequester(focusRequester)
|
||||
.fillMaxWidth(),
|
||||
iconResId = if (state.accessCodeHidden) {
|
||||
R.drawable.ic_eye_outline_24
|
||||
} else {
|
||||
R.drawable.ic_eye_off_outline_24
|
||||
},
|
||||
iconColor = TangemTheme.colors.icon.primary1,
|
||||
onIconClick = state.onAccessCodeHideClick,
|
||||
value = if (reEnterAccessCodeState) {
|
||||
state.accessCodeSecond
|
||||
} else {
|
||||
state.accessCodeFirst
|
||||
},
|
||||
onValueChange = if (reEnterAccessCodeState) {
|
||||
state.onAccessCodeSecondChange
|
||||
} else {
|
||||
state.onAccessCodeFirstChange
|
||||
},
|
||||
label = stringResource(id = R.string.onboarding_wallet_info_title_third),
|
||||
isError = state.codesNotMatchError || state.atLeast4CharError,
|
||||
visualTransformation = if (state.accessCodeHidden) {
|
||||
PasswordVisualTransformation()
|
||||
} else {
|
||||
VisualTransformation.None
|
||||
},
|
||||
caption = when {
|
||||
state.codesNotMatchError && reEnterAccessCodeState ->
|
||||
stringResource(R.string.onboarding_access_codes_doesnt_match)
|
||||
state.atLeast4CharError && !reEnterAccessCodeState ->
|
||||
stringResource(R.string.onboarding_access_code_too_short)
|
||||
else -> null
|
||||
},
|
||||
)
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
delay(timeMillis = 200)
|
||||
focusRequester.requestFocus()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(showBackground = true)
|
||||
@Composable
|
||||
private fun Preview() {
|
||||
TangemThemePreview {
|
||||
OnboardingVisaAccessCode(
|
||||
state = OnboardingVisaAccessCodeUM(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
package com.tangem.features.onboarding.v2.visa.impl.child.accesscode.ui.state
|
||||
|
||||
import androidx.compose.ui.text.input.TextFieldValue
|
||||
|
||||
data class OnboardingVisaAccessCodeUM(
|
||||
val step: Step = Step.Enter,
|
||||
val accessCodeFirst: TextFieldValue = TextFieldValue(""),
|
||||
val accessCodeSecond: TextFieldValue = TextFieldValue(""),
|
||||
val codesNotMatchError: Boolean = false,
|
||||
val atLeast4CharError: Boolean = false,
|
||||
val accessCodeHidden: Boolean = true,
|
||||
val onAccessCodeFirstChange: (TextFieldValue) -> Unit = {},
|
||||
val onAccessCodeSecondChange: (TextFieldValue) -> Unit = {},
|
||||
val onContinue: () -> Unit = {},
|
||||
val onAccessCodeHideClick: () -> Unit = {},
|
||||
) {
|
||||
enum class Step {
|
||||
Enter, ReEnter
|
||||
}
|
||||
}
|
||||
|
|
@ -6,8 +6,10 @@ import androidx.compose.runtime.remember
|
|||
import androidx.compose.ui.Modifier
|
||||
import com.tangem.core.decompose.context.AppComponentContext
|
||||
import com.tangem.core.ui.decompose.ComposableContentComponent
|
||||
import com.tangem.features.onboarding.v2.visa.impl.child.welcome.ui.OnboardingVisaWelcome
|
||||
import com.tangem.features.onboarding.v2.visa.impl.child.welcome.ui.state.OnboardingVisaWelcomeUM
|
||||
|
||||
class OnboardingVisaWelcomeComponent(
|
||||
internal class OnboardingVisaWelcomeComponent(
|
||||
appComponentContext: AppComponentContext,
|
||||
private val params: Params,
|
||||
) : ComposableContentComponent, AppComponentContext by appComponentContext {
|
||||
|
|
@ -15,9 +17,15 @@ class OnboardingVisaWelcomeComponent(
|
|||
@Composable
|
||||
override fun Content(modifier: Modifier) {
|
||||
BackHandler(onBack = remember(this) { { params.onBack() } })
|
||||
|
||||
OnboardingVisaWelcome(
|
||||
modifier = modifier,
|
||||
state = OnboardingVisaWelcomeUM(),
|
||||
)
|
||||
}
|
||||
|
||||
data class Params(
|
||||
val onBack: () -> Unit,
|
||||
val startActivation: () -> Unit,
|
||||
)
|
||||
}
|
||||
|
|
@ -0,0 +1,124 @@
|
|||
package com.tangem.features.onboarding.v2.visa.impl.child.welcome.ui
|
||||
|
||||
import androidx.compose.foundation.Canvas
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import coil.compose.AsyncImage
|
||||
import com.tangem.core.ui.components.PrimaryButton
|
||||
import com.tangem.core.ui.components.PrimaryButtonIconEnd
|
||||
import com.tangem.core.ui.components.SpacerH
|
||||
import com.tangem.core.ui.components.SpacerH12
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.features.onboarding.v2.impl.R
|
||||
import com.tangem.features.onboarding.v2.visa.impl.child.welcome.ui.state.OnboardingVisaWelcomeUM
|
||||
|
||||
@Composable
|
||||
internal fun OnboardingVisaWelcome(state: OnboardingVisaWelcomeUM, modifier: Modifier = Modifier) {
|
||||
Column(
|
||||
modifier = modifier
|
||||
.fillMaxSize()
|
||||
.navigationBarsPadding(),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
Column(
|
||||
Modifier
|
||||
.padding(
|
||||
top = 20.dp,
|
||||
bottom = 32.dp,
|
||||
start = 32.dp,
|
||||
end = 32.dp,
|
||||
)
|
||||
.fillMaxSize()
|
||||
.weight(1f),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
Artwork()
|
||||
|
||||
SpacerH(50.dp)
|
||||
|
||||
Text(
|
||||
text = when (state.mode) {
|
||||
OnboardingVisaWelcomeUM.Mode.Hello -> "Hello, ${state.userName}!"
|
||||
OnboardingVisaWelcomeUM.Mode.WelcomeBack -> "Welcome back, ${state.userName}!"
|
||||
},
|
||||
style = TangemTheme.typography.h2,
|
||||
color = TangemTheme.colors.text.primary1,
|
||||
)
|
||||
|
||||
SpacerH12()
|
||||
|
||||
Text(
|
||||
text = when (state.mode) {
|
||||
OnboardingVisaWelcomeUM.Mode.Hello -> "bla bla bla //TODO"
|
||||
OnboardingVisaWelcomeUM.Mode.WelcomeBack -> "bla bla bla? //TODO"
|
||||
},
|
||||
style = TangemTheme.typography.body1,
|
||||
color = TangemTheme.colors.text.secondary,
|
||||
)
|
||||
}
|
||||
|
||||
when (state.mode) {
|
||||
OnboardingVisaWelcomeUM.Mode.Hello -> {
|
||||
PrimaryButton(
|
||||
modifier = Modifier
|
||||
.padding(start = 16.dp, end = 16.dp, bottom = 16.dp)
|
||||
.fillMaxWidth(),
|
||||
text = "Start Activation",
|
||||
onClick = state.onContinueClick,
|
||||
)
|
||||
}
|
||||
OnboardingVisaWelcomeUM.Mode.WelcomeBack -> {
|
||||
PrimaryButtonIconEnd(
|
||||
modifier = Modifier
|
||||
.padding(start = 16.dp, end = 16.dp, bottom = 16.dp)
|
||||
.fillMaxWidth(),
|
||||
text = "Start Activation",
|
||||
iconResId = R.drawable.ic_tangem_24,
|
||||
onClick = state.onContinueClick,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun Artwork(modifier: Modifier = Modifier) {
|
||||
Box(modifier) {
|
||||
val circleColor = TangemTheme.colors.background.secondary
|
||||
|
||||
Canvas(
|
||||
modifier = Modifier
|
||||
.align(Alignment.Center)
|
||||
.size(254.dp)
|
||||
.fillMaxSize(),
|
||||
) {
|
||||
drawCircle(
|
||||
color = circleColor,
|
||||
radius = size.width / 2,
|
||||
center = center,
|
||||
)
|
||||
}
|
||||
|
||||
AsyncImage(
|
||||
model = R.drawable.img_card_visa,
|
||||
contentDescription = null,
|
||||
modifier = Modifier
|
||||
.align(Alignment.Center)
|
||||
.size(128.dp), // Adjust the size as needed
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(showBackground = true)
|
||||
@Composable
|
||||
private fun Preview() {
|
||||
TangemThemePreview {
|
||||
OnboardingVisaWelcome(state = OnboardingVisaWelcomeUM())
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
package com.tangem.features.onboarding.v2.visa.impl.child.welcome.ui.state
|
||||
|
||||
internal data class OnboardingVisaWelcomeUM(
|
||||
val mode: Mode = Mode.Hello,
|
||||
val userName: String = "",
|
||||
val onContinueClick: () -> Unit = {},
|
||||
) {
|
||||
enum class Mode {
|
||||
Hello, WelcomeBack
|
||||
}
|
||||
}
|
||||
|
|
@ -13,10 +13,10 @@ import androidx.compose.ui.Alignment
|
|||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import com.tangem.core.ui.components.SecondaryButton
|
||||
import com.tangem.core.ui.components.SpacerH32
|
||||
import com.tangem.core.ui.components.SpacerW8
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.feature.onboarding.R
|
||||
import com.tangem.feature.onboarding.presentation.wallet2.model.AboutState
|
||||
|
|
@ -56,7 +56,7 @@ fun AboutSeedPhraseScreen(state: AboutState, modifier: Modifier = Modifier) {
|
|||
SecondaryButton(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth(),
|
||||
text = stringResource(id = R.string.onboarding_seed_intro_button_generate),
|
||||
text = stringResourceSafe(id = R.string.onboarding_seed_intro_button_generate),
|
||||
enabled = state.buttonGenerateSeedPhrase.enabled,
|
||||
showProgress = state.buttonGenerateSeedPhrase.showProgress,
|
||||
onClick = state.buttonGenerateSeedPhrase.onClick,
|
||||
|
|
@ -66,7 +66,7 @@ fun AboutSeedPhraseScreen(state: AboutState, modifier: Modifier = Modifier) {
|
|||
SecondaryButton(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth(),
|
||||
text = stringResource(id = R.string.onboarding_seed_intro_button_import),
|
||||
text = stringResourceSafe(id = R.string.onboarding_seed_intro_button_import),
|
||||
enabled = state.buttonImportSeedPhrase.enabled,
|
||||
showProgress = state.buttonImportSeedPhrase.showProgress,
|
||||
onClick = state.buttonImportSeedPhrase.onClick,
|
||||
|
|
@ -105,7 +105,7 @@ private fun EditIconBlock() {
|
|||
horizontal = TangemTheme.dimens.size12,
|
||||
vertical = TangemTheme.dimens.size4,
|
||||
),
|
||||
text = stringResource(id = R.string.onboarding_seed_phrase_intro_legacy),
|
||||
text = stringResourceSafe(id = R.string.onboarding_seed_phrase_intro_legacy),
|
||||
color = TangemTheme.colors.text.warning,
|
||||
style = TangemTheme.typography.body1,
|
||||
)
|
||||
|
|
@ -143,7 +143,7 @@ private fun ReadMoreBlock(state: AboutState) {
|
|||
)
|
||||
SpacerW8()
|
||||
Text(
|
||||
text = stringResource(id = R.string.onboarding_seed_button_read_more),
|
||||
text = stringResourceSafe(id = R.string.onboarding_seed_button_read_more),
|
||||
color = TangemTheme.colors.text.primary1,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,10 +4,10 @@ import androidx.compose.foundation.layout.*
|
|||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import com.tangem.core.ui.R
|
||||
import com.tangem.core.ui.components.OutlineTextField
|
||||
import com.tangem.core.ui.components.PrimaryButtonIconEnd
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.feature.onboarding.presentation.wallet2.model.CheckSeedPhraseState
|
||||
import com.tangem.feature.onboarding.presentation.wallet2.ui.components.Description
|
||||
|
|
@ -29,7 +29,6 @@ fun CheckSeedPhraseScreen(state: CheckSeedPhraseState, modifier: Modifier = Modi
|
|||
.weight(1f)
|
||||
.fillMaxWidth(),
|
||||
) {
|
||||
|
||||
item {
|
||||
OnboardingDescriptionBlock(
|
||||
modifier = Modifier
|
||||
|
|
@ -59,7 +58,7 @@ fun CheckSeedPhraseScreen(state: CheckSeedPhraseState, modifier: Modifier = Modi
|
|||
PrimaryButtonIconEnd(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth(),
|
||||
text = stringResource(id = R.string.onboarding_create_wallet_button_create_wallet),
|
||||
text = stringResourceSafe(id = R.string.onboarding_create_wallet_button_create_wallet),
|
||||
iconResId = R.drawable.ic_tangem_24,
|
||||
enabled = state.buttonCreateWallet.enabled,
|
||||
showProgress = state.buttonCreateWallet.showProgress,
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@ import androidx.compose.runtime.remember
|
|||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.SpanStyle
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
|
|
@ -22,8 +21,9 @@ import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameter
|
|||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.IntOffset
|
||||
import com.tangem.core.ui.components.*
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.feature.onboarding.R
|
||||
import com.tangem.feature.onboarding.presentation.wallet2.model.ButtonState
|
||||
import com.tangem.feature.onboarding.presentation.wallet2.model.ImportSeedPhraseState
|
||||
|
|
@ -49,7 +49,7 @@ fun ImportSeedPhraseScreen(state: ImportSeedPhraseState, modifier: Modifier = Mo
|
|||
OnboardingDescriptionBlock(
|
||||
modifier = Modifier.padding(top = TangemTheme.dimens.size16),
|
||||
) {
|
||||
DescriptionSubTitleText(text = stringResource(id = R.string.onboarding_seed_import_message))
|
||||
DescriptionSubTitleText(text = stringResourceSafe(id = R.string.onboarding_seed_import_message))
|
||||
}
|
||||
PhraseBlock(
|
||||
modifier = Modifier
|
||||
|
|
@ -70,7 +70,7 @@ fun ImportSeedPhraseScreen(state: ImportSeedPhraseState, modifier: Modifier = Mo
|
|||
PrimaryButtonIconEnd(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth(),
|
||||
text = stringResource(id = R.string.common_import),
|
||||
text = stringResourceSafe(id = R.string.common_import),
|
||||
iconResId = R.drawable.ic_tangem_24,
|
||||
enabled = state.buttonCreateWallet.enabled,
|
||||
showProgress = state.buttonCreateWallet.showProgress,
|
||||
|
|
@ -108,8 +108,8 @@ private fun PassphraseBlock(
|
|||
onValueChange = passphraseField.onTextFieldValueChanged,
|
||||
iconResId = R.drawable.ic_information_24,
|
||||
iconColor = TangemTheme.colors.icon.informative,
|
||||
label = stringResource(id = R.string.common_passphrase),
|
||||
placeholder = stringResource(id = R.string.send_optional_field),
|
||||
label = stringResourceSafe(id = R.string.common_passphrase),
|
||||
placeholder = stringResourceSafe(id = R.string.send_optional_field),
|
||||
onIconClick = onPassphraseInfoClick,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,11 +8,11 @@ import androidx.compose.ui.Modifier
|
|||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import coil.compose.SubcomposeAsyncImage
|
||||
import coil.request.ImageRequest
|
||||
import com.tangem.core.ui.components.PrimaryButtonIconEnd
|
||||
import com.tangem.core.ui.components.SecondaryButton
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.feature.onboarding.R
|
||||
import com.tangem.feature.onboarding.presentation.wallet2.model.IntroState
|
||||
|
|
@ -49,7 +49,7 @@ fun IntroScreen(state: IntroState, modifier: Modifier = Modifier) {
|
|||
PrimaryButtonIconEnd(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth(),
|
||||
text = stringResource(id = R.string.onboarding_create_wallet_button_create_wallet),
|
||||
text = stringResourceSafe(id = R.string.onboarding_create_wallet_button_create_wallet),
|
||||
iconResId = R.drawable.ic_tangem_24,
|
||||
enabled = state.buttonCreateWallet.enabled,
|
||||
showProgress = state.buttonCreateWallet.showProgress,
|
||||
|
|
@ -60,7 +60,7 @@ fun IntroScreen(state: IntroState, modifier: Modifier = Modifier) {
|
|||
SecondaryButton(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth(),
|
||||
text = stringResource(id = R.string.onboarding_create_wallet_options_button_options),
|
||||
text = stringResourceSafe(id = R.string.onboarding_create_wallet_options_button_options),
|
||||
enabled = state.buttonOtherOptions.enabled,
|
||||
showProgress = state.buttonOtherOptions.showProgress,
|
||||
onClick = state.buttonOtherOptions.onClick,
|
||||
|
|
|
|||
|
|
@ -11,12 +11,12 @@ 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.text.style.TextAlign
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import com.tangem.core.ui.components.PrimaryButton
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheet
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.feature.onboarding.R
|
||||
|
|
@ -50,7 +50,7 @@ fun PassphraseInfoBottomSheetContent(content: ShowPassphraseInfoBottomSheetConte
|
|||
)
|
||||
|
||||
Text(
|
||||
text = stringResource(id = R.string.common_passphrase),
|
||||
text = stringResourceSafe(id = R.string.common_passphrase),
|
||||
modifier = Modifier
|
||||
.padding(top = TangemTheme.dimens.size40)
|
||||
.align(Alignment.CenterHorizontally),
|
||||
|
|
@ -59,7 +59,7 @@ fun PassphraseInfoBottomSheetContent(content: ShowPassphraseInfoBottomSheetConte
|
|||
)
|
||||
|
||||
Text(
|
||||
text = stringResource(id = R.string.onboarding_bottom_sheet_passphrase_description),
|
||||
text = stringResourceSafe(id = R.string.onboarding_bottom_sheet_passphrase_description),
|
||||
modifier = Modifier
|
||||
.padding(top = TangemTheme.dimens.size16)
|
||||
.padding(horizontal = TangemTheme.dimens.size24)
|
||||
|
|
@ -75,7 +75,7 @@ fun PassphraseInfoBottomSheetContent(content: ShowPassphraseInfoBottomSheetConte
|
|||
.padding(top = TangemTheme.dimens.size40)
|
||||
.padding(bottom = TangemTheme.dimens.size32)
|
||||
.fillMaxWidth(),
|
||||
text = stringResource(id = R.string.common_ok),
|
||||
text = stringResourceSafe(id = R.string.common_ok),
|
||||
onClick = content.onOkClick,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,13 +9,13 @@ 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.pluralStringResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import com.tangem.core.ui.components.PrimaryButton
|
||||
import com.tangem.core.ui.components.SpacerH16
|
||||
import com.tangem.core.ui.components.buttons.segmentedbutton.SegmentedButtons
|
||||
import com.tangem.core.ui.extensions.pluralStringResourceSafe
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.feature.onboarding.R
|
||||
|
|
@ -60,7 +60,7 @@ fun YourSeedPhraseScreen(state: YourSeedPhraseState, modifier: Modifier = Modifi
|
|||
firstActionContent = {
|
||||
PrimaryButton(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
text = stringResource(id = R.string.common_continue),
|
||||
text = stringResourceSafe(id = R.string.common_continue),
|
||||
onClick = state.buttonContinue.onClick,
|
||||
)
|
||||
},
|
||||
|
|
@ -77,10 +77,10 @@ private fun TitleBlock(state: SegmentSeedState) {
|
|||
.fillMaxWidth(),
|
||||
) {
|
||||
Column {
|
||||
DescriptionTitleText(text = stringResource(id = R.string.onboarding_seed_generate_title))
|
||||
DescriptionTitleText(text = stringResourceSafe(id = R.string.onboarding_seed_generate_title))
|
||||
SpacerH16()
|
||||
DescriptionSubTitleText(
|
||||
text = pluralStringResource(
|
||||
text = pluralStringResourceSafe(
|
||||
id = R.plurals.onboarding_seed_generate_message_words_count,
|
||||
count = state.selectedSeedType.count,
|
||||
state.selectedSeedType.count,
|
||||
|
|
@ -101,7 +101,7 @@ private fun SegmentSeedBlock(state: SegmentSeedState, modifier: Modifier = Modif
|
|||
},
|
||||
) {
|
||||
Text(
|
||||
text = pluralStringResource(
|
||||
text = pluralStringResourceSafe(
|
||||
id = R.plurals.onboarding_seed_generate_words_count,
|
||||
count = it.count,
|
||||
it.count,
|
||||
|
|
|
|||
|
|
@ -8,10 +8,10 @@ import androidx.compose.foundation.layout.padding
|
|||
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.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.sp
|
||||
import com.tangem.core.ui.components.SpacerH16
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
|
||||
/**
|
||||
|
|
@ -31,9 +31,9 @@ fun OnboardingDescriptionBlock(modifier: Modifier = Modifier, content: @Composab
|
|||
@Composable
|
||||
fun Description(@StringRes titleRes: Int, @StringRes subTitleRes: Int) {
|
||||
Column {
|
||||
DescriptionTitleText(text = stringResource(id = titleRes))
|
||||
DescriptionTitleText(text = stringResourceSafe(id = titleRes))
|
||||
SpacerH16()
|
||||
DescriptionSubTitleText(text = stringResource(id = subTitleRes))
|
||||
DescriptionSubTitleText(text = stringResourceSafe(id = subTitleRes))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ import androidx.compose.ui.Alignment
|
|||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.platform.LocalDensity
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
|
|
@ -23,6 +22,7 @@ import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
|
|||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfigContent
|
||||
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
|
||||
import com.tangem.features.onramp.confirmresidency.ConfirmResidencyComponent
|
||||
|
|
@ -55,7 +55,7 @@ internal fun ConfirmResidencyBottomSheetContent(model: ConfirmResidencyUM, modif
|
|||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(top = TangemTheme.dimens.spacing10),
|
||||
text = stringResource(id = R.string.onramp_residency_bottomsheet_title),
|
||||
text = stringResourceSafe(id = R.string.onramp_residency_bottomsheet_title),
|
||||
style = TangemTheme.typography.subtitle1,
|
||||
color = TangemTheme.colors.text.primary1,
|
||||
textAlign = TextAlign.Center,
|
||||
|
|
@ -114,7 +114,7 @@ private fun CountryContent(name: String, flagUrl: String, isCountrySupported: Bo
|
|||
if (!isCountrySupported) {
|
||||
Text(
|
||||
modifier = Modifier.padding(top = TangemTheme.dimens.spacing6),
|
||||
text = stringResource(id = R.string.onramp_residency_bottomsheet_country_not_supported),
|
||||
text = stringResourceSafe(id = R.string.onramp_residency_bottomsheet_country_not_supported),
|
||||
color = TangemTheme.colors.text.warning,
|
||||
style = TangemTheme.typography.body2,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
package com.tangem.features.onramp.main.model
|
||||
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import com.arkivanov.decompose.router.slot.SlotNavigation
|
||||
import com.arkivanov.decompose.router.slot.activate
|
||||
import com.tangem.common.ui.alerts.models.AlertDemoModeUM
|
||||
|
|
@ -14,6 +13,7 @@ import com.tangem.core.navigation.url.UrlOpener
|
|||
import com.tangem.core.ui.components.BasicDialog
|
||||
import com.tangem.core.ui.components.DialogButtonUM
|
||||
import com.tangem.core.ui.extensions.resolveReference
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.core.ui.message.ContentMessage
|
||||
import com.tangem.domain.demo.IsDemoCardUseCase
|
||||
import com.tangem.domain.onramp.*
|
||||
|
|
@ -358,7 +358,7 @@ internal class OnrampMainComponentModel @Inject constructor(
|
|||
)
|
||||
|
||||
val dismissButton = DialogButtonUM(
|
||||
title = stringResource(id = R.string.common_cancel),
|
||||
title = stringResourceSafe(id = R.string.common_cancel),
|
||||
onClick = onDismiss,
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -13,11 +13,11 @@ import androidx.compose.runtime.Composable
|
|||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.SpanStyle
|
||||
import androidx.compose.ui.text.buildAnnotatedString
|
||||
import androidx.compose.ui.text.withStyle
|
||||
import com.tangem.core.ui.extensions.appendSpace
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.features.onramp.impl.R
|
||||
import com.tangem.features.onramp.main.entity.OnrampProviderBlockUM
|
||||
|
|
@ -47,7 +47,7 @@ private fun OnrampProviderBlock(state: OnrampProviderBlockUM.Content, modifier:
|
|||
Column(modifier = Modifier.weight(1F)) {
|
||||
Text(
|
||||
text = buildAnnotatedString {
|
||||
append(stringResource(id = R.string.onramp_pay_with))
|
||||
append(stringResourceSafe(id = R.string.onramp_pay_with))
|
||||
appendSpace()
|
||||
withStyle(
|
||||
style = SpanStyle(
|
||||
|
|
@ -63,7 +63,7 @@ private fun OnrampProviderBlock(state: OnrampProviderBlockUM.Content, modifier:
|
|||
)
|
||||
Text(
|
||||
text = buildAnnotatedString {
|
||||
append(stringResource(id = R.string.onramp_via))
|
||||
append(stringResourceSafe(id = R.string.onramp_via))
|
||||
appendSpace()
|
||||
append(state.providerName)
|
||||
},
|
||||
|
|
@ -87,7 +87,7 @@ private fun OnrampProviderBlock(state: OnrampProviderBlockUM.Content, modifier:
|
|||
horizontal = TangemTheme.dimens.spacing6,
|
||||
vertical = TangemTheme.dimens.spacing1,
|
||||
),
|
||||
text = stringResource(id = R.string.express_provider_best_rate),
|
||||
text = stringResourceSafe(id = R.string.express_provider_best_rate),
|
||||
style = TangemTheme.typography.caption1,
|
||||
color = TangemTheme.colors.text.primary2,
|
||||
)
|
||||
|
|
@ -105,7 +105,7 @@ private fun OnrampProviderLoading(modifier: Modifier = Modifier) {
|
|||
verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing8),
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(id = R.string.express_provider),
|
||||
text = stringResourceSafe(id = R.string.express_provider),
|
||||
style = TangemTheme.typography.subtitle2,
|
||||
color = TangemTheme.colors.text.tertiary,
|
||||
)
|
||||
|
|
@ -119,7 +119,7 @@ private fun OnrampProviderLoading(modifier: Modifier = Modifier) {
|
|||
modifier = Modifier.size(TangemTheme.dimens.size16),
|
||||
)
|
||||
Text(
|
||||
text = stringResource(id = R.string.express_fetch_best_rates),
|
||||
text = stringResourceSafe(id = R.string.express_fetch_best_rates),
|
||||
style = TangemTheme.typography.body2,
|
||||
color = TangemTheme.colors.text.tertiary,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@ import androidx.compose.ui.graphics.vector.ImageVector
|
|||
import androidx.compose.ui.graphics.vector.rememberVectorPainter
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.res.vectorResource
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
|
|
@ -33,6 +32,7 @@ import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfigContent
|
|||
import com.tangem.core.ui.extensions.TextReference
|
||||
import com.tangem.core.ui.extensions.resolveReference
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.domain.onramp.model.OnrampPaymentMethod
|
||||
|
|
@ -61,7 +61,7 @@ internal fun SelectProviderBottomSheetContent(state: SelectPaymentAndProviderUM,
|
|||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(id = R.string.onramp_choose_provider_title_hint),
|
||||
text = stringResourceSafe(id = R.string.onramp_choose_provider_title_hint),
|
||||
style = TangemTheme.typography.caption2,
|
||||
color = TangemTheme.colors.text.secondary,
|
||||
textAlign = TextAlign.Center,
|
||||
|
|
@ -102,7 +102,7 @@ private fun PaymentMethodBlock(
|
|||
PaymentMethodIcon(imageUrl = state.imageUrl)
|
||||
Column(modifier = Modifier.weight(1F)) {
|
||||
Text(
|
||||
text = stringResource(id = R.string.onramp_pay_with),
|
||||
text = stringResourceSafe(id = R.string.onramp_pay_with),
|
||||
style = TangemTheme.typography.body2,
|
||||
color = TangemTheme.colors.text.tertiary,
|
||||
)
|
||||
|
|
@ -193,7 +193,7 @@ private fun AvailableProviderItem(state: ProviderListItemUM.Available.Content, m
|
|||
when {
|
||||
state.isBestRate -> {
|
||||
Text(
|
||||
text = stringResource(R.string.express_provider_best_rate),
|
||||
text = stringResourceSafe(R.string.express_provider_best_rate),
|
||||
style = TangemTheme.typography.caption1,
|
||||
color = TangemTheme.colors.text.constantWhite,
|
||||
modifier = Modifier
|
||||
|
|
@ -278,7 +278,7 @@ private fun OnrampMoreProviders() {
|
|||
.padding(top = 16.dp),
|
||||
)
|
||||
Text(
|
||||
text = stringResource(R.string.express_more_providers_soon),
|
||||
text = stringResourceSafe(R.string.express_more_providers_soon),
|
||||
style = TangemTheme.typography.caption2,
|
||||
color = TangemTheme.colors.icon.informative,
|
||||
modifier = Modifier
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
package com.tangem.features.onramp.redirect.model
|
||||
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import com.tangem.core.analytics.api.AnalyticsEventHandler
|
||||
import com.tangem.core.decompose.model.Model
|
||||
import com.tangem.core.decompose.model.ParamsContainer
|
||||
|
|
@ -10,10 +9,7 @@ import com.tangem.core.navigation.url.UrlOpener
|
|||
import com.tangem.core.ui.components.BasicDialog
|
||||
import com.tangem.core.ui.components.DialogButtonUM
|
||||
import com.tangem.core.ui.components.appbar.models.TopAppBarButtonUM
|
||||
import com.tangem.core.ui.extensions.combinedReference
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.extensions.stringReference
|
||||
import com.tangem.core.ui.extensions.wrappedList
|
||||
import com.tangem.core.ui.extensions.*
|
||||
import com.tangem.core.ui.message.ContentMessage
|
||||
import com.tangem.domain.onramp.GetOnrampRedirectUrlUseCase
|
||||
import com.tangem.domain.onramp.model.error.OnrampError
|
||||
|
|
@ -88,9 +84,9 @@ internal class OnrampRedirectModel @Inject constructor(
|
|||
)
|
||||
val contentMessage = ContentMessage { onDismiss ->
|
||||
BasicDialog(
|
||||
message = stringResource(id = R.string.common_unknown_error),
|
||||
message = stringResourceSafe(id = R.string.common_unknown_error),
|
||||
confirmButton = DialogButtonUM(
|
||||
title = stringResource(id = R.string.common_ok),
|
||||
title = stringResourceSafe(id = R.string.common_ok),
|
||||
onClick = {
|
||||
params.onBack()
|
||||
onDismiss()
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ import androidx.compose.ui.Alignment
|
|||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.alpha
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import coil.compose.AsyncImage
|
||||
import com.tangem.core.ui.components.CircleShimmer
|
||||
|
|
@ -24,6 +23,7 @@ import com.tangem.core.ui.components.buttons.SecondarySmallButton
|
|||
import com.tangem.core.ui.components.buttons.SmallButtonConfig
|
||||
import com.tangem.core.ui.components.fields.SearchBar
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.features.onramp.impl.R
|
||||
import com.tangem.features.onramp.selectcountry.entity.CountryItemState
|
||||
|
|
@ -67,7 +67,7 @@ private fun LazyListScope.countryListError(state: CountryListUM.Error) {
|
|||
verticalArrangement = Arrangement.Center,
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(id = R.string.markets_loading_error_title),
|
||||
text = stringResourceSafe(id = R.string.markets_loading_error_title),
|
||||
style = TangemTheme.typography.caption1,
|
||||
color = TangemTheme.colors.text.tertiary,
|
||||
)
|
||||
|
|
@ -185,7 +185,7 @@ private fun UnavailableCountryItem(state: CountryItemState.WithContent.Unavailab
|
|||
color = TangemTheme.colors.text.disabled,
|
||||
)
|
||||
Text(
|
||||
text = stringResource(R.string.onramp_country_unavailable),
|
||||
text = stringResourceSafe(R.string.onramp_country_unavailable),
|
||||
maxLines = 1,
|
||||
style = TangemTheme.typography.body2,
|
||||
color = TangemTheme.colors.text.tertiary,
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ import androidx.compose.runtime.Composable
|
|||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.util.fastForEach
|
||||
import coil.compose.AsyncImage
|
||||
import com.tangem.core.ui.components.CircleShimmer
|
||||
|
|
@ -24,6 +23,7 @@ import com.tangem.core.ui.components.buttons.SmallButtonConfig
|
|||
import com.tangem.core.ui.components.fields.SearchBar
|
||||
import com.tangem.core.ui.extensions.resolveReference
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.features.onramp.impl.R
|
||||
import com.tangem.features.onramp.selectcurrency.entity.CurrenciesListUM
|
||||
|
|
@ -67,7 +67,7 @@ private fun LazyListScope.currencyListError(state: CurrenciesListUM.Error) {
|
|||
verticalArrangement = Arrangement.Center,
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(id = R.string.markets_loading_error_title),
|
||||
text = stringResourceSafe(id = R.string.markets_loading_error_title),
|
||||
style = TangemTheme.typography.caption1,
|
||||
color = TangemTheme.colors.text.tertiary,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
package com.tangem.features.onramp.selecttoken.model
|
||||
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import arrow.core.getOrElse
|
||||
import com.tangem.common.routing.AppRouter
|
||||
import com.tangem.common.ui.alerts.models.AlertDemoModeUM
|
||||
|
|
@ -14,6 +13,7 @@ import com.tangem.core.decompose.ui.UiMessageSender
|
|||
import com.tangem.core.ui.components.BasicDialog
|
||||
import com.tangem.core.ui.components.DialogButtonUM
|
||||
import com.tangem.core.ui.extensions.resolveReference
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.core.ui.message.ContentMessage
|
||||
import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
|
||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
|
|
@ -141,7 +141,7 @@ internal class OnrampOperationModel @Inject constructor(
|
|||
)
|
||||
|
||||
val dismissButton = DialogButtonUM(
|
||||
title = stringResource(id = R.string.common_cancel),
|
||||
title = stringResourceSafe(id = R.string.common_cancel),
|
||||
onClick = onDismiss,
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -10,9 +10,9 @@ import androidx.compose.foundation.lazy.LazyColumn
|
|||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.tangem.core.ui.components.appbar.AppBarWithBackButton
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.utils.rememberHideKeyboardNestedScrollConnection
|
||||
import com.tangem.features.onramp.impl.R
|
||||
|
|
@ -39,7 +39,7 @@ internal fun OnrampSelectToken(
|
|||
stickyHeader(key = "header") {
|
||||
AppBarWithBackButton(
|
||||
onBackClick = state.onBackClick,
|
||||
text = stringResource(id = state.titleResId),
|
||||
text = stringResourceSafe(id = state.titleResId),
|
||||
iconRes = R.drawable.ic_close_24,
|
||||
containerColor = TangemTheme.colors.background.secondary,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -13,11 +13,11 @@ import androidx.compose.ui.Alignment
|
|||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.util.fastForEach
|
||||
import coil.compose.AsyncImage
|
||||
import com.tangem.core.ui.components.SpacerWMax
|
||||
import com.tangem.core.ui.components.appbar.AppBarWithBackButton
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.utils.WindowInsetsZero
|
||||
import com.tangem.features.onramp.impl.R
|
||||
|
|
@ -35,7 +35,7 @@ internal fun OnrampSettingsContent(state: OnrampSettingsUM, modifier: Modifier =
|
|||
AppBarWithBackButton(
|
||||
modifier = Modifier.statusBarsPadding(),
|
||||
onBackClick = state.onBack,
|
||||
text = stringResource(id = R.string.onramp_settings_title),
|
||||
text = stringResourceSafe(id = R.string.onramp_settings_title),
|
||||
iconRes = R.drawable.ic_close_24,
|
||||
)
|
||||
},
|
||||
|
|
@ -81,7 +81,7 @@ private fun ResidenceSection(state: OnrampSettingsItemUM.Residence, modifier: Mo
|
|||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(id = R.string.onramp_settings_residence),
|
||||
text = stringResourceSafe(id = R.string.onramp_settings_residence),
|
||||
color = TangemTheme.colors.text.tertiary,
|
||||
style = TangemTheme.typography.subtitle2,
|
||||
)
|
||||
|
|
@ -103,7 +103,7 @@ private fun ResidenceSection(state: OnrampSettingsItemUM.Residence, modifier: Mo
|
|||
)
|
||||
}
|
||||
Text(
|
||||
text = stringResource(id = R.string.onramp_settings_residence_description),
|
||||
text = stringResourceSafe(id = R.string.onramp_settings_residence_description),
|
||||
color = TangemTheme.colors.text.tertiary,
|
||||
style = TangemTheme.typography.caption2,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ import androidx.compose.ui.Alignment
|
|||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
|
|
@ -27,10 +26,7 @@ import com.tangem.core.ui.components.appbar.TangemTopAppBar
|
|||
import com.tangem.core.ui.components.appbar.models.TopAppBarButtonUM
|
||||
import com.tangem.core.ui.components.containers.FooterContainer
|
||||
import com.tangem.core.ui.components.transactions.TransactionDoneTitle
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
import com.tangem.core.ui.extensions.resolveReference
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.extensions.wrappedList
|
||||
import com.tangem.core.ui.extensions.*
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.core.ui.utils.DateTimeFormatters
|
||||
|
|
@ -73,7 +69,7 @@ private fun Content(state: OnrampSuccessComponentUM.Content, onBackClick: () ->
|
|||
},
|
||||
bottomBar = {
|
||||
PrimaryButton(
|
||||
text = stringResource(R.string.common_close),
|
||||
text = stringResourceSafe(R.string.common_close),
|
||||
onClick = onBackClick,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
|
|
@ -171,7 +167,7 @@ private fun AmountProviderBlock(providerName: TextReference, providerImageUrl: S
|
|||
horizontalArrangement = Arrangement.spacedBy(6.dp),
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(R.string.common_with),
|
||||
text = stringResourceSafe(R.string.common_with),
|
||||
style = TangemTheme.typography.body2,
|
||||
color = TangemTheme.colors.text.tertiary,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@ import androidx.compose.runtime.Composable
|
|||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
|
|
@ -25,10 +24,7 @@ import com.tangem.core.ui.components.marketprice.PriceChangeType
|
|||
import com.tangem.core.ui.components.rows.NetworkTitle
|
||||
import com.tangem.core.ui.components.token.TokenItem
|
||||
import com.tangem.core.ui.components.token.state.TokenItemState
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
import com.tangem.core.ui.extensions.resolveReference
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.extensions.stringReference
|
||||
import com.tangem.core.ui.extensions.*
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.core.ui.utils.dashedBorder
|
||||
|
|
@ -98,7 +94,7 @@ private fun RemoveButton(state: ExchangeCardUM.RemoveButtonUM?) {
|
|||
state ?: return@AnimatedVisibility
|
||||
|
||||
Text(
|
||||
text = stringResource(id = R.string.manage_tokens_remove),
|
||||
text = stringResourceSafe(id = R.string.manage_tokens_remove),
|
||||
modifier = Modifier.clickable(
|
||||
indication = ripple(bounded = false),
|
||||
interactionSource = remember { MutableInteractionSource() },
|
||||
|
|
|
|||
|
|
@ -13,9 +13,9 @@ import androidx.compose.runtime.Composable
|
|||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.tangem.core.ui.components.appbar.AppBarWithBackButton
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.utils.rememberHideKeyboardNestedScrollConnection
|
||||
import com.tangem.features.onramp.impl.R
|
||||
|
|
@ -59,7 +59,7 @@ internal fun SwapSelectTokens(
|
|||
stickyHeader(key = "header") {
|
||||
AppBarWithBackButton(
|
||||
onBackClick = state.onBackClick,
|
||||
text = stringResource(id = R.string.common_swap),
|
||||
text = stringResourceSafe(id = R.string.common_swap),
|
||||
iconRes = R.drawable.ic_close_24,
|
||||
containerColor = TangemTheme.colors.background.secondary,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@ import com.tangem.feature.qrscanning.viewmodel.QrScanningViewModel
|
|||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
import java.io.IOException
|
||||
import java.util.concurrent.ExecutorService
|
||||
import java.util.concurrent.Executors
|
||||
import javax.inject.Inject
|
||||
|
|
@ -62,8 +64,15 @@ internal class QrScanningFragment : ComposeFragment() {
|
|||
private val galleryLauncher = registerForActivityResult(ActivityResultContracts.GetContent()) {
|
||||
val selectedImage = it ?: Uri.EMPTY
|
||||
if (selectedImage != Uri.EMPTY) {
|
||||
val image = InputImage.fromFilePath(requireContext(), selectedImage)
|
||||
analyzer.analyze(image)
|
||||
val mimeType = requireContext().contentResolver.getType(selectedImage)
|
||||
if (mimeType.isImageMimeType()) {
|
||||
try {
|
||||
val image = InputImage.fromFilePath(requireContext(), selectedImage)
|
||||
analyzer.analyze(image)
|
||||
} catch (e: IOException) {
|
||||
Timber.e(e, "Unable to get image $selectedImage from gallery")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -80,7 +89,7 @@ internal class QrScanningFragment : ComposeFragment() {
|
|||
repeatOnLifecycle(Lifecycle.State.STARTED) {
|
||||
viewModel.launchGalleryEvent
|
||||
.collect {
|
||||
galleryLauncher.launch(it.imageFilter)
|
||||
galleryLauncher.launch(GALLERY_IMAGE_FILTER)
|
||||
delay(timeMillis = 2000)
|
||||
}
|
||||
}
|
||||
|
|
@ -137,8 +146,13 @@ internal class QrScanningFragment : ComposeFragment() {
|
|||
}
|
||||
}
|
||||
|
||||
private fun String?.isImageMimeType() = this?.startsWith(prefix = "$IMAGE_MIME_TYPE/") == true
|
||||
|
||||
companion object {
|
||||
|
||||
private const val IMAGE_MIME_TYPE = "image"
|
||||
private const val GALLERY_IMAGE_FILTER = "$IMAGE_MIME_TYPE/*"
|
||||
|
||||
fun create() = QrScanningFragment()
|
||||
}
|
||||
}
|
||||
|
|
@ -3,6 +3,7 @@ package com.tangem.feature.qrscanning.presentation
|
|||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfigContent
|
||||
|
||||
data class CameraDeniedBottomSheetConfig(
|
||||
val onSettingsClick: () -> Unit,
|
||||
val onGalleryClick: () -> Unit,
|
||||
val onCancelClick: () -> Unit,
|
||||
) : TangemBottomSheetConfigContent
|
||||
|
|
@ -1,9 +1,6 @@
|
|||
package com.tangem.feature.qrscanning.presentation
|
||||
|
||||
import android.content.Intent
|
||||
import android.content.res.Configuration
|
||||
import android.net.Uri
|
||||
import android.provider.Settings
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.padding
|
||||
|
|
@ -11,13 +8,11 @@ import androidx.compose.material3.Text
|
|||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.core.content.ContextCompat
|
||||
import com.tangem.core.ui.components.SimpleSettingsRow
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheet
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.feature.qrscanning.impl.R
|
||||
|
|
@ -36,26 +31,19 @@ fun CameraDeniedBottomSheet(config: TangemBottomSheetConfig) {
|
|||
|
||||
@Composable
|
||||
private fun CameraDeniedBottomSheet(content: CameraDeniedBottomSheetConfig) {
|
||||
val context = LocalContext.current
|
||||
Column {
|
||||
SimpleSettingsRow(
|
||||
title = stringResource(id = R.string.qr_scanner_camera_denied_settings_button),
|
||||
title = stringResourceSafe(id = R.string.qr_scanner_camera_denied_settings_button),
|
||||
icon = R.drawable.ic_settings_24,
|
||||
onItemsClick = {
|
||||
val intent = Intent(
|
||||
Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
|
||||
Uri.fromParts("package", context.packageName, null),
|
||||
)
|
||||
ContextCompat.startActivity(context, intent, null)
|
||||
},
|
||||
onItemsClick = content.onSettingsClick,
|
||||
)
|
||||
SimpleSettingsRow(
|
||||
title = stringResource(id = R.string.qr_scanner_camera_denied_gallery_button),
|
||||
title = stringResourceSafe(id = R.string.qr_scanner_camera_denied_gallery_button),
|
||||
icon = R.drawable.ic_gallery_24,
|
||||
onItemsClick = content.onGalleryClick,
|
||||
)
|
||||
SimpleSettingsRow(
|
||||
title = stringResource(id = R.string.common_close),
|
||||
title = stringResourceSafe(id = R.string.common_close),
|
||||
icon = R.drawable.ic_close_24,
|
||||
onItemsClick = content.onCancelClick,
|
||||
modifier = Modifier.padding(bottom = TangemTheme.dimens.spacing16),
|
||||
|
|
@ -75,12 +63,12 @@ private fun CameraDeniedBottomSheetHeader(modifier: Modifier = Modifier) {
|
|||
verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing4),
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(id = R.string.qr_scanner_camera_denied_title),
|
||||
text = stringResourceSafe(id = R.string.qr_scanner_camera_denied_title),
|
||||
style = TangemTheme.typography.subtitle1,
|
||||
color = TangemTheme.colors.text.primary1,
|
||||
)
|
||||
Text(
|
||||
text = stringResource(id = R.string.qr_scanner_camera_denied_text),
|
||||
text = stringResourceSafe(id = R.string.qr_scanner_camera_denied_text),
|
||||
style = TangemTheme.typography.body2,
|
||||
color = TangemTheme.colors.text.secondary,
|
||||
)
|
||||
|
|
@ -98,6 +86,7 @@ private fun Preview_CameraDeniedBottomSheet() {
|
|||
isShow = true,
|
||||
onDismissRequest = {},
|
||||
content = CameraDeniedBottomSheetConfig(
|
||||
onSettingsClick = {},
|
||||
onCancelClick = {},
|
||||
onGalleryClick = {},
|
||||
),
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ internal class ShowCameraDeniedBottomSheetTransformer(
|
|||
isShow = true,
|
||||
onDismissRequest = clickIntents::onBackClick,
|
||||
content = CameraDeniedBottomSheetConfig(
|
||||
onSettingsClick = clickIntents::onSettingsClick,
|
||||
onCancelClick = clickIntents::onBackClick,
|
||||
onGalleryClick = clickIntents::onGalleryClicked,
|
||||
),
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package com.tangem.feature.qrscanning.viewmodel
|
||||
|
||||
import com.tangem.core.navigation.settings.SettingsManager
|
||||
import com.tangem.domain.qrscanning.usecases.EmitQrScannedEventUseCase
|
||||
import com.tangem.feature.qrscanning.presentation.QrScanningStateController
|
||||
import com.tangem.feature.qrscanning.presentation.transformers.DismissBottomSheetTransformer
|
||||
|
|
@ -11,32 +12,30 @@ import kotlinx.coroutines.flow.SharedFlow
|
|||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
||||
interface QrScanningClickIntents {
|
||||
internal interface QrScanningClickIntents {
|
||||
|
||||
val launchGallery: SharedFlow<GalleryRequest>
|
||||
val launchGallery: SharedFlow<Unit>
|
||||
|
||||
fun onBackClick()
|
||||
|
||||
fun onQrScanned(qrCode: String)
|
||||
|
||||
fun onGalleryClicked()
|
||||
}
|
||||
|
||||
@JvmInline
|
||||
value class GalleryRequest(
|
||||
val imageFilter: String,
|
||||
)
|
||||
fun onSettingsClick()
|
||||
}
|
||||
|
||||
@ViewModelScoped
|
||||
internal class QrScanningClickIntentsImplementor @Inject constructor(
|
||||
private val stateHolder: QrScanningStateController,
|
||||
private val emitQrScannedEventUseCase: EmitQrScannedEventUseCase,
|
||||
private val settingsManager: SettingsManager,
|
||||
private val dispatcher: CoroutineDispatcherProvider,
|
||||
) : BaseQrScanningClickIntents(), QrScanningClickIntents {
|
||||
|
||||
private var isScanned = false
|
||||
|
||||
override val launchGallery = MutableSharedFlow<GalleryRequest>(
|
||||
override val launchGallery = MutableSharedFlow<Unit>(
|
||||
extraBufferCapacity = 1,
|
||||
onBufferOverflow = BufferOverflow.DROP_LATEST,
|
||||
)
|
||||
|
|
@ -56,13 +55,13 @@ internal class QrScanningClickIntentsImplementor @Inject constructor(
|
|||
}
|
||||
|
||||
override fun onGalleryClicked() {
|
||||
launchGallery.tryEmit(GalleryRequest(imageFilter = GALLERY_IMAGE_FILTER))
|
||||
launchGallery.tryEmit(Unit)
|
||||
if (stateHolder.value.bottomSheetConfig != null) {
|
||||
stateHolder.update(DismissBottomSheetTransformer())
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val GALLERY_IMAGE_FILTER = "image/*"
|
||||
override fun onSettingsClick() {
|
||||
settingsManager.openSettings()
|
||||
}
|
||||
}
|
||||
|
|
@ -31,7 +31,7 @@ internal class QrScanningViewModel @Inject constructor(
|
|||
private val network: String? = savedStateHandle[AppRoute.QrScanning.NETWORK_KEY]
|
||||
|
||||
val uiState: StateFlow<QrScanningState> = stateHolder.uiState
|
||||
val launchGalleryEvent: SharedFlow<GalleryRequest> = clickIntents.launchGallery
|
||||
val launchGalleryEvent: SharedFlow<Unit> = clickIntents.launchGallery
|
||||
|
||||
init {
|
||||
// samsung for some reason disables reader mode, and then it works unstable
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ dependencies {
|
|||
/** Core modules */
|
||||
implementation(projects.core.analytics)
|
||||
implementation(projects.core.analytics.models)
|
||||
implementation(projects.core.navigation)
|
||||
implementation(projects.core.res)
|
||||
implementation(projects.core.utils)
|
||||
implementation(projects.core.ui)
|
||||
|
|
@ -37,7 +38,6 @@ dependencies {
|
|||
|
||||
/** Other libraries */
|
||||
implementation(deps.compose.shimmer)
|
||||
implementation(deps.compose.accompanist.webView)
|
||||
implementation(deps.compose.accompanist.systemUiController)
|
||||
|
||||
/** DI */
|
||||
|
|
|
|||
|
|
@ -50,6 +50,6 @@ internal data class ReferralStateHolder(
|
|||
data class Analytics(
|
||||
val onAgreementClicked: () -> Unit,
|
||||
val onCopyClicked: () -> Unit,
|
||||
val onShareClicked: () -> Unit,
|
||||
val onShareClicked: (String) -> Unit,
|
||||
)
|
||||
}
|
||||
|
|
@ -1,66 +0,0 @@
|
|||
package com.tangem.feature.referral.ui
|
||||
|
||||
import android.content.res.Configuration
|
||||
import androidx.compose.foundation.background
|
||||
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.rememberScrollState
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalInspectionMode
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.google.accompanist.web.WebView
|
||||
import com.google.accompanist.web.rememberWebViewState
|
||||
import com.tangem.core.ui.components.appbar.TangemTopAppBar
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.core.ui.webview.applySafeSettings
|
||||
import com.tangem.feature.referral.presentation.R
|
||||
|
||||
/**
|
||||
* Bottom sheet content with referral program terms of use
|
||||
*
|
||||
* @param url link to the html page
|
||||
* @param bottomBarHeight bottom insets
|
||||
*/
|
||||
@Composable
|
||||
internal fun AgreementBottomSheetContent(url: String, bottomBarHeight: Dp) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.verticalScroll(rememberScrollState()),
|
||||
) {
|
||||
TangemTopAppBar(title = stringResource(id = R.string.details_referral_title))
|
||||
AgreementHtmlView(url = url)
|
||||
Spacer(modifier = Modifier.height(bottomBarHeight))
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun AgreementHtmlView(url: String) {
|
||||
val state = rememberWebViewState(url)
|
||||
val isInPreviewMode = LocalInspectionMode.current
|
||||
WebView(
|
||||
state = state,
|
||||
modifier = Modifier.background(TangemTheme.colors.background.primary),
|
||||
captureBackPresses = false,
|
||||
onCreated = {
|
||||
if (!isInPreviewMode) it.applySafeSettings()
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
@Composable
|
||||
private fun Preview_AgreementBottomSheet() {
|
||||
TangemThemePreview {
|
||||
AgreementBottomSheetContent(url = "https://tangem.com/en/", 50.dp)
|
||||
}
|
||||
}
|
||||
|
|
@ -9,20 +9,20 @@ import androidx.compose.foundation.layout.padding
|
|||
import androidx.compose.foundation.text.ClickableText
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.AnnotatedString
|
||||
import androidx.compose.ui.text.SpanStyle
|
||||
import androidx.compose.ui.text.buildAnnotatedString
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.text.withStyle
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.feature.referral.presentation.R
|
||||
|
||||
@Composable
|
||||
internal fun AgreementText(@StringRes firstPartResId: Int, onClick: () -> Unit) {
|
||||
val agreementText = annotatedAgreementString(firstPart = stringResource(firstPartResId))
|
||||
val agreementText = annotatedAgreementString(firstPart = stringResourceSafe(firstPartResId))
|
||||
ClickableText(
|
||||
text = agreementText,
|
||||
modifier = Modifier
|
||||
|
|
@ -46,10 +46,10 @@ private fun annotatedAgreementString(firstPart: String): AnnotatedString {
|
|||
append("$firstPart ")
|
||||
}
|
||||
withStyle(SpanStyle(color = TangemTheme.colors.text.accent)) {
|
||||
append(stringResource(id = R.string.common_terms_and_conditions))
|
||||
append(stringResourceSafe(id = R.string.common_terms_and_conditions))
|
||||
}
|
||||
withStyle(SpanStyle(color = TangemTheme.colors.text.tertiary)) {
|
||||
append(" ${stringResource(id = R.string.referral_tos_suffix)}")
|
||||
append(" ${stringResourceSafe(id = R.string.referral_tos_suffix)}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,9 +7,9 @@ import androidx.compose.foundation.layout.fillMaxWidth
|
|||
import androidx.compose.foundation.layout.padding
|
||||
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.PrimaryButtonIconEnd
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.feature.referral.presentation.R
|
||||
|
|
@ -23,7 +23,7 @@ internal fun NonParticipateBottomBlock(onAgreementClick: () -> Unit, onParticipa
|
|||
)
|
||||
|
||||
PrimaryButtonIconEnd(
|
||||
text = stringResource(id = R.string.referral_button_participate),
|
||||
text = stringResourceSafe(id = R.string.referral_button_participate),
|
||||
iconResId = R.drawable.ic_tangem_24,
|
||||
onClick = onParticipateClick,
|
||||
modifier = Modifier
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue