Jorge Martin Espinosa
8 months ago
committed by
GitHub
5 changed files with 175 additions and 1 deletions
@ -0,0 +1 @@
@@ -0,0 +1 @@
|
||||
Remove room creation, self-join of room creator and 'this is the beginning of X' timeline items for DMs. |
@ -0,0 +1,61 @@
@@ -0,0 +1,61 @@
|
||||
/* |
||||
* Copyright (c) 2024 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 io.element.android.libraries.matrix.impl.timeline.postprocessor |
||||
|
||||
import io.element.android.libraries.matrix.api.timeline.MatrixTimelineItem |
||||
import io.element.android.libraries.matrix.api.timeline.item.event.MembershipChange |
||||
import io.element.android.libraries.matrix.api.timeline.item.event.OtherState |
||||
import io.element.android.libraries.matrix.api.timeline.item.event.RoomMembershipContent |
||||
import io.element.android.libraries.matrix.api.timeline.item.event.StateContent |
||||
|
||||
/** |
||||
* This timeline post-processor removes the room creation event and the self-join event from the timeline for DMs. |
||||
*/ |
||||
class DmBeginningTimelineProcessor { |
||||
fun process( |
||||
items: List<MatrixTimelineItem>, |
||||
isDm: Boolean, |
||||
isAtStartOfTimeline: Boolean |
||||
): List<MatrixTimelineItem> { |
||||
if (!isDm || !isAtStartOfTimeline) return items |
||||
|
||||
// Find room creation event. This is usually index 0 |
||||
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 |
||||
val selfUserJoinedEventIndex = roomCreatorUserId?.let { creatorUserId -> |
||||
items.indexOfFirst { |
||||
val stateEventContent = (it as? MatrixTimelineItem.Event)?.event?.content as? RoomMembershipContent |
||||
stateEventContent?.change == MembershipChange.JOINED && stateEventContent.userId == creatorUserId |
||||
} |
||||
} ?: -1 |
||||
|
||||
// Remove items at the indices we found |
||||
val newItems = items.toMutableList() |
||||
if (selfUserJoinedEventIndex in newItems.indices) { |
||||
newItems.removeAt(selfUserJoinedEventIndex) |
||||
} |
||||
if (roomCreationEventIndex in newItems.indices) { |
||||
newItems.removeAt(roomCreationEventIndex) |
||||
} |
||||
return newItems |
||||
} |
||||
} |
@ -0,0 +1,102 @@
@@ -0,0 +1,102 @@
|
||||
/* |
||||
* Copyright (c) 2024 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 io.element.android.libraries.matrix.impl.timeline.postprocessor |
||||
|
||||
import com.google.common.truth.Truth.assertThat |
||||
import io.element.android.libraries.matrix.api.timeline.MatrixTimelineItem |
||||
import io.element.android.libraries.matrix.api.timeline.item.event.MembershipChange |
||||
import io.element.android.libraries.matrix.api.timeline.item.event.OtherState |
||||
import io.element.android.libraries.matrix.api.timeline.item.event.RoomMembershipContent |
||||
import io.element.android.libraries.matrix.api.timeline.item.event.StateContent |
||||
import io.element.android.libraries.matrix.test.A_USER_ID |
||||
import io.element.android.libraries.matrix.test.A_USER_ID_2 |
||||
import io.element.android.libraries.matrix.test.timeline.aMessageContent |
||||
import io.element.android.libraries.matrix.test.timeline.anEventTimelineItem |
||||
import org.junit.Test |
||||
|
||||
class DmBeginningTimelineProcessorTest { |
||||
@Test |
||||
fun `processor removes room creation event and self-join event from DM timeline`() { |
||||
val timelineItems = listOf( |
||||
MatrixTimelineItem.Event("m.room.create", anEventTimelineItem(sender = A_USER_ID, content = StateContent("", OtherState.RoomCreate))), |
||||
MatrixTimelineItem.Event("m.room.member", anEventTimelineItem(content = RoomMembershipContent(A_USER_ID, MembershipChange.JOINED))), |
||||
) |
||||
val processor = DmBeginningTimelineProcessor() |
||||
val processedItems = processor.process(timelineItems, isDm = true, isAtStartOfTimeline = true) |
||||
assertThat(processedItems).isEmpty() |
||||
} |
||||
|
||||
@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("m.room.member_other", anEventTimelineItem(content = RoomMembershipContent(A_USER_ID_2, MembershipChange.JOINED))), |
||||
MatrixTimelineItem.Event("m.room.create", anEventTimelineItem(sender = A_USER_ID, content = StateContent("", OtherState.RoomCreate))), |
||||
MatrixTimelineItem.Event("m.room.message", anEventTimelineItem(content = aMessageContent("hi"))), |
||||
MatrixTimelineItem.Event("m.room.member", anEventTimelineItem(content = RoomMembershipContent(A_USER_ID, MembershipChange.JOINED))), |
||||
) |
||||
val expected = listOf( |
||||
MatrixTimelineItem.Event("m.room.member_other", anEventTimelineItem(content = RoomMembershipContent(A_USER_ID_2, MembershipChange.JOINED))), |
||||
MatrixTimelineItem.Event("m.room.message", anEventTimelineItem(content = aMessageContent("hi"))), |
||||
) |
||||
val processor = DmBeginningTimelineProcessor() |
||||
val processedItems = processor.process(timelineItems, isDm = true, isAtStartOfTimeline = true) |
||||
assertThat(processedItems).isEqualTo(expected) |
||||
} |
||||
|
||||
@Test |
||||
fun `processor won't remove items if it's not a DM`() { |
||||
val timelineItems = listOf( |
||||
MatrixTimelineItem.Event("m.room.create", anEventTimelineItem(sender = A_USER_ID, content = StateContent("", OtherState.RoomCreate))), |
||||
MatrixTimelineItem.Event("m.room.member", anEventTimelineItem(content = RoomMembershipContent(A_USER_ID, MembershipChange.JOINED))), |
||||
) |
||||
val processor = DmBeginningTimelineProcessor() |
||||
val processedItems = processor.process(timelineItems, isDm = false, isAtStartOfTimeline = true) |
||||
assertThat(processedItems).isEqualTo(timelineItems) |
||||
} |
||||
|
||||
@Test |
||||
fun `processor won't remove items if it's not at the start of the timeline`() { |
||||
val timelineItems = listOf( |
||||
MatrixTimelineItem.Event("m.room.create", anEventTimelineItem(sender = A_USER_ID, content = StateContent("", OtherState.RoomCreate))), |
||||
MatrixTimelineItem.Event("m.room.member", anEventTimelineItem(content = RoomMembershipContent(A_USER_ID, MembershipChange.JOINED))), |
||||
) |
||||
val processor = DmBeginningTimelineProcessor() |
||||
val processedItems = processor.process(timelineItems, isDm = true, isAtStartOfTimeline = false) |
||||
assertThat(processedItems).isEqualTo(timelineItems) |
||||
} |
||||
|
||||
@Test |
||||
fun `processor won't remove the first member join event if it can't find the room creation event`() { |
||||
val timelineItems = listOf( |
||||
MatrixTimelineItem.Event("m.room.member", anEventTimelineItem(content = RoomMembershipContent(A_USER_ID, MembershipChange.JOINED))), |
||||
) |
||||
val processor = DmBeginningTimelineProcessor() |
||||
val processedItems = processor.process(timelineItems, isDm = true, isAtStartOfTimeline = false) |
||||
assertThat(processedItems).isEqualTo(timelineItems) |
||||
} |
||||
|
||||
@Test |
||||
fun `processor won't remove the first member join event if it's not from the room creator`() { |
||||
val timelineItems = listOf( |
||||
MatrixTimelineItem.Event("m.room.create", anEventTimelineItem(sender = A_USER_ID, content = StateContent("", OtherState.RoomCreate))), |
||||
MatrixTimelineItem.Event("m.room.member", anEventTimelineItem(content = RoomMembershipContent(A_USER_ID_2, MembershipChange.JOINED))), |
||||
) |
||||
val processor = DmBeginningTimelineProcessor() |
||||
val processedItems = processor.process(timelineItems, isDm = true, isAtStartOfTimeline = false) |
||||
assertThat(processedItems).isEqualTo(timelineItems) |
||||
} |
||||
} |
Loading…
Reference in new issue