Merge pull request #4896 from element-hq/feature/fga/fix_dm_predecessor_room_banner

fix (room upgrade) : room predecessor banner on DM room
This commit is contained in:
ganfra 2025-06-18 18:21:46 +02:00 committed by GitHub
commit 4cc814590e
6 changed files with 49 additions and 47 deletions

View file

@ -45,6 +45,7 @@ fun TimelineItemVirtualRow(
TimelineItemRoomBeginningView( TimelineItemRoomBeginningView(
predecessorRoom = timelineRoomInfo.predecessorRoom, predecessorRoom = timelineRoomInfo.predecessorRoom,
roomName = timelineRoomInfo.name, roomName = timelineRoomInfo.name,
isDm = timelineRoomInfo.isDm,
onPredecessorRoomClick = { roomId -> onPredecessorRoomClick = { roomId ->
eventSink(TimelineEvents.NavigateToRoom(roomId)) eventSink(TimelineEvents.NavigateToRoom(roomId))
}, },

View file

@ -25,6 +25,7 @@ import io.element.android.libraries.designsystem.preview.ElementPreview
import io.element.android.libraries.designsystem.preview.PreviewsDayNight import io.element.android.libraries.designsystem.preview.PreviewsDayNight
import io.element.android.libraries.designsystem.text.toAnnotatedString import io.element.android.libraries.designsystem.text.toAnnotatedString
import io.element.android.libraries.designsystem.theme.components.Text import io.element.android.libraries.designsystem.theme.components.Text
import io.element.android.libraries.designsystem.utils.allBooleans
import io.element.android.libraries.matrix.api.core.EventId import io.element.android.libraries.matrix.api.core.EventId
import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.room.tombstone.PredecessorRoom import io.element.android.libraries.matrix.api.room.tombstone.PredecessorRoom
@ -33,6 +34,7 @@ import io.element.android.libraries.matrix.api.room.tombstone.PredecessorRoom
fun TimelineItemRoomBeginningView( fun TimelineItemRoomBeginningView(
roomName: String?, roomName: String?,
predecessorRoom: PredecessorRoom?, predecessorRoom: PredecessorRoom?,
isDm: Boolean,
onPredecessorRoomClick: (RoomId) -> Unit, onPredecessorRoomClick: (RoomId) -> Unit,
modifier: Modifier = Modifier modifier: Modifier = Modifier
) { ) {
@ -48,24 +50,26 @@ fun TimelineItemRoomBeginningView(
submitText = stringResource(R.string.screen_room_timeline_upgraded_room_action) submitText = stringResource(R.string.screen_room_timeline_upgraded_room_action)
) )
} }
// Only display for non-DM room
Box( if (!isDm) {
modifier = Modifier Box(
modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.padding(horizontal = 16.dp, vertical = 8.dp), .padding(horizontal = 16.dp, vertical = 8.dp),
contentAlignment = Alignment.Center, contentAlignment = Alignment.Center,
) { ) {
val text = if (roomName == null) { val text = if (roomName == null) {
stringResource(id = R.string.screen_room_timeline_beginning_of_room_no_name) stringResource(id = R.string.screen_room_timeline_beginning_of_room_no_name)
} else { } else {
stringResource(id = R.string.screen_room_timeline_beginning_of_room, roomName) stringResource(id = R.string.screen_room_timeline_beginning_of_room, roomName)
}
Text(
color = ElementTheme.colors.textSecondary,
style = ElementTheme.typography.fontBodyMdRegular,
text = text,
textAlign = TextAlign.Center,
)
} }
Text(
color = ElementTheme.colors.textSecondary,
style = ElementTheme.typography.fontBodyMdRegular,
text = text,
textAlign = TextAlign.Center,
)
} }
} }
} }
@ -74,20 +78,25 @@ fun TimelineItemRoomBeginningView(
@Composable @Composable
internal fun TimelineItemRoomBeginningViewPreview() = ElementPreview { internal fun TimelineItemRoomBeginningViewPreview() = ElementPreview {
Column(verticalArrangement = spacedBy(16.dp)) { Column(verticalArrangement = spacedBy(16.dp)) {
TimelineItemRoomBeginningView( allBooleans.forEach { isDm ->
predecessorRoom = null, TimelineItemRoomBeginningView(
roomName = null, predecessorRoom = null,
onPredecessorRoomClick = {}, roomName = null,
) isDm = isDm,
TimelineItemRoomBeginningView( onPredecessorRoomClick = {},
predecessorRoom = null, )
roomName = "Room Name", TimelineItemRoomBeginningView(
onPredecessorRoomClick = {}, predecessorRoom = null,
) roomName = "Room Name",
TimelineItemRoomBeginningView( isDm = isDm,
predecessorRoom = PredecessorRoom(RoomId("!roomId:matrix.org"), EventId("\$eventId:matrix.org")), onPredecessorRoomClick = {},
roomName = "Room Name", )
onPredecessorRoomClick = {}, TimelineItemRoomBeginningView(
) predecessorRoom = PredecessorRoom(RoomId("!roomId:matrix.org"), EventId("\$eventId:matrix.org")),
roomName = "Room Name",
isDm = isDm,
onPredecessorRoomClick = {},
)
}
} }
} }

View file

@ -14,11 +14,10 @@ import io.element.android.libraries.matrix.api.timeline.item.event.MembershipCha
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.RoomMembershipContent 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.api.timeline.item.event.StateContent
import io.element.android.libraries.matrix.api.timeline.item.virtual.VirtualTimelineItem
/** /**
* This timeline post-processor removes the room creation event and the self-join event from the timeline for DMs * This timeline post-processor removes the room creation event and the self-join event from the timeline for DMs
* or add the RoomBeginning item for non DM room. * or add the RoomBeginning item.
*/ */
class RoomBeginningPostProcessor(private val mode: Timeline.Mode) { class RoomBeginningPostProcessor(private val mode: Timeline.Mode) {
fun process( fun process(
@ -30,7 +29,7 @@ class RoomBeginningPostProcessor(private val mode: Timeline.Mode) {
return when { return when {
items.isEmpty() -> items items.isEmpty() -> items
mode == Timeline.Mode.PINNED_EVENTS -> items mode == Timeline.Mode.PINNED_EVENTS -> items
isDm -> processForDM(items, roomCreator, hasMoreToLoadBackwards) isDm -> processForDM(items, roomCreator)
hasMoreToLoadBackwards -> items hasMoreToLoadBackwards -> items
else -> processForRoom(items) else -> processForRoom(items)
} }
@ -41,13 +40,7 @@ class RoomBeginningPostProcessor(private val mode: Timeline.Mode) {
return items return items
} }
private fun processForDM(items: List<MatrixTimelineItem>, roomCreator: UserId?, hasMoreToLoadBackwards: Boolean): List<MatrixTimelineItem> { private fun processForDM(items: List<MatrixTimelineItem>, roomCreator: UserId?): List<MatrixTimelineItem> {
val roomBeginningItemIndex = if (!hasMoreToLoadBackwards) {
items.indexOfFirst { it is MatrixTimelineItem.Virtual && it.virtual is VirtualTimelineItem.RoomBeginning }.takeIf { it >= 0 }
} else {
null
}
// Find room creation event. // Find room creation event.
// This is usually the first MatrixTimelineItem.Event (so index 1, index 0 is a date) // This is usually the first MatrixTimelineItem.Event (so index 1, index 0 is a date)
val roomCreationEventIndex = items.indexOfFirst { val roomCreationEventIndex = items.indexOfFirst {
@ -69,7 +62,6 @@ class RoomBeginningPostProcessor(private val mode: Timeline.Mode) {
} }
val indicesToRemove = listOfNotNull( val indicesToRemove = listOfNotNull(
roomBeginningItemIndex,
roomCreationEventIndex, roomCreationEventIndex,
selfUserJoinedEventIndex, selfUserJoinedEventIndex,
) )

View file

@ -50,7 +50,7 @@ class RoomBeginningPostProcessorTest {
} }
@Test @Test
fun `processor removes timeline start, room creation event and self-join event from DM timeline`() { fun `processor removes room creation event and self-join event from DM timeline`() {
val timelineItems = listOf( val timelineItems = listOf(
timelineStartEvent, timelineStartEvent,
roomCreateEvent, roomCreateEvent,
@ -63,7 +63,7 @@ class RoomBeginningPostProcessorTest {
roomCreator = A_USER_ID, roomCreator = A_USER_ID,
hasMoreToLoadBackwards = false, hasMoreToLoadBackwards = false,
) )
assertThat(processedItems).isEmpty() assertThat(processedItems).containsExactly(timelineStartEvent)
} }
@Test @Test

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:abf66dd56be501e27477d83f97eed4c948fdf049130d46dc5a23e46e4cf18dfc oid sha256:f4494a2cf13d267a1051ea3fbe4476d2354b8c7827d1b93aabacf5bbe063dc3a
size 33561 size 49269

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:603ce16c8ce5e92c6cf1b2639be69e0dc64b99c1c7f1879762661258d222fd84 oid sha256:affff20aa09000132ffa8535a81d888263e9d530144c8b96e15d25c1873254c9
size 36317 size 54426