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 <benoitm+elementbot@element.io>
This commit is contained in:
parent
75a6af068c
commit
bb47ff8f49
47 changed files with 195 additions and 73 deletions
|
|
@ -33,6 +33,7 @@ data class NotificationData(
|
|||
val roomAvatarUrl: String?,
|
||||
val roomDisplayName: String?,
|
||||
val isDirect: Boolean,
|
||||
val isDm: Boolean,
|
||||
val isEncrypted: Boolean,
|
||||
val isNoisy: Boolean,
|
||||
val timestamp: Long,
|
||||
|
|
|
|||
|
|
@ -57,9 +57,6 @@ interface MatrixRoom : Closeable {
|
|||
val activeMemberCount: Long
|
||||
val joinedMemberCount: Long
|
||||
|
||||
/** Whether the room is a direct message. */
|
||||
val isDm: Boolean get() = isDirect && isOneToOne
|
||||
|
||||
val roomInfoFlow: Flow<MatrixRoomInfo>
|
||||
val roomTypingMembersFlow: Flow<List<UserId>>
|
||||
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
|
@ -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(),
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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(),
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ fun aNotificationData(
|
|||
roomAvatarUrl = null,
|
||||
roomDisplayName = null,
|
||||
isDirect = false,
|
||||
isDm = false,
|
||||
isEncrypted = false,
|
||||
isNoisy = false,
|
||||
timestamp = 0L,
|
||||
|
|
|
|||
|
|
@ -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(),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue