From 0be7058416af8fda694acdcb67242e5bb23c9ed4 Mon Sep 17 00:00:00 2001 From: Jorge Martin Espinosa Date: Wed, 10 Jul 2024 18:28:46 +0200 Subject: [PATCH] Unify the way we decide whether a room is a DM or a group room (#3100) * Add centralised 'room is DM' check Also add extension functions for `MatrixRoom` and `MatrixRoomInfo`. * Use the centralised method and extension functions through the app, including: - Room list. - Room details screen. - Invites. - Notifications. Replace most `isDirect` usages with `isDm`. * Update screenshots --------- Co-authored-by: ElementBot --- .../AcceptDeclineInviteStateProvider.kt | 4 +- .../invite/api/response/InviteData.kt | 2 +- .../impl/response/AcceptDeclineInviteView.kt | 4 +- .../AcceptDeclineInvitePresenterTest.kt | 4 +- .../joinroom/impl/JoinRoomPresenter.kt | 9 +-- .../features/joinroom/impl/JoinRoomState.kt | 2 +- .../joinroom/impl/JoinRoomStateProvider.kt | 11 +++- .../joinroom/impl/JoinRoomPresenterTest.kt | 6 +- .../impl/DefaultLeaveRoomPresenter.kt | 1 + .../impl/DefaultLeaveRoomPresenterTest.kt | 2 +- .../messages/impl/MessagesPresenter.kt | 3 +- .../MessageComposerPresenter.kt | 1 + .../impl/timeline/TimelinePresenter.kt | 1 + .../MessageComposerPresenterTest.kt | 4 +- .../roomdetails/impl/RoomDetailsPresenter.kt | 1 + .../DefaultRoomMembersModerationPresenter.kt | 4 +- ...faultRoomMembersModerationPresenterTest.kt | 6 +- .../roomlist/impl/RoomListPresenter.kt | 2 +- .../impl/components/RoomSummaryRow.kt | 8 +-- .../datasource/RoomListRoomSummaryFactory.kt | 2 +- .../impl/model/RoomListRoomSummaryProvider.kt | 2 +- .../api/notification/NotificationData.kt | 1 + .../libraries/matrix/api/room/MatrixRoom.kt | 3 - .../matrix/api/room/RoomIsDmCheck.kt | 38 ++++++++++++ .../api/room/recent/RecentDirectRoom.kt | 1 + .../matrix/api/room/RoomIsDmCheckTest.kt | 62 +++++++++++++++++++ .../impl/notification/NotificationMapper.kt | 8 ++- .../matrix/impl/roomlist/RoomListFilter.kt | 4 +- .../roomlist/RoomSummaryDetailsFactory.kt | 3 +- .../matrix/impl/timeline/RustTimeline.kt | 1 + .../impl/roomlist/RoomListFilterTest.kt | 10 +-- .../test/notification/NotificationData.kt | 1 + .../matrix/test/room/FakeMatrixRoom.kt | 1 - .../CallNotificationEventResolver.kt | 2 +- .../DefaultNotifiableEventResolver.kt | 10 +-- .../NotificationBroadcastReceiverHandler.kt | 3 +- .../notifications/NotificationDataFactory.kt | 12 ++-- .../impl/notifications/RoomEventGroupInfo.kt | 2 +- .../notifications/RoomGroupMessageCreator.kt | 5 +- .../factories/NotificationCreator.kt | 2 +- .../model/NotifiableMessageEvent.kt | 2 +- .../DefaultNotifiableEventResolverTest.kt | 5 +- .../DefaultRoomGroupMessageCreatorTest.kt | 4 +- .../DefaultNotificationCreatorTest.kt | 2 - .../fixtures/NotifiableEventFixture.kt | 1 - ...s.joinroom.impl_JoinRoomView_Day_10_en.png | 3 + ...joinroom.impl_JoinRoomView_Night_10_en.png | 3 + 47 files changed, 195 insertions(+), 73 deletions(-) create mode 100644 libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/RoomIsDmCheck.kt create mode 100644 libraries/matrix/api/src/test/kotlin/io/element/android/libraries/matrix/api/room/RoomIsDmCheckTest.kt create mode 100644 tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Day_10_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Night_10_en.png diff --git a/features/invite/api/src/main/kotlin/io/element/android/features/invite/api/response/AcceptDeclineInviteStateProvider.kt b/features/invite/api/src/main/kotlin/io/element/android/features/invite/api/response/AcceptDeclineInviteStateProvider.kt index af2c37e68f..ec262a7506 100644 --- a/features/invite/api/src/main/kotlin/io/element/android/features/invite/api/response/AcceptDeclineInviteStateProvider.kt +++ b/features/invite/api/src/main/kotlin/io/element/android/features/invite/api/response/AcceptDeclineInviteStateProvider.kt @@ -27,13 +27,13 @@ open class AcceptDeclineInviteStateProvider : PreviewParameterProvider Unit, modifier: Modifier = Modifier ) { - val contentResource = if (invite.isDirect) { + val contentResource = if (invite.isDm) { R.string.screen_invites_decline_direct_chat_message } else { R.string.screen_invites_decline_chat_message } - val titleResource = if (invite.isDirect) { + val titleResource = if (invite.isDm) { R.string.screen_invites_decline_direct_chat_title } else { R.string.screen_invites_decline_chat_title diff --git a/features/invite/impl/src/test/kotlin/io/element/android/features/invite/impl/response/AcceptDeclineInvitePresenterTest.kt b/features/invite/impl/src/test/kotlin/io/element/android/features/invite/impl/response/AcceptDeclineInvitePresenterTest.kt index 672c5b58ee..faa1388fea 100644 --- a/features/invite/impl/src/test/kotlin/io/element/android/features/invite/impl/response/AcceptDeclineInvitePresenterTest.kt +++ b/features/invite/impl/src/test/kotlin/io/element/android/features/invite/impl/response/AcceptDeclineInvitePresenterTest.kt @@ -260,12 +260,12 @@ class AcceptDeclineInvitePresenterTest { private fun anInviteData( roomId: RoomId = A_ROOM_ID, name: String = A_ROOM_NAME, - isDirect: Boolean = false + isDm: Boolean = false ): InviteData { return InviteData( roomId = roomId, roomName = name, - isDirect = isDirect + isDm = isDm ) } diff --git a/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomPresenter.kt b/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomPresenter.kt index 5f1efe827e..bba2a82a34 100644 --- a/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomPresenter.kt +++ b/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomPresenter.kt @@ -45,6 +45,7 @@ import io.element.android.libraries.matrix.api.core.RoomIdOrAlias import io.element.android.libraries.matrix.api.room.CurrentUserMembership import io.element.android.libraries.matrix.api.room.MatrixRoomInfo import io.element.android.libraries.matrix.api.room.RoomType +import io.element.android.libraries.matrix.api.room.isDm import io.element.android.libraries.matrix.api.room.join.JoinRoom import io.element.android.libraries.matrix.api.room.preview.RoomPreview import io.element.android.libraries.matrix.ui.model.toInviteSender @@ -173,7 +174,7 @@ private fun RoomPreview.toContentState(): ContentState { topic = topic, alias = canonicalAlias, numberOfMembers = numberOfJoinedMembers, - isDirect = false, + isDm = false, roomType = roomType, roomAvatarUrl = avatarUrl, joinAuthorisationStatus = when { @@ -194,7 +195,7 @@ internal fun RoomDescription.toContentState(): ContentState { topic = topic, alias = alias, numberOfMembers = numberOfMembers, - isDirect = false, + isDm = false, roomType = RoomType.Room, roomAvatarUrl = avatarUrl, joinAuthorisationStatus = when (joinRule) { @@ -213,7 +214,7 @@ internal fun MatrixRoomInfo.toContentState(): ContentState { topic = topic, alias = canonicalAlias, numberOfMembers = activeMembersCount, - isDirect = isDirect, + isDm = isDm, roomType = if (isSpace) RoomType.Space else RoomType.Room, roomAvatarUrl = avatarUrl, joinAuthorisationStatus = when { @@ -233,7 +234,7 @@ internal fun ContentState.toInviteData(): InviteData? { roomId = roomId, // Note: name should not be null at this point, but use Id just in case... roomName = name ?: roomId.value, - isDirect = isDirect + isDm = isDm ) else -> null } diff --git a/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomState.kt b/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomState.kt index 905d5dd2d1..ab66d0d80c 100644 --- a/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomState.kt +++ b/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomState.kt @@ -53,7 +53,7 @@ sealed interface ContentState { val topic: String?, val alias: RoomAlias?, val numberOfMembers: Long?, - val isDirect: Boolean, + val isDm: Boolean, val roomType: RoomType, val roomAvatarUrl: String?, val joinAuthorisationStatus: JoinAuthorisationStatus, diff --git a/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomStateProvider.kt b/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomStateProvider.kt index f897026600..8da0573b51 100644 --- a/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomStateProvider.kt +++ b/features/joinroom/impl/src/main/kotlin/io/element/android/features/joinroom/impl/JoinRoomStateProvider.kt @@ -28,6 +28,7 @@ import io.element.android.libraries.matrix.api.core.RoomIdOrAlias import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.core.toRoomIdOrAlias import io.element.android.libraries.matrix.api.room.RoomType +import io.element.android.libraries.matrix.api.room.isDm import io.element.android.libraries.matrix.ui.model.InviteSender open class JoinRoomStateProvider : PreviewParameterProvider { @@ -84,6 +85,12 @@ open class JoinRoomStateProvider : PreviewParameterProvider { roomType = RoomType.Space, ) ), + aJoinRoomState( + contentState = aLoadedContentState( + name = "A DM", + isDm = true, + ) + ), ) } @@ -106,7 +113,7 @@ fun aLoadedContentState( alias: RoomAlias? = RoomAlias("#exa:matrix.org"), topic: String? = "Element X is a secure, private and decentralized messenger.", numberOfMembers: Long? = null, - isDirect: Boolean = false, + isDm: Boolean = false, roomType: RoomType = RoomType.Room, roomAvatarUrl: String? = null, joinAuthorisationStatus: JoinAuthorisationStatus = JoinAuthorisationStatus.Unknown @@ -116,7 +123,7 @@ fun aLoadedContentState( alias = alias, topic = topic, numberOfMembers = numberOfMembers, - isDirect = isDirect, + isDm = isDm, roomType = roomType, roomAvatarUrl = roomAvatarUrl, joinAuthorisationStatus = joinAuthorisationStatus diff --git a/features/joinroom/impl/src/test/kotlin/io/element/android/features/joinroom/impl/JoinRoomPresenterTest.kt b/features/joinroom/impl/src/test/kotlin/io/element/android/features/joinroom/impl/JoinRoomPresenterTest.kt index 2a054b820f..7a6e08244c 100644 --- a/features/joinroom/impl/src/test/kotlin/io/element/android/features/joinroom/impl/JoinRoomPresenterTest.kt +++ b/features/joinroom/impl/src/test/kotlin/io/element/android/features/joinroom/impl/JoinRoomPresenterTest.kt @@ -93,7 +93,7 @@ class JoinRoomPresenterTest { assertThat(contentState.topic).isEqualTo(roomInfo.topic) assertThat(contentState.alias).isEqualTo(roomInfo.canonicalAlias) assertThat(contentState.numberOfMembers).isEqualTo(roomInfo.activeMembersCount) - assertThat(contentState.isDirect).isEqualTo(roomInfo.isDirect) + assertThat(contentState.isDm).isEqualTo(roomInfo.isDirect) assertThat(contentState.roomAvatarUrl).isEqualTo(roomInfo.avatarUrl) } } @@ -283,7 +283,7 @@ class JoinRoomPresenterTest { assertThat(contentState.topic).isEqualTo(roomDescription.topic) assertThat(contentState.alias).isEqualTo(roomDescription.alias) assertThat(contentState.numberOfMembers).isEqualTo(roomDescription.numberOfMembers) - assertThat(contentState.isDirect).isFalse() + assertThat(contentState.isDm).isFalse() assertThat(contentState.roomAvatarUrl).isEqualTo(roomDescription.avatarUrl) } } @@ -398,7 +398,7 @@ class JoinRoomPresenterTest { topic = "Room topic", alias = RoomAlias("#alias:matrix.org"), numberOfMembers = 2, - isDirect = false, + isDm = false, roomType = RoomType.Room, roomAvatarUrl = "avatarUrl", joinAuthorisationStatus = JoinAuthorisationStatus.CanJoin diff --git a/features/leaveroom/impl/src/main/kotlin/io/element/android/features/leaveroom/impl/DefaultLeaveRoomPresenter.kt b/features/leaveroom/impl/src/main/kotlin/io/element/android/features/leaveroom/impl/DefaultLeaveRoomPresenter.kt index c949a5f446..4b121073a0 100644 --- a/features/leaveroom/impl/src/main/kotlin/io/element/android/features/leaveroom/impl/DefaultLeaveRoomPresenter.kt +++ b/features/leaveroom/impl/src/main/kotlin/io/element/android/features/leaveroom/impl/DefaultLeaveRoomPresenter.kt @@ -34,6 +34,7 @@ import io.element.android.libraries.di.SessionScope import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.room.RoomMembershipObserver +import io.element.android.libraries.matrix.api.room.isDm import kotlinx.coroutines.launch import timber.log.Timber import javax.inject.Inject diff --git a/features/leaveroom/impl/src/test/kotlin/io/element/android/features/leaveroom/impl/DefaultLeaveRoomPresenterTest.kt b/features/leaveroom/impl/src/test/kotlin/io/element/android/features/leaveroom/impl/DefaultLeaveRoomPresenterTest.kt index 9962a3bd32..49b44851de 100644 --- a/features/leaveroom/impl/src/test/kotlin/io/element/android/features/leaveroom/impl/DefaultLeaveRoomPresenterTest.kt +++ b/features/leaveroom/impl/src/test/kotlin/io/element/android/features/leaveroom/impl/DefaultLeaveRoomPresenterTest.kt @@ -119,7 +119,7 @@ class DefaultLeaveRoomPresenterTest { client = FakeMatrixClient().apply { givenGetRoomResult( roomId = A_ROOM_ID, - result = FakeMatrixRoom(activeMemberCount = 2, isDirect = true, isOneToOne = true), + result = FakeMatrixRoom(activeMemberCount = 2, isDirect = true), ) } ) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesPresenter.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesPresenter.kt index fc8a8c3975..b13a95d4f2 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesPresenter.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesPresenter.kt @@ -72,6 +72,7 @@ import io.element.android.libraries.matrix.api.room.MatrixRoom import io.element.android.libraries.matrix.api.room.MatrixRoomInfo import io.element.android.libraries.matrix.api.room.MatrixRoomMembersState import io.element.android.libraries.matrix.api.room.MessageEventType +import io.element.android.libraries.matrix.api.room.isDm import io.element.android.libraries.matrix.ui.messages.reply.map import io.element.android.libraries.matrix.ui.model.getAvatarData import io.element.android.libraries.matrix.ui.room.canCall @@ -162,7 +163,7 @@ class MessagesPresenter @AssistedInject constructor( var showReinvitePrompt by remember { mutableStateOf(false) } LaunchedEffect(hasDismissedInviteDialog, composerState.textEditorState.hasFocus(), syncUpdateFlow.value) { withContext(dispatchers.io) { - showReinvitePrompt = !hasDismissedInviteDialog && composerState.textEditorState.hasFocus() && room.isDirect && room.activeMemberCount == 1L + showReinvitePrompt = !hasDismissedInviteDialog && composerState.textEditorState.hasFocus() && room.isDm && room.activeMemberCount == 1L } } val networkConnectionStatus by networkMonitor.connectivity.collectAsState() diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenter.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenter.kt index 9a80985bd0..85eacc38ae 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenter.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerPresenter.kt @@ -57,6 +57,7 @@ import io.element.android.libraries.matrix.api.room.MatrixRoom import io.element.android.libraries.matrix.api.room.Mention import io.element.android.libraries.matrix.api.room.draft.ComposerDraft import io.element.android.libraries.matrix.api.room.draft.ComposerDraftType +import io.element.android.libraries.matrix.api.room.isDm import io.element.android.libraries.matrix.ui.messages.reply.InReplyToDetails import io.element.android.libraries.matrix.ui.messages.reply.map import io.element.android.libraries.mediapickers.api.PickerProvider diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelinePresenter.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelinePresenter.kt index 81ef19e587..f5903f036b 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelinePresenter.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelinePresenter.kt @@ -42,6 +42,7 @@ import io.element.android.libraries.core.coroutine.CoroutineDispatchers import io.element.android.libraries.matrix.api.core.EventId import io.element.android.libraries.matrix.api.room.MatrixRoom import io.element.android.libraries.matrix.api.room.MessageEventType +import io.element.android.libraries.matrix.api.room.isDm import io.element.android.libraries.matrix.api.room.roomMembers import io.element.android.libraries.matrix.api.timeline.ReceiptType import io.element.android.libraries.matrix.api.timeline.item.event.TimelineItemEventOrigin diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/textcomposer/MessageComposerPresenterTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/textcomposer/MessageComposerPresenterTest.kt index c2d5966fd0..667d43b56e 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/textcomposer/MessageComposerPresenterTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/textcomposer/MessageComposerPresenterTest.kt @@ -839,7 +839,6 @@ class MessageComposerPresenterTest { val david = aRoomMember(userId = A_USER_ID_4, displayName = "Dave", membership = RoomMembershipState.JOIN) val room = FakeMatrixRoom( isDirect = false, - isOneToOne = false, ).apply { givenRoomMembersState( MatrixRoomMembersState.Ready( @@ -904,7 +903,8 @@ class MessageComposerPresenterTest { val david = aRoomMember(userId = A_USER_ID_4, displayName = "Dave", membership = RoomMembershipState.JOIN) val room = FakeMatrixRoom( isDirect = true, - isOneToOne = true, + activeMemberCount = 2, + isEncrypted = true, ).apply { givenRoomMembersState( MatrixRoomMembersState.Ready( diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsPresenter.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsPresenter.kt index 50fad866d9..163e466e1f 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsPresenter.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsPresenter.kt @@ -41,6 +41,7 @@ import io.element.android.libraries.matrix.api.room.MatrixRoom import io.element.android.libraries.matrix.api.room.MatrixRoomMembersState import io.element.android.libraries.matrix.api.room.RoomMember import io.element.android.libraries.matrix.api.room.StateEventType +import io.element.android.libraries.matrix.api.room.isDm import io.element.android.libraries.matrix.api.room.powerlevels.canInvite import io.element.android.libraries.matrix.api.room.powerlevels.canSendState import io.element.android.libraries.matrix.api.room.roomNotificationSettings diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/moderation/DefaultRoomMembersModerationPresenter.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/moderation/DefaultRoomMembersModerationPresenter.kt index f35aa1f211..326255effd 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/moderation/DefaultRoomMembersModerationPresenter.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/moderation/DefaultRoomMembersModerationPresenter.kt @@ -35,6 +35,7 @@ import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.room.MatrixRoom import io.element.android.libraries.matrix.api.room.RoomMember import io.element.android.libraries.matrix.api.room.RoomMembershipState +import io.element.android.libraries.matrix.api.room.isDm import io.element.android.libraries.matrix.api.room.powerlevels.canBan import io.element.android.libraries.matrix.api.room.powerlevels.canKick import io.element.android.services.analytics.api.AnalyticsService @@ -58,8 +59,7 @@ class DefaultRoomMembersModerationPresenter @Inject constructor( private suspend fun canKick() = room.canKick().getOrDefault(false) override suspend fun canDisplayModerationActions(): Boolean { - val isDm = room.isDm && room.isEncrypted - return !isDm && (canBan() || canKick()) + return !room.isDm && (canBan() || canKick()) } @Composable diff --git a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/members/moderation/DefaultRoomMembersModerationPresenterTest.kt b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/members/moderation/DefaultRoomMembersModerationPresenterTest.kt index 8909870669..ae789f8958 100644 --- a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/members/moderation/DefaultRoomMembersModerationPresenterTest.kt +++ b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/members/moderation/DefaultRoomMembersModerationPresenterTest.kt @@ -45,7 +45,7 @@ import org.junit.Test class DefaultRoomMembersModerationPresenterTest { @Test fun `canDisplayModerationActions - when room is DM is false`() = runTest { - val room = FakeMatrixRoom(isDirect = true, isPublic = true, isOneToOne = true).apply { + val room = FakeMatrixRoom(isDirect = true, isPublic = true, activeMemberCount = 2).apply { givenRoomInfo(aRoomInfo(isDirect = true, isPublic = false, activeMembersCount = 2)) } val presenter = createDefaultRoomMembersModerationPresenter(matrixRoom = room) @@ -54,7 +54,7 @@ class DefaultRoomMembersModerationPresenterTest { @Test fun `canDisplayModerationActions - when user can kick other users, FF is enabled and room is not a DM returns true`() = runTest { - val room = FakeMatrixRoom(isDirect = false, isOneToOne = false).apply { + val room = FakeMatrixRoom(isDirect = false, activeMemberCount = 10).apply { givenCanKickResult(Result.success(true)) } val presenter = createDefaultRoomMembersModerationPresenter(matrixRoom = room) @@ -63,7 +63,7 @@ class DefaultRoomMembersModerationPresenterTest { @Test fun `canDisplayModerationActions - when user can ban other users, FF is enabled and room is not a DM returns true`() = runTest { - val room = FakeMatrixRoom(isDirect = false, isOneToOne = false).apply { + val room = FakeMatrixRoom(isDirect = false, activeMemberCount = 10).apply { givenCanBanResult(Result.success(true)) } val presenter = createDefaultRoomMembersModerationPresenter(matrixRoom = room) diff --git a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListPresenter.kt b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListPresenter.kt index 8d838441e6..fc874c3a84 100644 --- a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListPresenter.kt +++ b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/RoomListPresenter.kt @@ -290,5 +290,5 @@ internal fun RoomListRoomSummary.toInviteData() = InviteData( roomId = roomId, // Note: `name` should not be null at this point, but just in case, fallback to the roomId roomName = name ?: roomId.value, - isDirect = isDirect, + isDm = isDm, ) diff --git a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/RoomSummaryRow.kt b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/RoomSummaryRow.kt index f7602faa16..f673998872 100644 --- a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/RoomSummaryRow.kt +++ b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/RoomSummaryRow.kt @@ -95,8 +95,8 @@ internal fun RoomSummaryRow( modifier = modifier ) { InviteNameAndIndicatorRow(name = room.name) - InviteSubtitle(isDirect = room.isDirect, inviteSender = room.inviteSender, canonicalAlias = room.canonicalAlias) - if (!room.isDirect && room.inviteSender != null) { + InviteSubtitle(isDm = room.isDm, inviteSender = room.inviteSender, canonicalAlias = room.canonicalAlias) + if (!room.isDm && room.inviteSender != null) { Spacer(modifier = Modifier.height(4.dp)) InviteSenderView( modifier = Modifier.fillMaxWidth(), @@ -206,12 +206,12 @@ private fun NameAndTimestampRow( @Composable private fun InviteSubtitle( - isDirect: Boolean, + isDm: Boolean, inviteSender: InviteSender?, canonicalAlias: RoomAlias?, modifier: Modifier = Modifier ) { - val subtitle = if (isDirect) { + val subtitle = if (isDm) { inviteSender?.userId?.value } else { canonicalAlias?.value diff --git a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/datasource/RoomListRoomSummaryFactory.kt b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/datasource/RoomListRoomSummaryFactory.kt index 3cde0908b4..153c7cf41d 100644 --- a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/datasource/RoomListRoomSummaryFactory.kt +++ b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/datasource/RoomListRoomSummaryFactory.kt @@ -45,7 +45,7 @@ class RoomListRoomSummaryFactory @Inject constructor( isMarkedUnread = details.isMarkedUnread, timestamp = lastMessageTimestampFormatter.format(details.lastMessageTimestamp), lastMessage = details.lastMessage?.let { message -> - roomLastMessageFormatter.format(message.event, details.isDirect) + roomLastMessageFormatter.format(message.event, details.isDm) }.orEmpty(), avatarData = avatarData, userDefinedNotificationMode = details.userDefinedNotificationMode, diff --git a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/model/RoomListRoomSummaryProvider.kt b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/model/RoomListRoomSummaryProvider.kt index 473c60049a..cf44be6090 100644 --- a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/model/RoomListRoomSummaryProvider.kt +++ b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/model/RoomListRoomSummaryProvider.kt @@ -101,7 +101,7 @@ open class RoomListRoomSummaryProvider : PreviewParameterProvider val roomTypingMembersFlow: Flow> diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/RoomIsDmCheck.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/RoomIsDmCheck.kt new file mode 100644 index 0000000000..1cc665ede9 --- /dev/null +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/RoomIsDmCheck.kt @@ -0,0 +1,38 @@ +/* + * 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.api.room + +/** + * Returns whether the room with the provided info is a DM. + * A DM is a room with at most 2 active members (one of them may have left). + * + * @param isDirect true if the room is direct + * @param activeMembersCount the number of active members in the room (joined or invited) + */ +fun isDm(isDirect: Boolean, activeMembersCount: Int): Boolean { + return isDirect && activeMembersCount <= 2 +} + +/** + * Returns whether the [MatrixRoom] is a DM. + */ +val MatrixRoom.isDm get() = isDm(isDirect, activeMemberCount.toInt()) + +/** + * Returns whether the [MatrixRoomInfo] is from a DM. + */ +val MatrixRoomInfo.isDm get() = isDm(isDirect, activeMembersCount.toInt()) diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/recent/RecentDirectRoom.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/recent/RecentDirectRoom.kt index c2fb147aa0..e97c903e07 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/recent/RecentDirectRoom.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/recent/RecentDirectRoom.kt @@ -21,6 +21,7 @@ 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.room.CurrentUserMembership import io.element.android.libraries.matrix.api.room.MatrixRoom +import io.element.android.libraries.matrix.api.room.isDm import io.element.android.libraries.matrix.api.room.toMatrixUser import io.element.android.libraries.matrix.api.user.MatrixUser import kotlinx.coroutines.flow.first diff --git a/libraries/matrix/api/src/test/kotlin/io/element/android/libraries/matrix/api/room/RoomIsDmCheckTest.kt b/libraries/matrix/api/src/test/kotlin/io/element/android/libraries/matrix/api/room/RoomIsDmCheckTest.kt new file mode 100644 index 0000000000..95b13e95af --- /dev/null +++ b/libraries/matrix/api/src/test/kotlin/io/element/android/libraries/matrix/api/room/RoomIsDmCheckTest.kt @@ -0,0 +1,62 @@ +/* + * 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.api.room + +import com.google.common.truth.Truth.assertThat +import org.junit.Test + +class RoomIsDmCheckTest { + @Test + fun `a room is a DM only if it has at most 2 members and is direct`() { + val isDirect = true + val activeMembersCount = 2 + + val isDm = isDm(isDirect, activeMembersCount) + + assertThat(isDm).isTrue() + } + + @Test + fun `a room can be a DM if it has also a single active user`() { + val isDirect = true + val activeMembersCount = 1 + + val isDm = isDm(isDirect, activeMembersCount) + + assertThat(isDm).isTrue() + } + + @Test + fun `a room is not a DM if it's not direct`() { + val isDirect = false + val activeMembersCount = 2 + + val isDm = isDm(isDirect, activeMembersCount) + + assertThat(isDm).isFalse() + } + + @Test + fun `a room is not a DM if it has more than 2 active users`() { + val isDirect = true + val activeMembersCount = 3 + + val isDm = isDm(isDirect, activeMembersCount) + + assertThat(isDm).isFalse() + } +} diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/notification/NotificationMapper.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/notification/NotificationMapper.kt index 4b7c08f9b4..48f79b5e93 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/notification/NotificationMapper.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/notification/NotificationMapper.kt @@ -23,6 +23,7 @@ import io.element.android.libraries.matrix.api.core.SessionId import io.element.android.libraries.matrix.api.notification.NotificationContent import io.element.android.libraries.matrix.api.notification.NotificationData import io.element.android.libraries.matrix.api.room.RoomMembershipState +import io.element.android.libraries.matrix.api.room.isDm import io.element.android.services.toolbox.api.systemclock.SystemClock import org.matrix.rustcomponents.sdk.NotificationEvent import org.matrix.rustcomponents.sdk.NotificationItem @@ -40,15 +41,20 @@ class NotificationMapper( notificationItem: NotificationItem ): NotificationData { return notificationItem.use { item -> + val isDm = isDm( + isDirect = item.roomInfo.isDirect, + activeMembersCount = item.roomInfo.joinedMembersCount.toInt(), + ) NotificationData( eventId = eventId, roomId = roomId, senderAvatarUrl = item.senderInfo.avatarUrl, senderDisplayName = item.senderInfo.displayName, senderIsNameAmbiguous = item.senderInfo.isNameAmbiguous, - roomAvatarUrl = item.roomInfo.avatarUrl ?: item.senderInfo.avatarUrl.takeIf { item.roomInfo.isDirect }, + roomAvatarUrl = item.roomInfo.avatarUrl ?: item.senderInfo.avatarUrl.takeIf { isDm }, roomDisplayName = item.roomInfo.displayName, isDirect = item.roomInfo.isDirect, + isDm = isDm, isEncrypted = item.roomInfo.isEncrypted.orFalse(), isNoisy = item.isNoisy.orFalse(), timestamp = item.timestamp() ?: clock.epochMillis(), diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListFilter.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListFilter.kt index bc66bb6b78..ac933443b1 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListFilter.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListFilter.kt @@ -26,10 +26,10 @@ val RoomListFilter.predicate is RoomListFilter.Any -> { _: RoomSummary -> true } RoomListFilter.None -> { _: RoomSummary -> false } RoomListFilter.Category.Group -> { roomSummary: RoomSummary -> - !roomSummary.isDirect && !roomSummary.isInvited() + !roomSummary.isDm && !roomSummary.isInvited() } RoomListFilter.Category.People -> { roomSummary: RoomSummary -> - roomSummary.isDirect && !roomSummary.isInvited() + roomSummary.isDm && !roomSummary.isInvited() } RoomListFilter.Favorite -> { roomSummary: RoomSummary -> roomSummary.isFavorite && !roomSummary.isInvited() diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryDetailsFactory.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryDetailsFactory.kt index 1361d74a3d..2528599343 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryDetailsFactory.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryDetailsFactory.kt @@ -18,6 +18,7 @@ package io.element.android.libraries.matrix.impl.roomlist import io.element.android.libraries.matrix.api.core.RoomAlias import io.element.android.libraries.matrix.api.core.RoomId +import io.element.android.libraries.matrix.api.room.isDm import io.element.android.libraries.matrix.api.roomlist.RoomSummary import io.element.android.libraries.matrix.impl.notificationsettings.RoomNotificationSettingsMapper import io.element.android.libraries.matrix.impl.room.elementHeroes @@ -47,7 +48,7 @@ class RoomSummaryDetailsFactory(private val roomMessageFactory: RoomMessageFacto inviter = roomInfo.inviter?.let(RoomMemberMapper::map), userDefinedNotificationMode = roomInfo.userDefinedNotificationMode?.let(RoomNotificationSettingsMapper::mapMode), hasRoomCall = roomInfo.hasRoomCall, - isDm = roomInfo.isDirect && roomInfo.activeMembersCount.toLong() == 2L, + isDm = isDm(isDirect = roomInfo.isDirect, activeMembersCount = roomInfo.activeMembersCount.toInt()), isFavorite = roomInfo.isFavourite, currentUserMembership = roomInfo.membership.map(), heroes = roomInfo.elementHeroes(), diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/RustTimeline.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/RustTimeline.kt index 443191a538..9cdb8d1366 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/RustTimeline.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/RustTimeline.kt @@ -28,6 +28,7 @@ import io.element.android.libraries.matrix.api.media.VideoInfo import io.element.android.libraries.matrix.api.poll.PollKind import io.element.android.libraries.matrix.api.room.MatrixRoom import io.element.android.libraries.matrix.api.room.Mention +import io.element.android.libraries.matrix.api.room.isDm import io.element.android.libraries.matrix.api.room.location.AssetType import io.element.android.libraries.matrix.api.timeline.MatrixTimelineItem import io.element.android.libraries.matrix.api.timeline.ReceiptType diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListFilterTest.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListFilterTest.kt index 5687cd0c14..beef6f4b2b 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListFilterTest.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListFilterTest.kt @@ -25,10 +25,10 @@ import org.junit.Test class RoomListFilterTest { private val regularRoom = aRoomSummary( - isDirect = false + isDm = false ) - private val directRoom = aRoomSummary( - isDirect = true + private val dmRoom = aRoomSummary( + isDm = true ) private val favoriteRoom = aRoomSummary( isFavorite = true @@ -48,7 +48,7 @@ class RoomListFilterTest { private val roomSummaries = listOf( regularRoom, - directRoom, + dmRoom, favoriteRoom, markedAsUnreadRoom, unreadNotificationRoom, @@ -71,7 +71,7 @@ class RoomListFilterTest { @Test fun `Room list filter people`() = runTest { val filter = RoomListFilter.Category.People - assertThat(roomSummaries.filter(filter)).containsExactly(directRoom) + assertThat(roomSummaries.filter(filter)).containsExactly(dmRoom) } @Test diff --git a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/notification/NotificationData.kt b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/notification/NotificationData.kt index 330db62274..b6827d13e5 100644 --- a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/notification/NotificationData.kt +++ b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/notification/NotificationData.kt @@ -34,6 +34,7 @@ fun aNotificationData( roomAvatarUrl = null, roomDisplayName = null, isDirect = false, + isDm = false, isEncrypted = false, isNoisy = false, timestamp = 0L, diff --git a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/FakeMatrixRoom.kt b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/FakeMatrixRoom.kt index 7b08b2ea63..849b8aa0a6 100644 --- a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/FakeMatrixRoom.kt +++ b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/FakeMatrixRoom.kt @@ -80,7 +80,6 @@ class FakeMatrixRoom( override val isPublic: Boolean = true, override val isSpace: Boolean = false, override val isDirect: Boolean = false, - override val isOneToOne: Boolean = false, override val joinedMemberCount: Long = 123L, override val activeMemberCount: Long = 234L, val notificationSettingsService: NotificationSettingsService = FakeNotificationSettingsService(), diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/CallNotificationEventResolver.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/CallNotificationEventResolver.kt index b14fcdeab3..1e50a25857 100644 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/CallNotificationEventResolver.kt +++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/CallNotificationEventResolver.kt @@ -79,7 +79,7 @@ class DefaultCallNotificationEventResolver @Inject constructor( senderDisambiguatedDisplayName = getDisambiguatedDisplayName(content.senderId), body = "☎️ ${stringProvider.getString(R.string.notification_incoming_call)}", roomName = roomDisplayName, - roomIsDirect = isDirect, + roomIsDm = isDm, roomAvatarPath = roomAvatarUrl, senderAvatarPath = senderAvatarUrl, type = EventType.CALL_NOTIFY, diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/DefaultNotifiableEventResolver.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/DefaultNotifiableEventResolver.kt index 30ede8f3d1..1e186b38a8 100644 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/DefaultNotifiableEventResolver.kt +++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/DefaultNotifiableEventResolver.kt @@ -120,7 +120,7 @@ class DefaultNotifiableEventResolver @Inject constructor( body = notificationBody, imageUriString = fetchImageIfPresent(client)?.toString(), roomName = roomDisplayName, - roomIsDirect = isDirect, + roomIsDm = isDm, roomAvatarPath = roomAvatarUrl, senderAvatarPath = senderAvatarUrl, ) @@ -168,7 +168,7 @@ class DefaultNotifiableEventResolver @Inject constructor( body = stringProvider.getString(CommonStrings.common_call_invite), imageUriString = fetchImageIfPresent(client)?.toString(), roomName = roomDisplayName, - roomIsDirect = isDirect, + roomIsDm = isDm, roomAvatarPath = roomAvatarUrl, senderAvatarPath = senderAvatarUrl, ) @@ -197,7 +197,7 @@ class DefaultNotifiableEventResolver @Inject constructor( body = stringProvider.getString(CommonStrings.common_poll_summary, content.question), imageUriString = null, roomName = roomDisplayName, - roomIsDirect = isDirect, + roomIsDm = isDm, roomAvatarPath = roomAvatarUrl, senderAvatarPath = senderAvatarUrl, ) @@ -330,7 +330,7 @@ internal fun buildNotifiableMessageEvent( imageUriString: String? = null, threadId: ThreadId? = null, roomName: String? = null, - roomIsDirect: Boolean = false, + roomIsDm: Boolean = false, roomAvatarPath: String? = null, senderAvatarPath: String? = null, soundName: String? = null, @@ -354,7 +354,7 @@ internal fun buildNotifiableMessageEvent( imageUriString = imageUriString, threadId = threadId, roomName = roomName, - roomIsDirect = roomIsDirect, + roomIsDm = roomIsDm, roomAvatarPath = roomAvatarPath, senderAvatarPath = senderAvatarPath, soundName = soundName, diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotificationBroadcastReceiverHandler.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotificationBroadcastReceiverHandler.kt index 5f32bd86ac..b1d26ce7ab 100644 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotificationBroadcastReceiverHandler.kt +++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotificationBroadcastReceiverHandler.kt @@ -25,6 +25,7 @@ import io.element.android.libraries.matrix.api.core.SessionId import io.element.android.libraries.matrix.api.core.ThreadId import io.element.android.libraries.matrix.api.core.asEventId import io.element.android.libraries.matrix.api.room.MatrixRoom +import io.element.android.libraries.matrix.api.room.isDm import io.element.android.libraries.matrix.api.timeline.ReceiptType import io.element.android.libraries.preferences.api.store.SessionPreferencesStoreFactory import io.element.android.libraries.push.api.notifications.NotificationDrawerManager @@ -160,7 +161,7 @@ class NotificationBroadcastReceiverHandler @Inject constructor( imageUriString = null, threadId = threadId, roomName = room.displayName, - roomIsDirect = room.isDirect, + roomIsDm = room.isDm, outGoingMessage = true, ) onNotifiableEventReceived.onNotifiableEventReceived(notifiableMessageEvent) diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotificationDataFactory.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotificationDataFactory.kt index a0b7e30218..2f0f90fc40 100644 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotificationDataFactory.kt +++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotificationDataFactory.kt @@ -79,7 +79,7 @@ class DefaultNotificationDataFactory @Inject constructor( .groupBy { it.roomId } return messagesToDisplay.map { (roomId, events) -> val roomName = events.lastOrNull()?.roomName ?: roomId.value - val isDirect = events.lastOrNull()?.roomIsDirect ?: false + val isDm = events.lastOrNull()?.roomIsDm ?: false val notification = roomGroupMessageCreator.createRoomMessage( currentUser = currentUser, events = events, @@ -90,7 +90,7 @@ class DefaultNotificationDataFactory @Inject constructor( RoomNotification( notification = notification, roomId = roomId, - summaryLine = createRoomMessagesGroupSummaryLine(events, roomName, isDirect), + summaryLine = createRoomMessagesGroupSummaryLine(events, roomName, isDm), messageCount = events.size, latestTimestamp = events.maxOf { it.timestamp }, shouldBing = events.any { it.noisy } @@ -167,9 +167,9 @@ class DefaultNotificationDataFactory @Inject constructor( } } - private fun createRoomMessagesGroupSummaryLine(events: List, roomName: String, roomIsDirect: Boolean): CharSequence { + private fun createRoomMessagesGroupSummaryLine(events: List, roomName: String, roomIsDm: Boolean): CharSequence { return when (events.size) { - 1 -> createFirstMessageSummaryLine(events.first(), roomName, roomIsDirect) + 1 -> createFirstMessageSummaryLine(events.first(), roomName, roomIsDm) else -> { stringProvider.getQuantityString( R.plurals.notification_compat_summary_line_for_room, @@ -181,8 +181,8 @@ class DefaultNotificationDataFactory @Inject constructor( } } - private fun createFirstMessageSummaryLine(event: NotifiableMessageEvent, roomName: String, roomIsDirect: Boolean): CharSequence { - return if (roomIsDirect) { + private fun createFirstMessageSummaryLine(event: NotifiableMessageEvent, roomName: String, roomIsDm: Boolean): CharSequence { + return if (roomIsDm) { buildSpannedString { event.senderDisambiguatedDisplayName?.let { inSpans(StyleSpan(Typeface.BOLD)) { diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/RoomEventGroupInfo.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/RoomEventGroupInfo.kt index 96a8b90f06..ffbbc7122b 100644 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/RoomEventGroupInfo.kt +++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/RoomEventGroupInfo.kt @@ -26,7 +26,7 @@ data class RoomEventGroupInfo( val sessionId: SessionId, val roomId: RoomId, val roomDisplayName: String, - val isDirect: Boolean = false, + val isDm: Boolean = false, // An event in the list has not yet been display val hasNewEvent: Boolean = false, // true if at least one on the not yet displayed event is noisy diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/RoomGroupMessageCreator.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/RoomGroupMessageCreator.kt index 9fcbf8c152..8b7e44096d 100644 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/RoomGroupMessageCreator.kt +++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/RoomGroupMessageCreator.kt @@ -56,7 +56,7 @@ class DefaultRoomGroupMessageCreator @Inject constructor( ): Notification { val lastKnownRoomEvent = events.last() val roomName = lastKnownRoomEvent.roomName ?: lastKnownRoomEvent.senderDisambiguatedDisplayName ?: "Room name (${roomId.value.take(8)}…)" - val roomIsGroup = !lastKnownRoomEvent.roomIsDirect + val roomIsGroup = !lastKnownRoomEvent.roomIsDm val tickerText = if (roomIsGroup) { stringProvider.getString(R.string.notification_ticker_text_group, roomName, events.last().senderDisambiguatedDisplayName, events.last().description) @@ -68,12 +68,13 @@ class DefaultRoomGroupMessageCreator @Inject constructor( val lastMessageTimestamp = events.last().timestamp val smartReplyErrors = events.filter { it.isSmartReplyError() } + val roomIsDm = !roomIsGroup return notificationCreator.createMessagesListNotification( RoomEventGroupInfo( sessionId = currentUser.userId, roomId = roomId, roomDisplayName = roomName, - isDirect = !roomIsGroup, + isDm = roomIsDm, hasSmartReplyError = smartReplyErrors.isNotEmpty(), shouldBing = events.any { it.noisy }, customSound = events.last().soundName, diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/factories/NotificationCreator.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/factories/NotificationCreator.kt index 67dbda63a4..c7a5eb40d6 100755 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/factories/NotificationCreator.kt +++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/factories/NotificationCreator.kt @@ -157,7 +157,7 @@ class DefaultNotificationCreator @Inject constructor( val messagingStyle = existingNotification?.let { MessagingStyle.extractMessagingStyleFromNotification(it) - } ?: messagingStyleFromCurrentUser(roomInfo.sessionId, currentUser, imageLoader, roomInfo.roomDisplayName, !roomInfo.isDirect) + } ?: messagingStyleFromCurrentUser(roomInfo.sessionId, currentUser, imageLoader, roomInfo.roomDisplayName, !roomInfo.isDm) messagingStyle.addMessagesFromEvents(events, imageLoader) diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/model/NotifiableMessageEvent.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/model/NotifiableMessageEvent.kt index 4f3dbf57b3..b90af3df94 100644 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/model/NotifiableMessageEvent.kt +++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/model/NotifiableMessageEvent.kt @@ -43,7 +43,7 @@ data class NotifiableMessageEvent( val imageUriString: String?, val threadId: ThreadId?, val roomName: String?, - val roomIsDirect: Boolean = false, + val roomIsDm: Boolean = false, val roomAvatarPath: String? = null, val senderAvatarPath: String? = null, val soundName: String? = null, diff --git a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/DefaultNotifiableEventResolverTest.kt b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/DefaultNotifiableEventResolverTest.kt index 6caaac207b..1f6c98e914 100644 --- a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/DefaultNotifiableEventResolverTest.kt +++ b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/DefaultNotifiableEventResolverTest.kt @@ -473,7 +473,6 @@ class DefaultNotifiableEventResolverTest { imageUriString = null, threadId = null, roomName = null, - roomIsDirect = false, roomAvatarPath = null, senderAvatarPath = null, soundName = null, @@ -544,7 +543,6 @@ class DefaultNotifiableEventResolverTest { roomId = A_ROOM_ID, threadId = null, roomName = null, - roomIsDirect = false, canBeReplaced = false, isRedacted = false, imageUriString = null, @@ -578,7 +576,6 @@ class DefaultNotifiableEventResolverTest { roomId = A_ROOM_ID, threadId = null, roomName = null, - roomIsDirect = false, canBeReplaced = false, isRedacted = false, imageUriString = null, @@ -686,6 +683,7 @@ class DefaultNotifiableEventResolverTest { timestamp = timestamp, content = content, hasMention = hasMention, + isDm = false, ) } @@ -704,7 +702,6 @@ class DefaultNotifiableEventResolverTest { imageUriString = null, threadId = null, roomName = null, - roomIsDirect = false, roomAvatarPath = null, senderAvatarPath = null, soundName = null, diff --git a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/DefaultRoomGroupMessageCreatorTest.kt b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/DefaultRoomGroupMessageCreatorTest.kt index 2b5b941292..a6bdb298c0 100644 --- a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/DefaultRoomGroupMessageCreatorTest.kt +++ b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/DefaultRoomGroupMessageCreatorTest.kt @@ -188,14 +188,14 @@ class DefaultRoomGroupMessageCreatorTest { } @Test - fun `test createRoomMessage for direct room`() = runTest { + fun `test createRoomMessage for DM`() = runTest { val sut = createRoomGroupMessageCreator() val fakeImageLoader = FakeImageLoader() val result = sut.createRoomMessage( currentUser = aMatrixUser(), events = listOf( aNotifiableMessageEvent(timestamp = A_TIMESTAMP).copy( - roomIsDirect = true, + roomIsDm = true, ), ), roomId = A_ROOM_ID, diff --git a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/factories/DefaultNotificationCreatorTest.kt b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/factories/DefaultNotificationCreatorTest.kt index 124c71adcf..176673450c 100644 --- a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/factories/DefaultNotificationCreatorTest.kt +++ b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/factories/DefaultNotificationCreatorTest.kt @@ -227,7 +227,6 @@ class DefaultNotificationCreatorTest { sessionId = A_SESSION_ID, roomId = A_ROOM_ID, roomDisplayName = "roomDisplayName", - isDirect = false, hasSmartReplyError = false, shouldBing = false, customSound = null, @@ -254,7 +253,6 @@ class DefaultNotificationCreatorTest { sessionId = A_SESSION_ID, roomId = A_ROOM_ID, roomDisplayName = "roomDisplayName", - isDirect = false, hasSmartReplyError = false, shouldBing = true, customSound = null, diff --git a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/fixtures/NotifiableEventFixture.kt b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/fixtures/NotifiableEventFixture.kt index fabe4bd353..f1228dd0ce 100644 --- a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/fixtures/NotifiableEventFixture.kt +++ b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/fixtures/NotifiableEventFixture.kt @@ -97,7 +97,6 @@ fun aNotifiableMessageEvent( roomId = roomId, threadId = threadId, roomName = "room-name", - roomIsDirect = false, canBeReplaced = false, isRedacted = isRedacted, imageUriString = null, diff --git a/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Day_10_en.png b/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Day_10_en.png new file mode 100644 index 0000000000..655bba1cb2 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Day_10_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fd2b534a026cb2c96c90f20eb0154b20672d4eae294c558804898cd927e93585 +size 106258 diff --git a/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Night_10_en.png b/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Night_10_en.png new file mode 100644 index 0000000000..02b54d0c29 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.joinroom.impl_JoinRoomView_Night_10_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:13ed33b9e0b040ac1052389728179014984dc765671384e2d7215377a19d8fcc +size 91575