@@ -28,6 +28,7 @@ import org.matrix.android.sdk.api.session.events.model.isLiveLocation
28
28
import org.matrix.android.sdk.api.session.events.model.isPoll
29
29
import org.matrix.android.sdk.api.session.events.model.isReply
30
30
import org.matrix.android.sdk.api.session.events.model.isSticker
31
+ import org.matrix.android.sdk.api.session.events.model.toContent
31
32
import org.matrix.android.sdk.api.session.events.model.toModel
32
33
import org.matrix.android.sdk.api.session.room.model.EventAnnotationsSummary
33
34
import org.matrix.android.sdk.api.session.room.model.ReadReceipt
@@ -36,6 +37,7 @@ import org.matrix.android.sdk.api.session.room.model.message.MessageBeaconLocati
36
37
import org.matrix.android.sdk.api.session.room.model.message.MessageContent
37
38
import org.matrix.android.sdk.api.session.room.model.message.MessageContentWithFormattedBody
38
39
import org.matrix.android.sdk.api.session.room.model.message.MessageEndPollContent
40
+ import org.matrix.android.sdk.api.session.room.model.message.MessageFormat
39
41
import org.matrix.android.sdk.api.session.room.model.message.MessagePollContent
40
42
import org.matrix.android.sdk.api.session.room.model.message.MessageStickerContent
41
43
import org.matrix.android.sdk.api.session.room.model.message.MessageTextContent
@@ -157,7 +159,39 @@ fun TimelineEvent.getLastMessageContent(): MessageContent? {
157
159
}
158
160
159
161
fun TimelineEvent.getLastEditNewContent (): Content ? {
160
- return annotations?.editSummary?.latestEdit?.getClearContent()?.toModel<MessageContent >()?.newContent
162
+ val lastContent = annotations?.editSummary?.latestEdit?.getClearContent()?.toModel<MessageContent >()?.newContent
163
+ return if (isReply()) {
164
+ val previousFormattedBody = root.getClearContent().toModel<MessageTextContent >()?.formattedBody
165
+ if (previousFormattedBody?.isNotEmpty() == true ) {
166
+ val lastMessageContent = lastContent.toModel<MessageTextContent >()
167
+ lastMessageContent?.let { ensureCorrectFormattedBodyInTextReply(it, previousFormattedBody) }?.toContent() ? : lastContent
168
+ } else {
169
+ lastContent
170
+ }
171
+ } else {
172
+ lastContent
173
+ }
174
+ }
175
+
176
+ private const val MX_REPLY_END_TAG = " </mx-reply>"
177
+
178
+ /* *
179
+ * Not every client sends a formatted body in the last edited event since this is not required in the
180
+ * [Matrix specification](https://spec.matrix.org/v1.4/client-server-api/#applying-mnew_content).
181
+ * We must ensure there is one so that it is still considered as a reply when rendering the message.
182
+ */
183
+ private fun ensureCorrectFormattedBodyInTextReply (messageTextContent : MessageTextContent , previousFormattedBody : String ): MessageTextContent {
184
+ return when {
185
+ messageTextContent.formattedBody.isNullOrEmpty() && previousFormattedBody.contains(MX_REPLY_END_TAG ) -> {
186
+ // take previous formatted body with the new body content
187
+ val newFormattedBody = previousFormattedBody.replaceAfterLast(MX_REPLY_END_TAG , messageTextContent.body)
188
+ messageTextContent.copy(
189
+ formattedBody = newFormattedBody,
190
+ format = MessageFormat .FORMAT_MATRIX_HTML ,
191
+ )
192
+ }
193
+ else -> messageTextContent
194
+ }
161
195
}
162
196
163
197
private fun TimelineEvent.getLastPollEditNewContent (): Content ? {
0 commit comments