mirror of
https://github.com/SchildiChat/SchildiChat-android.git
synced 2025-02-18 13:00:18 +03:00
commit
ebbc432570
11 changed files with 126 additions and 45 deletions
|
@ -8,10 +8,13 @@ Features ✨:
|
||||||
Improvements 🙌:
|
Improvements 🙌:
|
||||||
- Better connectivity lost indicator when airplane mode is on
|
- Better connectivity lost indicator when airplane mode is on
|
||||||
- Add a setting to hide redacted events (#951)
|
- Add a setting to hide redacted events (#951)
|
||||||
|
- Render formatted_body for m.notice and m.emote (#1196)
|
||||||
|
|
||||||
Bugfix 🐛:
|
Bugfix 🐛:
|
||||||
- After jump to unread, newer messages are never loaded (#1008)
|
- After jump to unread, newer messages are never loaded (#1008)
|
||||||
- Fix issues with FontScale switch (#69, #645)
|
- Fix issues with FontScale switch (#69, #645)
|
||||||
|
- "Seen by" uses 12h time (#1378)
|
||||||
|
- Enable markdown (if active) when sending emote (#734)
|
||||||
|
|
||||||
Translations 🗣:
|
Translations 🗣:
|
||||||
-
|
-
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020 New Vector Ltd
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package im.vector.matrix.android.api.session.room.model.message
|
||||||
|
|
||||||
|
interface MessageContentWithFormattedBody : MessageContent {
|
||||||
|
/**
|
||||||
|
* The format used in the formatted_body. Currently only "org.matrix.custom.html" is supported.
|
||||||
|
*/
|
||||||
|
val format: String?
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The formatted version of the body. This is required if format is specified.
|
||||||
|
*/
|
||||||
|
val formattedBody: String?
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the formattedBody, only if not blank and if the format is equal to "org.matrix.custom.html"
|
||||||
|
*/
|
||||||
|
val matrixFormattedBody: String?
|
||||||
|
get() = formattedBody?.takeIf { it.isNotBlank() && format == MessageFormat.FORMAT_MATRIX_HTML }
|
||||||
|
}
|
|
@ -34,15 +34,15 @@ data class MessageEmoteContent(
|
||||||
@Json(name = "body") override val body: String,
|
@Json(name = "body") override val body: String,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The format used in the formatted_body. Currently only org.matrix.custom.html is supported.
|
* The format used in the formatted_body. Currently only "org.matrix.custom.html" is supported.
|
||||||
*/
|
*/
|
||||||
@Json(name = "format") val format: String? = null,
|
@Json(name = "format") override val format: String? = null,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The formatted version of the body. This is required if format is specified.
|
* The formatted version of the body. This is required if format is specified.
|
||||||
*/
|
*/
|
||||||
@Json(name = "formatted_body") val formattedBody: String? = null,
|
@Json(name = "formatted_body") override val formattedBody: String? = null,
|
||||||
|
|
||||||
@Json(name = "m.relates_to") override val relatesTo: RelationDefaultContent? = null,
|
@Json(name = "m.relates_to") override val relatesTo: RelationDefaultContent? = null,
|
||||||
@Json(name = "m.new_content") override val newContent: Content? = null
|
@Json(name = "m.new_content") override val newContent: Content? = null
|
||||||
) : MessageContent
|
) : MessageContentWithFormattedBody
|
||||||
|
|
|
@ -34,15 +34,15 @@ data class MessageNoticeContent(
|
||||||
@Json(name = "body") override val body: String,
|
@Json(name = "body") override val body: String,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The format used in the formatted_body. Currently only org.matrix.custom.html is supported.
|
* The format used in the formatted_body. Currently only "org.matrix.custom.html" is supported.
|
||||||
*/
|
*/
|
||||||
@Json(name = "format") val format: String? = null,
|
@Json(name = "format") override val format: String? = null,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The formatted version of the body. This is required if format is specified.
|
* The formatted version of the body. This is required if format is specified.
|
||||||
*/
|
*/
|
||||||
@Json(name = "formatted_body") val formattedBody: String? = null,
|
@Json(name = "formatted_body") override val formattedBody: String? = null,
|
||||||
|
|
||||||
@Json(name = "m.relates_to") override val relatesTo: RelationDefaultContent? = null,
|
@Json(name = "m.relates_to") override val relatesTo: RelationDefaultContent? = null,
|
||||||
@Json(name = "m.new_content") override val newContent: Content? = null
|
@Json(name = "m.new_content") override val newContent: Content? = null
|
||||||
) : MessageContent
|
) : MessageContentWithFormattedBody
|
||||||
|
|
|
@ -34,15 +34,15 @@ data class MessageTextContent(
|
||||||
@Json(name = "body") override val body: String,
|
@Json(name = "body") override val body: String,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The format used in the formatted_body. Currently only org.matrix.custom.html is supported.
|
* The format used in the formatted_body. Currently only "org.matrix.custom.html" is supported.
|
||||||
*/
|
*/
|
||||||
@Json(name = "format") val format: String? = null,
|
@Json(name = "format") override val format: String? = null,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The formatted version of the body. This is required if format is specified.
|
* The formatted version of the body. This is required if format is specified.
|
||||||
*/
|
*/
|
||||||
@Json(name = "formatted_body") val formattedBody: String? = null,
|
@Json(name = "formatted_body") override val formattedBody: String? = null,
|
||||||
|
|
||||||
@Json(name = "m.relates_to") override val relatesTo: RelationDefaultContent? = null,
|
@Json(name = "m.relates_to") override val relatesTo: RelationDefaultContent? = null,
|
||||||
@Json(name = "m.new_content") override val newContent: Content? = null
|
@Json(name = "m.new_content") override val newContent: Content? = null
|
||||||
) : MessageContent
|
) : MessageContentWithFormattedBody
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020 New Vector Ltd
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package im.vector.matrix.android.internal.extensions
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ex: "abcdef".subStringBetween("a", "f") -> "bcde"
|
||||||
|
* Ex: "abcdefff".subStringBetween("a", "f") -> "bcdeff"
|
||||||
|
* Ex: "aaabcdef".subStringBetween("a", "f") -> "aabcde"
|
||||||
|
*/
|
||||||
|
internal fun String.subStringBetween(prefix: String, suffix: String) = substringAfter(prefix).substringBeforeLast(suffix)
|
|
@ -35,6 +35,7 @@ import im.vector.matrix.android.api.session.room.model.message.FileInfo
|
||||||
import im.vector.matrix.android.api.session.room.model.message.ImageInfo
|
import im.vector.matrix.android.api.session.room.model.message.ImageInfo
|
||||||
import im.vector.matrix.android.api.session.room.model.message.MessageAudioContent
|
import im.vector.matrix.android.api.session.room.model.message.MessageAudioContent
|
||||||
import im.vector.matrix.android.api.session.room.model.message.MessageContent
|
import im.vector.matrix.android.api.session.room.model.message.MessageContent
|
||||||
|
import im.vector.matrix.android.api.session.room.model.message.MessageContentWithFormattedBody
|
||||||
import im.vector.matrix.android.api.session.room.model.message.MessageFileContent
|
import im.vector.matrix.android.api.session.room.model.message.MessageFileContent
|
||||||
import im.vector.matrix.android.api.session.room.model.message.MessageFormat
|
import im.vector.matrix.android.api.session.room.model.message.MessageFormat
|
||||||
import im.vector.matrix.android.api.session.room.model.message.MessageImageContent
|
import im.vector.matrix.android.api.session.room.model.message.MessageImageContent
|
||||||
|
@ -56,6 +57,7 @@ import im.vector.matrix.android.api.session.room.model.relation.ReplyToContent
|
||||||
import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
|
import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
|
||||||
import im.vector.matrix.android.api.session.room.timeline.getLastMessageContent
|
import im.vector.matrix.android.api.session.room.timeline.getLastMessageContent
|
||||||
import im.vector.matrix.android.internal.di.UserId
|
import im.vector.matrix.android.internal.di.UserId
|
||||||
|
import im.vector.matrix.android.internal.extensions.subStringBetween
|
||||||
import im.vector.matrix.android.internal.session.content.ThumbnailExtractor
|
import im.vector.matrix.android.internal.session.content.ThumbnailExtractor
|
||||||
import im.vector.matrix.android.internal.session.room.send.pills.TextPillsUtils
|
import im.vector.matrix.android.internal.session.room.send.pills.TextPillsUtils
|
||||||
import im.vector.matrix.android.internal.task.TaskExecutor
|
import im.vector.matrix.android.internal.task.TaskExecutor
|
||||||
|
@ -84,6 +86,7 @@ internal class LocalEchoEventFactory @Inject constructor(
|
||||||
) {
|
) {
|
||||||
// TODO Inject
|
// TODO Inject
|
||||||
private val parser = Parser.builder().build()
|
private val parser = Parser.builder().build()
|
||||||
|
|
||||||
// TODO Inject
|
// TODO Inject
|
||||||
private val renderer = HtmlRenderer.builder().build()
|
private val renderer = HtmlRenderer.builder().build()
|
||||||
|
|
||||||
|
@ -102,8 +105,15 @@ internal class LocalEchoEventFactory @Inject constructor(
|
||||||
val document = parser.parse(source)
|
val document = parser.parse(source)
|
||||||
val htmlText = renderer.render(document)
|
val htmlText = renderer.render(document)
|
||||||
|
|
||||||
if (isFormattedTextPertinent(source, htmlText)) {
|
// Cleanup extra paragraph
|
||||||
return TextContent(text.toString(), htmlText)
|
val cleanHtmlText = if (htmlText.startsWith("<p>") && htmlText.endsWith("</p>\n")) {
|
||||||
|
htmlText.subStringBetween("<p>", "</p>\n")
|
||||||
|
} else {
|
||||||
|
htmlText
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isFormattedTextPertinent(source, cleanHtmlText)) {
|
||||||
|
return TextContent(text.toString(), cleanHtmlText)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Try to detect pills
|
// Try to detect pills
|
||||||
|
@ -433,10 +443,8 @@ internal class LocalEchoEventFactory @Inject constructor(
|
||||||
MessageType.MSGTYPE_TEXT,
|
MessageType.MSGTYPE_TEXT,
|
||||||
MessageType.MSGTYPE_NOTICE -> {
|
MessageType.MSGTYPE_NOTICE -> {
|
||||||
var formattedText: String? = null
|
var formattedText: String? = null
|
||||||
if (content is MessageTextContent) {
|
if (content is MessageContentWithFormattedBody) {
|
||||||
if (content.format == MessageFormat.FORMAT_MATRIX_HTML) {
|
formattedText = content.matrixFormattedBody
|
||||||
formattedText = content.formattedBody
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
val isReply = content.isReply() || originalContent.isReply()
|
val isReply = content.isReply() || originalContent.isReply()
|
||||||
return if (isReply) {
|
return if (isReply) {
|
||||||
|
|
|
@ -45,11 +45,12 @@ class VectorDateFormatter @Inject constructor(private val context: Context,
|
||||||
if (time == null) {
|
if (time == null) {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
return DateUtils.getRelativeDateTimeString(context,
|
return DateUtils.getRelativeDateTimeString(
|
||||||
time,
|
context,
|
||||||
DateUtils.DAY_IN_MILLIS,
|
time,
|
||||||
2 * DateUtils.DAY_IN_MILLIS,
|
DateUtils.DAY_IN_MILLIS,
|
||||||
DateUtils.FORMAT_SHOW_WEEKDAY
|
2 * DateUtils.DAY_IN_MILLIS,
|
||||||
|
DateUtils.FORMAT_SHOW_WEEKDAY or DateUtils.FORMAT_SHOW_TIME
|
||||||
).toString()
|
).toString()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -117,8 +117,10 @@ class RoomDetailViewModel @AssistedInject constructor(
|
||||||
|
|
||||||
// Slot to keep a pending action during permission request
|
// Slot to keep a pending action during permission request
|
||||||
var pendingAction: RoomDetailAction? = null
|
var pendingAction: RoomDetailAction? = null
|
||||||
|
|
||||||
// Slot to keep a pending uri during permission request
|
// Slot to keep a pending uri during permission request
|
||||||
var pendingUri: Uri? = null
|
var pendingUri: Uri? = null
|
||||||
|
|
||||||
// Slot to store if we want to prevent preview of attachment
|
// Slot to store if we want to prevent preview of attachment
|
||||||
var preventAttachmentPreview = false
|
var preventAttachmentPreview = false
|
||||||
|
|
||||||
|
@ -390,7 +392,7 @@ class RoomDetailViewModel @AssistedInject constructor(
|
||||||
_viewEvents.post(RoomDetailViewEvents.SlashCommandNotImplemented)
|
_viewEvents.post(RoomDetailViewEvents.SlashCommandNotImplemented)
|
||||||
}
|
}
|
||||||
is ParsedCommand.SendEmote -> {
|
is ParsedCommand.SendEmote -> {
|
||||||
room.sendTextMessage(slashCommandResult.message, msgType = MessageType.MSGTYPE_EMOTE)
|
room.sendTextMessage(slashCommandResult.message, msgType = MessageType.MSGTYPE_EMOTE, autoMarkdown = action.autoMarkdown)
|
||||||
_viewEvents.post(RoomDetailViewEvents.SlashCommandHandled())
|
_viewEvents.post(RoomDetailViewEvents.SlashCommandHandled())
|
||||||
popDraft()
|
popDraft()
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,7 @@ import im.vector.matrix.android.api.session.events.model.Event
|
||||||
import im.vector.matrix.android.api.session.events.model.toModel
|
import im.vector.matrix.android.api.session.events.model.toModel
|
||||||
import im.vector.matrix.android.api.session.room.model.message.MessageTextContent
|
import im.vector.matrix.android.api.session.room.model.message.MessageTextContent
|
||||||
import im.vector.matrix.android.api.util.ContentUtils.extractUsefulTextFromReply
|
import im.vector.matrix.android.api.util.ContentUtils.extractUsefulTextFromReply
|
||||||
|
import im.vector.matrix.android.internal.session.room.send.TextContent
|
||||||
import im.vector.riotx.R
|
import im.vector.riotx.R
|
||||||
import im.vector.riotx.core.date.VectorDateFormatter
|
import im.vector.riotx.core.date.VectorDateFormatter
|
||||||
import im.vector.riotx.core.extensions.localDateTime
|
import im.vector.riotx.core.extensions.localDateTime
|
||||||
|
@ -90,17 +91,15 @@ class ViewEditHistoryEpoxyController(private val context: Context,
|
||||||
}
|
}
|
||||||
lastDate = evDate
|
lastDate = evDate
|
||||||
val cContent = getCorrectContent(timelineEvent, isOriginalReply)
|
val cContent = getCorrectContent(timelineEvent, isOriginalReply)
|
||||||
val body = cContent.second?.let { eventHtmlRenderer.render(it) }
|
val body = cContent.formattedText?.let { eventHtmlRenderer.render(it) } ?: cContent.text
|
||||||
?: cContent.first
|
|
||||||
|
|
||||||
val nextEvent = sourceEvents.getOrNull(index + 1)
|
val nextEvent = sourceEvents.getOrNull(index + 1)
|
||||||
|
|
||||||
var spannedDiff: Spannable? = null
|
var spannedDiff: Spannable? = null
|
||||||
if (nextEvent != null && cContent.second == null /*No diff for html*/) {
|
if (nextEvent != null && cContent.formattedText == null /*No diff for html*/) {
|
||||||
// compares the body
|
// compares the body
|
||||||
val nContent = getCorrectContent(nextEvent, isOriginalReply)
|
val nContent = getCorrectContent(nextEvent, isOriginalReply)
|
||||||
val nextBody = nContent.second?.let { eventHtmlRenderer.render(it) }
|
val nextBody = nContent.formattedText?.let { eventHtmlRenderer.render(it) } ?: nContent.text
|
||||||
?: nContent.first
|
|
||||||
val dmp = diff_match_patch()
|
val dmp = diff_match_patch()
|
||||||
val diff = dmp.diff_main(nextBody.toString(), body.toString())
|
val diff = dmp.diff_main(nextBody.toString(), body.toString())
|
||||||
dmp.diff_cleanupSemantic(diff)
|
dmp.diff_cleanupSemantic(diff)
|
||||||
|
@ -138,15 +137,14 @@ class ViewEditHistoryEpoxyController(private val context: Context,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getCorrectContent(event: Event, isOriginalReply: Boolean): Pair<String, String?> {
|
private fun getCorrectContent(event: Event, isOriginalReply: Boolean): TextContent {
|
||||||
val clearContent = event.getClearContent().toModel<MessageTextContent>()
|
val clearContent = event.getClearContent().toModel<MessageTextContent>()
|
||||||
val newContent = clearContent
|
val newContent = clearContent
|
||||||
?.newContent
|
?.newContent
|
||||||
?.toModel<MessageTextContent>()
|
?.toModel<MessageTextContent>()
|
||||||
if (isOriginalReply) {
|
if (isOriginalReply) {
|
||||||
return extractUsefulTextFromReply(newContent?.body ?: clearContent?.body ?: "") to null
|
return TextContent(extractUsefulTextFromReply(newContent?.body ?: clearContent?.body ?: ""))
|
||||||
}
|
}
|
||||||
return (newContent?.body ?: clearContent?.body ?: "") to (newContent?.formattedBody
|
return TextContent(newContent?.body ?: clearContent?.body ?: "", newContent?.formattedBody ?: clearContent?.formattedBody)
|
||||||
?: clearContent?.formattedBody)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,7 @@ import im.vector.matrix.android.api.session.events.model.RelationType
|
||||||
import im.vector.matrix.android.api.session.events.model.toModel
|
import im.vector.matrix.android.api.session.events.model.toModel
|
||||||
import im.vector.matrix.android.api.session.room.model.message.MessageAudioContent
|
import im.vector.matrix.android.api.session.room.model.message.MessageAudioContent
|
||||||
import im.vector.matrix.android.api.session.room.model.message.MessageContent
|
import im.vector.matrix.android.api.session.room.model.message.MessageContent
|
||||||
|
import im.vector.matrix.android.api.session.room.model.message.MessageContentWithFormattedBody
|
||||||
import im.vector.matrix.android.api.session.room.model.message.MessageEmoteContent
|
import im.vector.matrix.android.api.session.room.model.message.MessageEmoteContent
|
||||||
import im.vector.matrix.android.api.session.room.model.message.MessageFileContent
|
import im.vector.matrix.android.api.session.room.model.message.MessageFileContent
|
||||||
import im.vector.matrix.android.api.session.room.model.message.MessageImageInfoContent
|
import im.vector.matrix.android.api.session.room.model.message.MessageImageInfoContent
|
||||||
|
@ -350,7 +351,7 @@ class MessageItemFactory @Inject constructor(
|
||||||
highlight: Boolean,
|
highlight: Boolean,
|
||||||
callback: TimelineEventController.Callback?,
|
callback: TimelineEventController.Callback?,
|
||||||
attributes: AbsMessageItem.Attributes): VectorEpoxyModel<*>? {
|
attributes: AbsMessageItem.Attributes): VectorEpoxyModel<*>? {
|
||||||
val isFormatted = messageContent.formattedBody.isNullOrBlank().not()
|
val isFormatted = messageContent.matrixFormattedBody.isNullOrBlank().not()
|
||||||
return if (isFormatted) {
|
return if (isFormatted) {
|
||||||
// First detect if the message contains some code block(s) or inline code
|
// First detect if the message contains some code block(s) or inline code
|
||||||
val localFormattedBody = htmlRenderer.get().parse(messageContent.body) as Document
|
val localFormattedBody = htmlRenderer.get().parse(messageContent.body) as Document
|
||||||
|
@ -462,14 +463,14 @@ class MessageItemFactory @Inject constructor(
|
||||||
highlight: Boolean,
|
highlight: Boolean,
|
||||||
callback: TimelineEventController.Callback?,
|
callback: TimelineEventController.Callback?,
|
||||||
attributes: AbsMessageItem.Attributes): MessageTextItem? {
|
attributes: AbsMessageItem.Attributes): MessageTextItem? {
|
||||||
val message = messageContent.body.let {
|
val formattedBody = span {
|
||||||
val formattedBody = span {
|
text = messageContent.getHtmlBody()
|
||||||
text = it
|
textColor = colorProvider.getColorFromAttribute(R.attr.riotx_text_secondary)
|
||||||
textColor = colorProvider.getColorFromAttribute(R.attr.riotx_text_secondary)
|
textStyle = "italic"
|
||||||
textStyle = "italic"
|
|
||||||
}
|
|
||||||
formattedBody.linkify(callback)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val message = formattedBody.linkify(callback)
|
||||||
|
|
||||||
return MessageTextItem_()
|
return MessageTextItem_()
|
||||||
.leftGuideline(avatarSizeProvider.leftGuideline)
|
.leftGuideline(avatarSizeProvider.leftGuideline)
|
||||||
.attributes(attributes)
|
.attributes(attributes)
|
||||||
|
@ -483,10 +484,12 @@ class MessageItemFactory @Inject constructor(
|
||||||
highlight: Boolean,
|
highlight: Boolean,
|
||||||
callback: TimelineEventController.Callback?,
|
callback: TimelineEventController.Callback?,
|
||||||
attributes: AbsMessageItem.Attributes): MessageTextItem? {
|
attributes: AbsMessageItem.Attributes): MessageTextItem? {
|
||||||
val message = messageContent.body.let {
|
val formattedBody = SpannableStringBuilder()
|
||||||
val formattedBody = "* ${informationData.memberName} $it"
|
formattedBody.append("* ${informationData.memberName} ")
|
||||||
formattedBody.linkify(callback)
|
formattedBody.append(messageContent.getHtmlBody())
|
||||||
}
|
|
||||||
|
val message = formattedBody.linkify(callback)
|
||||||
|
|
||||||
return MessageTextItem_()
|
return MessageTextItem_()
|
||||||
.apply {
|
.apply {
|
||||||
if (informationData.hasBeenEdited) {
|
if (informationData.hasBeenEdited) {
|
||||||
|
@ -502,6 +505,13 @@ class MessageItemFactory @Inject constructor(
|
||||||
.movementMethod(createLinkMovementMethod(callback))
|
.movementMethod(createLinkMovementMethod(callback))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun MessageContentWithFormattedBody.getHtmlBody(): CharSequence {
|
||||||
|
return matrixFormattedBody
|
||||||
|
?.let { htmlCompressor.compress(it) }
|
||||||
|
?.let { htmlRenderer.get().render(it) }
|
||||||
|
?: body
|
||||||
|
}
|
||||||
|
|
||||||
private fun buildRedactedItem(attributes: AbsMessageItem.Attributes,
|
private fun buildRedactedItem(attributes: AbsMessageItem.Attributes,
|
||||||
highlight: Boolean): RedactedMessageItem? {
|
highlight: Boolean): RedactedMessageItem? {
|
||||||
return RedactedMessageItem_()
|
return RedactedMessageItem_()
|
||||||
|
|
Loading…
Add table
Reference in a new issue