Updated on 2026-08-14
This commit is contained in:
parent
0dd4d45b62
commit
479a67f3be
19 changed files with 257 additions and 61 deletions
|
|
@ -0,0 +1,9 @@
|
|||
package com.tangem.feature.wallet.presentation.wallet.state
|
||||
|
||||
import androidx.compose.runtime.Immutable
|
||||
|
||||
@Immutable
|
||||
internal sealed class WalletAlertState {
|
||||
|
||||
data class WalletAlreadySignedHashes(val onUnderstandClick: () -> Unit) : WalletAlertState()
|
||||
}
|
||||
|
|
@ -13,4 +13,6 @@ internal sealed class WalletEvent {
|
|||
data class ShowToast(val text: TextReference) : WalletEvent()
|
||||
|
||||
data class CopyAddress(val address: String) : WalletEvent()
|
||||
|
||||
data class ShowWalletAlreadySignedHashesMessage(val onUnderstandClick: () -> Unit) : WalletEvent()
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
package com.tangem.feature.wallet.presentation.wallet.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.DialogButton
|
||||
import com.tangem.feature.wallet.impl.R
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.WalletAlertState
|
||||
|
||||
@Composable
|
||||
internal fun WalletAlert(config: WalletAlertState, onDismiss: () -> Unit) {
|
||||
when (config) {
|
||||
is WalletAlertState.WalletAlreadySignedHashes -> {
|
||||
WalletAlreadySignedHashesAlert(config = config, onDismiss = onDismiss)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun WalletAlreadySignedHashesAlert(config: WalletAlertState.WalletAlreadySignedHashes, onDismiss: () -> Unit) {
|
||||
BasicDialog(
|
||||
message = stringResource(id = R.string.alert_signed_hashes_message),
|
||||
confirmButton = DialogButton(
|
||||
title = stringResource(id = R.string.common_understand),
|
||||
onClick = {
|
||||
config.onUnderstandClick()
|
||||
onDismiss()
|
||||
},
|
||||
),
|
||||
onDismissDialog = onDismiss,
|
||||
title = stringResource(id = R.string.warning_important_security_info, "\u26A0"),
|
||||
dismissButton = DialogButton(title = stringResource(id = R.string.common_cancel), onClick = onDismiss),
|
||||
)
|
||||
}
|
||||
|
|
@ -10,6 +10,7 @@ import androidx.compose.ui.text.AnnotatedString
|
|||
import com.tangem.core.ui.event.EventEffect
|
||||
import com.tangem.core.ui.event.StateEvent
|
||||
import com.tangem.core.ui.extensions.resolveReference
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.WalletAlertState
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.WalletEvent
|
||||
|
||||
@Composable
|
||||
|
|
@ -18,6 +19,7 @@ internal fun WalletEventEffect(
|
|||
snackbarHostState: SnackbarHostState,
|
||||
event: StateEvent<WalletEvent>,
|
||||
onAutoScrollSet: () -> Unit,
|
||||
onAlertConfigSet: (WalletAlertState) -> Unit,
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
val resources = LocalContext.current.resources
|
||||
|
|
@ -39,6 +41,11 @@ internal fun WalletEventEffect(
|
|||
is WalletEvent.CopyAddress -> {
|
||||
clipboardManager.setText(AnnotatedString(value.address))
|
||||
}
|
||||
is WalletEvent.ShowWalletAlreadySignedHashesMessage -> {
|
||||
onAlertConfigSet(
|
||||
WalletAlertState.WalletAlreadySignedHashes(onUnderstandClick = value.onUnderstandClick),
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
)
|
||||
|
|
|
|||
|
|
@ -12,10 +12,7 @@ import androidx.compose.material3.FabPosition
|
|||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.SnackbarHost
|
||||
import androidx.compose.material3.SnackbarHostState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.State
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
|
|
@ -30,6 +27,7 @@ import com.tangem.core.ui.components.transactions.state.TxHistoryState
|
|||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.feature.wallet.impl.R
|
||||
import com.tangem.feature.wallet.presentation.common.WalletPreviewData
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.WalletAlertState
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.WalletMultiCurrencyState
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.WalletSingleCurrencyState
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.WalletState
|
||||
|
|
@ -72,12 +70,19 @@ internal fun WalletScreen(state: WalletState) {
|
|||
onAutoScrollReset = { isAutoScroll.value = false },
|
||||
)
|
||||
|
||||
var alertConfig by remember { mutableStateOf<WalletAlertState?>(value = null) }
|
||||
|
||||
WalletEventEffect(
|
||||
walletsListState = walletsListState,
|
||||
snackbarHostState = snackbarHostState,
|
||||
event = state.event,
|
||||
onAutoScrollSet = { isAutoScroll.value = true },
|
||||
onAlertConfigSet = { alertConfig = it },
|
||||
)
|
||||
|
||||
alertConfig?.let {
|
||||
WalletAlert(config = it, onDismiss = { alertConfig = null })
|
||||
}
|
||||
}
|
||||
is WalletState.Initial -> Unit
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
package com.tangem.feature.wallet.presentation.wallet.viewmodels
|
||||
|
||||
import com.tangem.domain.card.GetCardWasScannedUseCase
|
||||
import com.tangem.domain.card.WasCardScannedUseCase
|
||||
import com.tangem.domain.common.CardTypesResolver
|
||||
import com.tangem.domain.demo.IsDemoCardUseCase
|
||||
import com.tangem.domain.settings.IsUserAlreadyRateAppUseCase
|
||||
|
|
@ -10,14 +10,16 @@ import com.tangem.feature.wallet.presentation.wallet.state.components.WalletNoti
|
|||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.flow
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlin.collections.count
|
||||
|
||||
/**
|
||||
* Wallet notifications list factory
|
||||
*
|
||||
* @property isDemoCardUseCase use case that check if card is demo
|
||||
* @property isUserAlreadyRateAppUseCase use case that check if card is user already rate app
|
||||
* @property getCardWasScannedUseCase use case that check if card was scanned
|
||||
* @property wasCardScannedUseCase use case that check if card was scanned
|
||||
* @property clickIntents screen click intents
|
||||
*
|
||||
[REDACTED_AUTHOR]
|
||||
|
|
@ -25,7 +27,7 @@ import kotlinx.coroutines.flow.flow
|
|||
internal class WalletNotificationsListFactory(
|
||||
private val isDemoCardUseCase: IsDemoCardUseCase,
|
||||
private val isUserAlreadyRateAppUseCase: IsUserAlreadyRateAppUseCase,
|
||||
private val getCardWasScannedUseCase: GetCardWasScannedUseCase,
|
||||
private val wasCardScannedUseCase: WasCardScannedUseCase,
|
||||
private val clickIntents: WalletClickIntents,
|
||||
) {
|
||||
|
||||
|
|
@ -33,8 +35,9 @@ internal class WalletNotificationsListFactory(
|
|||
cardTypesResolver: CardTypesResolver,
|
||||
cryptoCurrencyList: List<CryptoCurrencyStatus>,
|
||||
): Flow<ImmutableList<WalletNotification>> {
|
||||
return flow {
|
||||
emit(
|
||||
return wasCardScannedUseCase.invoke(cardTypesResolver.getCardId())
|
||||
.distinctUntilChanged()
|
||||
.map {
|
||||
buildList {
|
||||
addCriticalNotifications(cardTypesResolver)
|
||||
|
||||
|
|
@ -42,11 +45,9 @@ internal class WalletNotificationsListFactory(
|
|||
|
||||
addRateTheAppNotification()
|
||||
|
||||
addWarningNotifications(cardTypesResolver, cryptoCurrencyList)
|
||||
}
|
||||
.toImmutableList(),
|
||||
)
|
||||
}
|
||||
addWarningNotifications(cardTypesResolver, cryptoCurrencyList, it)
|
||||
}.toImmutableList()
|
||||
}
|
||||
}
|
||||
|
||||
private fun MutableList<WalletNotification>.addCriticalNotifications(cardTypesResolver: CardTypesResolver) {
|
||||
|
|
@ -112,9 +113,10 @@ internal class WalletNotificationsListFactory(
|
|||
)
|
||||
}
|
||||
|
||||
private suspend fun MutableList<WalletNotification>.addWarningNotifications(
|
||||
private fun MutableList<WalletNotification>.addWarningNotifications(
|
||||
cardTypesResolver: CardTypesResolver,
|
||||
cryptoCurrencyList: List<CryptoCurrencyStatus>,
|
||||
wasCardScanned: Boolean,
|
||||
) {
|
||||
addIf(
|
||||
element = WalletNotification.Warning.MissingBackup(
|
||||
|
|
@ -133,14 +135,22 @@ internal class WalletNotificationsListFactory(
|
|||
if (cardTypesResolver.isBackupForbidden()) {
|
||||
addIf(
|
||||
element = WalletNotification.Warning.NumberOfSignedHashesIncorrect,
|
||||
condition = checkSignedHashes(cardTypesResolver = cardTypesResolver, isDemo = isDemo),
|
||||
condition = checkSignedHashes(
|
||||
cardTypesResolver = cardTypesResolver,
|
||||
isDemo = isDemo,
|
||||
wasCardScanned,
|
||||
),
|
||||
)
|
||||
} else {
|
||||
addIf(
|
||||
element = WalletNotification.Warning.MultiWalletSignedHashesIncorrect(
|
||||
onClick = clickIntents::onMultiWalletSignedHashesNotificationClick,
|
||||
),
|
||||
condition = checkSignedHashes(cardTypesResolver = cardTypesResolver, isDemo = isDemo),
|
||||
condition = checkSignedHashes(
|
||||
cardTypesResolver = cardTypesResolver,
|
||||
isDemo = isDemo,
|
||||
wasCardScanned,
|
||||
),
|
||||
)
|
||||
}
|
||||
} else {
|
||||
|
|
@ -159,7 +169,7 @@ internal class WalletNotificationsListFactory(
|
|||
|
||||
addIf(
|
||||
element = WalletNotification.Warning.NumberOfSignedHashesIncorrect,
|
||||
condition = checkSignedHashes(cardTypesResolver, isDemo),
|
||||
condition = checkSignedHashes(cardTypesResolver, isDemo, wasCardScanned),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -176,9 +186,13 @@ internal class WalletNotificationsListFactory(
|
|||
return any { it.value is CryptoCurrencyStatus.NoAccount }
|
||||
}
|
||||
|
||||
private suspend fun checkSignedHashes(cardTypesResolver: CardTypesResolver, isDemo: Boolean): Boolean {
|
||||
return cardTypesResolver.isReleaseFirmwareType() && cardTypesResolver.hasWalletSignedHashes() &&
|
||||
!isDemo && !getCardWasScannedUseCase(cardId = cardTypesResolver.getCardId())
|
||||
private fun checkSignedHashes(
|
||||
cardTypesResolver: CardTypesResolver,
|
||||
isDemo: Boolean,
|
||||
wasCardScanned: Boolean,
|
||||
): Boolean {
|
||||
return cardTypesResolver.isReleaseFirmwareType() && cardTypesResolver.hasWalletSignedHashes() && !isDemo &&
|
||||
!wasCardScanned
|
||||
}
|
||||
|
||||
private companion object {
|
||||
|
|
|
|||
|
|
@ -106,7 +106,8 @@ internal class WalletViewModel @Inject constructor(
|
|||
private val reduxStateHolder: ReduxStateHolder,
|
||||
private val dispatchers: CoroutineDispatcherProvider,
|
||||
private val analyticsEventsHandler: AnalyticsEventHandler,
|
||||
getCardWasScannedUseCase: GetCardWasScannedUseCase,
|
||||
private val setCardWasScannedUseCase: SetCardWasScannedUseCase,
|
||||
wasCardScannedUseCase: WasCardScannedUseCase,
|
||||
isUserAlreadyRateAppUseCase: IsUserAlreadyRateAppUseCase,
|
||||
isDemoCardUseCase: IsDemoCardUseCase,
|
||||
// endregion Parameters
|
||||
|
|
@ -119,7 +120,7 @@ internal class WalletViewModel @Inject constructor(
|
|||
private var isBalanceHidden = true
|
||||
|
||||
private val notificationsListFactory = WalletNotificationsListFactory(
|
||||
getCardWasScannedUseCase = getCardWasScannedUseCase,
|
||||
wasCardScannedUseCase = wasCardScannedUseCase,
|
||||
isUserAlreadyRateAppUseCase = isUserAlreadyRateAppUseCase,
|
||||
isDemoCardUseCase = isDemoCardUseCase,
|
||||
clickIntents = this,
|
||||
|
|
@ -413,7 +414,21 @@ internal class WalletViewModel @Inject constructor(
|
|||
}
|
||||
|
||||
override fun onMultiWalletSignedHashesNotificationClick() {
|
||||
// TODO: [REDACTED_JIRA]
|
||||
val state = uiState as? WalletState.ContentState ?: return
|
||||
|
||||
uiState = stateFactory.getStateAndTriggerEvent(
|
||||
state = uiState,
|
||||
event = WalletEvent.ShowWalletAlreadySignedHashesMessage(
|
||||
onUnderstandClick = {
|
||||
viewModelScope.launch(dispatchers.main) {
|
||||
setCardWasScannedUseCase(
|
||||
cardId = getWallet(index = state.walletsListConfig.selectedWalletIndex).cardId,
|
||||
)
|
||||
}
|
||||
},
|
||||
),
|
||||
setUiState = { uiState = it },
|
||||
)
|
||||
}
|
||||
|
||||
override fun onLikeTangemAppClick() {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue