Fix placeholder visibility in media-send.

This commit is contained in:
Alex Hart
2026-08-10 16:32:54 -04:00
committed by Greyson Parrelli
parent 09caf6b63f
commit d603cc1612
3 changed files with 29 additions and 10 deletions
@@ -100,7 +100,7 @@ class MediaSendFlowViewModel(
isReply = args.isReply,
isAddToGroupStoryFlow = args.isAddToGroupStoryFlow,
maxSelection = args.maxSelection,
message = if (args.asTextStory) null else args.initialMessage,
message = if (args.asTextStory) null else normalizeMessageBody(args.initialMessage),
isContactSelectionRequired = args.mode == MediaSendFlowActivityContract.Mode.ChooseAfterMediaSelection,
sendType = args.sendType
)
@@ -1077,11 +1077,7 @@ class MediaSendFlowViewModel(
//region Message
fun setMessage(text: CharSequence?) {
updateState { copy(message = text) }
}
private fun onMessageChange(message: String) {
setMessage(message)
updateState { copy(message = normalizeMessageBody(text)) }
}
//endregion
@@ -1321,6 +1317,14 @@ class MediaSendFlowViewModel(
private const val KEY_STATE = "media_send_vm_state"
private const val KEY_EDITED_VIDEO_URIS = "media_send_vm_edited_video_uris"
private const val KEY_BACK_STACK = "media_send_vm_back_stack"
/**
* Trims a body the way the chat compose field does before a send, preserving spans like mentions and styling, and
* collapses a whitespace-only body to null so it is indistinguishable from a body the user never typed.
*/
private fun normalizeMessageBody(text: CharSequence?): CharSequence? {
return text?.let { StringUtil.trimSequence(it) }?.takeIf { it.isNotEmpty() }
}
}
/**
@@ -113,7 +113,7 @@ fun AddAMessageRow(
}
LocalAddAMessageRowTextField.current(
message ?: stringResource(R.string.AddAMessageRow__message),
message?.takeIf { it.isNotBlank() } ?: stringResource(R.string.AddAMessageRow__message),
Modifier
.weight(1f)
.padding(end = if (viewOnceAvailable) 0.dp else 16.dp)
@@ -9,6 +9,7 @@ import android.app.Application
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.longClick
import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.performClick
import androidx.compose.ui.test.performTouchInput
import androidx.test.core.app.ApplicationProvider
@@ -25,7 +26,7 @@ import org.signal.mediasend.test.TestTags
/**
* Covers the send affordance's two gestures: a tap advances the flow, while a long press offers the schedule menu when
* the flow allows scheduling.
* the flow allows scheduling. Also covers when the row falls back to its placeholder.
*/
@RunWith(RobolectricTestRunner::class)
@Config(application = Application::class)
@@ -74,11 +75,25 @@ class AddAMessageRowTest {
assertEquals(emptyList<MediaEditScreenEvents>(), events)
}
private fun setContent(canScheduleSend: Boolean) {
@Test
fun `Given a blank message, when the row is displayed, then the placeholder is shown`() {
setContent(message = " ")
composeTestRule.onNodeWithText("Message").assertExists()
}
@Test
fun `Given a message, when the row is displayed, then the message is shown`() {
setContent(message = "Check this out")
composeTestRule.onNodeWithText("Check this out").assertExists()
}
private fun setContent(canScheduleSend: Boolean = false, message: CharSequence? = null) {
composeTestRule.setContent {
SignalTheme {
AddAMessageRow(
message = null,
message = message,
onEvent = { events += it },
onNextClick = { nextClicks++ },
canScheduleSend = canScheduleSend