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,