From 00e9a8ab71d3c09666c21923874f722e21e0a2fa Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 12 Aug 2026 16:40:49 +0200 Subject: [PATCH 1/2] 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. --- .../messagecomposer/MessageComposerPresenter.kt | 1 + .../impl/messagecomposer/MessageComposerState.kt | 1 + .../MessageComposerStateProvider.kt | 2 ++ .../impl/messagecomposer/MessageComposerView.kt | 1 + .../MessageComposerPresenterTest.kt | 14 ++++++++++++++ .../android/libraries/textcomposer/TextComposer.kt | 3 ++- 6 files changed, 21 insertions(+), 1 deletion(-) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenter.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenter.kt index 18252ee17d..5f12bf4be1 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenter.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenter.kt @@ -425,6 +425,7 @@ class MessageComposerPresenter( textEditorState = textEditorState, isFullScreen = isFullScreen.value, mode = messageComposerContext.composerMode, + isInThreadTimeline = isInThread, showAttachmentSourcePicker = showAttachmentSourcePicker, showTextFormatting = showTextFormatting, canShareLocation = canShareLocation.value, diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerState.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerState.kt index f3fdb3d59a..b4da119d96 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerState.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerState.kt @@ -21,6 +21,7 @@ data class MessageComposerState( val textEditorState: TextEditorState, val isFullScreen: Boolean, val mode: MessageComposerMode, + val isInThreadTimeline: Boolean, val showAttachmentSourcePicker: Boolean, val showTextFormatting: Boolean, val canShareLocation: Boolean, diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerStateProvider.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerStateProvider.kt index ef9cd7933b..b08fea28ec 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerStateProvider.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerStateProvider.kt @@ -29,6 +29,7 @@ fun aMessageComposerState( textEditorState: TextEditorState = aTextEditorStateRich(), isFullScreen: Boolean = false, mode: MessageComposerMode = MessageComposerMode.Normal, + isInThreadTimeline: Boolean = false, showTextFormatting: Boolean = false, showAttachmentSourcePicker: Boolean = false, canShareLocation: Boolean = true, @@ -39,6 +40,7 @@ fun aMessageComposerState( textEditorState = textEditorState, isFullScreen = isFullScreen, mode = mode, + isInThreadTimeline = isInThreadTimeline, showTextFormatting = showTextFormatting, showAttachmentSourcePicker = showAttachmentSourcePicker, canShareLocation = canShareLocation, diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerView.kt index 245b23cf8e..cd20f3e58b 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerView.kt @@ -102,6 +102,7 @@ internal fun MessageComposerView( onRequestFocus = ::onRequestFocus, onSendMessage = ::sendMessage, composerMode = state.mode, + isInThreadTimeline = state.isInThreadTimeline, showTextFormatting = state.showTextFormatting, onResetComposerMode = ::onCloseSpecialMode, onAddAttachment = ::onAddAttachment, diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenterTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenterTest.kt index fda8621087..07b9a4e330 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenterTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenterTest.kt @@ -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_REPLY 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_USER_ID import io.element.android.libraries.matrix.test.A_USER_ID_2 @@ -148,12 +149,25 @@ class MessageComposerPresenterTest : RobolectricTest() { assertThat(initialState.isFullScreen).isFalse() assertThat(initialState.textEditorState.messageHtml()).isEqualTo("") assertThat(initialState.mode).isEqualTo(MessageComposerMode.Normal) + assertThat(initialState.isInThreadTimeline).isFalse() assertThat(initialState.showAttachmentSourcePicker).isFalse() assertThat(initialState.canShareLocation).isTrue() 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 fun `present - toggle fullscreen`() = runTest { val presenter = createPresenter() diff --git a/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/TextComposer.kt b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/TextComposer.kt index 0f62eb5234..a2ee9dd867 100644 --- a/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/TextComposer.kt +++ b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/TextComposer.kt @@ -131,6 +131,7 @@ fun TextComposer( resolveAtRoomMentionDisplay: () -> TextDisplay, modifier: Modifier = Modifier, showTextFormatting: Boolean = false, + isInThreadTimeline: Boolean = false, ) { val markdown = when (state) { is TextEditorState.Markdown -> state.state.text.value() @@ -153,7 +154,7 @@ fun TextComposer( .fillMaxSize() .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) } else if (composerMode is MessageComposerMode.Attachment || composerMode is MessageComposerMode.EditCaption) { stringResource(id = R.string.rich_text_editor_composer_caption_placeholder) From ae5c4161c7bd4d6c9c08cbe9477c53bf42da2e19 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 12 Aug 2026 18:14:36 +0200 Subject: [PATCH 2/2] Remove redundant parenthesis --- .../io/element/android/libraries/textcomposer/TextComposer.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/TextComposer.kt b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/TextComposer.kt index a2ee9dd867..b8839cac67 100644 --- a/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/TextComposer.kt +++ b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/TextComposer.kt @@ -154,7 +154,7 @@ fun TextComposer( .fillMaxSize() .height(IntrinsicSize.Min) - val placeholder = if (composerMode.inThread || (composerMode is MessageComposerMode.Normal && isInThreadTimeline)) { + val placeholder = if (composerMode.inThread || composerMode is MessageComposerMode.Normal && isInThreadTimeline) { stringResource(id = CommonStrings.action_reply_in_thread) } else if (composerMode is MessageComposerMode.Attachment || composerMode is MessageComposerMode.EditCaption) { stringResource(id = R.string.rich_text_editor_composer_caption_placeholder)