Fix issue where text is cleared when cancelling a reply (#1617)
This commit is contained in:
parent
46bfbc06fa
commit
3a39e747fd
10 changed files with 48 additions and 22 deletions
1
changelog.d/1617.bugfix
Normal file
1
changelog.d/1617.bugfix
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
Fix issue where text is cleared when cancelling a reply
|
||||||
|
|
@ -59,7 +59,7 @@ fun aMessagesState() = MessagesState(
|
||||||
composerState = aMessageComposerState().copy(
|
composerState = aMessageComposerState().copy(
|
||||||
richTextEditorState = RichTextEditorState("Hello", initialFocus = true),
|
richTextEditorState = RichTextEditorState("Hello", initialFocus = true),
|
||||||
isFullScreen = false,
|
isFullScreen = false,
|
||||||
mode = MessageComposerMode.Normal("Hello"),
|
mode = MessageComposerMode.Normal,
|
||||||
),
|
),
|
||||||
voiceMessageComposerState = aVoiceMessageComposerState(),
|
voiceMessageComposerState = aVoiceMessageComposerState(),
|
||||||
timelineState = aTimelineState().copy(
|
timelineState = aTimelineState().copy(
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,6 @@ import javax.inject.Inject
|
||||||
@SingleIn(RoomScope::class)
|
@SingleIn(RoomScope::class)
|
||||||
@ContributesBinding(RoomScope::class)
|
@ContributesBinding(RoomScope::class)
|
||||||
class MessageComposerContextImpl @Inject constructor() : MessageComposerContext {
|
class MessageComposerContextImpl @Inject constructor() : MessageComposerContext {
|
||||||
override var composerMode: MessageComposerMode by mutableStateOf(MessageComposerMode.Normal(""))
|
override var composerMode: MessageComposerMode by mutableStateOf(MessageComposerMode.Normal)
|
||||||
internal set
|
internal set
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -155,10 +155,12 @@ class MessageComposerPresenter @Inject constructor(
|
||||||
when (event) {
|
when (event) {
|
||||||
MessageComposerEvents.ToggleFullScreenState -> isFullScreen.value = !isFullScreen.value
|
MessageComposerEvents.ToggleFullScreenState -> isFullScreen.value = !isFullScreen.value
|
||||||
MessageComposerEvents.CloseSpecialMode -> {
|
MessageComposerEvents.CloseSpecialMode -> {
|
||||||
localCoroutineScope.launch {
|
if (messageComposerContext.composerMode is MessageComposerMode.Edit) {
|
||||||
richTextEditorState.setHtml("")
|
localCoroutineScope.launch {
|
||||||
|
richTextEditorState.setHtml("")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
messageComposerContext.composerMode = MessageComposerMode.Normal("")
|
messageComposerContext.composerMode = MessageComposerMode.Normal
|
||||||
}
|
}
|
||||||
is MessageComposerEvents.SendMessage -> appCoroutineScope.sendMessage(
|
is MessageComposerEvents.SendMessage -> appCoroutineScope.sendMessage(
|
||||||
message = event.message,
|
message = event.message,
|
||||||
|
|
@ -253,7 +255,7 @@ class MessageComposerPresenter @Inject constructor(
|
||||||
val capturedMode = messageComposerContext.composerMode
|
val capturedMode = messageComposerContext.composerMode
|
||||||
// Reset composer right away
|
// Reset composer right away
|
||||||
richTextEditorState.setHtml("")
|
richTextEditorState.setHtml("")
|
||||||
updateComposerMode(MessageComposerMode.Normal(""))
|
updateComposerMode(MessageComposerMode.Normal)
|
||||||
when (capturedMode) {
|
when (capturedMode) {
|
||||||
is MessageComposerMode.Normal -> room.sendMessage(body = message.markdown, htmlBody = message.html)
|
is MessageComposerMode.Normal -> room.sendMessage(body = message.markdown, htmlBody = message.html)
|
||||||
is MessageComposerMode.Edit -> {
|
is MessageComposerMode.Edit -> {
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ open class MessageComposerStateProvider : PreviewParameterProvider<MessageCompos
|
||||||
fun aMessageComposerState(
|
fun aMessageComposerState(
|
||||||
composerState: RichTextEditorState = RichTextEditorState(""),
|
composerState: RichTextEditorState = RichTextEditorState(""),
|
||||||
isFullScreen: Boolean = false,
|
isFullScreen: Boolean = false,
|
||||||
mode: MessageComposerMode = MessageComposerMode.Normal(content = ""),
|
mode: MessageComposerMode = MessageComposerMode.Normal,
|
||||||
showTextFormatting: Boolean = false,
|
showTextFormatting: Boolean = false,
|
||||||
showAttachmentSourcePicker: Boolean = false,
|
showAttachmentSourcePicker: Boolean = false,
|
||||||
canShareLocation: Boolean = true,
|
canShareLocation: Boolean = true,
|
||||||
|
|
|
||||||
|
|
@ -99,7 +99,7 @@ class MessageComposerPresenterTest {
|
||||||
val initialState = awaitItem()
|
val initialState = awaitItem()
|
||||||
assertThat(initialState.isFullScreen).isFalse()
|
assertThat(initialState.isFullScreen).isFalse()
|
||||||
assertThat(initialState.richTextEditorState.messageHtml).isEqualTo("")
|
assertThat(initialState.richTextEditorState.messageHtml).isEqualTo("")
|
||||||
assertThat(initialState.mode).isEqualTo(MessageComposerMode.Normal(""))
|
assertThat(initialState.mode).isEqualTo(MessageComposerMode.Normal)
|
||||||
assertThat(initialState.showAttachmentSourcePicker).isFalse()
|
assertThat(initialState.showAttachmentSourcePicker).isFalse()
|
||||||
assertThat(initialState.canShareLocation).isTrue()
|
assertThat(initialState.canShareLocation).isTrue()
|
||||||
assertThat(initialState.attachmentsState).isEqualTo(AttachmentsState.None)
|
assertThat(initialState.attachmentsState).isEqualTo(AttachmentsState.None)
|
||||||
|
|
@ -153,7 +153,10 @@ class MessageComposerPresenterTest {
|
||||||
assertThat(state.mode).isEqualTo(mode)
|
assertThat(state.mode).isEqualTo(mode)
|
||||||
state = awaitItem()
|
state = awaitItem()
|
||||||
assertThat(state.richTextEditorState.messageHtml).isEqualTo(A_MESSAGE)
|
assertThat(state.richTextEditorState.messageHtml).isEqualTo(A_MESSAGE)
|
||||||
backToNormalMode(state, skipCount = 1)
|
state = backToNormalMode(state, skipCount = 1)
|
||||||
|
|
||||||
|
// The message that was being edited is cleared
|
||||||
|
assertThat(state.richTextEditorState.messageHtml).isEqualTo("")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -174,6 +177,26 @@ class MessageComposerPresenterTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `present - cancel reply`() = runTest {
|
||||||
|
val presenter = createPresenter(this)
|
||||||
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
|
presenter.present()
|
||||||
|
}.test {
|
||||||
|
skipItems(1)
|
||||||
|
var state = awaitItem()
|
||||||
|
val mode = aReplyMode()
|
||||||
|
state.eventSink.invoke(MessageComposerEvents.SetMode(mode))
|
||||||
|
state = awaitItem()
|
||||||
|
assertThat(state.mode).isEqualTo(mode)
|
||||||
|
state.richTextEditorState.setHtml(A_REPLY)
|
||||||
|
state = backToNormalMode(state)
|
||||||
|
|
||||||
|
// The message typed while replying is not cleared
|
||||||
|
assertThat(state.richTextEditorState.messageHtml).isEqualTo(A_REPLY)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `present - change mode to quote`() = runTest {
|
fun `present - change mode to quote`() = runTest {
|
||||||
val presenter = createPresenter(this)
|
val presenter = createPresenter(this)
|
||||||
|
|
@ -683,12 +706,12 @@ class MessageComposerPresenterTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun ReceiveTurbine<MessageComposerState>.backToNormalMode(state: MessageComposerState, skipCount: Int = 0) {
|
private suspend fun ReceiveTurbine<MessageComposerState>.backToNormalMode(state: MessageComposerState, skipCount: Int = 0): MessageComposerState {
|
||||||
state.eventSink.invoke(MessageComposerEvents.CloseSpecialMode)
|
state.eventSink.invoke(MessageComposerEvents.CloseSpecialMode)
|
||||||
skipItems(skipCount)
|
skipItems(skipCount)
|
||||||
val normalState = awaitItem()
|
val normalState = awaitItem()
|
||||||
assertThat(normalState.mode).isEqualTo(MessageComposerMode.Normal(""))
|
assertThat(normalState.mode).isEqualTo(MessageComposerMode.Normal)
|
||||||
assertThat(normalState.richTextEditorState.messageHtml).isEqualTo("")
|
return normalState
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createPresenter(
|
private fun createPresenter(
|
||||||
|
|
|
||||||
|
|
@ -20,5 +20,5 @@ import io.element.android.features.messages.api.MessageComposerContext
|
||||||
import io.element.android.libraries.textcomposer.model.MessageComposerMode
|
import io.element.android.libraries.textcomposer.model.MessageComposerMode
|
||||||
|
|
||||||
class MessageComposerContextFake(
|
class MessageComposerContextFake(
|
||||||
override var composerMode: MessageComposerMode = MessageComposerMode.Normal(null)
|
override var composerMode: MessageComposerMode = MessageComposerMode.Normal
|
||||||
) : MessageComposerContext
|
) : MessageComposerContext
|
||||||
|
|
|
||||||
|
|
@ -483,7 +483,7 @@ internal fun TextComposerSimplePreview() = ElementPreview {
|
||||||
RichTextEditorState("", initialFocus = true),
|
RichTextEditorState("", initialFocus = true),
|
||||||
voiceMessageState = VoiceMessageState.Idle,
|
voiceMessageState = VoiceMessageState.Idle,
|
||||||
onSendMessage = {},
|
onSendMessage = {},
|
||||||
composerMode = MessageComposerMode.Normal(""),
|
composerMode = MessageComposerMode.Normal,
|
||||||
onResetComposerMode = {},
|
onResetComposerMode = {},
|
||||||
enableTextFormatting = true,
|
enableTextFormatting = true,
|
||||||
enableVoiceMessages = true,
|
enableVoiceMessages = true,
|
||||||
|
|
@ -493,7 +493,7 @@ internal fun TextComposerSimplePreview() = ElementPreview {
|
||||||
RichTextEditorState("A message", initialFocus = true),
|
RichTextEditorState("A message", initialFocus = true),
|
||||||
voiceMessageState = VoiceMessageState.Idle,
|
voiceMessageState = VoiceMessageState.Idle,
|
||||||
onSendMessage = {},
|
onSendMessage = {},
|
||||||
composerMode = MessageComposerMode.Normal(""),
|
composerMode = MessageComposerMode.Normal,
|
||||||
onResetComposerMode = {},
|
onResetComposerMode = {},
|
||||||
enableTextFormatting = true,
|
enableTextFormatting = true,
|
||||||
enableVoiceMessages = true,
|
enableVoiceMessages = true,
|
||||||
|
|
@ -506,7 +506,7 @@ internal fun TextComposerSimplePreview() = ElementPreview {
|
||||||
),
|
),
|
||||||
voiceMessageState = VoiceMessageState.Idle,
|
voiceMessageState = VoiceMessageState.Idle,
|
||||||
onSendMessage = {},
|
onSendMessage = {},
|
||||||
composerMode = MessageComposerMode.Normal(""),
|
composerMode = MessageComposerMode.Normal,
|
||||||
onResetComposerMode = {},
|
onResetComposerMode = {},
|
||||||
enableTextFormatting = true,
|
enableTextFormatting = true,
|
||||||
enableVoiceMessages = true,
|
enableVoiceMessages = true,
|
||||||
|
|
@ -516,7 +516,7 @@ internal fun TextComposerSimplePreview() = ElementPreview {
|
||||||
RichTextEditorState("A message without focus", initialFocus = false),
|
RichTextEditorState("A message without focus", initialFocus = false),
|
||||||
voiceMessageState = VoiceMessageState.Idle,
|
voiceMessageState = VoiceMessageState.Idle,
|
||||||
onSendMessage = {},
|
onSendMessage = {},
|
||||||
composerMode = MessageComposerMode.Normal(""),
|
composerMode = MessageComposerMode.Normal,
|
||||||
onResetComposerMode = {},
|
onResetComposerMode = {},
|
||||||
enableTextFormatting = true,
|
enableTextFormatting = true,
|
||||||
enableVoiceMessages = true,
|
enableVoiceMessages = true,
|
||||||
|
|
@ -533,7 +533,7 @@ internal fun TextComposerFormattingPreview() = ElementPreview {
|
||||||
RichTextEditorState("", initialFocus = false),
|
RichTextEditorState("", initialFocus = false),
|
||||||
voiceMessageState = VoiceMessageState.Idle,
|
voiceMessageState = VoiceMessageState.Idle,
|
||||||
showTextFormatting = true,
|
showTextFormatting = true,
|
||||||
composerMode = MessageComposerMode.Normal(""),
|
composerMode = MessageComposerMode.Normal,
|
||||||
enableTextFormatting = true,
|
enableTextFormatting = true,
|
||||||
enableVoiceMessages = true,
|
enableVoiceMessages = true,
|
||||||
)
|
)
|
||||||
|
|
@ -542,7 +542,7 @@ internal fun TextComposerFormattingPreview() = ElementPreview {
|
||||||
RichTextEditorState("A message", initialFocus = false),
|
RichTextEditorState("A message", initialFocus = false),
|
||||||
voiceMessageState = VoiceMessageState.Idle,
|
voiceMessageState = VoiceMessageState.Idle,
|
||||||
showTextFormatting = true,
|
showTextFormatting = true,
|
||||||
composerMode = MessageComposerMode.Normal(""),
|
composerMode = MessageComposerMode.Normal,
|
||||||
enableTextFormatting = true,
|
enableTextFormatting = true,
|
||||||
enableVoiceMessages = true,
|
enableVoiceMessages = true,
|
||||||
)
|
)
|
||||||
|
|
@ -551,7 +551,7 @@ internal fun TextComposerFormattingPreview() = ElementPreview {
|
||||||
RichTextEditorState("A message\nWith several lines\nTo preview larger textfields and long lines with overflow", initialFocus = false),
|
RichTextEditorState("A message\nWith several lines\nTo preview larger textfields and long lines with overflow", initialFocus = false),
|
||||||
voiceMessageState = VoiceMessageState.Idle,
|
voiceMessageState = VoiceMessageState.Idle,
|
||||||
showTextFormatting = true,
|
showTextFormatting = true,
|
||||||
composerMode = MessageComposerMode.Normal(""),
|
composerMode = MessageComposerMode.Normal,
|
||||||
enableTextFormatting = true,
|
enableTextFormatting = true,
|
||||||
enableVoiceMessages = true,
|
enableVoiceMessages = true,
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -93,7 +93,7 @@ internal fun SendButton(
|
||||||
@PreviewsDayNight
|
@PreviewsDayNight
|
||||||
@Composable
|
@Composable
|
||||||
internal fun SendButtonPreview() = ElementPreview {
|
internal fun SendButtonPreview() = ElementPreview {
|
||||||
val normalMode = MessageComposerMode.Normal("")
|
val normalMode = MessageComposerMode.Normal
|
||||||
val editMode = MessageComposerMode.Edit(null, "", null)
|
val editMode = MessageComposerMode.Edit(null, "", null)
|
||||||
Row {
|
Row {
|
||||||
SendButton(canSendMessage = true, onClick = {}, composerMode = normalMode)
|
SendButton(canSendMessage = true, onClick = {}, composerMode = normalMode)
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ import kotlinx.parcelize.Parcelize
|
||||||
|
|
||||||
sealed interface MessageComposerMode : Parcelable {
|
sealed interface MessageComposerMode : Parcelable {
|
||||||
@Parcelize
|
@Parcelize
|
||||||
data class Normal(val content: CharSequence?) : MessageComposerMode
|
data object Normal: MessageComposerMode
|
||||||
|
|
||||||
sealed class Special(open val eventId: EventId?, open val defaultContent: String) :
|
sealed class Special(open val eventId: EventId?, open val defaultContent: String) :
|
||||||
MessageComposerMode
|
MessageComposerMode
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue