Browse Source

Use member display names in membership timeline item text (#2883)

* Use member display names in membership timeline item text
pull/2885/head
Jorge Martin Espinosa 4 months ago committed by GitHub
parent
commit
8bd9880c23
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 1
      changelog.d/2286.bugfix
  2. 1
      features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/model/InReplyToDetailTest.kt
  3. 2
      features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/model/InReplyToMetadataKtTest.kt
  4. 33
      libraries/eventformatter/impl/src/main/kotlin/io/element/android/libraries/eventformatter/impl/RoomMembershipContentFormatter.kt
  5. 145
      libraries/eventformatter/impl/src/test/kotlin/io/element/android/libraries/eventformatter/impl/DefaultRoomLastMessageFormatterTest.kt
  6. 1
      libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/item/event/EventContent.kt
  7. 5
      libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/item/event/TimelineEventContentMapper.kt
  8. 16
      libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/timeline/postprocessor/RoomBeginningPostProcessorTest.kt

1
changelog.d/2286.bugfix

@ -0,0 +1 @@
Use members display names for their membership state events.

1
features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/model/InReplyToDetailTest.kt

@ -58,6 +58,7 @@ class InReplyToDetailTest {
senderProfile = aProfileTimelineDetails(), senderProfile = aProfileTimelineDetails(),
content = RoomMembershipContent( content = RoomMembershipContent(
userId = A_USER_ID, userId = A_USER_ID,
userDisplayName = null,
change = MembershipChange.INVITED, change = MembershipChange.INVITED,
) )
) )

2
features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/model/InReplyToMetadataKtTest.kt

@ -380,7 +380,7 @@ class InReplyToMetadataKtTest {
fun `room membership content`() = runTest { fun `room membership content`() = runTest {
moleculeFlow(RecompositionMode.Immediate) { moleculeFlow(RecompositionMode.Immediate) {
anInReplyToDetailsReady( anInReplyToDetailsReady(
eventContent = RoomMembershipContent(A_USER_ID, null) eventContent = RoomMembershipContent(A_USER_ID, null, null)
).metadata() ).metadata()
}.test { }.test {
awaitItem().let { awaitItem().let {

33
libraries/eventformatter/impl/src/main/kotlin/io/element/android/libraries/eventformatter/impl/RoomMembershipContentFormatter.kt

@ -34,6 +34,7 @@ class RoomMembershipContentFormatter @Inject constructor(
): CharSequence? { ): CharSequence? {
val userId = membershipContent.userId val userId = membershipContent.userId
val memberIsYou = matrixClient.isMe(userId) val memberIsYou = matrixClient.isMe(userId)
val userDisplayNameOrId = membershipContent.userDisplayName ?: userId.value
return when (membershipContent.change) { return when (membershipContent.change) {
MembershipChange.JOINED -> if (memberIsYou) { MembershipChange.JOINED -> if (memberIsYou) {
sp.getString(R.string.state_event_room_join_by_you) sp.getString(R.string.state_event_room_join_by_you)
@ -46,41 +47,41 @@ class RoomMembershipContentFormatter @Inject constructor(
sp.getString(R.string.state_event_room_leave, senderDisambiguatedDisplayName) sp.getString(R.string.state_event_room_leave, senderDisambiguatedDisplayName)
} }
MembershipChange.BANNED, MembershipChange.KICKED_AND_BANNED -> if (senderIsYou) { MembershipChange.BANNED, MembershipChange.KICKED_AND_BANNED -> if (senderIsYou) {
sp.getString(R.string.state_event_room_ban_by_you, userId.value) sp.getString(R.string.state_event_room_ban_by_you, userDisplayNameOrId)
} else { } else {
sp.getString(R.string.state_event_room_ban, senderDisambiguatedDisplayName, userId.value) sp.getString(R.string.state_event_room_ban, senderDisambiguatedDisplayName, userDisplayNameOrId)
} }
MembershipChange.UNBANNED -> if (senderIsYou) { MembershipChange.UNBANNED -> if (senderIsYou) {
sp.getString(R.string.state_event_room_unban_by_you, userId.value) sp.getString(R.string.state_event_room_unban_by_you, userDisplayNameOrId)
} else { } else {
sp.getString(R.string.state_event_room_unban, senderDisambiguatedDisplayName, userId.value) sp.getString(R.string.state_event_room_unban, senderDisambiguatedDisplayName, userDisplayNameOrId)
} }
MembershipChange.KICKED -> if (senderIsYou) { MembershipChange.KICKED -> if (senderIsYou) {
sp.getString(R.string.state_event_room_remove_by_you, userId.value) sp.getString(R.string.state_event_room_remove_by_you, userDisplayNameOrId)
} else { } else {
sp.getString(R.string.state_event_room_remove, senderDisambiguatedDisplayName, userId.value) sp.getString(R.string.state_event_room_remove, senderDisambiguatedDisplayName, userDisplayNameOrId)
} }
MembershipChange.INVITED -> if (senderIsYou) { MembershipChange.INVITED -> if (senderIsYou) {
sp.getString(R.string.state_event_room_invite_by_you, userId.value) sp.getString(R.string.state_event_room_invite_by_you, userDisplayNameOrId)
} else if (memberIsYou) { } else if (memberIsYou) {
sp.getString(R.string.state_event_room_invite_you, senderDisambiguatedDisplayName) sp.getString(R.string.state_event_room_invite_you, senderDisambiguatedDisplayName)
} else { } else {
sp.getString(R.string.state_event_room_invite, senderDisambiguatedDisplayName, userId.value) sp.getString(R.string.state_event_room_invite, senderDisambiguatedDisplayName, userDisplayNameOrId)
} }
MembershipChange.INVITATION_ACCEPTED -> if (memberIsYou) { MembershipChange.INVITATION_ACCEPTED -> if (memberIsYou) {
sp.getString(R.string.state_event_room_invite_accepted_by_you) sp.getString(R.string.state_event_room_invite_accepted_by_you)
} else { } else {
sp.getString(R.string.state_event_room_invite_accepted, userId.value) sp.getString(R.string.state_event_room_invite_accepted, userDisplayNameOrId)
} }
MembershipChange.INVITATION_REJECTED -> if (memberIsYou) { MembershipChange.INVITATION_REJECTED -> if (memberIsYou) {
sp.getString(R.string.state_event_room_reject_by_you) sp.getString(R.string.state_event_room_reject_by_you)
} else { } else {
sp.getString(R.string.state_event_room_reject, userId.value) sp.getString(R.string.state_event_room_reject, userDisplayNameOrId)
} }
MembershipChange.INVITATION_REVOKED -> if (senderIsYou) { MembershipChange.INVITATION_REVOKED -> if (senderIsYou) {
sp.getString(R.string.state_event_room_third_party_revoked_invite_by_you, userId.value) sp.getString(R.string.state_event_room_third_party_revoked_invite_by_you, userDisplayNameOrId)
} else { } else {
sp.getString(R.string.state_event_room_third_party_revoked_invite, senderDisambiguatedDisplayName, userId.value) sp.getString(R.string.state_event_room_third_party_revoked_invite, senderDisambiguatedDisplayName, userDisplayNameOrId)
} }
MembershipChange.KNOCKED -> if (memberIsYou) { MembershipChange.KNOCKED -> if (memberIsYou) {
sp.getString(R.string.state_event_room_knock_by_you) sp.getString(R.string.state_event_room_knock_by_you)
@ -88,9 +89,9 @@ class RoomMembershipContentFormatter @Inject constructor(
sp.getString(R.string.state_event_room_knock, senderDisambiguatedDisplayName) sp.getString(R.string.state_event_room_knock, senderDisambiguatedDisplayName)
} }
MembershipChange.KNOCK_ACCEPTED -> if (senderIsYou) { MembershipChange.KNOCK_ACCEPTED -> if (senderIsYou) {
sp.getString(R.string.state_event_room_knock_accepted_by_you, userId.value) sp.getString(R.string.state_event_room_knock_accepted_by_you, userDisplayNameOrId)
} else { } else {
sp.getString(R.string.state_event_room_knock_accepted, senderDisambiguatedDisplayName, userId.value) sp.getString(R.string.state_event_room_knock_accepted, senderDisambiguatedDisplayName, userDisplayNameOrId)
} }
MembershipChange.KNOCK_RETRACTED -> if (memberIsYou) { MembershipChange.KNOCK_RETRACTED -> if (memberIsYou) {
sp.getString(R.string.state_event_room_knock_retracted_by_you) sp.getString(R.string.state_event_room_knock_retracted_by_you)
@ -98,11 +99,11 @@ class RoomMembershipContentFormatter @Inject constructor(
sp.getString(R.string.state_event_room_knock_retracted, senderDisambiguatedDisplayName) sp.getString(R.string.state_event_room_knock_retracted, senderDisambiguatedDisplayName)
} }
MembershipChange.KNOCK_DENIED -> if (senderIsYou) { MembershipChange.KNOCK_DENIED -> if (senderIsYou) {
sp.getString(R.string.state_event_room_knock_denied_by_you, userId.value) sp.getString(R.string.state_event_room_knock_denied_by_you, userDisplayNameOrId)
} else if (memberIsYou) { } else if (memberIsYou) {
sp.getString(R.string.state_event_room_knock_denied_you, senderDisambiguatedDisplayName) sp.getString(R.string.state_event_room_knock_denied_you, senderDisambiguatedDisplayName)
} else { } else {
sp.getString(R.string.state_event_room_knock_denied, senderDisambiguatedDisplayName, userId.value) sp.getString(R.string.state_event_room_knock_denied, senderDisambiguatedDisplayName, userDisplayNameOrId)
} }
MembershipChange.NONE -> if (senderIsYou) { MembershipChange.NONE -> if (senderIsYou) {
sp.getString(R.string.state_event_room_none_by_you) sp.getString(R.string.state_event_room_none_by_you)

145
libraries/eventformatter/impl/src/test/kotlin/io/element/android/libraries/eventformatter/impl/DefaultRoomLastMessageFormatterTest.kt

@ -254,9 +254,9 @@ class DefaultRoomLastMessageFormatterTest {
@Test @Test
@Config(qualifiers = "en") @Config(qualifiers = "en")
fun `Membership change - joined`() { fun `Membership change - joined`() {
val otherName = "Someone" val otherName = "Other"
val youContent = RoomMembershipContent(A_USER_ID, MembershipChange.JOINED) val youContent = RoomMembershipContent(A_USER_ID, null, MembershipChange.JOINED)
val someoneContent = RoomMembershipContent(UserId("@someone_else:domain"), MembershipChange.JOINED) val someoneContent = RoomMembershipContent(UserId("@someone_else:domain"), otherName, MembershipChange.JOINED)
val youJoinedRoomEvent = createRoomEvent(sentByYou = true, senderDisplayName = null, content = youContent) val youJoinedRoomEvent = createRoomEvent(sentByYou = true, senderDisplayName = null, content = youContent)
val youJoinedRoom = formatter.format(youJoinedRoomEvent, false) val youJoinedRoom = formatter.format(youJoinedRoomEvent, false)
@ -270,9 +270,9 @@ class DefaultRoomLastMessageFormatterTest {
@Test @Test
@Config(qualifiers = "en") @Config(qualifiers = "en")
fun `Membership change - left`() { fun `Membership change - left`() {
val otherName = "Someone" val otherName = "Other"
val youContent = RoomMembershipContent(A_USER_ID, MembershipChange.LEFT) val youContent = RoomMembershipContent(A_USER_ID, null, MembershipChange.LEFT)
val someoneContent = RoomMembershipContent(UserId("@someone_else:domain"), MembershipChange.LEFT) val someoneContent = RoomMembershipContent(UserId("@someone_else:domain"), otherName, MembershipChange.LEFT)
val youLeftRoomEvent = createRoomEvent(sentByYou = true, senderDisplayName = null, content = youContent) val youLeftRoomEvent = createRoomEvent(sentByYou = true, senderDisplayName = null, content = youContent)
val youLeftRoom = formatter.format(youLeftRoomEvent, false) val youLeftRoom = formatter.format(youLeftRoomEvent, false)
@ -286,67 +286,71 @@ class DefaultRoomLastMessageFormatterTest {
@Test @Test
@Config(qualifiers = "en") @Config(qualifiers = "en")
fun `Membership change - banned`() { fun `Membership change - banned`() {
val otherName = "Someone" val otherName = "Other"
val youContent = RoomMembershipContent(UserId("@someone_else:domain"), MembershipChange.BANNED) val third = "Someone"
val youKickedContent = RoomMembershipContent(UserId("@someone_else:domain"), MembershipChange.KICKED_AND_BANNED) val youContent = RoomMembershipContent(UserId("@someone_else:domain"), third, MembershipChange.BANNED)
val someoneContent = RoomMembershipContent(UserId("@someone_else:domain"), MembershipChange.BANNED) val youKickedContent = RoomMembershipContent(UserId("@someone_else:domain"), third, MembershipChange.KICKED_AND_BANNED)
val someoneKickedContent = RoomMembershipContent(UserId("@someone_else:domain"), MembershipChange.KICKED_AND_BANNED) val someoneContent = RoomMembershipContent(UserId("@someone_else:domain"), third, MembershipChange.BANNED)
val someoneKickedContent = RoomMembershipContent(UserId("@someone_else:domain"), third, MembershipChange.KICKED_AND_BANNED)
val youBannedEvent = createRoomEvent(sentByYou = true, senderDisplayName = null, content = youContent) val youBannedEvent = createRoomEvent(sentByYou = true, senderDisplayName = null, content = youContent)
val youBanned = formatter.format(youBannedEvent, false) val youBanned = formatter.format(youBannedEvent, false)
assertThat(youBanned).isEqualTo("You banned ${youContent.userId}") assertThat(youBanned).isEqualTo("You banned $third")
val youKickBannedEvent = createRoomEvent(sentByYou = true, senderDisplayName = null, content = youKickedContent) val youKickBannedEvent = createRoomEvent(sentByYou = true, senderDisplayName = null, content = youKickedContent)
val youKickedBanned = formatter.format(youKickBannedEvent, false) val youKickedBanned = formatter.format(youKickBannedEvent, false)
assertThat(youKickedBanned).isEqualTo("You banned ${youContent.userId}") assertThat(youKickedBanned).isEqualTo("You banned $third")
val someoneBannedEvent = createRoomEvent(sentByYou = false, senderDisplayName = otherName, content = someoneContent) val someoneBannedEvent = createRoomEvent(sentByYou = false, senderDisplayName = otherName, content = someoneContent)
val someoneBanned = formatter.format(someoneBannedEvent, false) val someoneBanned = formatter.format(someoneBannedEvent, false)
assertThat(someoneBanned).isEqualTo("$otherName banned ${someoneContent.userId}") assertThat(someoneBanned).isEqualTo("$otherName banned $third")
val someoneKickBannedEvent = createRoomEvent(sentByYou = false, senderDisplayName = otherName, content = someoneKickedContent) val someoneKickBannedEvent = createRoomEvent(sentByYou = false, senderDisplayName = otherName, content = someoneKickedContent)
val someoneKickBanned = formatter.format(someoneKickBannedEvent, false) val someoneKickBanned = formatter.format(someoneKickBannedEvent, false)
assertThat(someoneKickBanned).isEqualTo("$otherName banned ${someoneContent.userId}") assertThat(someoneKickBanned).isEqualTo("$otherName banned $third")
} }
@Test @Test
@Config(qualifiers = "en") @Config(qualifiers = "en")
fun `Membership change - unban`() { fun `Membership change - unban`() {
val otherName = "Someone" val otherName = "Other"
val youContent = RoomMembershipContent(UserId("@someone_else:domain"), MembershipChange.UNBANNED) val third = "Someone"
val someoneContent = RoomMembershipContent(UserId("@someone_else:domain"), MembershipChange.UNBANNED) val youContent = RoomMembershipContent(UserId("@someone_else:domain"), third, MembershipChange.UNBANNED)
val someoneContent = RoomMembershipContent(UserId("@someone_else:domain"), third, MembershipChange.UNBANNED)
val youUnbannedEvent = createRoomEvent(sentByYou = true, senderDisplayName = null, content = youContent) val youUnbannedEvent = createRoomEvent(sentByYou = true, senderDisplayName = null, content = youContent)
val youUnbanned = formatter.format(youUnbannedEvent, false) val youUnbanned = formatter.format(youUnbannedEvent, false)
assertThat(youUnbanned).isEqualTo("You unbanned ${youContent.userId}") assertThat(youUnbanned).isEqualTo("You unbanned $third")
val someoneUnbannedEvent = createRoomEvent(sentByYou = false, senderDisplayName = otherName, content = someoneContent) val someoneUnbannedEvent = createRoomEvent(sentByYou = false, senderDisplayName = otherName, content = someoneContent)
val someoneUnbanned = formatter.format(someoneUnbannedEvent, false) val someoneUnbanned = formatter.format(someoneUnbannedEvent, false)
assertThat(someoneUnbanned).isEqualTo("$otherName unbanned ${someoneContent.userId}") assertThat(someoneUnbanned).isEqualTo("$otherName unbanned $third")
} }
@Test @Test
@Config(qualifiers = "en") @Config(qualifiers = "en")
fun `Membership change - kicked`() { fun `Membership change - kicked`() {
val otherName = "Someone" val otherName = "Other"
val youContent = RoomMembershipContent(UserId("@someone_else:domain"), MembershipChange.KICKED) val third = "Someone"
val someoneContent = RoomMembershipContent(UserId("@someone_else:domain"), MembershipChange.KICKED) val youContent = RoomMembershipContent(UserId("@someone_else:domain"), third, MembershipChange.KICKED)
val someoneContent = RoomMembershipContent(UserId("@someone_else:domain"), third, MembershipChange.KICKED)
val youKickedEvent = createRoomEvent(sentByYou = true, senderDisplayName = null, content = youContent) val youKickedEvent = createRoomEvent(sentByYou = true, senderDisplayName = null, content = youContent)
val youKicked = formatter.format(youKickedEvent, false) val youKicked = formatter.format(youKickedEvent, false)
assertThat(youKicked).isEqualTo("You removed ${youContent.userId}") assertThat(youKicked).isEqualTo("You removed $third")
val someoneKickedEvent = createRoomEvent(sentByYou = false, senderDisplayName = otherName, content = someoneContent) val someoneKickedEvent = createRoomEvent(sentByYou = false, senderDisplayName = otherName, content = someoneContent)
val someoneKicked = formatter.format(someoneKickedEvent, false) val someoneKicked = formatter.format(someoneKickedEvent, false)
assertThat(someoneKicked).isEqualTo("$otherName removed ${someoneContent.userId}") assertThat(someoneKicked).isEqualTo("$otherName removed $third")
} }
@Test @Test
@Config(qualifiers = "en") @Config(qualifiers = "en")
fun `Membership change - invited`() { fun `Membership change - invited`() {
val otherName = "Someone" val otherName = "Other"
val youContent = RoomMembershipContent(A_USER_ID, MembershipChange.INVITED) val third = "Someone"
val someoneContent = RoomMembershipContent(UserId("@someone_else:domain"), MembershipChange.INVITED) val youContent = RoomMembershipContent(A_USER_ID, null, MembershipChange.INVITED)
val someoneContent = RoomMembershipContent(UserId("@someone_else:domain"), third, MembershipChange.INVITED)
val youWereInvitedEvent = createRoomEvent(sentByYou = false, senderDisplayName = otherName, content = youContent) val youWereInvitedEvent = createRoomEvent(sentByYou = false, senderDisplayName = otherName, content = youContent)
val youWereInvited = formatter.format(youWereInvitedEvent, false) val youWereInvited = formatter.format(youWereInvitedEvent, false)
@ -354,19 +358,19 @@ class DefaultRoomLastMessageFormatterTest {
val youInvitedEvent = createRoomEvent(sentByYou = true, senderDisplayName = null, content = someoneContent) val youInvitedEvent = createRoomEvent(sentByYou = true, senderDisplayName = null, content = someoneContent)
val youInvited = formatter.format(youInvitedEvent, false) val youInvited = formatter.format(youInvitedEvent, false)
assertThat(youInvited).isEqualTo("You invited ${someoneContent.userId}") assertThat(youInvited).isEqualTo("You invited $third")
val someoneInvitedEvent = createRoomEvent(sentByYou = false, senderDisplayName = otherName, content = someoneContent) val someoneInvitedEvent = createRoomEvent(sentByYou = false, senderDisplayName = otherName, content = someoneContent)
val someoneInvited = formatter.format(someoneInvitedEvent, false) val someoneInvited = formatter.format(someoneInvitedEvent, false)
assertThat(someoneInvited).isEqualTo("$otherName invited ${someoneContent.userId}") assertThat(someoneInvited).isEqualTo("$otherName invited $third")
} }
@Test @Test
@Config(qualifiers = "en") @Config(qualifiers = "en")
fun `Membership change - invitation accepted`() { fun `Membership change - invitation accepted`() {
val otherName = "Someone" val otherName = "Other"
val youContent = RoomMembershipContent(A_USER_ID, MembershipChange.INVITATION_ACCEPTED) val youContent = RoomMembershipContent(A_USER_ID, null, MembershipChange.INVITATION_ACCEPTED)
val someoneContent = RoomMembershipContent(UserId("@someone_else:domain"), MembershipChange.INVITATION_ACCEPTED) val someoneContent = RoomMembershipContent(UserId("@someone_else:domain"), otherName, MembershipChange.INVITATION_ACCEPTED)
val youAcceptedInviteEvent = createRoomEvent(sentByYou = true, senderDisplayName = null, content = youContent) val youAcceptedInviteEvent = createRoomEvent(sentByYou = true, senderDisplayName = null, content = youContent)
val youAcceptedInvite = formatter.format(youAcceptedInviteEvent, false) val youAcceptedInvite = formatter.format(youAcceptedInviteEvent, false)
@ -374,15 +378,15 @@ class DefaultRoomLastMessageFormatterTest {
val someoneAcceptedInviteEvent = createRoomEvent(sentByYou = false, senderDisplayName = otherName, content = someoneContent) val someoneAcceptedInviteEvent = createRoomEvent(sentByYou = false, senderDisplayName = otherName, content = someoneContent)
val someoneAcceptedInvite = formatter.format(someoneAcceptedInviteEvent, false) val someoneAcceptedInvite = formatter.format(someoneAcceptedInviteEvent, false)
assertThat(someoneAcceptedInvite).isEqualTo("${someoneContent.userId} accepted the invite") assertThat(someoneAcceptedInvite).isEqualTo("$otherName accepted the invite")
} }
@Test @Test
@Config(qualifiers = "en") @Config(qualifiers = "en")
fun `Membership change - invitation rejected`() { fun `Membership change - invitation rejected`() {
val otherName = "Someone" val otherName = "Other"
val youContent = RoomMembershipContent(A_USER_ID, MembershipChange.INVITATION_REJECTED) val youContent = RoomMembershipContent(A_USER_ID, null, MembershipChange.INVITATION_REJECTED)
val someoneContent = RoomMembershipContent(UserId("@someone_else:domain"), MembershipChange.INVITATION_REJECTED) val someoneContent = RoomMembershipContent(UserId("@someone_else:domain"), otherName, MembershipChange.INVITATION_REJECTED)
val youRejectedInviteEvent = createRoomEvent(sentByYou = true, senderDisplayName = null, content = youContent) val youRejectedInviteEvent = createRoomEvent(sentByYou = true, senderDisplayName = null, content = youContent)
val youRejectedInvite = formatter.format(youRejectedInviteEvent, false) val youRejectedInvite = formatter.format(youRejectedInviteEvent, false)
@ -390,30 +394,31 @@ class DefaultRoomLastMessageFormatterTest {
val someoneRejectedInviteEvent = createRoomEvent(sentByYou = false, senderDisplayName = otherName, content = someoneContent) val someoneRejectedInviteEvent = createRoomEvent(sentByYou = false, senderDisplayName = otherName, content = someoneContent)
val someoneRejectedInvite = formatter.format(someoneRejectedInviteEvent, false) val someoneRejectedInvite = formatter.format(someoneRejectedInviteEvent, false)
assertThat(someoneRejectedInvite).isEqualTo("${someoneContent.userId} rejected the invitation") assertThat(someoneRejectedInvite).isEqualTo("$otherName rejected the invitation")
} }
@Test @Test
@Config(qualifiers = "en") @Config(qualifiers = "en")
fun `Membership change - invitation revoked`() { fun `Membership change - invitation revoked`() {
val otherName = "Someone" val otherName = "Other"
val someoneContent = RoomMembershipContent(UserId("@someone_else:domain"), MembershipChange.INVITATION_REVOKED) val third = "Someone"
val someoneContent = RoomMembershipContent(UserId("@someone_else:domain"), third, MembershipChange.INVITATION_REVOKED)
val youRevokedInviteEvent = createRoomEvent(sentByYou = true, senderDisplayName = null, content = someoneContent) val youRevokedInviteEvent = createRoomEvent(sentByYou = true, senderDisplayName = null, content = someoneContent)
val youRevokedInvite = formatter.format(youRevokedInviteEvent, false) val youRevokedInvite = formatter.format(youRevokedInviteEvent, false)
assertThat(youRevokedInvite).isEqualTo("You revoked the invitation for ${someoneContent.userId} to join the room") assertThat(youRevokedInvite).isEqualTo("You revoked the invitation for $third to join the room")
val someoneRevokedInviteEvent = createRoomEvent(sentByYou = false, senderDisplayName = otherName, content = someoneContent) val someoneRevokedInviteEvent = createRoomEvent(sentByYou = false, senderDisplayName = otherName, content = someoneContent)
val someoneRevokedInvite = formatter.format(someoneRevokedInviteEvent, false) val someoneRevokedInvite = formatter.format(someoneRevokedInviteEvent, false)
assertThat(someoneRevokedInvite).isEqualTo("$otherName revoked the invitation for ${someoneContent.userId} to join the room") assertThat(someoneRevokedInvite).isEqualTo("$otherName revoked the invitation for $third to join the room")
} }
@Test @Test
@Config(qualifiers = "en") @Config(qualifiers = "en")
fun `Membership change - knocked`() { fun `Membership change - knocked`() {
val otherName = "Someone" val otherName = "Other"
val youContent = RoomMembershipContent(A_USER_ID, MembershipChange.KNOCKED) val youContent = RoomMembershipContent(A_USER_ID, null, MembershipChange.KNOCKED)
val someoneContent = RoomMembershipContent(UserId("@someone_else:domain"), MembershipChange.KNOCKED) val someoneContent = RoomMembershipContent(UserId("@someone_else:domain"), otherName, MembershipChange.KNOCKED)
val youKnockedEvent = createRoomEvent(sentByYou = true, senderDisplayName = null, content = youContent) val youKnockedEvent = createRoomEvent(sentByYou = true, senderDisplayName = null, content = youContent)
val youKnocked = formatter.format(youKnockedEvent, false) val youKnocked = formatter.format(youKnockedEvent, false)
@ -427,24 +432,25 @@ class DefaultRoomLastMessageFormatterTest {
@Test @Test
@Config(qualifiers = "en") @Config(qualifiers = "en")
fun `Membership change - knock accepted`() { fun `Membership change - knock accepted`() {
val otherName = "Someone" val otherName = "Other"
val someoneContent = RoomMembershipContent(UserId("@someone_else:domain"), MembershipChange.KNOCK_ACCEPTED) val third = "Someone"
val someoneContent = RoomMembershipContent(UserId("@someone_else:domain"), third, MembershipChange.KNOCK_ACCEPTED)
val youAcceptedKnockEvent = createRoomEvent(sentByYou = true, senderDisplayName = null, content = someoneContent) val youAcceptedKnockEvent = createRoomEvent(sentByYou = true, senderDisplayName = null, content = someoneContent)
val youAcceptedKnock = formatter.format(youAcceptedKnockEvent, false) val youAcceptedKnock = formatter.format(youAcceptedKnockEvent, false)
assertThat(youAcceptedKnock).isEqualTo("You allowed ${someoneContent.userId} to join") assertThat(youAcceptedKnock).isEqualTo("You allowed $third to join")
val someoneAcceptedKnockEvent = createRoomEvent(sentByYou = false, senderDisplayName = otherName, content = someoneContent) val someoneAcceptedKnockEvent = createRoomEvent(sentByYou = false, senderDisplayName = otherName, content = someoneContent)
val someoneAcceptedKnock = formatter.format(someoneAcceptedKnockEvent, false) val someoneAcceptedKnock = formatter.format(someoneAcceptedKnockEvent, false)
assertThat(someoneAcceptedKnock).isEqualTo("$otherName allowed ${someoneContent.userId} to join") assertThat(someoneAcceptedKnock).isEqualTo("$otherName allowed $third to join")
} }
@Test @Test
@Config(qualifiers = "en") @Config(qualifiers = "en")
fun `Membership change - knock retracted`() { fun `Membership change - knock retracted`() {
val otherName = "Someone" val otherName = "Other"
val youContent = RoomMembershipContent(A_USER_ID, MembershipChange.KNOCK_RETRACTED) val youContent = RoomMembershipContent(A_USER_ID, null, MembershipChange.KNOCK_RETRACTED)
val someoneContent = RoomMembershipContent(UserId("@someone_else:domain"), MembershipChange.KNOCK_RETRACTED) val someoneContent = RoomMembershipContent(UserId("@someone_else:domain"), null, MembershipChange.KNOCK_RETRACTED)
val youRetractedKnockEvent = createRoomEvent(sentByYou = true, senderDisplayName = null, content = youContent) val youRetractedKnockEvent = createRoomEvent(sentByYou = true, senderDisplayName = null, content = youContent)
val youRetractedKnock = formatter.format(youRetractedKnockEvent, false) val youRetractedKnock = formatter.format(youRetractedKnockEvent, false)
@ -458,17 +464,18 @@ class DefaultRoomLastMessageFormatterTest {
@Test @Test
@Config(qualifiers = "en") @Config(qualifiers = "en")
fun `Membership change - knock denied`() { fun `Membership change - knock denied`() {
val otherName = "Someone" val otherName = "Other"
val youContent = RoomMembershipContent(A_USER_ID, MembershipChange.KNOCK_DENIED) val third = "Someone"
val someoneContent = RoomMembershipContent(UserId("@someone_else:domain"), MembershipChange.KNOCK_DENIED) val youContent = RoomMembershipContent(A_USER_ID, third, MembershipChange.KNOCK_DENIED)
val someoneContent = RoomMembershipContent(UserId("@someone_else:domain"), third, MembershipChange.KNOCK_DENIED)
val youDeniedKnockEvent = createRoomEvent(sentByYou = true, senderDisplayName = null, content = someoneContent) val youDeniedKnockEvent = createRoomEvent(sentByYou = true, senderDisplayName = null, content = someoneContent)
val youDeniedKnock = formatter.format(youDeniedKnockEvent, false) val youDeniedKnock = formatter.format(youDeniedKnockEvent, false)
assertThat(youDeniedKnock).isEqualTo("You rejected ${someoneContent.userId}'s request to join") assertThat(youDeniedKnock).isEqualTo("You rejected $third's request to join")
val someoneDeniedKnockEvent = createRoomEvent(sentByYou = false, senderDisplayName = otherName, content = someoneContent) val someoneDeniedKnockEvent = createRoomEvent(sentByYou = false, senderDisplayName = otherName, content = someoneContent)
val someoneDeniedKnock = formatter.format(someoneDeniedKnockEvent, false) val someoneDeniedKnock = formatter.format(someoneDeniedKnockEvent, false)
assertThat(someoneDeniedKnock).isEqualTo("$otherName rejected ${someoneContent.userId}'s request to join") assertThat(someoneDeniedKnock).isEqualTo("$otherName rejected $third's request to join")
val someoneDeniedYourKnockEvent = createRoomEvent(sentByYou = false, senderDisplayName = otherName, content = youContent) val someoneDeniedYourKnockEvent = createRoomEvent(sentByYou = false, senderDisplayName = otherName, content = youContent)
val someoneDeniedYourKnock = formatter.format(someoneDeniedYourKnockEvent, false) val someoneDeniedYourKnock = formatter.format(someoneDeniedYourKnockEvent, false)
@ -478,9 +485,9 @@ class DefaultRoomLastMessageFormatterTest {
@Test @Test
@Config(qualifiers = "en") @Config(qualifiers = "en")
fun `Membership change - None`() { fun `Membership change - None`() {
val otherName = "Someone" val otherName = "Other"
val youContent = RoomMembershipContent(A_USER_ID, MembershipChange.NONE) val youContent = RoomMembershipContent(A_USER_ID, null, MembershipChange.NONE)
val someoneContent = RoomMembershipContent(UserId("@someone_else:domain"), MembershipChange.NONE) val someoneContent = RoomMembershipContent(UserId("@someone_else:domain"), otherName, MembershipChange.NONE)
val youNoneRoomEvent = createRoomEvent(sentByYou = true, senderDisplayName = null, content = youContent) val youNoneRoomEvent = createRoomEvent(sentByYou = true, senderDisplayName = null, content = youContent)
val youNoneRoom = formatter.format(youNoneRoomEvent, false) val youNoneRoom = formatter.format(youNoneRoomEvent, false)
@ -497,7 +504,7 @@ class DefaultRoomLastMessageFormatterTest {
val otherChanges = arrayOf(MembershipChange.ERROR, MembershipChange.NOT_IMPLEMENTED, null) val otherChanges = arrayOf(MembershipChange.ERROR, MembershipChange.NOT_IMPLEMENTED, null)
val results = otherChanges.map { change -> val results = otherChanges.map { change ->
val content = RoomMembershipContent(A_USER_ID, change) val content = RoomMembershipContent(A_USER_ID, null, change)
val event = createRoomEvent(sentByYou = false, senderDisplayName = "Someone", content = content) val event = createRoomEvent(sentByYou = false, senderDisplayName = "Someone", content = content)
val result = formatter.format(event, false) val result = formatter.format(event, false)
change to result change to result
@ -513,7 +520,7 @@ class DefaultRoomLastMessageFormatterTest {
@Test @Test
@Config(qualifiers = "en") @Config(qualifiers = "en")
fun `Room state change - avatar`() { fun `Room state change - avatar`() {
val otherName = "Someone" val otherName = "Other"
val changedContent = StateContent("", OtherState.RoomAvatar("new_avatar")) val changedContent = StateContent("", OtherState.RoomAvatar("new_avatar"))
val removedContent = StateContent("", OtherState.RoomAvatar(null)) val removedContent = StateContent("", OtherState.RoomAvatar(null))
@ -537,7 +544,7 @@ class DefaultRoomLastMessageFormatterTest {
@Test @Test
@Config(qualifiers = "en") @Config(qualifiers = "en")
fun `Room state change - create`() { fun `Room state change - create`() {
val otherName = "Someone" val otherName = "Other"
val content = StateContent("", OtherState.RoomCreate) val content = StateContent("", OtherState.RoomCreate)
val youCreatedRoomMessage = createRoomEvent(sentByYou = true, senderDisplayName = null, content = content) val youCreatedRoomMessage = createRoomEvent(sentByYou = true, senderDisplayName = null, content = content)
@ -552,7 +559,7 @@ class DefaultRoomLastMessageFormatterTest {
@Test @Test
@Config(qualifiers = "en") @Config(qualifiers = "en")
fun `Room state change - encryption`() { fun `Room state change - encryption`() {
val otherName = "Someone" val otherName = "Other"
val content = StateContent("", OtherState.RoomEncryption) val content = StateContent("", OtherState.RoomEncryption)
val youCreatedRoomMessage = createRoomEvent(sentByYou = true, senderDisplayName = null, content = content) val youCreatedRoomMessage = createRoomEvent(sentByYou = true, senderDisplayName = null, content = content)
@ -567,7 +574,7 @@ class DefaultRoomLastMessageFormatterTest {
@Test @Test
@Config(qualifiers = "en") @Config(qualifiers = "en")
fun `Room state change - room name`() { fun `Room state change - room name`() {
val otherName = "Someone" val otherName = "Other"
val newName = "New name" val newName = "New name"
val changedContent = StateContent("", OtherState.RoomName(newName)) val changedContent = StateContent("", OtherState.RoomName(newName))
val removedContent = StateContent("", OtherState.RoomName(null)) val removedContent = StateContent("", OtherState.RoomName(null))
@ -592,7 +599,7 @@ class DefaultRoomLastMessageFormatterTest {
@Test @Test
@Config(qualifiers = "en") @Config(qualifiers = "en")
fun `Room state change - third party invite`() { fun `Room state change - third party invite`() {
val otherName = "Someone" val otherName = "Other"
val inviteeName = "Alice" val inviteeName = "Alice"
val changedContent = StateContent("", OtherState.RoomThirdPartyInvite(inviteeName)) val changedContent = StateContent("", OtherState.RoomThirdPartyInvite(inviteeName))
val removedContent = StateContent("", OtherState.RoomThirdPartyInvite(null)) val removedContent = StateContent("", OtherState.RoomThirdPartyInvite(null))
@ -617,7 +624,7 @@ class DefaultRoomLastMessageFormatterTest {
@Test @Test
@Config(qualifiers = "en") @Config(qualifiers = "en")
fun `Room state change - room topic`() { fun `Room state change - room topic`() {
val otherName = "Someone" val otherName = "Other"
val roomTopic = "New topic" val roomTopic = "New topic"
val changedContent = StateContent("", OtherState.RoomTopic(roomTopic)) val changedContent = StateContent("", OtherState.RoomTopic(roomTopic))
val removedContent = StateContent("", OtherState.RoomTopic(null)) val removedContent = StateContent("", OtherState.RoomTopic(null))
@ -677,7 +684,7 @@ class DefaultRoomLastMessageFormatterTest {
@Test @Test
@Config(qualifiers = "en") @Config(qualifiers = "en")
fun `Profile change - avatar`() { fun `Profile change - avatar`() {
val otherName = "Someone" val otherName = "Other"
val changedContent = aProfileChangeMessageContent(avatarUrl = "new_avatar_url", prevAvatarUrl = "old_avatar_url") val changedContent = aProfileChangeMessageContent(avatarUrl = "new_avatar_url", prevAvatarUrl = "old_avatar_url")
val setContent = aProfileChangeMessageContent(avatarUrl = "new_avatar_url", prevAvatarUrl = null) val setContent = aProfileChangeMessageContent(avatarUrl = "new_avatar_url", prevAvatarUrl = null)
val removedContent = aProfileChangeMessageContent(avatarUrl = null, prevAvatarUrl = "old_avatar_url") val removedContent = aProfileChangeMessageContent(avatarUrl = null, prevAvatarUrl = "old_avatar_url")
@ -722,7 +729,7 @@ class DefaultRoomLastMessageFormatterTest {
fun `Profile change - display name`() { fun `Profile change - display name`() {
val newDisplayName = "New" val newDisplayName = "New"
val oldDisplayName = "Old" val oldDisplayName = "Old"
val otherName = "Someone" val otherName = "Other"
val changedContent = aProfileChangeMessageContent(displayName = newDisplayName, prevDisplayName = oldDisplayName) val changedContent = aProfileChangeMessageContent(displayName = newDisplayName, prevDisplayName = oldDisplayName)
val setContent = aProfileChangeMessageContent(displayName = newDisplayName, prevDisplayName = null) val setContent = aProfileChangeMessageContent(displayName = newDisplayName, prevDisplayName = null)
val removedContent = aProfileChangeMessageContent(displayName = null, prevDisplayName = oldDisplayName) val removedContent = aProfileChangeMessageContent(displayName = null, prevDisplayName = oldDisplayName)

1
libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/item/event/EventContent.kt

@ -73,6 +73,7 @@ data class UnableToDecryptContent(
data class RoomMembershipContent( data class RoomMembershipContent(
val userId: UserId, val userId: UserId,
val userDisplayName: String?,
val change: MembershipChange? val change: MembershipChange?
) : EventContent ) : EventContent

5
libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/item/event/TimelineEventContentMapper.kt

@ -88,8 +88,9 @@ class TimelineEventContentMapper(private val eventMessageMapper: EventMessageMap
} }
is TimelineItemContentKind.RoomMembership -> { is TimelineItemContentKind.RoomMembership -> {
RoomMembershipContent( RoomMembershipContent(
UserId(kind.userId), userId = UserId(kind.userId),
kind.change?.map() userDisplayName = kind.userDisplayName,
change = kind.change?.map()
) )
} }
is TimelineItemContentKind.State -> { is TimelineItemContentKind.State -> {

16
libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/timeline/postprocessor/RoomBeginningPostProcessorTest.kt

@ -34,7 +34,7 @@ class RoomBeginningPostProcessorTest {
fun `processor removes 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(
MatrixTimelineItem.Event("m.room.create", anEventTimelineItem(sender = A_USER_ID, content = StateContent("", OtherState.RoomCreate))), 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))), MatrixTimelineItem.Event("m.room.member", anEventTimelineItem(content = RoomMembershipContent(A_USER_ID, null, MembershipChange.JOINED))),
) )
val processor = RoomBeginningPostProcessor() val processor = RoomBeginningPostProcessor()
val processedItems = processor.process(timelineItems, isDm = true, hasMoreToLoadBackwards = false) val processedItems = processor.process(timelineItems, isDm = true, hasMoreToLoadBackwards = false)
@ -44,13 +44,13 @@ class RoomBeginningPostProcessorTest {
@Test @Test
fun `processor removes room creation event and self-join event from DM timeline even if they're not the first items`() { fun `processor removes room creation event and self-join event from DM timeline even if they're not the first items`() {
val timelineItems = listOf( val timelineItems = listOf(
MatrixTimelineItem.Event("m.room.member_other", anEventTimelineItem(content = RoomMembershipContent(A_USER_ID_2, MembershipChange.JOINED))), MatrixTimelineItem.Event("m.room.member_other", anEventTimelineItem(content = RoomMembershipContent(A_USER_ID_2, null, MembershipChange.JOINED))),
MatrixTimelineItem.Event("m.room.create", anEventTimelineItem(sender = A_USER_ID, content = StateContent("", OtherState.RoomCreate))), 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.message", anEventTimelineItem(content = aMessageContent("hi"))),
MatrixTimelineItem.Event("m.room.member", anEventTimelineItem(content = RoomMembershipContent(A_USER_ID, MembershipChange.JOINED))), MatrixTimelineItem.Event("m.room.member", anEventTimelineItem(content = RoomMembershipContent(A_USER_ID, null, MembershipChange.JOINED))),
) )
val expected = listOf( val expected = listOf(
MatrixTimelineItem.Event("m.room.member_other", anEventTimelineItem(content = RoomMembershipContent(A_USER_ID_2, MembershipChange.JOINED))), MatrixTimelineItem.Event("m.room.member_other", anEventTimelineItem(content = RoomMembershipContent(A_USER_ID_2, null, MembershipChange.JOINED))),
MatrixTimelineItem.Event("m.room.message", anEventTimelineItem(content = aMessageContent("hi"))), MatrixTimelineItem.Event("m.room.message", anEventTimelineItem(content = aMessageContent("hi"))),
) )
val processor = RoomBeginningPostProcessor() val processor = RoomBeginningPostProcessor()
@ -62,7 +62,7 @@ class RoomBeginningPostProcessorTest {
fun `processor will add beginning of room item if it's not a DM`() { fun `processor will add beginning of room item if it's not a DM`() {
val timelineItems = listOf( val timelineItems = listOf(
MatrixTimelineItem.Event("m.room.create", anEventTimelineItem(sender = A_USER_ID, content = StateContent("", OtherState.RoomCreate))), 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))), MatrixTimelineItem.Event("m.room.member", anEventTimelineItem(content = RoomMembershipContent(A_USER_ID, null, MembershipChange.JOINED))),
) )
val processor = RoomBeginningPostProcessor() val processor = RoomBeginningPostProcessor()
val processedItems = processor.process(timelineItems, isDm = false, hasMoreToLoadBackwards = false) val processedItems = processor.process(timelineItems, isDm = false, hasMoreToLoadBackwards = false)
@ -85,7 +85,7 @@ class RoomBeginningPostProcessorTest {
fun `processor won't remove items if it's not at the start of the timeline`() { fun `processor won't remove items if it's not at the start of the timeline`() {
val timelineItems = listOf( val timelineItems = listOf(
MatrixTimelineItem.Event("m.room.create", anEventTimelineItem(sender = A_USER_ID, content = StateContent("", OtherState.RoomCreate))), 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))), MatrixTimelineItem.Event("m.room.member", anEventTimelineItem(content = RoomMembershipContent(A_USER_ID, null, MembershipChange.JOINED))),
) )
val processor = RoomBeginningPostProcessor() val processor = RoomBeginningPostProcessor()
val processedItems = processor.process(timelineItems, isDm = true, hasMoreToLoadBackwards = true) val processedItems = processor.process(timelineItems, isDm = true, hasMoreToLoadBackwards = true)
@ -95,7 +95,7 @@ class RoomBeginningPostProcessorTest {
@Test @Test
fun `processor won't remove the first member join event if it can't find the room creation event`() { fun `processor won't remove the first member join event if it can't find the room creation event`() {
val timelineItems = listOf( val timelineItems = listOf(
MatrixTimelineItem.Event("m.room.member", anEventTimelineItem(content = RoomMembershipContent(A_USER_ID, MembershipChange.JOINED))), MatrixTimelineItem.Event("m.room.member", anEventTimelineItem(content = RoomMembershipContent(A_USER_ID, null, MembershipChange.JOINED))),
) )
val processor = RoomBeginningPostProcessor() val processor = RoomBeginningPostProcessor()
val processedItems = processor.process(timelineItems, isDm = true, hasMoreToLoadBackwards = true) val processedItems = processor.process(timelineItems, isDm = true, hasMoreToLoadBackwards = true)
@ -106,7 +106,7 @@ class RoomBeginningPostProcessorTest {
fun `processor won't remove the first member join event if it's not from the room creator`() { fun `processor won't remove the first member join event if it's not from the room creator`() {
val timelineItems = listOf( val timelineItems = listOf(
MatrixTimelineItem.Event("m.room.create", anEventTimelineItem(sender = A_USER_ID, content = StateContent("", OtherState.RoomCreate))), 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))), MatrixTimelineItem.Event("m.room.member", anEventTimelineItem(content = RoomMembershipContent(A_USER_ID_2, null, MembershipChange.JOINED))),
) )
val processor = RoomBeginningPostProcessor() val processor = RoomBeginningPostProcessor()
val processedItems = processor.process(timelineItems, isDm = true, hasMoreToLoadBackwards = true) val processedItems = processor.process(timelineItems, isDm = true, hasMoreToLoadBackwards = true)

Loading…
Cancel
Save