mirror of
https://github.com/Novaloop-AG/element-x-android.git
synced 2026-11-02 12:07:28 +00:00
Use the new SDK thread info for redacted messages
This commit is contained in:
+1
-1
@@ -91,7 +91,7 @@ internal fun MatrixTimelineItem.Event.canBeDisplayedInBubbleBlock(): Boolean {
|
|||||||
// Can be grouped
|
// Can be grouped
|
||||||
is FailedToParseMessageLikeContent,
|
is FailedToParseMessageLikeContent,
|
||||||
is MessageContent,
|
is MessageContent,
|
||||||
RedactedContent,
|
is RedactedContent,
|
||||||
is StickerContent,
|
is StickerContent,
|
||||||
is PollContent,
|
is PollContent,
|
||||||
is UnableToDecryptContent,
|
is UnableToDecryptContent,
|
||||||
|
|||||||
+2
-2
@@ -47,7 +47,6 @@ import io.element.android.libraries.matrix.api.timeline.Timeline
|
|||||||
import io.element.android.libraries.matrix.api.timeline.item.event.EventReaction
|
import io.element.android.libraries.matrix.api.timeline.item.event.EventReaction
|
||||||
import io.element.android.libraries.matrix.api.timeline.item.event.ReactionSender
|
import io.element.android.libraries.matrix.api.timeline.item.event.ReactionSender
|
||||||
import io.element.android.libraries.matrix.api.timeline.item.event.Receipt
|
import io.element.android.libraries.matrix.api.timeline.item.event.Receipt
|
||||||
import io.element.android.libraries.matrix.api.timeline.item.event.RedactedContent
|
|
||||||
import io.element.android.libraries.matrix.api.timeline.item.event.TimelineItemEventOrigin
|
import io.element.android.libraries.matrix.api.timeline.item.event.TimelineItemEventOrigin
|
||||||
import io.element.android.libraries.matrix.api.timeline.item.virtual.VirtualTimelineItem
|
import io.element.android.libraries.matrix.api.timeline.item.virtual.VirtualTimelineItem
|
||||||
import io.element.android.libraries.matrix.test.AN_EVENT_ID
|
import io.element.android.libraries.matrix.test.AN_EVENT_ID
|
||||||
@@ -65,6 +64,7 @@ import io.element.android.libraries.matrix.test.room.aRoomMember
|
|||||||
import io.element.android.libraries.matrix.test.room.powerlevels.FakeRoomPermissions
|
import io.element.android.libraries.matrix.test.room.powerlevels.FakeRoomPermissions
|
||||||
import io.element.android.libraries.matrix.test.timeline.FakeTimeline
|
import io.element.android.libraries.matrix.test.timeline.FakeTimeline
|
||||||
import io.element.android.libraries.matrix.test.timeline.aMessageContent
|
import io.element.android.libraries.matrix.test.timeline.aMessageContent
|
||||||
|
import io.element.android.libraries.matrix.test.timeline.aRedactedContent
|
||||||
import io.element.android.libraries.matrix.test.timeline.anEventTimelineItem
|
import io.element.android.libraries.matrix.test.timeline.anEventTimelineItem
|
||||||
import io.element.android.libraries.matrix.test.timeline.item.event.aRoomMembershipContent
|
import io.element.android.libraries.matrix.test.timeline.item.event.aRoomMembershipContent
|
||||||
import io.element.android.libraries.matrix.ui.components.aMatrixUserList
|
import io.element.android.libraries.matrix.ui.components.aMatrixUserList
|
||||||
@@ -876,7 +876,7 @@ class TimelinePresenterTest {
|
|||||||
(0 until 3).map { index ->
|
(0 until 3).map { index ->
|
||||||
MatrixTimelineItem.Event(
|
MatrixTimelineItem.Event(
|
||||||
uniqueId = UniqueId("redacted_$index"),
|
uniqueId = UniqueId("redacted_$index"),
|
||||||
event = anEventTimelineItem(eventId = EventId("\$R$index"), content = RedactedContent),
|
event = anEventTimelineItem(eventId = EventId("\$R$index"), content = aRedactedContent()),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
|
|||||||
+40
@@ -12,10 +12,14 @@ import com.google.common.truth.Truth.assertThat
|
|||||||
import io.element.android.features.messages.impl.fixtures.aTimelineItemsFactory
|
import io.element.android.features.messages.impl.fixtures.aTimelineItemsFactory
|
||||||
import io.element.android.features.messages.impl.timeline.model.TimelineItem
|
import io.element.android.features.messages.impl.timeline.model.TimelineItem
|
||||||
import io.element.android.features.messages.impl.timeline.model.TimelineItemGroupPosition
|
import io.element.android.features.messages.impl.timeline.model.TimelineItemGroupPosition
|
||||||
|
import io.element.android.features.messages.impl.timeline.model.TimelineItemThreadInfo
|
||||||
import io.element.android.libraries.matrix.api.core.UniqueId
|
import io.element.android.libraries.matrix.api.core.UniqueId
|
||||||
import io.element.android.libraries.matrix.api.timeline.MatrixTimelineItem
|
import io.element.android.libraries.matrix.api.timeline.MatrixTimelineItem
|
||||||
|
import io.element.android.libraries.matrix.api.timeline.item.EventThreadInfo
|
||||||
|
import io.element.android.libraries.matrix.test.A_THREAD_ID
|
||||||
import io.element.android.libraries.matrix.test.A_USER_ID
|
import io.element.android.libraries.matrix.test.A_USER_ID
|
||||||
import io.element.android.libraries.matrix.test.timeline.aMessageContent
|
import io.element.android.libraries.matrix.test.timeline.aMessageContent
|
||||||
|
import io.element.android.libraries.matrix.test.timeline.aRedactedContent
|
||||||
import io.element.android.libraries.matrix.test.timeline.anEventTimelineItem
|
import io.element.android.libraries.matrix.test.timeline.anEventTimelineItem
|
||||||
import kotlinx.coroutines.test.TestScope
|
import kotlinx.coroutines.test.TestScope
|
||||||
import kotlinx.coroutines.test.runTest
|
import kotlinx.coroutines.test.runTest
|
||||||
@@ -82,6 +86,42 @@ class TimelineItemsFactoryTest {
|
|||||||
).inOrder()
|
).inOrder()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `redacted message keeps its thread info`() = runTest {
|
||||||
|
val factory = aTimelineItemsFactory(
|
||||||
|
config = TimelineItemsFactoryConfig(
|
||||||
|
computeReadReceipts = false,
|
||||||
|
computeReactions = false,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
val items = listOf(
|
||||||
|
MatrixTimelineItem.Event(
|
||||||
|
uniqueId = UniqueId("event-0"),
|
||||||
|
event = anEventTimelineItem(
|
||||||
|
sender = A_USER_ID,
|
||||||
|
timestamp = 0L,
|
||||||
|
content = aRedactedContent(
|
||||||
|
threadInfo = EventThreadInfo.ThreadResponse(A_THREAD_ID),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
var threadInfo: TimelineItemThreadInfo? = null
|
||||||
|
factory.timelineItems.test {
|
||||||
|
factory.replaceWith(
|
||||||
|
timelineItems = items,
|
||||||
|
roomMembers = emptyList(),
|
||||||
|
renderReadReceipts = false,
|
||||||
|
)
|
||||||
|
threadInfo = awaitItem()
|
||||||
|
.filterIsInstance<TimelineItem.Event>()
|
||||||
|
.firstOrNull()
|
||||||
|
?.threadInfo
|
||||||
|
cancelAndIgnoreRemainingEvents()
|
||||||
|
}
|
||||||
|
assertThat(threadInfo).isEqualTo(TimelineItemThreadInfo.ThreadResponse(A_THREAD_ID))
|
||||||
|
}
|
||||||
|
|
||||||
private suspend fun TestScope.groupPositionsOf(timestamps: List<Long>): List<TimelineItemGroupPosition> {
|
private suspend fun TestScope.groupPositionsOf(timestamps: List<Long>): List<TimelineItemGroupPosition> {
|
||||||
val factory = aTimelineItemsFactory(
|
val factory = aTimelineItemsFactory(
|
||||||
config = TimelineItemsFactoryConfig(
|
config = TimelineItemsFactoryConfig(
|
||||||
|
|||||||
+2
-2
@@ -16,11 +16,11 @@ import io.element.android.libraries.matrix.api.timeline.MatrixTimelineItem
|
|||||||
import io.element.android.libraries.matrix.api.timeline.item.TimelineItemDebugInfo
|
import io.element.android.libraries.matrix.api.timeline.item.TimelineItemDebugInfo
|
||||||
import io.element.android.libraries.matrix.api.timeline.item.event.EventTimelineItem
|
import io.element.android.libraries.matrix.api.timeline.item.event.EventTimelineItem
|
||||||
import io.element.android.libraries.matrix.api.timeline.item.event.ProfileDetails
|
import io.element.android.libraries.matrix.api.timeline.item.event.ProfileDetails
|
||||||
import io.element.android.libraries.matrix.api.timeline.item.event.RedactedContent
|
|
||||||
import io.element.android.libraries.matrix.test.AN_EVENT_ID
|
import io.element.android.libraries.matrix.test.AN_EVENT_ID
|
||||||
import io.element.android.libraries.matrix.test.AN_EVENT_ID_2
|
import io.element.android.libraries.matrix.test.AN_EVENT_ID_2
|
||||||
import io.element.android.libraries.matrix.test.A_USER_ID
|
import io.element.android.libraries.matrix.test.A_USER_ID
|
||||||
import io.element.android.libraries.matrix.test.core.FakeSendHandle
|
import io.element.android.libraries.matrix.test.core.FakeSendHandle
|
||||||
|
import io.element.android.libraries.matrix.test.timeline.aRedactedContent
|
||||||
import io.element.android.libraries.mediaplayer.api.MediaPlayer
|
import io.element.android.libraries.mediaplayer.api.MediaPlayer
|
||||||
import io.element.android.libraries.mediaplayer.test.FakeMediaPlayer
|
import io.element.android.libraries.mediaplayer.test.FakeMediaPlayer
|
||||||
import io.element.android.tests.testutils.testCoroutineDispatchers
|
import io.element.android.tests.testutils.testCoroutineDispatchers
|
||||||
@@ -88,7 +88,7 @@ fun aRedactedMatrixTimeline(eventId: EventId) = listOf<MatrixTimelineItem>(
|
|||||||
sender = A_USER_ID,
|
sender = A_USER_ID,
|
||||||
senderProfile = ProfileDetails.Unavailable,
|
senderProfile = ProfileDetails.Unavailable,
|
||||||
timestamp = 9442,
|
timestamp = 9442,
|
||||||
content = RedactedContent,
|
content = aRedactedContent(),
|
||||||
origin = null,
|
origin = null,
|
||||||
timelineItemDebugInfoProvider = {
|
timelineItemDebugInfoProvider = {
|
||||||
TimelineItemDebugInfo(
|
TimelineItemDebugInfo(
|
||||||
|
|||||||
+1
-1
@@ -56,7 +56,7 @@ class DefaultPinnedMessagesBannerFormatter(
|
|||||||
is PollContent -> {
|
is PollContent -> {
|
||||||
content.question.prefixWith(CommonStrings.a11y_poll)
|
content.question.prefixWith(CommonStrings.a11y_poll)
|
||||||
}
|
}
|
||||||
RedactedContent -> {
|
is RedactedContent -> {
|
||||||
sp.getString(CommonStrings.common_message_removed)
|
sp.getString(CommonStrings.common_message_removed)
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
|
|||||||
+1
-1
@@ -89,7 +89,7 @@ class DefaultRoomLatestEventFormatter(
|
|||||||
): CharSequence? {
|
): CharSequence? {
|
||||||
return when (content) {
|
return when (content) {
|
||||||
is MessageContent -> content.process(senderDisambiguatedDisplayName, isDmRoom, isOutgoing)
|
is MessageContent -> content.process(senderDisambiguatedDisplayName, isDmRoom, isOutgoing)
|
||||||
RedactedContent -> {
|
is RedactedContent -> {
|
||||||
val message = sp.getString(CommonStrings.common_message_removed)
|
val message = sp.getString(CommonStrings.common_message_removed)
|
||||||
message.prefixIfNeeded(senderDisambiguatedDisplayName, isDmRoom, isOutgoing)
|
message.prefixIfNeeded(senderDisambiguatedDisplayName, isDmRoom, isOutgoing)
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -62,7 +62,7 @@ class DefaultTimelineEventFormatter(
|
|||||||
is CallNotifyContent -> {
|
is CallNotifyContent -> {
|
||||||
sp.getString(CommonStrings.common_call_started)
|
sp.getString(CommonStrings.common_call_started)
|
||||||
}
|
}
|
||||||
RedactedContent,
|
is RedactedContent,
|
||||||
is LegacyCallInviteContent,
|
is LegacyCallInviteContent,
|
||||||
is StickerContent,
|
is StickerContent,
|
||||||
is PollContent,
|
is PollContent,
|
||||||
|
|||||||
+1
-1
@@ -81,7 +81,7 @@ class DefaultPinnedMessagesBannerFormatterTest : RobolectricTest() {
|
|||||||
fun `Redacted content`() {
|
fun `Redacted content`() {
|
||||||
val expected = "Message removed"
|
val expected = "Message removed"
|
||||||
val senderName = "Someone"
|
val senderName = "Someone"
|
||||||
val message = createRoomEvent(false, senderName, RedactedContent)
|
val message = createRoomEvent(false, senderName, RedactedContent(threadInfo = null))
|
||||||
val result = formatter.format(message)
|
val result = formatter.format(message)
|
||||||
assertThat(result).isEqualTo(expected)
|
assertThat(result).isEqualTo(expected)
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -85,7 +85,7 @@ class DefaultRoomLatestEventFormatterTest : RobolectricTest() {
|
|||||||
val expected = "Message removed"
|
val expected = "Message removed"
|
||||||
val senderName = "Someone"
|
val senderName = "Someone"
|
||||||
sequenceOf(false, true).forEach { isDm ->
|
sequenceOf(false, true).forEach { isDm ->
|
||||||
val message = createLatestEvent(false, senderName, RedactedContent)
|
val message = createLatestEvent(false, senderName, RedactedContent(threadInfo = null))
|
||||||
val result = formatter.format(message, isDm)
|
val result = formatter.format(message, isDm)
|
||||||
if (isDm) {
|
if (isDm) {
|
||||||
assertThat(result).isEqualTo(expected)
|
assertThat(result).isEqualTo(expected)
|
||||||
|
|||||||
+3
-1
@@ -32,7 +32,9 @@ data class MessageContent(
|
|||||||
val type: MessageType,
|
val type: MessageType,
|
||||||
) : EventContent
|
) : EventContent
|
||||||
|
|
||||||
data object RedactedContent : EventContent
|
data class RedactedContent(
|
||||||
|
val threadInfo: EventThreadInfo?,
|
||||||
|
) : EventContent
|
||||||
|
|
||||||
data class StickerContent(
|
data class StickerContent(
|
||||||
val filename: String,
|
val filename: String,
|
||||||
|
|||||||
+1
@@ -51,6 +51,7 @@ data class EventTimelineItem(
|
|||||||
is PollContent -> content.threadInfo
|
is PollContent -> content.threadInfo
|
||||||
is StickerContent -> content.threadInfo
|
is StickerContent -> content.threadInfo
|
||||||
is UnableToDecryptContent -> content.threadInfo
|
is UnableToDecryptContent -> content.threadInfo
|
||||||
|
is RedactedContent -> content.threadInfo
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -81,7 +81,7 @@ class TimelineEventContentMapper(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
is MsgLikeKind.Redacted -> {
|
is MsgLikeKind.Redacted -> {
|
||||||
RedactedContent
|
RedactedContent(threadInfo = extractThreadInfo(it.content))
|
||||||
}
|
}
|
||||||
is MsgLikeKind.Poll -> {
|
is MsgLikeKind.Poll -> {
|
||||||
PollContent(
|
PollContent(
|
||||||
|
|||||||
+5
@@ -29,6 +29,7 @@ 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.ProfileChangeContent
|
||||||
import io.element.android.libraries.matrix.api.timeline.item.event.ProfileDetails
|
import io.element.android.libraries.matrix.api.timeline.item.event.ProfileDetails
|
||||||
import io.element.android.libraries.matrix.api.timeline.item.event.Receipt
|
import io.element.android.libraries.matrix.api.timeline.item.event.Receipt
|
||||||
|
import io.element.android.libraries.matrix.api.timeline.item.event.RedactedContent
|
||||||
import io.element.android.libraries.matrix.api.timeline.item.event.SendHandleProvider
|
import io.element.android.libraries.matrix.api.timeline.item.event.SendHandleProvider
|
||||||
import io.element.android.libraries.matrix.api.timeline.item.event.StickerContent
|
import io.element.android.libraries.matrix.api.timeline.item.event.StickerContent
|
||||||
import io.element.android.libraries.matrix.api.timeline.item.event.TextMessageType
|
import io.element.android.libraries.matrix.api.timeline.item.event.TextMessageType
|
||||||
@@ -137,6 +138,10 @@ fun aStickerContent(
|
|||||||
threadInfo = threadInfo,
|
threadInfo = threadInfo,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
fun aRedactedContent(
|
||||||
|
threadInfo: EventThreadInfo? = null,
|
||||||
|
) = RedactedContent(threadInfo = threadInfo)
|
||||||
|
|
||||||
fun aTimelineItemDebugInfo(
|
fun aTimelineItemDebugInfo(
|
||||||
model: String = "Rust(Model())",
|
model: String = "Rust(Model())",
|
||||||
originalJson: String? = null,
|
originalJson: String? = null,
|
||||||
|
|||||||
+1
-1
@@ -117,7 +117,7 @@ class InReplyToDetailsDisambiguatedProvider : InReplyToDetailsProvider() {
|
|||||||
class InReplyToDetailsInformativeProvider : InReplyToDetailsProvider() {
|
class InReplyToDetailsInformativeProvider : InReplyToDetailsProvider() {
|
||||||
override val values: Sequence<InReplyToDetails>
|
override val values: Sequence<InReplyToDetails>
|
||||||
get() = sequenceOf(
|
get() = sequenceOf(
|
||||||
RedactedContent,
|
RedactedContent(threadInfo = null),
|
||||||
UnableToDecryptContent(data = UnableToDecryptContent.Data.Unknown, threadInfo = null),
|
UnableToDecryptContent(data = UnableToDecryptContent.Data.Unknown, threadInfo = null),
|
||||||
).map {
|
).map {
|
||||||
aInReplyToDetails(
|
aInReplyToDetails(
|
||||||
|
|||||||
+1
-1
@@ -656,7 +656,7 @@ class InReplyToMetadataKtTest : RobolectricTest() {
|
|||||||
fun `redacted content`() = runTest {
|
fun `redacted content`() = runTest {
|
||||||
moleculeFlow(RecompositionMode.Immediate) {
|
moleculeFlow(RecompositionMode.Immediate) {
|
||||||
anInReplyToDetailsReady(
|
anInReplyToDetailsReady(
|
||||||
eventContent = RedactedContent
|
eventContent = RedactedContent(threadInfo = null)
|
||||||
).metadata(hideImage = false)
|
).metadata(hideImage = false)
|
||||||
}.test {
|
}.test {
|
||||||
awaitItem().let {
|
awaitItem().let {
|
||||||
|
|||||||
+1
-1
@@ -79,7 +79,7 @@ class EventItemFactory(
|
|||||||
LegacyCallInviteContent,
|
LegacyCallInviteContent,
|
||||||
is PollContent,
|
is PollContent,
|
||||||
is ProfileChangeContent,
|
is ProfileChangeContent,
|
||||||
RedactedContent,
|
is RedactedContent,
|
||||||
is RoomMembershipContent,
|
is RoomMembershipContent,
|
||||||
is StateContent,
|
is StateContent,
|
||||||
is StickerContent,
|
is StickerContent,
|
||||||
|
|||||||
+2
-2
@@ -35,7 +35,6 @@ import io.element.android.libraries.matrix.api.timeline.item.event.LocationMessa
|
|||||||
import io.element.android.libraries.matrix.api.timeline.item.event.NoticeMessageType
|
import io.element.android.libraries.matrix.api.timeline.item.event.NoticeMessageType
|
||||||
import io.element.android.libraries.matrix.api.timeline.item.event.OtherMessageType
|
import io.element.android.libraries.matrix.api.timeline.item.event.OtherMessageType
|
||||||
import io.element.android.libraries.matrix.api.timeline.item.event.OtherState
|
import io.element.android.libraries.matrix.api.timeline.item.event.OtherState
|
||||||
import io.element.android.libraries.matrix.api.timeline.item.event.RedactedContent
|
|
||||||
import io.element.android.libraries.matrix.api.timeline.item.event.StateContent
|
import io.element.android.libraries.matrix.api.timeline.item.event.StateContent
|
||||||
import io.element.android.libraries.matrix.api.timeline.item.event.StickerMessageType
|
import io.element.android.libraries.matrix.api.timeline.item.event.StickerMessageType
|
||||||
import io.element.android.libraries.matrix.api.timeline.item.event.TextMessageType
|
import io.element.android.libraries.matrix.api.timeline.item.event.TextMessageType
|
||||||
@@ -49,6 +48,7 @@ import io.element.android.libraries.matrix.test.A_USER_ID
|
|||||||
import io.element.android.libraries.matrix.test.timeline.aMessageContent
|
import io.element.android.libraries.matrix.test.timeline.aMessageContent
|
||||||
import io.element.android.libraries.matrix.test.timeline.aPollContent
|
import io.element.android.libraries.matrix.test.timeline.aPollContent
|
||||||
import io.element.android.libraries.matrix.test.timeline.aProfileChangeMessageContent
|
import io.element.android.libraries.matrix.test.timeline.aProfileChangeMessageContent
|
||||||
|
import io.element.android.libraries.matrix.test.timeline.aRedactedContent
|
||||||
import io.element.android.libraries.matrix.test.timeline.aStickerContent
|
import io.element.android.libraries.matrix.test.timeline.aStickerContent
|
||||||
import io.element.android.libraries.matrix.test.timeline.anEventTimelineItem
|
import io.element.android.libraries.matrix.test.timeline.anEventTimelineItem
|
||||||
import io.element.android.libraries.matrix.test.timeline.item.event.aRoomMembershipContent
|
import io.element.android.libraries.matrix.test.timeline.item.event.aRoomMembershipContent
|
||||||
@@ -80,7 +80,7 @@ class EventItemFactoryTest {
|
|||||||
LegacyCallInviteContent,
|
LegacyCallInviteContent,
|
||||||
aPollContent(),
|
aPollContent(),
|
||||||
aProfileChangeMessageContent(),
|
aProfileChangeMessageContent(),
|
||||||
RedactedContent,
|
aRedactedContent(),
|
||||||
aRoomMembershipContent(
|
aRoomMembershipContent(
|
||||||
userId = A_USER_ID,
|
userId = A_USER_ID,
|
||||||
),
|
),
|
||||||
|
|||||||
Reference in New Issue
Block a user