diff --git a/apps/flipcash/core/src/main/res/values/strings.xml b/apps/flipcash/core/src/main/res/values/strings.xml index 2c93fe1a90..8f7656e9cb 100644 --- a/apps/flipcash/core/src/main/res/values/strings.xml +++ b/apps/flipcash/core/src/main/res/values/strings.xml @@ -899,8 +899,8 @@ Swipe to Tip Enter a custom amount Minimum tip %1$s - Tips Start at %1$s - Enter a larger amount to send this tip + %1$s Minimum + Increase the amount to send via Tip Card Block diff --git a/apps/flipcash/features/messenger/src/main/kotlin/com/flipcash/app/messenger/internal/ChatViewModel.kt b/apps/flipcash/features/messenger/src/main/kotlin/com/flipcash/app/messenger/internal/ChatViewModel.kt index c4cb22b025..4b1341b9db 100644 --- a/apps/flipcash/features/messenger/src/main/kotlin/com/flipcash/app/messenger/internal/ChatViewModel.kt +++ b/apps/flipcash/features/messenger/src/main/kotlin/com/flipcash/app/messenger/internal/ChatViewModel.kt @@ -121,7 +121,7 @@ internal class ChatViewModel @Inject constructor( } data class State( - val separatorConfig: SeparatorConfig= SeparatorConfig.Continuous(), + val separatorConfig: SeparatorConfig = SeparatorConfig.Continuous(), val chatId: ChatId? = null, val participant: ChatParticipant? = null, // The kind of DM this conversation is, resolved from the fast local contact lookup ahead of @@ -268,7 +268,7 @@ internal class ChatViewModel @Inject constructor( // tip (from the tip payment delegate); a contact DM swipes to *send* with no minimum. private fun amountStyle(isTip: Boolean) = AmountEntryStyle( actionLabel = AmountEntryLabel.Plain( - resources.getString(if (isTip) R.string.action_swipeToTip else R.string.action_swipeToSend) + resources.getString(R.string.action_swipeToSend) ), actionStyle = ConfirmationStyle.Slide, infoHint = { resources.getString(R.string.subtitle_sendHint, it) }, @@ -665,6 +665,17 @@ internal class ChatViewModel @Inject constructor( val source = owner.withTimelockForToken(token) val balance = tokenCoordinator.balanceForToken(token) + + val minimum = minAmountFlow.value + if (minimum != null && amount.valueLessThan(minimum)) { + dispatchEvent(Event.SendStateUpdated()) + BottomBarManager.showAlert( + title = resources.getString(R.string.error_title_tipMinimum, minimum.formatted()), + message = resources.getString(R.string.error_description_tipMinimum), + ) + return@launch + } + val verifiedFiat = verifiedFiatCalculator.compute( amount = amount, token = token, diff --git a/apps/flipcash/features/messenger/src/main/kotlin/com/flipcash/app/messenger/internal/screens/cash/ChatAmountEntryScreen.kt b/apps/flipcash/features/messenger/src/main/kotlin/com/flipcash/app/messenger/internal/screens/cash/ChatAmountEntryScreen.kt index 90e6802bb9..84f5860ff5 100644 --- a/apps/flipcash/features/messenger/src/main/kotlin/com/flipcash/app/messenger/internal/screens/cash/ChatAmountEntryScreen.kt +++ b/apps/flipcash/features/messenger/src/main/kotlin/com/flipcash/app/messenger/internal/screens/cash/ChatAmountEntryScreen.kt @@ -4,12 +4,8 @@ import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.wrapContentHeight import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier -import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel -import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.flipcash.app.core.AppRoute -import com.flipcash.app.core.chat.ChatIdentifier import com.flipcash.app.core.tokens.TokenPurpose import com.flipcash.app.core.ui.TokenSelectionPill import com.flipcash.app.messenger.internal.ChatViewModel @@ -27,30 +23,6 @@ import kotlinx.coroutines.flow.filterIsInstance import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach -/** - * Standalone amount entry screen — used when navigating directly from the contact list - * (messenger disabled). Creates its own [ChatViewModel] scoped to this nav entry. - */ -@Composable -fun ChatAmountEntryScreen(identifier: ChatIdentifier) { - val viewModel = hiltViewModel() - val state by viewModel.stateFlow.collectAsStateWithLifecycle() - - val navigator = LocalCodeNavigator.current - LaunchedEffect(viewModel, identifier) { - viewModel.dispatchEvent(ChatViewModel.Event.OnChatOpened(identifier)) - } - - ChatAmountEntryContent( - amountDelegate = viewModel.amountDelegate, - resolveState = state.resolveState, - token = state.token, - eventFlow = viewModel.eventFlow, - onExit = { navigator.pop() }, - onConfirm = { viewModel.dispatchEvent(ChatViewModel.Event.OnConfirmRequested) }, - ) -} - @Composable internal fun ChatAmountEntryContent( amountDelegate: AmountEntryDelegate,