Adapt to new DM definition changes in the SDK (#6748)
* Set `DmRoomDefinition.TwoPeople` in `ClientBuilder`. This applies the 'direct and with at most 2 non-service members' rule to what the SDK should consider a DM. * Map `RoomInfo.isDm` from the SDK * Map `NotificationData.isDm` from `NotificationInfo.roomInfo.isDm` * Remove `RoomIsDmCheck` file as its extension functions are now redundant. Move `Room.isDm` helper function to `BaseRoom`. * Map `isDm` in `SpaceRoom` from the SDK too * Replace `isDirect` with `isDm` where possible * Map `RoomMember.isServiceMember` from the SDK and use it to tell apart normal members of a room from service members (i.e. `RoomMembersState.getDirectRoomMember`)
This commit is contained in:
parent
5e5e0bbc6e
commit
11476c73cf
66 changed files with 115 additions and 232 deletions
|
|
@ -41,6 +41,7 @@ import org.matrix.rustcomponents.sdk.SlidingSyncVersion
|
|||
import org.matrix.rustcomponents.sdk.SlidingSyncVersionBuilder
|
||||
import org.matrix.rustcomponents.sdk.use
|
||||
import timber.log.Timber
|
||||
import uniffi.matrix_sdk_base.DmRoomDefinition
|
||||
import uniffi.matrix_sdk_base.MediaRetentionPolicy
|
||||
import uniffi.matrix_sdk_crypto.CollectStrategy
|
||||
import uniffi.matrix_sdk_crypto.DecryptionSettings
|
||||
|
|
@ -169,6 +170,7 @@ class RustMatrixClientFactory(
|
|||
)
|
||||
.enableShareHistoryOnInvite(true)
|
||||
.threadsEnabled(featureFlagService.isFeatureEnabled(FeatureFlags.Threads), threadSubscriptions = false)
|
||||
.dmRoomDefinition(DmRoomDefinition.TWO_MEMBERS)
|
||||
.requestConfig(
|
||||
RequestConfig(
|
||||
timeout = 30_000uL,
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ package io.element.android.libraries.matrix.impl.analytics
|
|||
import im.vector.app.features.analytics.plan.JoinedRoom
|
||||
import io.element.android.libraries.matrix.api.room.BaseRoom
|
||||
import io.element.android.libraries.matrix.api.room.RoomInfo
|
||||
import io.element.android.libraries.matrix.api.room.isDm
|
||||
import kotlinx.coroutines.flow.first
|
||||
|
||||
private fun Long.toAnalyticsRoomSize(): JoinedRoom.RoomSize {
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@ import io.element.android.libraries.matrix.api.core.ThreadId
|
|||
import io.element.android.libraries.matrix.api.core.UserId
|
||||
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.isDm
|
||||
import io.element.android.libraries.matrix.impl.room.join.map
|
||||
import io.element.android.services.toolbox.api.systemclock.SystemClock
|
||||
import org.matrix.rustcomponents.sdk.NotificationEvent
|
||||
|
|
@ -37,10 +36,6 @@ class NotificationMapper(
|
|||
): Result<NotificationData> {
|
||||
return runCatchingExceptions {
|
||||
notificationItem.use { item ->
|
||||
val isDm = isDm(
|
||||
isDirect = item.roomInfo.isDirect,
|
||||
activeMembersCount = item.roomInfo.joinedMembersCount.toInt(),
|
||||
)
|
||||
val timestamp = item.timestamp() ?: clock.epochMillis()
|
||||
NotificationData(
|
||||
sessionId = sessionId,
|
||||
|
|
@ -50,10 +45,10 @@ class NotificationMapper(
|
|||
senderAvatarUrl = item.senderInfo.avatarUrl,
|
||||
senderDisplayName = item.senderInfo.displayName,
|
||||
senderIsNameAmbiguous = item.senderInfo.isNameAmbiguous,
|
||||
roomAvatarUrl = item.roomInfo.avatarUrl ?: item.senderInfo.avatarUrl.takeIf { isDm },
|
||||
roomAvatarUrl = item.roomInfo.avatarUrl ?: item.senderInfo.avatarUrl.takeIf { item.roomInfo.isDm },
|
||||
roomDisplayName = item.roomInfo.displayName,
|
||||
isDirect = item.roomInfo.isDirect,
|
||||
isDm = isDm,
|
||||
isDm = item.roomInfo.isDm,
|
||||
isSpace = item.roomInfo.isSpace,
|
||||
isEncrypted = item.roomInfo.isEncrypted.orFalse(),
|
||||
isNoisy = item.isNoisy.orFalse(),
|
||||
|
|
|
|||
|
|
@ -62,11 +62,11 @@ class RustNotificationSettingsService(
|
|||
override suspend fun setDefaultRoomNotificationMode(
|
||||
isEncrypted: Boolean,
|
||||
mode: RoomNotificationMode,
|
||||
isOneToOne: Boolean
|
||||
isDM: Boolean
|
||||
): Result<Unit> = withContext(dispatchers.io) {
|
||||
runCatchingExceptions {
|
||||
try {
|
||||
notificationSettings.await().setDefaultRoomNotificationMode(isEncrypted, isOneToOne, mode.let(RoomNotificationSettingsMapper::mapMode))
|
||||
notificationSettings.await().setDefaultRoomNotificationMode(isEncrypted, isDM, mode.let(RoomNotificationSettingsMapper::mapMode))
|
||||
} catch (exception: NotificationSettingsException.RuleNotFound) {
|
||||
// `setDefaultRoomNotificationMode` updates multiple rules including unstable rules (e.g. the polls push rules defined in the MSC3930)
|
||||
// since production home servers may not have these rules yet, we drop the RuleNotFound error
|
||||
|
|
|
|||
|
|
@ -348,7 +348,7 @@ class JoinedRustRoom(
|
|||
roomNotificationSettingsStateFlow.value = RoomNotificationSettingsState.Pending(prevRoomNotificationSettings = currentRoomNotificationSettings)
|
||||
runCatchingExceptions {
|
||||
val isEncrypted = roomInfoFlow.value.isEncrypted ?: getUpdatedIsEncrypted().getOrThrow()
|
||||
notificationSettingsService.getRoomNotificationSettings(roomId, isEncrypted, isOneToOne).getOrThrow()
|
||||
notificationSettingsService.getRoomNotificationSettings(roomId = roomId, isEncrypted = isEncrypted, isOneToOne = isDm()).getOrThrow()
|
||||
}.map {
|
||||
roomNotificationSettingsStateFlow.value = RoomNotificationSettingsState.Ready(it)
|
||||
}.onFailure {
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ import org.matrix.rustcomponents.sdk.RoomInfo
|
|||
*/
|
||||
fun RoomInfo.elementHeroes(): List<MatrixUser> {
|
||||
return heroes
|
||||
.takeIf { isDirect && activeMembersCount.toLong() == 2L }
|
||||
.takeIf { isDm }
|
||||
?.takeIf { it.size == 1 }
|
||||
?.map { it.map() }
|
||||
.orEmpty()
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ class RoomInfoMapper {
|
|||
avatarUrl = it.avatarUrl,
|
||||
isPublic = it.isPublic,
|
||||
isDirect = it.isDirect,
|
||||
isDm = it.isDm,
|
||||
isEncrypted = when (it.encryptionState) {
|
||||
EncryptionState.ENCRYPTED -> true
|
||||
EncryptionState.NOT_ENCRYPTED -> false
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@ import io.element.android.libraries.matrix.api.room.RoomMember
|
|||
import io.element.android.libraries.matrix.api.room.RoomMembersState
|
||||
import io.element.android.libraries.matrix.api.room.RoomMembershipObserver
|
||||
import io.element.android.libraries.matrix.api.room.draft.ComposerDraft
|
||||
import io.element.android.libraries.matrix.api.room.isDm
|
||||
import io.element.android.libraries.matrix.api.room.powerlevels.RoomPermissions
|
||||
import io.element.android.libraries.matrix.api.room.powerlevels.RoomPowerLevelsValues
|
||||
import io.element.android.libraries.matrix.api.room.tombstone.PredecessorRoom
|
||||
|
|
@ -119,7 +118,7 @@ class RustBaseRoom(
|
|||
innerRoom.membersNoSync().use { members ->
|
||||
members.nextChunk(members.len())
|
||||
?.map(RoomMemberMapper::map)
|
||||
?.firstOrNull { roomMember -> roomMember.userId != sessionId && roomMember.membership.isActive() }
|
||||
?.firstOrNull { roomMember -> !roomMember.isServiceMember && roomMember.userId != sessionId && roomMember.membership.isActive() }
|
||||
}
|
||||
} else {
|
||||
null
|
||||
|
|
|
|||
|
|
@ -28,7 +28,8 @@ object RoomMemberMapper {
|
|||
powerLevel = powerLevel,
|
||||
isIgnored = roomMember.isIgnored,
|
||||
role = mapRole(roomMember.suggestedRoleForPowerLevel, powerLevel),
|
||||
membershipChangeReason = roomMember.membershipChangeReason
|
||||
membershipChangeReason = roomMember.membershipChangeReason,
|
||||
isServiceMember = roomMember.isServiceMember,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ class SpaceRoomMapper {
|
|||
worldReadable = spaceRoom.worldReadable.orFalse(),
|
||||
via = spaceRoom.via.toImmutableList(),
|
||||
isDirect = spaceRoom.isDirect,
|
||||
isDm = spaceRoom.isDm,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@ 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.IntentionalMention
|
||||
import io.element.android.libraries.matrix.api.room.JoinedRoom
|
||||
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.MsgType
|
||||
|
|
|
|||
|
|
@ -43,6 +43,19 @@ class JoinedExtKtTest {
|
|||
@Test
|
||||
fun `test isDirect parameter mapping`() = runTest {
|
||||
assertThat(aRoom(isDirect = true).toAnalyticsJoinedRoom(null))
|
||||
.isEqualTo(
|
||||
JoinedRoom(
|
||||
isDM = false,
|
||||
isSpace = false,
|
||||
roomSize = JoinedRoom.RoomSize.One,
|
||||
trigger = null
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test isDm parameter mapping`() = runTest {
|
||||
assertThat(aRoom(isDm = true).toAnalyticsJoinedRoom(null))
|
||||
.isEqualTo(
|
||||
JoinedRoom(
|
||||
isDM = true,
|
||||
|
|
@ -80,12 +93,13 @@ class JoinedExtKtTest {
|
|||
}
|
||||
|
||||
private fun aRoom(
|
||||
isDm: Boolean = false,
|
||||
isDirect: Boolean = false,
|
||||
isSpace: Boolean = false,
|
||||
joinedMemberCount: Long = 0
|
||||
): FakeBaseRoom {
|
||||
return FakeBaseRoom().apply {
|
||||
givenRoomInfo(aRoomInfo(isDirect = isDirect, isSpace = isSpace, joinedMembersCount = joinedMemberCount))
|
||||
givenRoomInfo(aRoomInfo(isDm = isDm, isDirect = isDirect, isSpace = isSpace, joinedMembersCount = joinedMemberCount))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,5 +50,5 @@ internal fun aRustSpaceRoom(
|
|||
childrenCount = childrenCount,
|
||||
state = state,
|
||||
heroes = heroes,
|
||||
via = emptyList()
|
||||
via = emptyList(),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ import org.matrix.rustcomponents.sdk.RequestConfig
|
|||
import org.matrix.rustcomponents.sdk.SlidingSyncVersionBuilder
|
||||
import org.matrix.rustcomponents.sdk.SqliteStoreBuilder
|
||||
import uniffi.matrix_sdk.BackupDownloadStrategy
|
||||
import uniffi.matrix_sdk_base.DmRoomDefinition
|
||||
import uniffi.matrix_sdk_crypto.CollectStrategy
|
||||
import uniffi.matrix_sdk_crypto.DecryptionSettings
|
||||
|
||||
|
|
@ -47,5 +48,6 @@ class FakeFfiClientBuilder(
|
|||
override fun sqliteStore(config: SqliteStoreBuilder): ClientBuilder = this
|
||||
override fun inMemoryStore(): ClientBuilder = this
|
||||
override fun crossProcessLockConfig(crossProcessLockConfig: CrossProcessLockConfig): ClientBuilder = this
|
||||
override fun dmRoomDefinition(dmRoomDefinition: DmRoomDefinition): ClientBuilder = this
|
||||
override suspend fun build() = buildResult()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,8 +20,7 @@ class RoomInfoExtTest {
|
|||
@Test
|
||||
fun `get non empty element Heroes`() {
|
||||
val result = aRustRoomInfo(
|
||||
isDirect = true,
|
||||
activeMembersCount = 2uL,
|
||||
isDm = true,
|
||||
heroes = listOf(aRustRoomHero())
|
||||
).elementHeroes()
|
||||
assertThat(result).isEqualTo(
|
||||
|
|
@ -38,8 +37,7 @@ class RoomInfoExtTest {
|
|||
@Test
|
||||
fun `too many heroes and element Heroes is empty`() {
|
||||
val result = aRustRoomInfo(
|
||||
isDirect = true,
|
||||
activeMembersCount = 2uL,
|
||||
isDm = true,
|
||||
heroes = listOf(aRustRoomHero(), aRustRoomHero())
|
||||
).elementHeroes()
|
||||
assertThat(result).isEmpty()
|
||||
|
|
@ -48,18 +46,7 @@ class RoomInfoExtTest {
|
|||
@Test
|
||||
fun `not direct and element Heroes is empty`() {
|
||||
val result = aRustRoomInfo(
|
||||
isDirect = false,
|
||||
activeMembersCount = 2uL,
|
||||
heroes = listOf(aRustRoomHero())
|
||||
).elementHeroes()
|
||||
assertThat(result).isEmpty()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `too many members and element Heroes is empty`() {
|
||||
val result = aRustRoomInfo(
|
||||
isDirect = true,
|
||||
activeMembersCount = 3uL,
|
||||
isDm = false,
|
||||
heroes = listOf(aRustRoomHero())
|
||||
).elementHeroes()
|
||||
assertThat(result).isEmpty()
|
||||
|
|
|
|||
|
|
@ -86,6 +86,7 @@ class RoomInfoMapperTest {
|
|||
privilegedCreatorsRole = true,
|
||||
isLowPriority = true,
|
||||
activeRoomCallConsensusIntent = RtcCallIntentConsensus.Full(RtcCallIntent.AUDIO),
|
||||
isDm = true,
|
||||
)
|
||||
)
|
||||
).isEqualTo(
|
||||
|
|
@ -136,6 +137,7 @@ class RoomInfoMapperTest {
|
|||
privilegedCreatorRole = true,
|
||||
isLowPriority = true,
|
||||
activeCallIntentConsensus = CallIntentConsensus.Full(CallIntent.AUDIO),
|
||||
isDm = true,
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
@ -181,6 +183,7 @@ class RoomInfoMapperTest {
|
|||
privilegedCreatorsRole = true,
|
||||
isLowPriority = true,
|
||||
activeRoomCallConsensusIntent = RtcCallIntentConsensus.None,
|
||||
isDm = false,
|
||||
)
|
||||
)
|
||||
).isEqualTo(
|
||||
|
|
@ -225,6 +228,7 @@ class RoomInfoMapperTest {
|
|||
privilegedCreatorRole = true,
|
||||
isLowPriority = true,
|
||||
activeCallIntentConsensus = CallIntentConsensus.None,
|
||||
isDm = false,
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue