Merge pull request #371 from vector-im/feature/composer_fix_edit_reply

Feature/composer fix edit reply
This commit is contained in:
Benoit Marty
2019-07-17 14:03:10 +02:00
committed by GitHub
12 changed files with 214 additions and 68 deletions

View File

@ -59,6 +59,7 @@ 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.timeline.TimelineEvent
import im.vector.matrix.android.api.session.room.timeline.getLastMessageContent
import im.vector.matrix.android.api.session.room.timeline.getTextEditableContent
import im.vector.matrix.android.api.session.user.model.User
import im.vector.riotx.R
import im.vector.riotx.core.di.ScreenComponent
@ -258,7 +259,7 @@ class RoomDetailFragment :
composerLayout.composerRelatedMessageContent.text = formattedBody
?: nonFormattedBody
composerLayout.composerEditText.setText(if (useText) nonFormattedBody else "")
composerLayout.composerEditText.setText(if (useText) event.getTextEditableContent() else "")
composerLayout.composerRelatedMessageActionIcon.setImageDrawable(ContextCompat.getDrawable(requireContext(), iconRes))
avatarRenderer.render(event.senderAvatar, event.root.senderId

View File

@ -39,7 +39,6 @@ import im.vector.matrix.android.api.session.room.model.message.getFileUrl
import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
import im.vector.matrix.android.internal.crypto.attachments.toElementToDecrypt
import im.vector.matrix.rx.rx
import im.vector.riotx.R
import im.vector.riotx.core.intent.getFilenameFromUri
import im.vector.riotx.core.platform.VectorViewModel
import im.vector.riotx.core.resources.UserPreferencesProvider
@ -52,8 +51,6 @@ import org.commonmark.parser.Parser
import org.commonmark.renderer.html.HtmlRenderer
import timber.log.Timber
import java.io.File
import java.text.SimpleDateFormat
import java.util.*
import java.util.concurrent.TimeUnit
@ -229,16 +226,24 @@ class RoomDetailViewModel @AssistedInject constructor(@Assisted initialState: Ro
}
}
is SendMode.EDIT -> {
val messageContent: MessageContent? =
state.sendMode.timelineEvent.annotations?.editSummary?.aggregatedContent.toModel()
?: state.sendMode.timelineEvent.root.getClearContent().toModel()
val nonFormattedBody = messageContent?.body ?: ""
if (nonFormattedBody != action.text) {
room.editTextMessage(state.sendMode.timelineEvent.root.eventId
?: "", messageContent?.type ?: MessageType.MSGTYPE_TEXT, action.text, action.autoMarkdown)
//is original event a reply?
val inReplyTo = state.sendMode.timelineEvent.root.getClearContent().toModel<MessageContent>()?.relatesTo?.inReplyTo?.eventId
if (inReplyTo != null) {
//TODO check if same content?
room.editReply(state.sendMode.timelineEvent, room.getTimeLineEvent(inReplyTo)?.root?.senderId, inReplyTo, action.text)
} else {
Timber.w("Same message content, do not send edition")
val messageContent: MessageContent? =
state.sendMode.timelineEvent.annotations?.editSummary?.aggregatedContent.toModel()
?: state.sendMode.timelineEvent.root.getClearContent().toModel()
val existingBody = messageContent?.body ?: ""
if (existingBody != action.text) {
room.editTextMessage(state.sendMode.timelineEvent.root.eventId
?: "", messageContent?.type
?: MessageType.MSGTYPE_TEXT, action.text, action.autoMarkdown)
} else {
Timber.w("Same message content, do not send edition")
}
}
setState {
copy(

View File

@ -26,6 +26,7 @@ import com.airbnb.mvrx.Success
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.room.model.message.MessageTextContent
import im.vector.matrix.android.api.util.ContentUtils.extractUsefulTextFromReply
import im.vector.riotx.R
import im.vector.riotx.core.extensions.localDateTime
import im.vector.riotx.core.ui.list.genericFooterItem
@ -60,13 +61,13 @@ class ViewEditHistoryEpoxyController(private val context: Context,
}
}
is Success -> {
state.editList()?.let { renderEvents(it) }
state.editList()?.let { renderEvents(it, state.isOriginalAReply) }
}
}
}
private fun renderEvents(sourceEvents: List<Event>) {
private fun renderEvents(sourceEvents: List<Event>, isOriginalReply: Boolean) {
if (sourceEvents.isEmpty()) {
genericItem {
id("footer")
@ -92,7 +93,7 @@ class ViewEditHistoryEpoxyController(private val context: Context,
}
}
lastDate = evDate
val cContent = getCorrectContent(timelineEvent)
val cContent = getCorrectContent(timelineEvent, isOriginalReply)
val body = cContent.second?.let { eventHtmlRenderer.render(it) }
?: cContent.first
@ -101,7 +102,7 @@ class ViewEditHistoryEpoxyController(private val context: Context,
var spannedDiff: Spannable? = null
if (nextEvent != null && cContent.second == null /*No diff for html*/) {
//compares the body
val nContent = getCorrectContent(nextEvent)
val nContent = getCorrectContent(nextEvent, isOriginalReply)
val nextBody = nContent.second?.let { eventHtmlRenderer.render(it) }
?: nContent.first
val dmp = diff_match_patch()
@ -144,11 +145,14 @@ class ViewEditHistoryEpoxyController(private val context: Context,
}
}
private fun getCorrectContent(event: Event): Pair<String, String?> {
private fun getCorrectContent(event: Event, isOriginalReply: Boolean): Pair<String, String?> {
val clearContent = event.getClearContent().toModel<MessageTextContent>()
val newContent = clearContent
?.newContent
?.toModel<MessageTextContent>()
if (isOriginalReply) {
return extractUsefulTextFromReply(newContent?.body ?: clearContent?.body ?: "") to null
}
return (newContent?.body ?: clearContent?.body ?: "") to (newContent?.formattedBody
?: clearContent?.formattedBody)
}

View File

@ -21,6 +21,9 @@ import com.squareup.inject.assisted.AssistedInject
import im.vector.matrix.android.api.MatrixCallback
import im.vector.matrix.android.api.session.Session
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.room.model.message.MessageContent
import im.vector.matrix.android.api.session.room.model.message.isReply
import im.vector.riotx.core.platform.VectorViewModel
import im.vector.riotx.features.home.room.detail.timeline.helper.TimelineDateFormatter
@ -28,6 +31,7 @@ import im.vector.riotx.features.home.room.detail.timeline.helper.TimelineDateFor
data class ViewEditHistoryViewState(
val eventId: String,
val roomId: String,
val isOriginalAReply: Boolean = false,
val editList: Async<List<Event>> = Uninitialized)
: MvRxState {
@ -77,11 +81,16 @@ class ViewEditHistoryViewModel @AssistedInject constructor(@Assisted
override fun onSuccess(data: List<Event>) {
//TODO until supported by API Add original event manually
val withOriginal = data.toMutableList()
var originalIsReply = false
room.getTimeLineEvent(eventId)?.let {
withOriginal.add(it.root)
originalIsReply = it.root.getClearContent().toModel<MessageContent>().isReply()
}
setState {
copy(editList = Success(withOriginal))
copy(
editList = Success(withOriginal),
isOriginalAReply = originalIsReply
)
}
}
})