Fix wrong TextComposer placeholder displayed when in a thread.

We cannot only use MessageComposerMode since use can edit a message in a thread, so this is becoming handly.
This commit is contained in:
Benoit Marty
2026-08-12 16:40:49 +02:00
parent 76092fcba6
commit 00e9a8ab71
6 changed files with 21 additions and 1 deletions
@@ -425,6 +425,7 @@ class MessageComposerPresenter(
textEditorState = textEditorState, textEditorState = textEditorState,
isFullScreen = isFullScreen.value, isFullScreen = isFullScreen.value,
mode = messageComposerContext.composerMode, mode = messageComposerContext.composerMode,
isInThreadTimeline = isInThread,
showAttachmentSourcePicker = showAttachmentSourcePicker, showAttachmentSourcePicker = showAttachmentSourcePicker,
showTextFormatting = showTextFormatting, showTextFormatting = showTextFormatting,
canShareLocation = canShareLocation.value, canShareLocation = canShareLocation.value,
@@ -21,6 +21,7 @@ data class MessageComposerState(
val textEditorState: TextEditorState, val textEditorState: TextEditorState,
val isFullScreen: Boolean, val isFullScreen: Boolean,
val mode: MessageComposerMode, val mode: MessageComposerMode,
val isInThreadTimeline: Boolean,
val showAttachmentSourcePicker: Boolean, val showAttachmentSourcePicker: Boolean,
val showTextFormatting: Boolean, val showTextFormatting: Boolean,
val canShareLocation: Boolean, val canShareLocation: Boolean,
@@ -29,6 +29,7 @@ fun aMessageComposerState(
textEditorState: TextEditorState = aTextEditorStateRich(), textEditorState: TextEditorState = aTextEditorStateRich(),
isFullScreen: Boolean = false, isFullScreen: Boolean = false,
mode: MessageComposerMode = MessageComposerMode.Normal, mode: MessageComposerMode = MessageComposerMode.Normal,
isInThreadTimeline: Boolean = false,
showTextFormatting: Boolean = false, showTextFormatting: Boolean = false,
showAttachmentSourcePicker: Boolean = false, showAttachmentSourcePicker: Boolean = false,
canShareLocation: Boolean = true, canShareLocation: Boolean = true,
@@ -39,6 +40,7 @@ fun aMessageComposerState(
textEditorState = textEditorState, textEditorState = textEditorState,
isFullScreen = isFullScreen, isFullScreen = isFullScreen,
mode = mode, mode = mode,
isInThreadTimeline = isInThreadTimeline,
showTextFormatting = showTextFormatting, showTextFormatting = showTextFormatting,
showAttachmentSourcePicker = showAttachmentSourcePicker, showAttachmentSourcePicker = showAttachmentSourcePicker,
canShareLocation = canShareLocation, canShareLocation = canShareLocation,
@@ -102,6 +102,7 @@ internal fun MessageComposerView(
onRequestFocus = ::onRequestFocus, onRequestFocus = ::onRequestFocus,
onSendMessage = ::sendMessage, onSendMessage = ::sendMessage,
composerMode = state.mode, composerMode = state.mode,
isInThreadTimeline = state.isInThreadTimeline,
showTextFormatting = state.showTextFormatting, showTextFormatting = state.showTextFormatting,
onResetComposerMode = ::onCloseSpecialMode, onResetComposerMode = ::onCloseSpecialMode,
onAddAttachment = ::onAddAttachment, onAddAttachment = ::onAddAttachment,
@@ -61,6 +61,7 @@ import io.element.android.libraries.matrix.test.A_CAPTION
import io.element.android.libraries.matrix.test.A_MESSAGE import io.element.android.libraries.matrix.test.A_MESSAGE
import io.element.android.libraries.matrix.test.A_REPLY import io.element.android.libraries.matrix.test.A_REPLY
import io.element.android.libraries.matrix.test.A_ROOM_ID import io.element.android.libraries.matrix.test.A_ROOM_ID
import io.element.android.libraries.matrix.test.A_THREAD_ID
import io.element.android.libraries.matrix.test.A_TRANSACTION_ID import io.element.android.libraries.matrix.test.A_TRANSACTION_ID
import io.element.android.libraries.matrix.test.A_USER_ID import io.element.android.libraries.matrix.test.A_USER_ID
import io.element.android.libraries.matrix.test.A_USER_ID_2 import io.element.android.libraries.matrix.test.A_USER_ID_2
@@ -148,12 +149,25 @@ class MessageComposerPresenterTest : RobolectricTest() {
assertThat(initialState.isFullScreen).isFalse() assertThat(initialState.isFullScreen).isFalse()
assertThat(initialState.textEditorState.messageHtml()).isEqualTo("") assertThat(initialState.textEditorState.messageHtml()).isEqualTo("")
assertThat(initialState.mode).isEqualTo(MessageComposerMode.Normal) assertThat(initialState.mode).isEqualTo(MessageComposerMode.Normal)
assertThat(initialState.isInThreadTimeline).isFalse()
assertThat(initialState.showAttachmentSourcePicker).isFalse() assertThat(initialState.showAttachmentSourcePicker).isFalse()
assertThat(initialState.canShareLocation).isTrue() assertThat(initialState.canShareLocation).isTrue()
assertThat(initialState.slashCommandAction).isEqualTo(AsyncAction.Uninitialized) assertThat(initialState.slashCommandAction).isEqualTo(AsyncAction.Uninitialized)
} }
} }
@Test
fun `present - when a threadRoot is provided, isInThreadTimeline is true`() = runTest {
val presenter = createPresenter(
threadRoot = A_THREAD_ID,
)
presenter.test {
val initialState = awaitFirstItem()
assertThat(initialState.mode).isEqualTo(MessageComposerMode.Normal)
assertThat(initialState.isInThreadTimeline).isTrue()
}
}
@Test @Test
fun `present - toggle fullscreen`() = runTest { fun `present - toggle fullscreen`() = runTest {
val presenter = createPresenter() val presenter = createPresenter()
@@ -131,6 +131,7 @@ fun TextComposer(
resolveAtRoomMentionDisplay: () -> TextDisplay, resolveAtRoomMentionDisplay: () -> TextDisplay,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
showTextFormatting: Boolean = false, showTextFormatting: Boolean = false,
isInThreadTimeline: Boolean = false,
) { ) {
val markdown = when (state) { val markdown = when (state) {
is TextEditorState.Markdown -> state.state.text.value() is TextEditorState.Markdown -> state.state.text.value()
@@ -153,7 +154,7 @@ fun TextComposer(
.fillMaxSize() .fillMaxSize()
.height(IntrinsicSize.Min) .height(IntrinsicSize.Min)
val placeholder = if (composerMode.inThread) { val placeholder = if (composerMode.inThread || (composerMode is MessageComposerMode.Normal && isInThreadTimeline)) {
stringResource(id = CommonStrings.action_reply_in_thread) stringResource(id = CommonStrings.action_reply_in_thread)
} else if (composerMode is MessageComposerMode.Attachment || composerMode is MessageComposerMode.EditCaption) { } else if (composerMode is MessageComposerMode.Attachment || composerMode is MessageComposerMode.EditCaption) {
stringResource(id = R.string.rich_text_editor_composer_caption_placeholder) stringResource(id = R.string.rich_text_editor_composer_caption_placeholder)