mirror of
https://github.com/vector-im/element-android.git
synced 2024-11-15 01:35:07 +08:00
fix / strip reply prefix on history
This commit is contained in:
parent
6effb90361
commit
d8092abc4e
@ -2,11 +2,12 @@ Changes in RiotX 0.2.1 (2019-XX-XX)
|
|||||||
===================================================
|
===================================================
|
||||||
|
|
||||||
Features:
|
Features:
|
||||||
- Message Editing: View edit history
|
- Message Editing: View edit history (#121)
|
||||||
- Rooms filtering (#304)
|
- Rooms filtering (#304)
|
||||||
|
|
||||||
Improvements:
|
Improvements:
|
||||||
- Handle click on redacted events: view source and create permalink
|
- Handle click on redacted events: view source and create permalink
|
||||||
|
- Improve edit of replies
|
||||||
|
|
||||||
Other changes:
|
Other changes:
|
||||||
-
|
-
|
||||||
|
@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 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.util
|
||||||
|
|
||||||
|
|
||||||
|
object ContentUtils {
|
||||||
|
fun extractUsefulTextFromReply(repliedBody: String): String {
|
||||||
|
val lines = repliedBody.lines()
|
||||||
|
var wellFormed = repliedBody.startsWith(">")
|
||||||
|
var endOfPreviousFound = false
|
||||||
|
val usefullines = ArrayList<String>()
|
||||||
|
lines.forEach {
|
||||||
|
if (it == "") {
|
||||||
|
endOfPreviousFound = true
|
||||||
|
return@forEach
|
||||||
|
}
|
||||||
|
if (!endOfPreviousFound) {
|
||||||
|
wellFormed = wellFormed && it.startsWith(">")
|
||||||
|
} else {
|
||||||
|
usefullines.add(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return usefullines.joinToString("\n").takeIf { wellFormed } ?: repliedBody
|
||||||
|
}
|
||||||
|
|
||||||
|
fun extractUsefulTextFromHtmlReply(repliedBody: String): String {
|
||||||
|
if (repliedBody.startsWith("<mx-reply>")) {
|
||||||
|
return repliedBody.substring(repliedBody.lastIndexOf("</mx-reply>") + "</mx-reply>".length).trim()
|
||||||
|
}
|
||||||
|
return repliedBody
|
||||||
|
}
|
||||||
|
}
|
@ -18,6 +18,8 @@ package im.vector.matrix.android.internal.session.room.send
|
|||||||
|
|
||||||
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.util.ContentUtils.extractUsefulTextFromHtmlReply
|
||||||
|
import im.vector.matrix.android.api.util.ContentUtils.extractUsefulTextFromReply
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Contains a text and eventually a formatted text
|
* Contains a text and eventually a formatted text
|
||||||
@ -47,28 +49,4 @@ fun TextContent.removeInReplyFallbacks(): TextContent {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun extractUsefulTextFromReply(repliedBody: String): String {
|
|
||||||
val lines = repliedBody.lines()
|
|
||||||
var wellFormed = repliedBody.startsWith(">")
|
|
||||||
var endOfPreviousFound = false
|
|
||||||
val usefullines = ArrayList<String>()
|
|
||||||
lines.forEach {
|
|
||||||
if (it == "") {
|
|
||||||
endOfPreviousFound = true
|
|
||||||
return@forEach
|
|
||||||
}
|
|
||||||
if (!endOfPreviousFound) {
|
|
||||||
wellFormed = wellFormed && it.startsWith(">")
|
|
||||||
} else {
|
|
||||||
usefullines.add(it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return usefullines.joinToString("\n").takeIf { wellFormed } ?: repliedBody
|
|
||||||
}
|
|
||||||
|
|
||||||
fun extractUsefulTextFromHtmlReply(repliedBody: String): String {
|
|
||||||
if (repliedBody.startsWith("<mx-reply>")) {
|
|
||||||
return repliedBody.substring(repliedBody.lastIndexOf("</mx-reply>") + "</mx-reply>".length).trim()
|
|
||||||
}
|
|
||||||
return repliedBody
|
|
||||||
}
|
|
||||||
|
@ -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.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.riotx.R
|
import im.vector.riotx.R
|
||||||
import im.vector.riotx.core.extensions.localDateTime
|
import im.vector.riotx.core.extensions.localDateTime
|
||||||
import im.vector.riotx.core.ui.list.genericFooterItem
|
import im.vector.riotx.core.ui.list.genericFooterItem
|
||||||
@ -60,13 +61,13 @@ class ViewEditHistoryEpoxyController(private val context: Context,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
is Success -> {
|
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()) {
|
if (sourceEvents.isEmpty()) {
|
||||||
genericItem {
|
genericItem {
|
||||||
id("footer")
|
id("footer")
|
||||||
@ -92,7 +93,7 @@ class ViewEditHistoryEpoxyController(private val context: Context,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
lastDate = evDate
|
lastDate = evDate
|
||||||
val cContent = getCorrectContent(timelineEvent)
|
val cContent = getCorrectContent(timelineEvent, isOriginalReply)
|
||||||
val body = cContent.second?.let { eventHtmlRenderer.render(it) }
|
val body = cContent.second?.let { eventHtmlRenderer.render(it) }
|
||||||
?: cContent.first
|
?: cContent.first
|
||||||
|
|
||||||
@ -101,7 +102,7 @@ class ViewEditHistoryEpoxyController(private val context: Context,
|
|||||||
var spannedDiff: Spannable? = null
|
var spannedDiff: Spannable? = null
|
||||||
if (nextEvent != null && cContent.second == null /*No diff for html*/) {
|
if (nextEvent != null && cContent.second == null /*No diff for html*/) {
|
||||||
//compares the body
|
//compares the body
|
||||||
val nContent = getCorrectContent(nextEvent)
|
val nContent = getCorrectContent(nextEvent, isOriginalReply)
|
||||||
val nextBody = nContent.second?.let { eventHtmlRenderer.render(it) }
|
val nextBody = nContent.second?.let { eventHtmlRenderer.render(it) }
|
||||||
?: nContent.first
|
?: nContent.first
|
||||||
val dmp = diff_match_patch()
|
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 clearContent = event.getClearContent().toModel<MessageTextContent>()
|
||||||
val newContent = clearContent
|
val newContent = clearContent
|
||||||
?.newContent
|
?.newContent
|
||||||
?.toModel<MessageTextContent>()
|
?.toModel<MessageTextContent>()
|
||||||
|
if (isOriginalReply) {
|
||||||
|
return extractUsefulTextFromReply(newContent?.body ?: clearContent?.body ?: "") to null
|
||||||
|
}
|
||||||
return (newContent?.body ?: clearContent?.body ?: "") to (newContent?.formattedBody
|
return (newContent?.body ?: clearContent?.body ?: "") to (newContent?.formattedBody
|
||||||
?: clearContent?.formattedBody)
|
?: clearContent?.formattedBody)
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,8 @@ import com.squareup.inject.assisted.AssistedInject
|
|||||||
import im.vector.matrix.android.api.MatrixCallback
|
import im.vector.matrix.android.api.MatrixCallback
|
||||||
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.Event
|
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.riotx.core.platform.VectorViewModel
|
import im.vector.riotx.core.platform.VectorViewModel
|
||||||
import im.vector.riotx.features.home.room.detail.timeline.helper.TimelineDateFormatter
|
import im.vector.riotx.features.home.room.detail.timeline.helper.TimelineDateFormatter
|
||||||
|
|
||||||
@ -28,6 +30,7 @@ import im.vector.riotx.features.home.room.detail.timeline.helper.TimelineDateFor
|
|||||||
data class ViewEditHistoryViewState(
|
data class ViewEditHistoryViewState(
|
||||||
val eventId: String,
|
val eventId: String,
|
||||||
val roomId: String,
|
val roomId: String,
|
||||||
|
val isOriginalAReply: Boolean = false,
|
||||||
val editList: Async<List<Event>> = Uninitialized)
|
val editList: Async<List<Event>> = Uninitialized)
|
||||||
: MvRxState {
|
: MvRxState {
|
||||||
|
|
||||||
@ -77,11 +80,16 @@ class ViewEditHistoryViewModel @AssistedInject constructor(@Assisted
|
|||||||
override fun onSuccess(data: List<Event>) {
|
override fun onSuccess(data: List<Event>) {
|
||||||
//TODO until supported by API Add original event manually
|
//TODO until supported by API Add original event manually
|
||||||
val withOriginal = data.toMutableList()
|
val withOriginal = data.toMutableList()
|
||||||
|
var originalIsReply = false
|
||||||
room.getTimeLineEvent(eventId)?.let {
|
room.getTimeLineEvent(eventId)?.let {
|
||||||
withOriginal.add(it.root)
|
withOriginal.add(it.root)
|
||||||
|
originalIsReply = it.root.getClearContent().toModel<MessageContent>()?.relatesTo?.inReplyTo?.eventId != null
|
||||||
}
|
}
|
||||||
setState {
|
setState {
|
||||||
copy(editList = Success(withOriginal))
|
copy(
|
||||||
|
editList = Success(withOriginal),
|
||||||
|
isOriginalAReply = originalIsReply
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
Loading…
Reference in New Issue
Block a user