Fix filtering of Event at the beginning of DM.
This commit is contained in:
parent
9d6c9456a5
commit
f87422a022
7 changed files with 150 additions and 43 deletions
|
|
@ -44,5 +44,6 @@ data class MatrixRoomInfo(
|
|||
val hasRoomCall: Boolean,
|
||||
val activeRoomCallParticipants: ImmutableList<String>,
|
||||
val heroes: ImmutableList<MatrixUser>,
|
||||
val pinnedEventIds: ImmutableList<EventId>
|
||||
val pinnedEventIds: ImmutableList<EventId>,
|
||||
val creator: UserId?,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ class MatrixRoomInfoMapper {
|
|||
fun map(rustRoomInfo: RustRoomInfo): MatrixRoomInfo = rustRoomInfo.let {
|
||||
return MatrixRoomInfo(
|
||||
id = RoomId(it.id),
|
||||
creator = it.creator?.let(::UserId),
|
||||
name = it.displayName,
|
||||
rawName = it.rawName,
|
||||
topic = it.topic,
|
||||
|
|
|
|||
|
|
@ -207,15 +207,17 @@ class RustTimeline(
|
|||
_timelineItems,
|
||||
backPaginationStatus.map { it.hasMoreToLoad }.distinctUntilChanged(),
|
||||
forwardPaginationStatus.map { it.hasMoreToLoad }.distinctUntilChanged(),
|
||||
matrixRoom.roomInfoFlow.map { it.creator },
|
||||
isInit,
|
||||
) { timelineItems, hasMoreToLoadBackward, hasMoreToLoadForward, isInit ->
|
||||
) { timelineItems, hasMoreToLoadBackward, hasMoreToLoadForward, roomCreator, isInit ->
|
||||
withContext(dispatcher) {
|
||||
timelineItems
|
||||
.process { items ->
|
||||
roomBeginningPostProcessor.process(
|
||||
items = items,
|
||||
isDm = matrixRoom.isDm,
|
||||
hasMoreToLoadBackwards = hasMoreToLoadBackward
|
||||
roomCreator = roomCreator,
|
||||
hasMoreToLoadBackwards = hasMoreToLoadBackward,
|
||||
)
|
||||
}
|
||||
.process(predicate = isInit) { items ->
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ package io.element.android.libraries.matrix.impl.timeline.postprocessor
|
|||
|
||||
import androidx.annotation.VisibleForTesting
|
||||
import io.element.android.libraries.matrix.api.core.UniqueId
|
||||
import io.element.android.libraries.matrix.api.core.UserId
|
||||
import io.element.android.libraries.matrix.api.timeline.MatrixTimelineItem
|
||||
import io.element.android.libraries.matrix.api.timeline.Timeline
|
||||
import io.element.android.libraries.matrix.api.timeline.item.event.MembershipChange
|
||||
|
|
@ -25,12 +26,14 @@ class RoomBeginningPostProcessor(private val mode: Timeline.Mode) {
|
|||
fun process(
|
||||
items: List<MatrixTimelineItem>,
|
||||
isDm: Boolean,
|
||||
hasMoreToLoadBackwards: Boolean
|
||||
roomCreator: UserId?,
|
||||
hasMoreToLoadBackwards: Boolean,
|
||||
): List<MatrixTimelineItem> {
|
||||
return when {
|
||||
items.isEmpty() -> items
|
||||
mode == Timeline.Mode.PINNED_EVENTS -> items
|
||||
isDm -> processForDM(items, roomCreator)
|
||||
hasMoreToLoadBackwards -> items
|
||||
isDm -> processForDM(items)
|
||||
else -> processForRoom(items)
|
||||
}
|
||||
}
|
||||
|
|
@ -40,15 +43,18 @@ class RoomBeginningPostProcessor(private val mode: Timeline.Mode) {
|
|||
return listOf(roomBeginningItem) + items
|
||||
}
|
||||
|
||||
private fun processForDM(items: List<MatrixTimelineItem>): List<MatrixTimelineItem> {
|
||||
// Find room creation event. This is usually index 0
|
||||
private fun processForDM(items: List<MatrixTimelineItem>, roomCreator: UserId?): List<MatrixTimelineItem> {
|
||||
// Find room creation event.
|
||||
// This is usually the first MatrixTimelineItem.Event (so index 1, index 0 is a date)
|
||||
val roomCreationEventIndex = items.indexOfFirst {
|
||||
val stateEventContent = (it as? MatrixTimelineItem.Event)?.event?.content as? StateContent
|
||||
stateEventContent?.content is OtherState.RoomCreate
|
||||
}
|
||||
|
||||
// Find self-join event for room creator. This is usually index 1
|
||||
val roomCreatorUserId = (items.getOrNull(roomCreationEventIndex) as? MatrixTimelineItem.Event)?.event?.sender
|
||||
// If the parameter roomCreator is null, the creator is the sender of the RoomCreate Event.
|
||||
val roomCreatorUserId = roomCreator ?: (items.getOrNull(roomCreationEventIndex) as? MatrixTimelineItem.Event)?.event?.sender
|
||||
// Find self-join event for the room creator.
|
||||
// This is usually the second MatrixTimelineItem.Event (so index 2)
|
||||
val selfUserJoinedEventIndex = roomCreatorUserId?.let { creatorUserId ->
|
||||
items.indexOfFirst {
|
||||
val stateEventContent = (it as? MatrixTimelineItem.Event)?.event?.content as? RoomMembershipContent
|
||||
|
|
@ -56,6 +62,9 @@ class RoomBeginningPostProcessor(private val mode: Timeline.Mode) {
|
|||
}
|
||||
} ?: -1
|
||||
|
||||
if (roomCreationEventIndex == -1 && selfUserJoinedEventIndex == -1) {
|
||||
return items
|
||||
}
|
||||
// Remove items at the indices we found
|
||||
val newItems = items.toMutableList()
|
||||
if (selfUserJoinedEventIndex in newItems.indices) {
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ package io.element.android.libraries.matrix.impl.roomlist
|
|||
import com.google.common.truth.Truth.assertThat
|
||||
import com.sun.jna.Pointer
|
||||
import io.element.android.libraries.matrix.api.core.RoomId
|
||||
import io.element.android.libraries.matrix.api.core.UserId
|
||||
import io.element.android.libraries.matrix.api.roomlist.RoomSummary
|
||||
import io.element.android.libraries.matrix.test.A_ROOM_ID
|
||||
import io.element.android.libraries.matrix.test.A_ROOM_ID_2
|
||||
|
|
@ -215,6 +216,7 @@ private fun aRustRoomInfo(
|
|||
numUnreadNotifications: ULong = 0uL,
|
||||
numUnreadMentions: ULong = 0uL,
|
||||
pinnedEventIds: List<String> = listOf(),
|
||||
roomCreator: UserId? = null,
|
||||
) = RoomInfo(
|
||||
id = id,
|
||||
displayName = displayName,
|
||||
|
|
@ -245,6 +247,7 @@ private fun aRustRoomInfo(
|
|||
numUnreadNotifications = numUnreadNotifications,
|
||||
numUnreadMentions = numUnreadMentions,
|
||||
pinnedEventIds = pinnedEventIds,
|
||||
creator = roomCreator?.value,
|
||||
)
|
||||
|
||||
class FakeRoomListItem(
|
||||
|
|
|
|||
|
|
@ -22,85 +22,174 @@ import io.element.android.libraries.matrix.test.timeline.anEventTimelineItem
|
|||
import org.junit.Test
|
||||
|
||||
class RoomBeginningPostProcessorTest {
|
||||
private val roomCreateEvent = MatrixTimelineItem.Event(
|
||||
uniqueId = UniqueId("m.room.create"),
|
||||
event = anEventTimelineItem(sender = A_USER_ID, content = StateContent("", OtherState.RoomCreate))
|
||||
)
|
||||
private val roomCreatorJoinEvent = MatrixTimelineItem.Event(
|
||||
uniqueId = UniqueId("m.room.member"),
|
||||
event = anEventTimelineItem(content = RoomMembershipContent(A_USER_ID, null, MembershipChange.JOINED))
|
||||
)
|
||||
private val otherMemberJoinEvent = MatrixTimelineItem.Event(
|
||||
uniqueId = UniqueId("m.room.member_other"),
|
||||
event = anEventTimelineItem(content = RoomMembershipContent(A_USER_ID_2, null, MembershipChange.JOINED))
|
||||
)
|
||||
private val messageEvent = MatrixTimelineItem.Event(
|
||||
uniqueId = UniqueId("m.room.message"),
|
||||
event = anEventTimelineItem(content = aMessageContent("hi"))
|
||||
)
|
||||
|
||||
@Test
|
||||
fun `processor returns empty list when empty list is provided`() {
|
||||
val processor = RoomBeginningPostProcessor(Timeline.Mode.LIVE)
|
||||
val processedItems = processor.process(
|
||||
items = emptyList(),
|
||||
isDm = true,
|
||||
roomCreator = A_USER_ID,
|
||||
hasMoreToLoadBackwards = false,
|
||||
)
|
||||
assertThat(processedItems).isEmpty()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `processor returns the provided list when it only contains a message`() {
|
||||
val processor = RoomBeginningPostProcessor(Timeline.Mode.LIVE)
|
||||
val processedItems = processor.process(
|
||||
items = listOf(messageEvent),
|
||||
isDm = true,
|
||||
roomCreator = A_USER_ID,
|
||||
hasMoreToLoadBackwards = false,
|
||||
)
|
||||
assertThat(processedItems).isEqualTo(listOf(messageEvent))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `processor returns the provided list when it only contains a message and the roomCreator is not provided`() {
|
||||
val processor = RoomBeginningPostProcessor(Timeline.Mode.LIVE)
|
||||
val processedItems = processor.process(
|
||||
items = listOf(messageEvent),
|
||||
isDm = true,
|
||||
roomCreator = null,
|
||||
hasMoreToLoadBackwards = false,
|
||||
)
|
||||
assertThat(processedItems).isEqualTo(listOf(messageEvent))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `processor removes room creation event and self-join event from DM timeline`() {
|
||||
val timelineItems = listOf(
|
||||
MatrixTimelineItem.Event(UniqueId("m.room.create"), anEventTimelineItem(sender = A_USER_ID, content = StateContent("", OtherState.RoomCreate))),
|
||||
MatrixTimelineItem.Event(UniqueId("m.room.member"), anEventTimelineItem(content = RoomMembershipContent(A_USER_ID, null, MembershipChange.JOINED))),
|
||||
roomCreateEvent,
|
||||
roomCreatorJoinEvent,
|
||||
)
|
||||
val processor = RoomBeginningPostProcessor(Timeline.Mode.LIVE)
|
||||
val processedItems = processor.process(timelineItems, isDm = true, hasMoreToLoadBackwards = false)
|
||||
val processedItems = processor.process(
|
||||
items = timelineItems,
|
||||
isDm = true,
|
||||
roomCreator = A_USER_ID,
|
||||
hasMoreToLoadBackwards = false,
|
||||
)
|
||||
assertThat(processedItems).isEmpty()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `processor does not remove anything with PINNED_EVENTS mode`() {
|
||||
val timelineItems = listOf(
|
||||
roomCreateEvent,
|
||||
roomCreatorJoinEvent,
|
||||
)
|
||||
val processor = RoomBeginningPostProcessor(Timeline.Mode.PINNED_EVENTS)
|
||||
val processedItems = processor.process(
|
||||
items = timelineItems,
|
||||
isDm = true,
|
||||
roomCreator = A_USER_ID,
|
||||
hasMoreToLoadBackwards = false,
|
||||
)
|
||||
assertThat(processedItems).isEqualTo(timelineItems)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `processor removes room creation event and self-join event from DM timeline even if they're not the first items`() {
|
||||
val timelineItems = listOf(
|
||||
MatrixTimelineItem.Event(
|
||||
UniqueId("m.room.member_other"),
|
||||
anEventTimelineItem(content = RoomMembershipContent(A_USER_ID_2, null, MembershipChange.JOINED))
|
||||
),
|
||||
MatrixTimelineItem.Event(UniqueId("m.room.create"), anEventTimelineItem(sender = A_USER_ID, content = StateContent("", OtherState.RoomCreate))),
|
||||
MatrixTimelineItem.Event(UniqueId("m.room.message"), anEventTimelineItem(content = aMessageContent("hi"))),
|
||||
MatrixTimelineItem.Event(UniqueId("m.room.member"), anEventTimelineItem(content = RoomMembershipContent(A_USER_ID, null, MembershipChange.JOINED))),
|
||||
otherMemberJoinEvent,
|
||||
roomCreateEvent,
|
||||
messageEvent,
|
||||
roomCreatorJoinEvent,
|
||||
)
|
||||
val expected = listOf(
|
||||
MatrixTimelineItem.Event(
|
||||
UniqueId("m.room.member_other"),
|
||||
anEventTimelineItem(content = RoomMembershipContent(A_USER_ID_2, null, MembershipChange.JOINED))
|
||||
),
|
||||
MatrixTimelineItem.Event(UniqueId("m.room.message"), anEventTimelineItem(content = aMessageContent("hi"))),
|
||||
otherMemberJoinEvent,
|
||||
messageEvent,
|
||||
)
|
||||
val processor = RoomBeginningPostProcessor(Timeline.Mode.LIVE)
|
||||
val processedItems = processor.process(timelineItems, isDm = true, hasMoreToLoadBackwards = false)
|
||||
val processedItems = processor.process(timelineItems, isDm = true, roomCreator = A_USER_ID, hasMoreToLoadBackwards = false)
|
||||
assertThat(processedItems).isEqualTo(expected)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `processor will add beginning of room item if it's not a DM`() {
|
||||
val timelineItems = listOf(
|
||||
MatrixTimelineItem.Event(UniqueId("m.room.create"), anEventTimelineItem(sender = A_USER_ID, content = StateContent("", OtherState.RoomCreate))),
|
||||
MatrixTimelineItem.Event(UniqueId("m.room.member"), anEventTimelineItem(content = RoomMembershipContent(A_USER_ID, null, MembershipChange.JOINED))),
|
||||
roomCreateEvent,
|
||||
roomCreatorJoinEvent,
|
||||
)
|
||||
val processor = RoomBeginningPostProcessor(Timeline.Mode.LIVE)
|
||||
val processedItems = processor.process(timelineItems, isDm = false, hasMoreToLoadBackwards = false)
|
||||
val processedItems = processor.process(timelineItems, isDm = false, roomCreator = A_USER_ID, hasMoreToLoadBackwards = false)
|
||||
assertThat(processedItems).isEqualTo(
|
||||
listOf(processor.createRoomBeginningItem()) + timelineItems
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `processor won't remove items if it's not at the start of the timeline`() {
|
||||
fun `processor will not add beginning of room item if it's not a DM but the room has more to load`() {
|
||||
val timelineItems = listOf(
|
||||
MatrixTimelineItem.Event(UniqueId("m.room.create"), anEventTimelineItem(sender = A_USER_ID, content = StateContent("", OtherState.RoomCreate))),
|
||||
MatrixTimelineItem.Event(UniqueId("m.room.member"), anEventTimelineItem(content = RoomMembershipContent(A_USER_ID, null, MembershipChange.JOINED))),
|
||||
roomCreateEvent,
|
||||
roomCreatorJoinEvent,
|
||||
)
|
||||
val processor = RoomBeginningPostProcessor(Timeline.Mode.LIVE)
|
||||
val processedItems = processor.process(timelineItems, isDm = true, hasMoreToLoadBackwards = true)
|
||||
val processedItems = processor.process(timelineItems, isDm = false, roomCreator = A_USER_ID, hasMoreToLoadBackwards = true)
|
||||
assertThat(processedItems).isEqualTo(timelineItems)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `processor won't remove the first member join event if it can't find the room creation event`() {
|
||||
fun `processor will add beginning of room item if it's not a DM, when the parameter roomCreator is null`() {
|
||||
val timelineItems = listOf(
|
||||
MatrixTimelineItem.Event(UniqueId("m.room.member"), anEventTimelineItem(content = RoomMembershipContent(A_USER_ID, null, MembershipChange.JOINED))),
|
||||
roomCreateEvent,
|
||||
roomCreatorJoinEvent,
|
||||
)
|
||||
val processor = RoomBeginningPostProcessor(Timeline.Mode.LIVE)
|
||||
val processedItems = processor.process(timelineItems, isDm = true, hasMoreToLoadBackwards = true)
|
||||
assertThat(processedItems).isEqualTo(timelineItems)
|
||||
val processedItems = processor.process(timelineItems, isDm = false, roomCreator = null, hasMoreToLoadBackwards = false)
|
||||
assertThat(processedItems).isEqualTo(
|
||||
listOf(processor.createRoomBeginningItem()) + timelineItems
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `processor removes items event it's not at the start of the timeline`() {
|
||||
val timelineItems = listOf(
|
||||
roomCreateEvent,
|
||||
roomCreatorJoinEvent,
|
||||
)
|
||||
val processor = RoomBeginningPostProcessor(Timeline.Mode.LIVE)
|
||||
val processedItems = processor.process(timelineItems, isDm = true, roomCreator = A_USER_ID, hasMoreToLoadBackwards = true)
|
||||
assertThat(processedItems).isEmpty()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `processor removes the first member join event if it matches the roomCreator parameter`() {
|
||||
val timelineItems = listOf(
|
||||
roomCreatorJoinEvent,
|
||||
)
|
||||
val processor = RoomBeginningPostProcessor(Timeline.Mode.LIVE)
|
||||
val processedItems = processor.process(timelineItems, isDm = true, roomCreator = A_USER_ID, hasMoreToLoadBackwards = true)
|
||||
assertThat(processedItems).isEmpty()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `processor won't remove the first member join event if it's not from the room creator`() {
|
||||
val timelineItems = listOf(
|
||||
MatrixTimelineItem.Event(UniqueId("m.room.create"), anEventTimelineItem(sender = A_USER_ID, content = StateContent("", OtherState.RoomCreate))),
|
||||
MatrixTimelineItem.Event(
|
||||
UniqueId("m.room.member"),
|
||||
anEventTimelineItem(content = RoomMembershipContent(A_USER_ID_2, null, MembershipChange.JOINED))
|
||||
),
|
||||
roomCreateEvent,
|
||||
otherMemberJoinEvent,
|
||||
)
|
||||
val processor = RoomBeginningPostProcessor(Timeline.Mode.LIVE)
|
||||
val processedItems = processor.process(timelineItems, isDm = true, hasMoreToLoadBackwards = true)
|
||||
assertThat(processedItems).isEqualTo(timelineItems)
|
||||
val processedItems = processor.process(timelineItems, isDm = true, roomCreator = A_USER_ID, hasMoreToLoadBackwards = true)
|
||||
assertThat(processedItems).isEqualTo(listOf(otherMemberJoinEvent))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -523,6 +523,7 @@ fun aRoomInfo(
|
|||
activeRoomCallParticipants: List<String> = emptyList(),
|
||||
heroes: List<MatrixUser> = emptyList(),
|
||||
pinnedEventIds: List<EventId> = emptyList(),
|
||||
roomCreator: UserId? = null,
|
||||
) = MatrixRoomInfo(
|
||||
id = id,
|
||||
name = name,
|
||||
|
|
@ -549,6 +550,7 @@ fun aRoomInfo(
|
|||
activeRoomCallParticipants = activeRoomCallParticipants.toImmutableList(),
|
||||
heroes = heroes.toImmutableList(),
|
||||
pinnedEventIds = pinnedEventIds.toImmutableList(),
|
||||
creator = roomCreator,
|
||||
)
|
||||
|
||||
fun defaultRoomPowerLevels() = MatrixRoomPowerLevels(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue