Fixing parsing of outcoming messages for @room chip (missing incoming messages)
This commit is contained in:
parent
2beff8d4cd
commit
fb2401d0b1
|
@ -43,8 +43,9 @@ sealed class MatrixItem(
|
|||
override fun updateAvatar(newAvatar: String?) = copy(avatarUrl = newAvatar)
|
||||
}
|
||||
|
||||
// TODO is it correct to represent it by a Matrix Item ? => to confirm
|
||||
data class EveryoneInRoomItem(override val id: String,
|
||||
override val displayName: String? = null,
|
||||
override val displayName: String = NOTIFY_EVERYONE,
|
||||
override val avatarUrl: String? = null,
|
||||
val roomDisplayName: String? = null) :
|
||||
MatrixItem(id, displayName, avatarUrl) {
|
||||
|
@ -190,7 +191,7 @@ fun RoomSummary.toMatrixItem() = if (roomType == RoomType.SPACE) {
|
|||
|
||||
fun RoomSummary.toRoomAliasMatrixItem() = MatrixItem.RoomAliasItem(canonicalAlias ?: roomId, displayName, avatarUrl)
|
||||
|
||||
fun RoomSummary.toEveryoneInRoomMatrixItem() = MatrixItem.EveryoneInRoomItem(roomId, MatrixItem.NOTIFY_EVERYONE, avatarUrl, displayName)
|
||||
fun RoomSummary.toEveryoneInRoomMatrixItem() = MatrixItem.EveryoneInRoomItem(id = roomId, avatarUrl = avatarUrl, roomDisplayName = displayName)
|
||||
|
||||
// If no name is available, use room alias as Riot-Web does
|
||||
fun PublicRoom.toMatrixItem() = MatrixItem.RoomItem(roomId, name ?: getPrimaryAlias() ?: "", avatarUrl)
|
||||
|
|
|
@ -17,6 +17,7 @@ package org.matrix.android.sdk.internal.session.room.send.pills
|
|||
|
||||
import android.text.SpannableString
|
||||
import org.matrix.android.sdk.api.session.room.send.MatrixItemSpan
|
||||
import org.matrix.android.sdk.api.util.MatrixItem
|
||||
import org.matrix.android.sdk.internal.session.displayname.DisplayNameResolver
|
||||
import java.util.Collections
|
||||
import javax.inject.Inject
|
||||
|
@ -51,6 +52,8 @@ internal class TextPillsUtils @Inject constructor(
|
|||
val pills = spannableString
|
||||
?.getSpans(0, text.length, MatrixItemSpan::class.java)
|
||||
?.map { MentionLinkSpec(it, spannableString.getSpanStart(it), spannableString.getSpanEnd(it)) }
|
||||
// we use the raw text for @room notification instead of a link
|
||||
?.filterNot { it.span.matrixItem is MatrixItem.EveryoneInRoomItem }
|
||||
?.toMutableList()
|
||||
?.takeIf { it.isNotEmpty() }
|
||||
?: return null
|
||||
|
|
|
@ -238,7 +238,7 @@ class AutoCompleter @AssistedInject constructor(
|
|||
|
||||
// Adding trailing space " " or ": " if the user started mention someone
|
||||
val displayNameSuffix =
|
||||
if (firstChar == TRIGGER_AUTO_COMPLETE_MEMBERS && startIndex == 0) {
|
||||
if (matrixItem is MatrixItem.UserItem) {
|
||||
": "
|
||||
} else {
|
||||
" "
|
||||
|
|
|
@ -549,6 +549,7 @@ class MessageItemFactory @Inject constructor(
|
|||
highlight: Boolean,
|
||||
callback: TimelineEventController.Callback?,
|
||||
attributes: AbsMessageItem.Attributes): MessageTextItem? {
|
||||
// TODO process body to add pills for @room texts: create a dedicated renderer with PillsPostProcessor ?
|
||||
val bindingOptions = spanUtils.getBindingOptions(body)
|
||||
val linkifiedBody = body.linkify(callback)
|
||||
|
||||
|
|
|
@ -36,58 +36,109 @@ class PillsPostProcessor @AssistedInject constructor(@Assisted private val roomI
|
|||
private val context: Context,
|
||||
private val avatarRenderer: AvatarRenderer,
|
||||
private val sessionHolder: ActiveSessionHolder) :
|
||||
EventHtmlRenderer.PostProcessor {
|
||||
EventHtmlRenderer.PostProcessor {
|
||||
|
||||
@AssistedFactory
|
||||
interface Factory {
|
||||
fun create(roomId: String?): PillsPostProcessor
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// SPECIALIZATION
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
override fun afterRender(renderedText: Spannable) {
|
||||
addPillSpans(renderedText, roomId)
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// HELPER METHODS
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
private fun addPillSpans(renderedText: Spannable, roomId: String?) {
|
||||
addLinkSpans(renderedText, roomId)
|
||||
roomId?.let { id -> addRawTextSpans(renderedText, id) }
|
||||
}
|
||||
|
||||
private fun addPillSpan(
|
||||
renderedText: Spannable,
|
||||
pillSpan: PillImageSpan,
|
||||
startSpan: Int,
|
||||
endSpan: Int
|
||||
) {
|
||||
renderedText.setSpan(pillSpan, startSpan, endSpan, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||
}
|
||||
|
||||
private fun addLinkSpans(renderedText: Spannable, roomId: String?) {
|
||||
// We let markdown handle links and then we add PillImageSpan if needed.
|
||||
val linkSpans = renderedText.getSpans(0, renderedText.length, LinkSpan::class.java)
|
||||
linkSpans.forEach { linkSpan ->
|
||||
val pillSpan = linkSpan.createPillSpan(roomId) ?: return@forEach
|
||||
val startSpan = renderedText.getSpanStart(linkSpan)
|
||||
val endSpan = renderedText.getSpanEnd(linkSpan)
|
||||
renderedText.setSpan(pillSpan, startSpan, endSpan, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||
addPillSpan(renderedText, pillSpan, startSpan, endSpan)
|
||||
}
|
||||
}
|
||||
|
||||
// TODO move this into another PostProcessor when there is no html
|
||||
private fun addRawTextSpans(renderedText: Spannable, roomId: String) {
|
||||
if (renderedText.contains(MatrixItem.NOTIFY_EVERYONE)) {
|
||||
addNotifyEveryoneSpans(renderedText, roomId)
|
||||
}
|
||||
}
|
||||
|
||||
private fun addNotifyEveryoneSpans(renderedText: Spannable, roomId: String) {
|
||||
val room: RoomSummary? = sessionHolder.getSafeActiveSession()?.getRoomSummary(roomId)
|
||||
val matrixItem = MatrixItem.EveryoneInRoomItem(
|
||||
id = roomId,
|
||||
avatarUrl = room?.avatarUrl,
|
||||
roomDisplayName = room?.displayName
|
||||
)
|
||||
val pillSpan = createPillImageSpan(matrixItem)
|
||||
|
||||
// search for notify everyone text
|
||||
var foundIndex = renderedText.indexOf(MatrixItem.NOTIFY_EVERYONE, 0)
|
||||
while (foundIndex >= 0) {
|
||||
val endSpan = foundIndex + MatrixItem.NOTIFY_EVERYONE.length
|
||||
addPillSpan(renderedText, pillSpan, foundIndex, endSpan)
|
||||
foundIndex = renderedText.indexOf(MatrixItem.NOTIFY_EVERYONE, endSpan)
|
||||
}
|
||||
}
|
||||
|
||||
private fun createPillImageSpan(matrixItem: MatrixItem) =
|
||||
PillImageSpan(GlideApp.with(context), avatarRenderer, context, matrixItem)
|
||||
|
||||
private fun LinkSpan.createPillSpan(roomId: String?): PillImageSpan? {
|
||||
// TODO handle @room text to create associated chip
|
||||
val permalinkData = PermalinkParser.parse(url)
|
||||
val matrixItem = when (permalinkData) {
|
||||
is PermalinkData.UserLink -> {
|
||||
if (roomId == null) {
|
||||
sessionHolder.getSafeActiveSession()?.getUser(permalinkData.userId)?.toMatrixItem()
|
||||
} else {
|
||||
sessionHolder.getSafeActiveSession()?.getRoomMember(permalinkData.userId, roomId)?.toMatrixItem()
|
||||
}
|
||||
}
|
||||
is PermalinkData.RoomLink -> {
|
||||
if (permalinkData.eventId == null) {
|
||||
val room: RoomSummary? = sessionHolder.getSafeActiveSession()?.getRoomSummary(permalinkData.roomIdOrAlias)
|
||||
if (permalinkData.isRoomAlias) {
|
||||
MatrixItem.RoomAliasItem(permalinkData.roomIdOrAlias, room?.displayName, room?.avatarUrl)
|
||||
} else {
|
||||
MatrixItem.RoomItem(permalinkData.roomIdOrAlias, room?.displayName, room?.avatarUrl)
|
||||
}
|
||||
} else {
|
||||
// Exclude event link (used in reply events, we do not want to pill the "in reply to")
|
||||
null
|
||||
}
|
||||
}
|
||||
is PermalinkData.GroupLink -> {
|
||||
val group = sessionHolder.getSafeActiveSession()?.getGroupSummary(permalinkData.groupId)
|
||||
MatrixItem.GroupItem(permalinkData.groupId, group?.displayName, group?.avatarUrl)
|
||||
}
|
||||
val matrixItem = when (val permalinkData = PermalinkParser.parse(url)) {
|
||||
is PermalinkData.UserLink -> permalinkData.toMatrixItem(roomId)
|
||||
is PermalinkData.RoomLink -> permalinkData.toMatrixItem()
|
||||
is PermalinkData.GroupLink -> permalinkData.toMatrixItem()
|
||||
else -> null
|
||||
} ?: return null
|
||||
return PillImageSpan(GlideApp.with(context), avatarRenderer, context, matrixItem)
|
||||
return createPillImageSpan(matrixItem)
|
||||
}
|
||||
|
||||
private fun PermalinkData.UserLink.toMatrixItem(roomId: String?): MatrixItem? =
|
||||
if (roomId == null) {
|
||||
sessionHolder.getSafeActiveSession()?.getUser(userId)?.toMatrixItem()
|
||||
} else {
|
||||
sessionHolder.getSafeActiveSession()?.getRoomMember(userId, roomId)?.toMatrixItem()
|
||||
}
|
||||
|
||||
private fun PermalinkData.RoomLink.toMatrixItem(): MatrixItem? =
|
||||
if (eventId == null) {
|
||||
val room: RoomSummary? = sessionHolder.getSafeActiveSession()?.getRoomSummary(roomIdOrAlias)
|
||||
when {
|
||||
isRoomAlias -> MatrixItem.RoomAliasItem(roomIdOrAlias, room?.displayName, room?.avatarUrl)
|
||||
else -> MatrixItem.RoomItem(roomIdOrAlias, room?.displayName, room?.avatarUrl)
|
||||
}
|
||||
} else {
|
||||
// Exclude event link (used in reply events, we do not want to pill the "in reply to")
|
||||
null
|
||||
}
|
||||
|
||||
private fun PermalinkData.GroupLink.toMatrixItem(): MatrixItem? {
|
||||
val group = sessionHolder.getSafeActiveSession()?.getGroupSummary(groupId)
|
||||
return MatrixItem.GroupItem(groupId, group?.displayName, group?.avatarUrl)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue