Updated on 2026-08-14

This commit is contained in:
Tangem 2024-04-09 19:21:07 +05:00
commit 049bb650c9
10 changed files with 49 additions and 42 deletions

View file

@ -5,6 +5,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.fragment.app.viewModels
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.lifecycle.flowWithLifecycle
import androidx.lifecycle.lifecycleScope
import arrow.core.getOrElse
@ -73,7 +74,8 @@ internal class SendFragment : ComposeFragment() {
SystemBarsEffect {
setSystemBarsColor(systemBarsColor)
}
SendScreen(viewModel.uiState, viewModel.stateRouter.currentState)
val currentState = viewModel.stateRouter.currentState.collectAsStateWithLifecycle()
SendScreen(viewModel.uiState, currentState.value)
}
override fun onDestroy() {

View file

@ -3,6 +3,7 @@ package com.tangem.features.send.impl.presentation.ui
import androidx.compose.material3.SnackbarHostState
import androidx.compose.runtime.*
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
import androidx.compose.ui.res.stringResource
import com.tangem.core.ui.components.BasicDialog
import com.tangem.core.ui.components.DialogButton
@ -18,6 +19,11 @@ internal fun SendEventEffect(event: StateEvent<SendEvent>, snackbarHostState: Sn
val resources = LocalContext.current.resources
var alertConfig by remember { mutableStateOf<SendAlertState?>(value = null) }
val keyboardController = LocalSoftwareKeyboardController.current
LaunchedEffect(key1 = alertConfig) {
keyboardController?.hide()
}
alertConfig?.let {
SendAlert(state = it, onDismiss = { alertConfig = null })
}

View file

@ -11,7 +11,6 @@ import androidx.compose.material3.SnackbarHostState
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.tangem.core.ui.components.appbar.AppBarWithBackButtonAndIcon
import com.tangem.core.ui.extensions.resolveReference
import com.tangem.core.ui.extensions.resourceReference
@ -25,11 +24,9 @@ import com.tangem.features.send.impl.presentation.ui.amount.SendAmountContent
import com.tangem.features.send.impl.presentation.ui.fee.SendSpeedAndFeeContent
import com.tangem.features.send.impl.presentation.ui.recipient.SendRecipientContent
import com.tangem.features.send.impl.presentation.ui.send.SendContent
import kotlinx.coroutines.flow.StateFlow
@Composable
internal fun SendScreen(uiState: SendUiState, currentStateFlow: StateFlow<SendUiCurrentScreen>) {
val currentState = currentStateFlow.collectAsStateWithLifecycle()
internal fun SendScreen(uiState: SendUiState, currentState: SendUiCurrentScreen) {
val snackbarHostState = remember { SnackbarHostState() }
val sendState = uiState.sendState ?: return
BackHandler { uiState.clickIntents.onBackClick() }
@ -37,11 +34,10 @@ internal fun SendScreen(uiState: SendUiState, currentStateFlow: StateFlow<SendUi
modifier = Modifier
.fillMaxSize()
.systemBarsPadding()
.imePadding()
.background(color = TangemTheme.colors.background.tertiary),
horizontalAlignment = Alignment.CenterHorizontally,
) {
val titleRes = when (currentState.value.type) {
val titleRes = when (currentState.type) {
SendUiStateType.Amount -> resourceReference(R.string.send_amount_label)
SendUiStateType.Recipient -> resourceReference(R.string.send_recipient_label)
SendUiStateType.Fee -> resourceReference(R.string.common_fee_selector_title)
@ -52,13 +48,13 @@ internal fun SendScreen(uiState: SendUiState, currentStateFlow: StateFlow<SendUi
}
else -> null
}
val isSending = currentState.value.type == SendUiStateType.Send && !uiState.sendState.isSuccess
val isSending = currentState.type == SendUiStateType.Send && !uiState.sendState.isSuccess
val subtitleRes = if (isSending) {
uiState.amountState?.walletName
} else {
null
}
val iconRes = if (currentState.value.type == SendUiStateType.Recipient) {
val iconRes = if (currentState.type == SendUiStateType.Recipient) {
R.drawable.ic_qrcode_scan_24
} else {
null
@ -74,17 +70,16 @@ internal fun SendScreen(uiState: SendUiState, currentStateFlow: StateFlow<SendUi
backgroundColor = TangemTheme.colors.background.tertiary,
modifier = Modifier.height(TangemTheme.dimens.size56),
)
Box(modifier = Modifier.weight(1f)) {
SendScreenContent(
uiState = uiState,
currentState = currentState.value,
)
SendNavigationButtons(
uiState = uiState,
currentState = currentState.value,
modifier = Modifier.align(Alignment.BottomCenter),
)
}
SendScreenContent(
uiState = uiState,
currentState = currentState,
modifier = Modifier.weight(1f),
)
SendNavigationButtons(
uiState = uiState,
currentState = currentState,
modifier = Modifier.imePadding(),
)
}
SendEventEffect(

View file

@ -24,7 +24,11 @@ internal fun SendAmountContent(
if (amountState == null) return
LazyColumn(
modifier = Modifier
.padding(horizontal = TangemTheme.dimens.spacing16)
.padding(
start = TangemTheme.dimens.spacing16,
end = TangemTheme.dimens.spacing16,
bottom = TangemTheme.dimens.spacing16,
)
.background(TangemTheme.colors.background.tertiary),
) {
amountField(amountState = amountState, isBalanceHiding = isBalanceHiding)

View file

@ -21,11 +21,6 @@ internal fun LazyListScope.notifications(
key = { _, item -> item::class.java },
contentType = { _, item -> item::class.java },
itemContent = { i, item ->
val bottomPadding = if (i == notifications.lastIndex) {
TangemTheme.dimens.spacing72
} else {
TangemTheme.dimens.spacing0
}
val topPadding = if (i == 0 && hasPaddingAbove) {
TangemTheme.dimens.spacing0
} else {
@ -34,10 +29,7 @@ internal fun LazyListScope.notifications(
Notification(
config = item.config,
modifier = modifier
.padding(
top = topPadding,
bottom = bottomPadding,
)
.padding(top = topPadding)
.animateItemPlacement(),
containerColor = when (item) {
is SendNotification.Error.ExceedsBalance,

View file

@ -29,20 +29,19 @@ internal fun SendCustomFee(
enter = expandVertically().plus(fadeIn()),
exit = shrinkVertically().plus(fadeOut()),
) {
val bottomPadding = if (hasNotifications) {
TangemTheme.dimens.spacing12
} else {
TangemTheme.dimens.spacing0
}
Column(
verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing12),
modifier = modifier,
modifier = modifier.padding(bottom = bottomPadding),
) {
repeat(customValues.size) { index ->
val value = customValues[index]
val bottomPadding = if (index == customValues.lastIndex && !hasNotifications) {
TangemTheme.dimens.spacing72
} else {
TangemTheme.dimens.spacing0
}
FooterContainer(
footer = value.footer.resolveReference(),
modifier = Modifier.padding(bottom = bottomPadding),
) {
if (value.label != null) {
InputRowEnterInfoAmount(

View file

@ -31,7 +31,9 @@ internal fun SendSpeedAndFeeContent(state: SendStates.FeeState?, clickIntents: S
.fillMaxSize()
.background(TangemTheme.colors.background.tertiary)
.padding(
horizontal = TangemTheme.dimens.spacing16,
start = TangemTheme.dimens.spacing16,
end = TangemTheme.dimens.spacing16,
bottom = TangemTheme.dimens.spacing16,
),
) {
feeSelector(state, clickIntents)

View file

@ -51,7 +51,11 @@ internal fun SendRecipientContent(
modifier = Modifier
.fillMaxSize()
.background(TangemTheme.colors.background.tertiary)
.padding(horizontal = TangemTheme.dimens.spacing16),
.padding(
start = TangemTheme.dimens.spacing16,
end = TangemTheme.dimens.spacing16,
bottom = TangemTheme.dimens.spacing16,
),
) {
addressItem(
address = address,
@ -222,7 +226,6 @@ private fun LazyListScope.listItem(
.then(
if (isLast && index == list.lastIndex) {
Modifier
.padding(bottom = TangemTheme.dimens.spacing72)
.clip(
shape = RoundedCornerShape(
bottomStart = TangemTheme.dimens.radius16,

View file

@ -35,7 +35,11 @@ internal fun SendContent(uiState: SendUiState) {
LazyColumn(
modifier = Modifier
.fillMaxSize()
.padding(horizontal = TangemTheme.dimens.spacing16),
.padding(
start = TangemTheme.dimens.spacing16,
end = TangemTheme.dimens.spacing16,
bottom = TangemTheme.dimens.spacing16,
),
) {
blocks(uiState)
tapHelp(isDisplay = sendState.showTapHelp)

View file

@ -465,7 +465,7 @@ internal class SendViewModel @Inject constructor(
.conflate()
.distinctUntilChanged()
.onEach { uiState = feeStateFactory.getFeeNotificationState(notifications = it) }
.flowOn(dispatchers.io)
.flowOn(dispatchers.main)
.launchIn(viewModelScope)
.saveIn(feeNotificationsJobHolder)
}