Browse Source

Merge pull request #1498 from vector-im/feature/bma/renderEmote

Render emote
pull/1500/head
Benoit Marty 12 months ago committed by GitHub
parent
commit
5d49196651
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      changelog.d/1497.feature
  2. 6
      features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemContentFactory.kt
  3. 11
      features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemContentMessageFactory.kt
  4. 8
      features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/util/toHtmlDocument.kt
  5. 2
      libraries/eventformatter/impl/src/main/kotlin/io/element/android/libraries/eventformatter/impl/DefaultRoomLastMessageFormatter.kt
  6. 4
      libraries/eventformatter/impl/src/test/kotlin/io/element/android/libraries/eventformatter/impl/DefaultRoomLastMessageFormatterTests.kt
  7. 6
      libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/item/event/EventContent.kt
  8. 7
      libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotifiableEventResolver.kt

1
changelog.d/1497.feature

@ -0,0 +1 @@ @@ -0,0 +1 @@
Improve rendering of m.emote.

6
features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemContentFactory.kt

@ -24,6 +24,7 @@ import io.element.android.libraries.matrix.api.timeline.item.event.FailedToParse @@ -24,6 +24,7 @@ import io.element.android.libraries.matrix.api.timeline.item.event.FailedToParse
import io.element.android.libraries.matrix.api.timeline.item.event.MessageContent
import io.element.android.libraries.matrix.api.timeline.item.event.PollContent
import io.element.android.libraries.matrix.api.timeline.item.event.ProfileChangeContent
import io.element.android.libraries.matrix.api.timeline.item.event.ProfileTimelineDetails
import io.element.android.libraries.matrix.api.timeline.item.event.RedactedContent
import io.element.android.libraries.matrix.api.timeline.item.event.RoomMembershipContent
import io.element.android.libraries.matrix.api.timeline.item.event.StateContent
@ -49,7 +50,10 @@ class TimelineItemContentFactory @Inject constructor( @@ -49,7 +50,10 @@ class TimelineItemContentFactory @Inject constructor(
return when (val itemContent = eventTimelineItem.content) {
is FailedToParseMessageLikeContent -> failedToParseMessageFactory.create(itemContent)
is FailedToParseStateContent -> failedToParseStateFactory.create(itemContent)
is MessageContent -> messageFactory.create(itemContent)
is MessageContent -> {
val senderDisplayName = (eventTimelineItem.senderProfile as? ProfileTimelineDetails.Ready)?.displayName ?: eventTimelineItem.sender.value
messageFactory.create(itemContent, senderDisplayName)
}
is ProfileChangeContent -> profileChangeFactory.create(eventTimelineItem)
is RedactedContent -> redactedMessageFactory.create(itemContent)
is RoomMembershipContent -> roomMembershipFactory.create(eventTimelineItem)

11
features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemContentMessageFactory.kt

@ -39,6 +39,7 @@ import io.element.android.libraries.matrix.api.timeline.item.event.LocationMessa @@ -39,6 +39,7 @@ import io.element.android.libraries.matrix.api.timeline.item.event.LocationMessa
import io.element.android.libraries.matrix.api.timeline.item.event.MessageContent
import io.element.android.libraries.matrix.api.timeline.item.event.NoticeMessageType
import io.element.android.libraries.matrix.api.timeline.item.event.TextMessageType
import io.element.android.libraries.matrix.api.timeline.item.event.UnknownMessageType
import io.element.android.libraries.matrix.api.timeline.item.event.VideoMessageType
import javax.inject.Inject
@ -47,11 +48,11 @@ class TimelineItemContentMessageFactory @Inject constructor( @@ -47,11 +48,11 @@ class TimelineItemContentMessageFactory @Inject constructor(
private val fileExtensionExtractor: FileExtensionExtractor,
) {
fun create(content: MessageContent): TimelineItemEventContent {
return when (val messageType = content.type) {
fun create(content: MessageContent, senderDisplayName: String): TimelineItemEventContent {
return when (val messageType = content.type ?: UnknownMessageType) {
is EmoteMessageType -> TimelineItemEmoteContent(
body = messageType.body,
htmlDocument = messageType.formatted?.toHtmlDocument(),
body = "* $senderDisplayName ${messageType.body}",
htmlDocument = messageType.formatted?.toHtmlDocument(prefix = "* senderDisplayName"),
isEdited = content.isEdited,
)
is ImageMessageType -> {
@ -130,7 +131,7 @@ class TimelineItemContentMessageFactory @Inject constructor( @@ -130,7 +131,7 @@ class TimelineItemContentMessageFactory @Inject constructor(
htmlDocument = messageType.formatted?.toHtmlDocument(),
isEdited = content.isEdited,
)
else -> TimelineItemUnknownContent
UnknownMessageType -> TimelineItemUnknownContent
}
}

8
features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/util/toHtmlDocument.kt

@ -21,8 +21,12 @@ import io.element.android.libraries.matrix.api.timeline.item.event.MessageFormat @@ -21,8 +21,12 @@ import io.element.android.libraries.matrix.api.timeline.item.event.MessageFormat
import org.jsoup.Jsoup
import org.jsoup.nodes.Document
fun FormattedBody.toHtmlDocument(): Document? {
fun FormattedBody.toHtmlDocument(prefix: String? = null): Document? {
return takeIf { it.format == MessageFormat.HTML }?.body?.let { formattedBody ->
Jsoup.parse(formattedBody)
if (prefix != null) {
Jsoup.parse("$prefix $formattedBody")
} else {
Jsoup.parse(formattedBody)
}
}
}

2
libraries/eventformatter/impl/src/main/kotlin/io/element/android/libraries/eventformatter/impl/DefaultRoomLastMessageFormatter.kt

@ -111,7 +111,7 @@ class DefaultRoomLastMessageFormatter @Inject constructor( @@ -111,7 +111,7 @@ class DefaultRoomLastMessageFormatter @Inject constructor(
val internalMessage = when (messageType) {
// Doesn't need a prefix
is EmoteMessageType -> {
return "- $senderDisplayName ${messageType.body}"
return "* $senderDisplayName ${messageType.body}"
}
is TextMessageType -> {
messageType.body

4
libraries/eventformatter/impl/src/test/kotlin/io/element/android/libraries/eventformatter/impl/DefaultRoomLastMessageFormatterTests.kt

@ -201,7 +201,7 @@ class DefaultRoomLastMessageFormatterTests { @@ -201,7 +201,7 @@ class DefaultRoomLastMessageFormatterTests {
is ImageMessageType -> "Image"
is FileMessageType -> "File"
is LocationMessageType -> "Shared location"
is EmoteMessageType -> "- $senderName ${type.body}"
is EmoteMessageType -> "* $senderName ${type.body}"
is TextMessageType, is NoticeMessageType -> body
UnknownMessageType -> "Unsupported event"
}
@ -217,7 +217,7 @@ class DefaultRoomLastMessageFormatterTests { @@ -217,7 +217,7 @@ class DefaultRoomLastMessageFormatterTests {
is ImageMessageType -> "$senderName: Image"
is FileMessageType -> "$senderName: File"
is LocationMessageType -> "$senderName: Shared location"
is EmoteMessageType -> "- $senderName ${type.body}"
is EmoteMessageType -> "* $senderName ${type.body}"
is TextMessageType, is NoticeMessageType -> "$senderName: $body"
UnknownMessageType -> "$senderName: Unsupported event"
}

6
libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/item/event/EventContent.kt

@ -63,7 +63,7 @@ sealed interface InReplyTo { @@ -63,7 +63,7 @@ sealed interface InReplyTo {
data object Error : InReplyTo
}
object RedactedContent : EventContent
data object RedactedContent : EventContent
data class StickerContent(
val body: String,
@ -124,11 +124,11 @@ data class FailedToParseStateContent( @@ -124,11 +124,11 @@ data class FailedToParseStateContent(
val error: String
) : EventContent
object UnknownContent : EventContent
data object UnknownContent : EventContent
sealed interface MessageType
object UnknownMessageType : MessageType
data object UnknownMessageType : MessageType
enum class MessageFormat {
HTML, UNKNOWN

7
libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotifiableEventResolver.kt

@ -87,7 +87,7 @@ class NotifiableEventResolver @Inject constructor( @@ -87,7 +87,7 @@ class NotifiableEventResolver @Inject constructor(
noisy = isNoisy,
timestamp = this.timestamp,
senderName = senderDisplayName,
body = descriptionFromMessageContent(content),
body = descriptionFromMessageContent(content, senderDisplayName ?: content.senderId.value),
imageUriString = this.contentUrl,
roomName = roomDisplayName,
roomIsDirect = isDirect,
@ -133,7 +133,7 @@ class NotifiableEventResolver @Inject constructor( @@ -133,7 +133,7 @@ class NotifiableEventResolver @Inject constructor(
NotificationContent.MessageLike.KeyVerificationStart -> null.also {
Timber.tag(loggerTag.value).d("Ignoring notification for verification ${content.javaClass.simpleName}")
}
is NotificationContent.MessageLike.Poll -> {
is NotificationContent.MessageLike.Poll -> {
buildNotifiableMessageEvent(
sessionId = userId,
senderId = content.senderId,
@ -205,10 +205,11 @@ class NotifiableEventResolver @Inject constructor( @@ -205,10 +205,11 @@ class NotifiableEventResolver @Inject constructor(
private fun descriptionFromMessageContent(
content: NotificationContent.MessageLike.RoomMessage,
senderDisplayName: String,
): String {
return when (val messageType = content.messageType) {
is AudioMessageType -> messageType.body
is EmoteMessageType -> messageType.body
is EmoteMessageType -> "* $senderDisplayName ${messageType.body}"
is FileMessageType -> messageType.body
is ImageMessageType -> messageType.body
is NoticeMessageType -> messageType.body

Loading…
Cancel
Save