Mutualize code, and also, when replying to an edited event, use the last text in the reply prefix content

This commit is contained in:
Benoit Marty 2019-07-10 17:37:22 +02:00
parent 9a57a02996
commit 794fd650a4
9 changed files with 31 additions and 27 deletions

View File

@ -16,8 +16,8 @@
package im.vector.matrix.android.api.session.room.model.relation package im.vector.matrix.android.api.session.room.model.relation
import androidx.lifecycle.LiveData import androidx.lifecycle.LiveData
import im.vector.matrix.android.api.session.events.model.Event
import im.vector.matrix.android.api.session.room.model.EventAnnotationsSummary import im.vector.matrix.android.api.session.room.model.EventAnnotationsSummary
import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
import im.vector.matrix.android.api.util.Cancelable import im.vector.matrix.android.api.util.Cancelable
/** /**
@ -79,7 +79,7 @@ interface RelationService {
* @param replyText the reply text * @param replyText the reply text
* @param autoMarkdown If true, the SDK will generate a formatted HTML message from the body text if markdown syntax is present * @param autoMarkdown If true, the SDK will generate a formatted HTML message from the body text if markdown syntax is present
*/ */
fun replyToMessage(eventReplied: Event, replyText: String, autoMarkdown: Boolean = false): Cancelable? fun replyToMessage(eventReplied: TimelineEvent, replyText: String, autoMarkdown: Boolean = false): Cancelable?
fun getEventSummaryLive(eventId: String): LiveData<EventAnnotationsSummary> fun getEventSummaryLive(eventId: String): LiveData<EventAnnotationsSummary>
} }

View File

@ -16,10 +16,11 @@
package im.vector.matrix.android.api.session.room.timeline package im.vector.matrix.android.api.session.room.timeline
import im.vector.matrix.android.api.session.events.model.Content
import im.vector.matrix.android.api.session.events.model.Event import im.vector.matrix.android.api.session.events.model.Event
import im.vector.matrix.android.api.session.events.model.EventType import im.vector.matrix.android.api.session.events.model.EventType
import im.vector.matrix.android.api.session.events.model.toModel
import im.vector.matrix.android.api.session.room.model.EventAnnotationsSummary import im.vector.matrix.android.api.session.room.model.EventAnnotationsSummary
import im.vector.matrix.android.api.session.room.model.message.MessageContent
import im.vector.matrix.android.api.session.room.send.SendState import im.vector.matrix.android.api.session.room.send.SendState
/** /**
@ -81,3 +82,9 @@ data class TimelineEvent(
return EventType.ENCRYPTED == root.type return EventType.ENCRYPTED == root.type
} }
} }
/**
* Get last MessageContent, after a possible edition
*/
fun TimelineEvent.getLastMessageContent(): MessageContent? = annotations?.editSummary?.aggregatedContent?.toModel()
?: root.getClearContent().toModel()

View File

@ -27,6 +27,7 @@ import im.vector.matrix.android.api.session.events.model.Event
import im.vector.matrix.android.api.session.room.model.EventAnnotationsSummary import im.vector.matrix.android.api.session.room.model.EventAnnotationsSummary
import im.vector.matrix.android.api.session.room.model.message.MessageType import im.vector.matrix.android.api.session.room.model.message.MessageType
import im.vector.matrix.android.api.session.room.model.relation.RelationService import im.vector.matrix.android.api.session.room.model.relation.RelationService
import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
import im.vector.matrix.android.api.util.Cancelable import im.vector.matrix.android.api.util.Cancelable
import im.vector.matrix.android.internal.database.RealmLiveData import im.vector.matrix.android.internal.database.RealmLiveData
import im.vector.matrix.android.internal.database.helper.addSendingEvent import im.vector.matrix.android.internal.database.helper.addSendingEvent
@ -127,7 +128,7 @@ internal class DefaultRelationService @Inject constructor(private val context: C
} }
override fun replyToMessage(eventReplied: Event, replyText: String, autoMarkdown: Boolean): Cancelable? { override fun replyToMessage(eventReplied: TimelineEvent, replyText: String, autoMarkdown: Boolean): Cancelable? {
val event = eventFactory.createReplyTextEvent(roomId, eventReplied, replyText, autoMarkdown)?.also { val event = eventFactory.createReplyTextEvent(roomId, eventReplied, replyText, autoMarkdown)?.also {
saveLocalEcho(it) saveLocalEcho(it)
} ?: return null } ?: return null

View File

@ -28,6 +28,8 @@ import im.vector.matrix.android.api.session.room.model.relation.ReactionContent
import im.vector.matrix.android.api.session.room.model.relation.ReactionInfo import im.vector.matrix.android.api.session.room.model.relation.ReactionInfo
import im.vector.matrix.android.api.session.room.model.relation.RelationDefaultContent import im.vector.matrix.android.api.session.room.model.relation.RelationDefaultContent
import im.vector.matrix.android.api.session.room.model.relation.ReplyToContent 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.getLastMessageContent
import im.vector.matrix.android.internal.database.helper.addSendingEvent import im.vector.matrix.android.internal.database.helper.addSendingEvent
import im.vector.matrix.android.internal.database.model.RoomEntity import im.vector.matrix.android.internal.database.model.RoomEntity
import im.vector.matrix.android.internal.database.query.where import im.vector.matrix.android.internal.database.query.where
@ -230,11 +232,11 @@ internal class LocalEchoEventFactory @Inject constructor(private val credentials
return "$LOCAL_ID_PREFIX${UUID.randomUUID()}" return "$LOCAL_ID_PREFIX${UUID.randomUUID()}"
} }
fun createReplyTextEvent(roomId: String, eventReplied: Event, replyText: String, autoMarkdown: Boolean): Event? { fun createReplyTextEvent(roomId: String, eventReplied: TimelineEvent, replyText: String, autoMarkdown: Boolean): Event? {
//Fallbacks and event representation //Fallbacks and event representation
//TODO Add error/warning logs when any of this is null //TODO Add error/warning logs when any of this is null
val permalink = PermalinkFactory.createPermalink(eventReplied) ?: return null val permalink = PermalinkFactory.createPermalink(eventReplied.root) ?: return null
val userId = eventReplied.senderId ?: return null val userId = eventReplied.root.senderId ?: return null
val userLink = PermalinkFactory.createPermalink(userId) ?: return null val userLink = PermalinkFactory.createPermalink(userId) ?: return null
// <mx-reply> // <mx-reply>
// <blockquote> // <blockquote>
@ -245,7 +247,7 @@ internal class LocalEchoEventFactory @Inject constructor(private val credentials
// </blockquote> // </blockquote>
// </mx-reply> // </mx-reply>
// This is where the reply goes. // This is where the reply goes.
val body = bodyForReply(eventReplied.getClearContent().toModel<MessageContent>()) val body = bodyForReply(eventReplied.getLastMessageContent())
val replyFormatted = REPLY_PATTERN.format( val replyFormatted = REPLY_PATTERN.format(
permalink, permalink,
stringProvider.getString(R.string.message_reply_to_prefix), stringProvider.getString(R.string.message_reply_to_prefix),
@ -268,7 +270,7 @@ internal class LocalEchoEventFactory @Inject constructor(private val credentials
} }
replyFallback.append("\n\n").append(replyText) replyFallback.append("\n\n").append(replyText)
val eventId = eventReplied.eventId ?: return null val eventId = eventReplied.root.eventId ?: return null
val content = MessageTextContent( val content = MessageTextContent(
type = MessageType.MSGTYPE_TEXT, type = MessageType.MSGTYPE_TEXT,
format = MessageType.FORMAT_MATRIX_HTML, format = MessageType.FORMAT_MATRIX_HTML,

View File

@ -54,11 +54,11 @@ import com.otaliastudios.autocomplete.AutocompleteCallback
import com.otaliastudios.autocomplete.CharPolicy import com.otaliastudios.autocomplete.CharPolicy
import im.vector.matrix.android.api.permalinks.PermalinkFactory import im.vector.matrix.android.api.permalinks.PermalinkFactory
import im.vector.matrix.android.api.session.Session import im.vector.matrix.android.api.session.Session
import im.vector.matrix.android.api.session.events.model.toModel
import im.vector.matrix.android.api.session.room.model.EditAggregatedSummary import im.vector.matrix.android.api.session.room.model.EditAggregatedSummary
import im.vector.matrix.android.api.session.room.model.Membership import im.vector.matrix.android.api.session.room.model.Membership
import im.vector.matrix.android.api.session.room.model.message.* import im.vector.matrix.android.api.session.room.model.message.*
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.user.model.User import im.vector.matrix.android.api.session.user.model.User
import im.vector.riotx.R import im.vector.riotx.R
import im.vector.riotx.core.di.ScreenComponent import im.vector.riotx.core.di.ScreenComponent
@ -249,10 +249,7 @@ class RoomDetailFragment :
setTextColor(ContextCompat.getColor(requireContext(), getColorFromUserId(event.root.senderId))) setTextColor(ContextCompat.getColor(requireContext(), getColorFromUserId(event.root.senderId)))
} }
//TODO this is used at several places, find way to refactor? val messageContent: MessageContent? = event.getLastMessageContent()
val messageContent: MessageContent? =
event.annotations?.editSummary?.aggregatedContent?.toModel()
?: event.root.getClearContent().toModel()
val nonFormattedBody = messageContent?.body ?: "" val nonFormattedBody = messageContent?.body ?: ""
var formattedBody: CharSequence? = null var formattedBody: CharSequence? = null
if (messageContent is MessageTextContent && messageContent.format == MessageType.FORMAT_MATRIX_HTML) { if (messageContent is MessageTextContent && messageContent.format == MessageType.FORMAT_MATRIX_HTML) {

View File

@ -275,7 +275,7 @@ class RoomDetailViewModel @AssistedInject constructor(@Assisted initialState: Ro
} }
is SendMode.REPLY -> { is SendMode.REPLY -> {
state.sendMode.timelineEvent.let { state.sendMode.timelineEvent.let {
room.replyToMessage(it.root, action.text, action.autoMarkdown) room.replyToMessage(it, action.text, action.autoMarkdown)
setState { setState {
copy( copy(
sendMode = SendMode.REGULAR sendMode = SendMode.REGULAR

View File

@ -21,11 +21,11 @@ import com.squareup.inject.assisted.AssistedInject
import dagger.Lazy import dagger.Lazy
import im.vector.matrix.android.api.session.Session import im.vector.matrix.android.api.session.Session
import im.vector.matrix.android.api.session.events.model.EventType import im.vector.matrix.android.api.session.events.model.EventType
import im.vector.matrix.android.api.session.events.model.toModel
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.MessageTextContent import im.vector.matrix.android.api.session.room.model.message.MessageTextContent
import im.vector.matrix.android.api.session.room.model.message.MessageType import im.vector.matrix.android.api.session.room.model.message.MessageType
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.rx.RxRoom import im.vector.matrix.rx.RxRoom
import im.vector.riotx.core.platform.VectorViewModel import im.vector.riotx.core.platform.VectorViewModel
import im.vector.riotx.features.home.room.detail.timeline.format.NoticeEventFormatter import im.vector.riotx.features.home.room.detail.timeline.format.NoticeEventFormatter
@ -57,8 +57,7 @@ data class MessageActionState(
fun messageBody(eventHtmlRenderer: EventHtmlRenderer?, noticeEventFormatter: NoticeEventFormatter?): CharSequence? { fun messageBody(eventHtmlRenderer: EventHtmlRenderer?, noticeEventFormatter: NoticeEventFormatter?): CharSequence? {
return when (timelineEvent()?.root?.getClearType()) { return when (timelineEvent()?.root?.getClearType()) {
EventType.MESSAGE -> { EventType.MESSAGE -> {
val messageContent: MessageContent? = timelineEvent()?.annotations?.editSummary?.aggregatedContent?.toModel() val messageContent: MessageContent? = timelineEvent()?.getLastMessageContent()
?: timelineEvent()?.root?.getClearContent().toModel()
if (messageContent is MessageTextContent && messageContent.format == MessageType.FORMAT_MATRIX_HTML) { if (messageContent is MessageTextContent && messageContent.format == MessageType.FORMAT_MATRIX_HTML) {
eventHtmlRenderer?.render(messageContent.formattedBody eventHtmlRenderer?.render(messageContent.formattedBody
?: messageContent.body) ?: messageContent.body)

View File

@ -27,11 +27,11 @@ import dagger.Lazy
import im.vector.matrix.android.api.permalinks.MatrixLinkify import im.vector.matrix.android.api.permalinks.MatrixLinkify
import im.vector.matrix.android.api.permalinks.MatrixPermalinkSpan import im.vector.matrix.android.api.permalinks.MatrixPermalinkSpan
import im.vector.matrix.android.api.session.events.model.RelationType 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.room.model.EditAggregatedSummary import im.vector.matrix.android.api.session.room.model.EditAggregatedSummary
import im.vector.matrix.android.api.session.room.model.message.* import im.vector.matrix.android.api.session.room.model.message.*
import im.vector.matrix.android.api.session.room.send.SendState import im.vector.matrix.android.api.session.room.send.SendState
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.internal.crypto.attachments.toElementToDecrypt import im.vector.matrix.android.internal.crypto.attachments.toElementToDecrypt
import im.vector.riotx.EmojiCompatFontProvider import im.vector.riotx.EmojiCompatFontProvider
import im.vector.riotx.R import im.vector.riotx.R
@ -79,8 +79,7 @@ class MessageItemFactory @Inject constructor(
} }
val messageContent: MessageContent = val messageContent: MessageContent =
event.annotations?.editSummary?.aggregatedContent?.toModel() event.getLastMessageContent()
?: event.root.getClearContent().toModel()
?: //Malformed content, we should echo something on screen ?: //Malformed content, we should echo something on screen
return DefaultItem_().text(stringProvider.getString(R.string.malformed_message)) return DefaultItem_().text(stringProvider.getString(R.string.malformed_message))

View File

@ -18,15 +18,14 @@ package im.vector.riotx.features.notifications
import androidx.core.app.NotificationCompat import androidx.core.app.NotificationCompat
import im.vector.matrix.android.api.session.Session import im.vector.matrix.android.api.session.Session
import im.vector.matrix.android.api.session.content.ContentUrlResolver import im.vector.matrix.android.api.session.content.ContentUrlResolver
import im.vector.matrix.android.api.session.crypto.CryptoService
import im.vector.matrix.android.api.session.crypto.MXCryptoError import im.vector.matrix.android.api.session.crypto.MXCryptoError
import im.vector.matrix.android.api.session.events.model.Event import im.vector.matrix.android.api.session.events.model.Event
import im.vector.matrix.android.api.session.events.model.EventType import im.vector.matrix.android.api.session.events.model.EventType
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.Membership import im.vector.matrix.android.api.session.room.model.Membership
import im.vector.matrix.android.api.session.room.model.RoomMember import im.vector.matrix.android.api.session.room.model.RoomMember
import im.vector.matrix.android.api.session.room.model.message.MessageContent
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.internal.crypto.algorithms.olm.OlmDecryptionResult import im.vector.matrix.android.internal.crypto.algorithms.olm.OlmDecryptionResult
import im.vector.riotx.BuildConfig import im.vector.riotx.BuildConfig
import im.vector.riotx.R import im.vector.riotx.R
@ -94,8 +93,8 @@ class NotifiableEventResolver @Inject constructor(private val stringProvider: St
Timber.e("## Unable to resolve room for eventId [${event}]") Timber.e("## Unable to resolve room for eventId [${event}]")
// Ok room is not known in store, but we can still display something // Ok room is not known in store, but we can still display something
val body = val body =
event.annotations?.editSummary?.aggregatedContent?.toModel<MessageContent>()?.body event.getLastMessageContent()
?: event.root.getClearContent().toModel<MessageContent>()?.body ?.body
?: stringProvider.getString(R.string.notification_unknown_new_event) ?: stringProvider.getString(R.string.notification_unknown_new_event)
val roomName = stringProvider.getString(R.string.notification_unknown_room_name) val roomName = stringProvider.getString(R.string.notification_unknown_room_name)
val senderDisplayName = event.senderName ?: event.root.senderId val senderDisplayName = event.senderName ?: event.root.senderId
@ -129,8 +128,8 @@ class NotifiableEventResolver @Inject constructor(private val stringProvider: St
} }
} }
val body = event.annotations?.editSummary?.aggregatedContent?.toModel<MessageContent>()?.body val body = event.getLastMessageContent()
?: event.root.getClearContent().toModel<MessageContent>()?.body ?.body
?: stringProvider.getString(R.string.notification_unknown_new_event) ?: stringProvider.getString(R.string.notification_unknown_new_event)
val roomName = room.roomSummary()?.displayName ?: "" val roomName = room.roomSummary()?.displayName ?: ""
val senderDisplayName = event.senderName ?: event.root.senderId val senderDisplayName = event.senderName ?: event.root.senderId