feat(security&privacy) : expose new sdk methods

This commit is contained in:
ganfra 2025-01-21 11:49:56 +01:00
parent 12d184f3b2
commit 6e4bcedc4c
20 changed files with 269 additions and 61 deletions

View file

@ -31,9 +31,9 @@ import io.element.android.libraries.matrix.api.MatrixClient
import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.createroom.CreateRoomParameters import io.element.android.libraries.matrix.api.createroom.CreateRoomParameters
import io.element.android.libraries.matrix.api.createroom.RoomPreset import io.element.android.libraries.matrix.api.createroom.RoomPreset
import io.element.android.libraries.matrix.api.createroom.RoomVisibility
import io.element.android.libraries.matrix.api.room.alias.RoomAliasHelper import io.element.android.libraries.matrix.api.room.alias.RoomAliasHelper
import io.element.android.libraries.matrix.api.roomAliasFromName import io.element.android.libraries.matrix.api.roomAliasFromName
import io.element.android.libraries.matrix.api.roomdirectory.RoomVisibility
import io.element.android.libraries.matrix.ui.media.AvatarAction import io.element.android.libraries.matrix.ui.media.AvatarAction
import io.element.android.libraries.mediapickers.api.PickerProvider import io.element.android.libraries.mediapickers.api.PickerProvider
import io.element.android.libraries.mediaupload.api.MediaPreProcessor import io.element.android.libraries.mediaupload.api.MediaPreProcessor
@ -191,7 +191,7 @@ class ConfigureRoomPresenter @Inject constructor(
topic = config.topic, topic = config.topic,
isEncrypted = false, isEncrypted = false,
isDirect = false, isDirect = false,
visibility = RoomVisibility.PUBLIC, visibility = RoomVisibility.Public,
joinRuleOverride = config.roomVisibility.roomAccess.toJoinRule(), joinRuleOverride = config.roomVisibility.roomAccess.toJoinRule(),
preset = RoomPreset.PUBLIC_CHAT, preset = RoomPreset.PUBLIC_CHAT,
invite = config.invites.map { it.userId }, invite = config.invites.map { it.userId },
@ -204,7 +204,7 @@ class ConfigureRoomPresenter @Inject constructor(
topic = config.topic, topic = config.topic,
isEncrypted = config.roomVisibility is RoomVisibilityState.Private, isEncrypted = config.roomVisibility is RoomVisibilityState.Private,
isDirect = false, isDirect = false,
visibility = RoomVisibility.PRIVATE, visibility = RoomVisibility.Private,
preset = RoomPreset.PRIVATE_CHAT, preset = RoomPreset.PRIVATE_CHAT,
invite = config.invites.map { it.userId }, invite = config.invites.map { it.userId },
avatar = avatarUrl, avatar = avatarUrl,

View file

@ -7,16 +7,16 @@
package io.element.android.features.createroom.impl.configureroom package io.element.android.features.createroom.impl.configureroom
import io.element.android.libraries.matrix.api.createroom.JoinRuleOverride import io.element.android.libraries.matrix.api.room.join.JoinRule
enum class RoomAccess { enum class RoomAccess {
Anyone, Anyone,
Knocking Knocking
} }
fun RoomAccess.toJoinRule(): JoinRuleOverride { fun RoomAccess.toJoinRule(): JoinRule? {
return when (this) { return when (this) {
RoomAccess.Anyone -> JoinRuleOverride.None RoomAccess.Anyone -> null
RoomAccess.Knocking -> JoinRuleOverride.Knock RoomAccess.Knocking -> JoinRule.Knock
} }
} }

View file

@ -8,6 +8,8 @@
package io.element.android.libraries.matrix.api.createroom package io.element.android.libraries.matrix.api.createroom
import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.api.room.join.JoinRule
import io.element.android.libraries.matrix.api.roomdirectory.RoomVisibility
import java.util.Optional import java.util.Optional
data class CreateRoomParameters( data class CreateRoomParameters(
@ -19,6 +21,6 @@ data class CreateRoomParameters(
val preset: RoomPreset, val preset: RoomPreset,
val invite: List<UserId>? = null, val invite: List<UserId>? = null,
val avatar: String? = null, val avatar: String? = null,
val joinRuleOverride: JoinRuleOverride = JoinRuleOverride.None, val joinRuleOverride: JoinRule? = null,
val roomAliasName: Optional<String> = Optional.empty(), val roomAliasName: Optional<String> = Optional.empty(),
) )

View file

@ -1,16 +0,0 @@
/*
* Copyright 2024 New Vector Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
* Please see LICENSE files in the repository root for full details.
*/
package io.element.android.libraries.matrix.api.createroom
/**
* Rules to override the default room join rules.
*/
sealed interface JoinRuleOverride {
data object Knock : JoinRuleOverride
data object None : JoinRuleOverride
}

View file

@ -1,12 +0,0 @@
/*
* Copyright 2023, 2024 New Vector Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
* Please see LICENSE files in the repository root for full details.
*/
package io.element.android.libraries.matrix.api.createroom
enum class RoomVisibility {
PUBLIC,
PRIVATE,
}

View file

@ -24,10 +24,12 @@ import io.element.android.libraries.matrix.api.media.MediaUploadHandler
import io.element.android.libraries.matrix.api.media.VideoInfo 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.poll.PollKind
import io.element.android.libraries.matrix.api.room.draft.ComposerDraft import io.element.android.libraries.matrix.api.room.draft.ComposerDraft
import io.element.android.libraries.matrix.api.room.history.RoomHistoryVisibility
import io.element.android.libraries.matrix.api.room.knock.KnockRequest import io.element.android.libraries.matrix.api.room.knock.KnockRequest
import io.element.android.libraries.matrix.api.room.location.AssetType import io.element.android.libraries.matrix.api.room.location.AssetType
import io.element.android.libraries.matrix.api.room.powerlevels.MatrixRoomPowerLevels import io.element.android.libraries.matrix.api.room.powerlevels.MatrixRoomPowerLevels
import io.element.android.libraries.matrix.api.room.powerlevels.UserRoleChange import io.element.android.libraries.matrix.api.room.powerlevels.UserRoleChange
import io.element.android.libraries.matrix.api.roomdirectory.RoomVisibility
import io.element.android.libraries.matrix.api.timeline.ReceiptType import io.element.android.libraries.matrix.api.timeline.ReceiptType
import io.element.android.libraries.matrix.api.timeline.Timeline import io.element.android.libraries.matrix.api.timeline.Timeline
import io.element.android.libraries.matrix.api.timeline.item.event.EventOrTransactionId import io.element.android.libraries.matrix.api.timeline.item.event.EventOrTransactionId
@ -402,4 +404,32 @@ interface MatrixRoom : Closeable {
suspend fun withdrawVerificationAndResend(userIds: List<UserId>, sendHandle: SendHandle): Result<Unit> suspend fun withdrawVerificationAndResend(userIds: List<UserId>, sendHandle: SendHandle): Result<Unit>
override fun close() = destroy() override fun close() = destroy()
/**
* Update the canonical alias of the room.
*
* Note that publishing the alias in the room directory is done separately.
*/
suspend fun updateCanonicalAlias(
canonicalAlias: RoomAlias?,
alternativeAliases: List<RoomAlias>
): Result<Unit>
/**
* Update the room's visibility in the room directory.
*/
suspend fun updateRoomVisibility(roomVisibility: RoomVisibility): Result<Unit>
/**
* Update room history visibility for this room.
*/
suspend fun updateHistoryVisibility(historyVisibility: RoomHistoryVisibility): Result<Unit>
/**
* Returns the visibility for this room in the room directory.
*
* [Public](`RoomVisibility::Public`) rooms are listed in the room
* directory and can be found using it.
*/
suspend fun getRoomVisibility(): Result<RoomVisibility>
} }

View file

@ -12,6 +12,7 @@ import io.element.android.libraries.matrix.api.core.EventId
import io.element.android.libraries.matrix.api.core.RoomAlias 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.core.RoomId
import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.api.room.history.RoomHistoryVisibility
import io.element.android.libraries.matrix.api.room.join.JoinRule import io.element.android.libraries.matrix.api.room.join.JoinRule
import io.element.android.libraries.matrix.api.user.MatrixUser import io.element.android.libraries.matrix.api.user.MatrixUser
import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableList
@ -71,6 +72,7 @@ data class MatrixRoomInfo(
val heroes: ImmutableList<MatrixUser>, val heroes: ImmutableList<MatrixUser>,
val pinnedEventIds: ImmutableList<EventId>, val pinnedEventIds: ImmutableList<EventId>,
val creator: UserId?, val creator: UserId?,
val historyVisibility: RoomHistoryVisibility,
) { ) {
val aliases: List<RoomAlias> val aliases: List<RoomAlias>
get() = listOfNotNull(canonicalAlias) + alternativeAliases get() = listOfNotNull(canonicalAlias) + alternativeAliases

View file

@ -0,0 +1,47 @@
/*
* Copyright 2025 New Vector Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
* Please see LICENSE files in the repository root for full details.
*/
package io.element.android.libraries.matrix.api.room.history
sealed interface RoomHistoryVisibility {
/**
* Previous events are accessible to newly joined members from the point
* they were invited onwards.
*
* Events stop being accessible when the member's state changes to
* something other than *invite* or *join*.
*/
data object Invited : RoomHistoryVisibility
/**
* Previous events are accessible to newly joined members from the point
* they joined the room onwards.
* Events stop being accessible when the member's state changes to
* something other than *join*.
*/
data object Joined : RoomHistoryVisibility
/**
* Previous events are always accessible to newly joined members.
*
* All events in the room are accessible, even those sent when the member
* was not a part of the room.
*/
data object Shared : RoomHistoryVisibility
/**
* All events while this is the `HistoryVisibility` value may be shared by
* any participating homeserver with anyone, regardless of whether they
* have ever joined the room.
*/
data object WorldReadable : RoomHistoryVisibility
/**
* A custom visibility value.
*/
data class Custom(val value: String) : RoomHistoryVisibility
}

View file

@ -0,0 +1,28 @@
/*
* Copyright 2025 New Vector Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
* Please see LICENSE files in the repository root for full details.
*/
package io.element.android.libraries.matrix.api.roomdirectory
/**
* Enum class representing the visibility of a room in the room directory.
*/
sealed interface RoomVisibility {
/**
* Indicates that the room will be shown in the published room list.
*/
data object Public : RoomVisibility
/**
* Indicates that the room will not be shown in the published room list.
*/
data object Private : RoomVisibility
/**
* A custom value that's not present in the spec.
*/
data class Custom(val value: String) : RoomVisibility
}

View file

@ -23,9 +23,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.UserId
import io.element.android.libraries.matrix.api.core.toRoomIdOrAlias import io.element.android.libraries.matrix.api.core.toRoomIdOrAlias
import io.element.android.libraries.matrix.api.createroom.CreateRoomParameters import io.element.android.libraries.matrix.api.createroom.CreateRoomParameters
import io.element.android.libraries.matrix.api.createroom.JoinRuleOverride
import io.element.android.libraries.matrix.api.createroom.RoomPreset import io.element.android.libraries.matrix.api.createroom.RoomPreset
import io.element.android.libraries.matrix.api.createroom.RoomVisibility
import io.element.android.libraries.matrix.api.encryption.EncryptionService import io.element.android.libraries.matrix.api.encryption.EncryptionService
import io.element.android.libraries.matrix.api.media.MatrixMediaLoader import io.element.android.libraries.matrix.api.media.MatrixMediaLoader
import io.element.android.libraries.matrix.api.notification.NotificationService import io.element.android.libraries.matrix.api.notification.NotificationService
@ -38,8 +36,10 @@ import io.element.android.libraries.matrix.api.room.PendingRoom
import io.element.android.libraries.matrix.api.room.RoomMember import io.element.android.libraries.matrix.api.room.RoomMember
import io.element.android.libraries.matrix.api.room.RoomMembershipObserver import io.element.android.libraries.matrix.api.room.RoomMembershipObserver
import io.element.android.libraries.matrix.api.room.alias.ResolvedRoomAlias import io.element.android.libraries.matrix.api.room.alias.ResolvedRoomAlias
import io.element.android.libraries.matrix.api.room.join.JoinRule
import io.element.android.libraries.matrix.api.room.preview.RoomPreviewInfo import io.element.android.libraries.matrix.api.room.preview.RoomPreviewInfo
import io.element.android.libraries.matrix.api.roomdirectory.RoomDirectoryService import io.element.android.libraries.matrix.api.roomdirectory.RoomDirectoryService
import io.element.android.libraries.matrix.api.roomdirectory.RoomVisibility
import io.element.android.libraries.matrix.api.roomlist.RoomListService import io.element.android.libraries.matrix.api.roomlist.RoomListService
import io.element.android.libraries.matrix.api.roomlist.RoomSummary import io.element.android.libraries.matrix.api.roomlist.RoomSummary
import io.element.android.libraries.matrix.api.sync.SlidingSyncVersion import io.element.android.libraries.matrix.api.sync.SlidingSyncVersion
@ -59,8 +59,10 @@ import io.element.android.libraries.matrix.impl.room.RoomContentForwarder
import io.element.android.libraries.matrix.impl.room.RoomSyncSubscriber import io.element.android.libraries.matrix.impl.room.RoomSyncSubscriber
import io.element.android.libraries.matrix.impl.room.RustRoomFactory import io.element.android.libraries.matrix.impl.room.RustRoomFactory
import io.element.android.libraries.matrix.impl.room.TimelineEventTypeFilterFactory import io.element.android.libraries.matrix.impl.room.TimelineEventTypeFilterFactory
import io.element.android.libraries.matrix.impl.room.join.map
import io.element.android.libraries.matrix.impl.room.preview.RoomPreviewInfoMapper import io.element.android.libraries.matrix.impl.room.preview.RoomPreviewInfoMapper
import io.element.android.libraries.matrix.impl.roomdirectory.RustRoomDirectoryService import io.element.android.libraries.matrix.impl.roomdirectory.RustRoomDirectoryService
import io.element.android.libraries.matrix.impl.roomdirectory.map
import io.element.android.libraries.matrix.impl.roomlist.RoomListFactory import io.element.android.libraries.matrix.impl.roomlist.RoomListFactory
import io.element.android.libraries.matrix.impl.roomlist.RustRoomListService import io.element.android.libraries.matrix.impl.roomlist.RustRoomListService
import io.element.android.libraries.matrix.impl.sync.RustSyncService import io.element.android.libraries.matrix.impl.sync.RustSyncService
@ -112,9 +114,7 @@ import kotlin.jvm.optionals.getOrNull
import kotlin.time.Duration import kotlin.time.Duration
import kotlin.time.Duration.Companion.seconds import kotlin.time.Duration.Companion.seconds
import org.matrix.rustcomponents.sdk.CreateRoomParameters as RustCreateRoomParameters import org.matrix.rustcomponents.sdk.CreateRoomParameters as RustCreateRoomParameters
import org.matrix.rustcomponents.sdk.JoinRule as RustJoinRule
import org.matrix.rustcomponents.sdk.RoomPreset as RustRoomPreset import org.matrix.rustcomponents.sdk.RoomPreset as RustRoomPreset
import org.matrix.rustcomponents.sdk.RoomVisibility as RustRoomVisibility
import org.matrix.rustcomponents.sdk.SyncService as ClientSyncService import org.matrix.rustcomponents.sdk.SyncService as ClientSyncService
class RustMatrixClient( class RustMatrixClient(
@ -310,36 +310,23 @@ class RustMatrixClient(
topic = createRoomParams.topic, topic = createRoomParams.topic,
isEncrypted = createRoomParams.isEncrypted, isEncrypted = createRoomParams.isEncrypted,
isDirect = createRoomParams.isDirect, isDirect = createRoomParams.isDirect,
visibility = when (createRoomParams.visibility) { visibility = createRoomParams.visibility.map(),
RoomVisibility.PUBLIC -> RustRoomVisibility.Public preset = when (createRoomParams.preset) {
RoomVisibility.PRIVATE -> RustRoomVisibility.Private RoomPreset.PRIVATE_CHAT -> RustRoomPreset.PRIVATE_CHAT
}, RoomPreset.TRUSTED_PRIVATE_CHAT -> RustRoomPreset.TRUSTED_PRIVATE_CHAT
preset = when (createRoomParams.visibility) { RoomPreset.PUBLIC_CHAT -> RustRoomPreset.PUBLIC_CHAT
RoomVisibility.PRIVATE -> {
if (createRoomParams.isDirect) {
RustRoomPreset.TRUSTED_PRIVATE_CHAT
} else {
RustRoomPreset.PRIVATE_CHAT
}
}
RoomVisibility.PUBLIC -> {
RustRoomPreset.PUBLIC_CHAT
}
}, },
invite = createRoomParams.invite?.map { it.value }, invite = createRoomParams.invite?.map { it.value },
avatar = createRoomParams.avatar, avatar = createRoomParams.avatar,
powerLevelContentOverride = defaultRoomCreationPowerLevels.copy( powerLevelContentOverride = defaultRoomCreationPowerLevels.copy(
invite = if (createRoomParams.joinRuleOverride == JoinRuleOverride.Knock) { invite = if (createRoomParams.joinRuleOverride == JoinRule.Knock) {
// override the invite power level so it's the same as kick. // override the invite power level so it's the same as kick.
RoomMember.Role.MODERATOR.powerLevel.toInt() RoomMember.Role.MODERATOR.powerLevel.toInt()
} else { } else {
null null
} }
), ),
joinRuleOverride = when (createRoomParams.joinRuleOverride) { joinRuleOverride = createRoomParams.joinRuleOverride?.map(),
JoinRuleOverride.Knock -> RustJoinRule.Knock
JoinRuleOverride.None -> null
},
canonicalAlias = createRoomParams.roomAliasName.getOrNull(), canonicalAlias = createRoomParams.roomAliasName.getOrNull(),
) )
val roomId = RoomId(innerClient.createRoom(rustParams)) val roomId = RoomId(innerClient.createRoom(rustParams))
@ -358,7 +345,7 @@ class RustMatrixClient(
name = null, name = null,
isEncrypted = true, isEncrypted = true,
isDirect = true, isDirect = true,
visibility = RoomVisibility.PRIVATE, visibility = RoomVisibility.Private,
preset = RoomPreset.TRUSTED_PRIVATE_CHAT, preset = RoomPreset.TRUSTED_PRIVATE_CHAT,
invite = listOf(userId), invite = listOf(userId),
) )

View file

@ -15,6 +15,7 @@ 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.MatrixRoomInfo
import io.element.android.libraries.matrix.api.room.RoomNotificationMode import io.element.android.libraries.matrix.api.room.RoomNotificationMode
import io.element.android.libraries.matrix.api.user.MatrixUser import io.element.android.libraries.matrix.api.user.MatrixUser
import io.element.android.libraries.matrix.impl.room.history.map
import io.element.android.libraries.matrix.impl.room.join.map import io.element.android.libraries.matrix.impl.room.join.map
import io.element.android.libraries.matrix.impl.room.member.RoomMemberMapper import io.element.android.libraries.matrix.impl.room.member.RoomMemberMapper
import kotlinx.collections.immutable.ImmutableMap import kotlinx.collections.immutable.ImmutableMap
@ -60,6 +61,7 @@ class MatrixRoomInfoMapper {
numUnreadMessages = it.numUnreadMessages.toLong(), numUnreadMessages = it.numUnreadMessages.toLong(),
numUnreadMentions = it.numUnreadMentions.toLong(), numUnreadMentions = it.numUnreadMentions.toLong(),
numUnreadNotifications = it.numUnreadNotifications.toLong(), numUnreadNotifications = it.numUnreadNotifications.toLong(),
historyVisibility = it.historyVisibility.map(),
) )
} }
} }

View file

@ -38,11 +38,13 @@ import io.element.android.libraries.matrix.api.room.RoomMember
import io.element.android.libraries.matrix.api.room.RoomMembershipObserver import io.element.android.libraries.matrix.api.room.RoomMembershipObserver
import io.element.android.libraries.matrix.api.room.StateEventType import io.element.android.libraries.matrix.api.room.StateEventType
import io.element.android.libraries.matrix.api.room.draft.ComposerDraft import io.element.android.libraries.matrix.api.room.draft.ComposerDraft
import io.element.android.libraries.matrix.api.room.history.RoomHistoryVisibility
import io.element.android.libraries.matrix.api.room.knock.KnockRequest import io.element.android.libraries.matrix.api.room.knock.KnockRequest
import io.element.android.libraries.matrix.api.room.location.AssetType import io.element.android.libraries.matrix.api.room.location.AssetType
import io.element.android.libraries.matrix.api.room.powerlevels.MatrixRoomPowerLevels import io.element.android.libraries.matrix.api.room.powerlevels.MatrixRoomPowerLevels
import io.element.android.libraries.matrix.api.room.powerlevels.UserRoleChange import io.element.android.libraries.matrix.api.room.powerlevels.UserRoleChange
import io.element.android.libraries.matrix.api.room.roomNotificationSettings import io.element.android.libraries.matrix.api.room.roomNotificationSettings
import io.element.android.libraries.matrix.api.roomdirectory.RoomVisibility
import io.element.android.libraries.matrix.api.timeline.ReceiptType import io.element.android.libraries.matrix.api.timeline.ReceiptType
import io.element.android.libraries.matrix.api.timeline.Timeline import io.element.android.libraries.matrix.api.timeline.Timeline
import io.element.android.libraries.matrix.api.timeline.item.event.EventOrTransactionId import io.element.android.libraries.matrix.api.timeline.item.event.EventOrTransactionId
@ -51,10 +53,12 @@ import io.element.android.libraries.matrix.api.widget.MatrixWidgetSettings
import io.element.android.libraries.matrix.impl.core.RustSendHandle import io.element.android.libraries.matrix.impl.core.RustSendHandle
import io.element.android.libraries.matrix.impl.mapper.map import io.element.android.libraries.matrix.impl.mapper.map
import io.element.android.libraries.matrix.impl.room.draft.into import io.element.android.libraries.matrix.impl.room.draft.into
import io.element.android.libraries.matrix.impl.room.history.map
import io.element.android.libraries.matrix.impl.room.knock.RustKnockRequest import io.element.android.libraries.matrix.impl.room.knock.RustKnockRequest
import io.element.android.libraries.matrix.impl.room.member.RoomMemberListFetcher import io.element.android.libraries.matrix.impl.room.member.RoomMemberListFetcher
import io.element.android.libraries.matrix.impl.room.member.RoomMemberMapper import io.element.android.libraries.matrix.impl.room.member.RoomMemberMapper
import io.element.android.libraries.matrix.impl.room.powerlevels.RoomPowerLevelsMapper import io.element.android.libraries.matrix.impl.room.powerlevels.RoomPowerLevelsMapper
import io.element.android.libraries.matrix.impl.roomdirectory.map
import io.element.android.libraries.matrix.impl.timeline.RustTimeline import io.element.android.libraries.matrix.impl.timeline.RustTimeline
import io.element.android.libraries.matrix.impl.timeline.toRustReceiptType import io.element.android.libraries.matrix.impl.timeline.toRustReceiptType
import io.element.android.libraries.matrix.impl.util.MessageEventContent import io.element.android.libraries.matrix.impl.util.MessageEventContent
@ -775,6 +779,30 @@ class RustMatrixRoom(
} }
} }
override suspend fun updateCanonicalAlias(canonicalAlias: RoomAlias?, alternativeAliases: List<RoomAlias>): Result<Unit> = withContext(roomDispatcher) {
runCatching {
innerRoom.updateCanonicalAlias(canonicalAlias?.value, alternativeAliases.map { it.value })
}
}
override suspend fun updateRoomVisibility(roomVisibility: RoomVisibility): Result<Unit> = withContext(roomDispatcher) {
runCatching {
innerRoom.updateRoomVisibility(roomVisibility.map())
}
}
override suspend fun updateHistoryVisibility(historyVisibility: RoomHistoryVisibility): Result<Unit> = withContext(roomDispatcher) {
runCatching {
innerRoom.updateHistoryVisibility(historyVisibility.map())
}
}
override suspend fun getRoomVisibility(): Result<RoomVisibility> = withContext(roomDispatcher) {
runCatching {
innerRoom.getRoomVisibility().map()
}
}
private fun createTimeline( private fun createTimeline(
timeline: InnerTimeline, timeline: InnerTimeline,
mode: Timeline.Mode, mode: Timeline.Mode,

View file

@ -0,0 +1,31 @@
/*
* Copyright 2025 New Vector Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
* Please see LICENSE files in the repository root for full details.
*/
package io.element.android.libraries.matrix.impl.room.history
import io.element.android.libraries.matrix.api.room.history.RoomHistoryVisibility
import org.matrix.rustcomponents.sdk.RoomHistoryVisibility as RustRoomHistoryVisibility
fun RoomHistoryVisibility.map(): RustRoomHistoryVisibility {
return when (this) {
RoomHistoryVisibility.WorldReadable -> RustRoomHistoryVisibility.WorldReadable
RoomHistoryVisibility.Invited -> RustRoomHistoryVisibility.Invited
RoomHistoryVisibility.Joined -> RustRoomHistoryVisibility.Joined
RoomHistoryVisibility.Shared -> RustRoomHistoryVisibility.Shared
is RoomHistoryVisibility.Custom -> RustRoomHistoryVisibility.Custom(value)
}
}
fun RustRoomHistoryVisibility.map(): RoomHistoryVisibility {
return when (this) {
RustRoomHistoryVisibility.WorldReadable -> RoomHistoryVisibility.WorldReadable
RustRoomHistoryVisibility.Invited -> RoomHistoryVisibility.Invited
RustRoomHistoryVisibility.Joined -> RoomHistoryVisibility.Joined
RustRoomHistoryVisibility.Shared -> RoomHistoryVisibility.Shared
is RustRoomHistoryVisibility.Custom -> RoomHistoryVisibility.Custom(value)
}
}

View file

@ -17,3 +17,10 @@ fun RustAllowRule.map(): AllowRule {
is RustAllowRule.Custom -> AllowRule.Custom(json) is RustAllowRule.Custom -> AllowRule.Custom(json)
} }
} }
fun AllowRule.map(): RustAllowRule {
return when (this) {
is AllowRule.RoomMembership -> RustAllowRule.RoomMembership(roomId.toString())
is AllowRule.Custom -> RustAllowRule.Custom(json)
}
}

View file

@ -21,3 +21,15 @@ fun RustJoinRule.map(): JoinRule {
is RustJoinRule.KnockRestricted -> JoinRule.KnockRestricted(rules.map { it.map() }) is RustJoinRule.KnockRestricted -> JoinRule.KnockRestricted(rules.map { it.map() })
} }
} }
fun JoinRule.map(): RustJoinRule {
return when (this) {
JoinRule.Public -> RustJoinRule.Public
JoinRule.Private -> RustJoinRule.Private
JoinRule.Knock -> RustJoinRule.Knock
JoinRule.Invite -> RustJoinRule.Invite
is JoinRule.Restricted -> RustJoinRule.Restricted(rules.map { it.map() })
is JoinRule.Custom -> RustJoinRule.Custom(value)
is JoinRule.KnockRestricted -> RustJoinRule.KnockRestricted(rules.map { it.map() })
}
}

View file

@ -0,0 +1,27 @@
/*
* Copyright 2025 New Vector Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
* Please see LICENSE files in the repository root for full details.
*/
package io.element.android.libraries.matrix.impl.roomdirectory
import io.element.android.libraries.matrix.api.roomdirectory.RoomVisibility
import org.matrix.rustcomponents.sdk.RoomVisibility as RustRoomVisibility
fun RoomVisibility.map(): RustRoomVisibility {
return when (this) {
RoomVisibility.Public -> RustRoomVisibility.Public
RoomVisibility.Private -> RustRoomVisibility.Private
is RoomVisibility.Custom -> RustRoomVisibility.Custom(value)
}
}
fun RustRoomVisibility.map(): RoomVisibility {
return when (this) {
RustRoomVisibility.Public -> RoomVisibility.Public
RustRoomVisibility.Private -> RoomVisibility.Private
is RustRoomVisibility.Custom -> RoomVisibility.Custom(value)
}
}

View file

@ -14,6 +14,7 @@ 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.CurrentUserMembership
import io.element.android.libraries.matrix.api.room.MatrixRoomInfo import io.element.android.libraries.matrix.api.room.MatrixRoomInfo
import io.element.android.libraries.matrix.api.room.RoomNotificationMode import io.element.android.libraries.matrix.api.room.RoomNotificationMode
import io.element.android.libraries.matrix.api.room.history.RoomHistoryVisibility
import io.element.android.libraries.matrix.api.room.join.JoinRule import io.element.android.libraries.matrix.api.room.join.JoinRule
import io.element.android.libraries.matrix.api.user.MatrixUser import io.element.android.libraries.matrix.api.user.MatrixUser
import io.element.android.libraries.matrix.impl.fixtures.factories.aRustRoomHero import io.element.android.libraries.matrix.impl.fixtures.factories.aRustRoomHero
@ -34,6 +35,7 @@ import org.junit.Test
import org.matrix.rustcomponents.sdk.Membership import org.matrix.rustcomponents.sdk.Membership
import org.matrix.rustcomponents.sdk.JoinRule as RustJoinRule import org.matrix.rustcomponents.sdk.JoinRule as RustJoinRule
import org.matrix.rustcomponents.sdk.RoomNotificationMode as RustRoomNotificationMode import org.matrix.rustcomponents.sdk.RoomNotificationMode as RustRoomNotificationMode
import org.matrix.rustcomponents.sdk.RoomHistoryVisibility as RustRoomHistoryVisibility
class MatrixRoomInfoMapperTest { class MatrixRoomInfoMapperTest {
@Test @Test
@ -72,6 +74,7 @@ class MatrixRoomInfoMapperTest {
numUnreadMentions = 14uL, numUnreadMentions = 14uL,
pinnedEventIds = listOf(AN_EVENT_ID.value), pinnedEventIds = listOf(AN_EVENT_ID.value),
roomCreator = A_USER_ID, roomCreator = A_USER_ID,
historyVisibility = RustRoomHistoryVisibility.Joined,
) )
) )
).isEqualTo( ).isEqualTo(
@ -113,6 +116,7 @@ class MatrixRoomInfoMapperTest {
numUnreadMessages = 12L, numUnreadMessages = 12L,
numUnreadNotifications = 13L, numUnreadNotifications = 13L,
numUnreadMentions = 14L, numUnreadMentions = 14L,
historyVisibility = RoomHistoryVisibility.Joined,
) )
) )
} }
@ -188,6 +192,7 @@ class MatrixRoomInfoMapperTest {
numUnreadMessages = 12L, numUnreadMessages = 12L,
numUnreadNotifications = 13L, numUnreadNotifications = 13L,
numUnreadMentions = 14L, numUnreadMentions = 14L,
historyVisibility = RoomHistoryVisibility.Joined,
) )
) )
} }

View file

@ -33,10 +33,12 @@ import io.element.android.libraries.matrix.api.room.MessageEventType
import io.element.android.libraries.matrix.api.room.RoomMember 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.StateEventType
import io.element.android.libraries.matrix.api.room.draft.ComposerDraft import io.element.android.libraries.matrix.api.room.draft.ComposerDraft
import io.element.android.libraries.matrix.api.room.history.RoomHistoryVisibility
import io.element.android.libraries.matrix.api.room.knock.KnockRequest import io.element.android.libraries.matrix.api.room.knock.KnockRequest
import io.element.android.libraries.matrix.api.room.location.AssetType import io.element.android.libraries.matrix.api.room.location.AssetType
import io.element.android.libraries.matrix.api.room.powerlevels.MatrixRoomPowerLevels import io.element.android.libraries.matrix.api.room.powerlevels.MatrixRoomPowerLevels
import io.element.android.libraries.matrix.api.room.powerlevels.UserRoleChange import io.element.android.libraries.matrix.api.room.powerlevels.UserRoleChange
import io.element.android.libraries.matrix.api.roomdirectory.RoomVisibility
import io.element.android.libraries.matrix.api.timeline.ReceiptType import io.element.android.libraries.matrix.api.timeline.ReceiptType
import io.element.android.libraries.matrix.api.timeline.Timeline import io.element.android.libraries.matrix.api.timeline.Timeline
import io.element.android.libraries.matrix.api.timeline.item.event.EventOrTransactionId import io.element.android.libraries.matrix.api.timeline.item.event.EventOrTransactionId
@ -145,6 +147,10 @@ class FakeMatrixRoom(
private val subscribeToSyncLambda: () -> Unit = { lambdaError() }, private val subscribeToSyncLambda: () -> Unit = { lambdaError() },
private val ignoreDeviceTrustAndResendResult: (Map<UserId, List<DeviceId>>, SendHandle) -> Result<Unit> = { _, _ -> lambdaError() }, private val ignoreDeviceTrustAndResendResult: (Map<UserId, List<DeviceId>>, SendHandle) -> Result<Unit> = { _, _ -> lambdaError() },
private val withdrawVerificationAndResendResult: (List<UserId>, SendHandle) -> Result<Unit> = { _, _ -> lambdaError() }, private val withdrawVerificationAndResendResult: (List<UserId>, SendHandle) -> Result<Unit> = { _, _ -> lambdaError() },
private val updateCanonicalAliasResult: (RoomAlias?, List<RoomAlias>) -> Result<Unit> = { _, _ -> lambdaError() },
private val updateRoomVisibilityResult: (RoomVisibility) -> Result<Unit> = { lambdaError() },
private val updateRoomHistoryVisibilityResult: (RoomHistoryVisibility) -> Result<Unit> = { lambdaError() },
private val roomVisibilityResult: () -> Result<RoomVisibility> = { lambdaError() },
) : MatrixRoom { ) : MatrixRoom {
private val _roomInfoFlow: MutableSharedFlow<MatrixRoomInfo> = MutableSharedFlow(replay = 1) private val _roomInfoFlow: MutableSharedFlow<MatrixRoomInfo> = MutableSharedFlow(replay = 1)
override val roomInfoFlow: Flow<MatrixRoomInfo> = _roomInfoFlow override val roomInfoFlow: Flow<MatrixRoomInfo> = _roomInfoFlow
@ -582,6 +588,22 @@ class FakeMatrixRoom(
return withdrawVerificationAndResendResult(userIds, sendHandle) return withdrawVerificationAndResendResult(userIds, sendHandle)
} }
override suspend fun updateCanonicalAlias(canonicalAlias: RoomAlias?, alternativeAliases: List<RoomAlias>): Result<Unit> = simulateLongTask {
updateCanonicalAliasResult(canonicalAlias, alternativeAliases)
}
override suspend fun updateRoomVisibility(roomVisibility: RoomVisibility): Result<Unit> = simulateLongTask {
updateRoomVisibilityResult(roomVisibility)
}
override suspend fun updateHistoryVisibility(historyVisibility: RoomHistoryVisibility): Result<Unit> = simulateLongTask {
updateRoomHistoryVisibilityResult(historyVisibility)
}
override suspend fun getRoomVisibility(): Result<RoomVisibility> = simulateLongTask {
roomVisibilityResult()
}
fun givenRoomMembersState(state: MatrixRoomMembersState) { fun givenRoomMembersState(state: MatrixRoomMembersState) {
membersStateFlow.value = state membersStateFlow.value = state
} }

View file

@ -15,6 +15,7 @@ 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.MatrixRoomInfo
import io.element.android.libraries.matrix.api.room.RoomMember import io.element.android.libraries.matrix.api.room.RoomMember
import io.element.android.libraries.matrix.api.room.RoomNotificationMode import io.element.android.libraries.matrix.api.room.RoomNotificationMode
import io.element.android.libraries.matrix.api.room.history.RoomHistoryVisibility
import io.element.android.libraries.matrix.api.room.join.JoinRule import io.element.android.libraries.matrix.api.room.join.JoinRule
import io.element.android.libraries.matrix.api.user.MatrixUser import io.element.android.libraries.matrix.api.user.MatrixUser
import io.element.android.libraries.matrix.test.AN_AVATAR_URL import io.element.android.libraries.matrix.test.AN_AVATAR_URL
@ -58,6 +59,7 @@ fun aRoomInfo(
numUnreadMessages: Long = 0, numUnreadMessages: Long = 0,
numUnreadNotifications: Long = 0, numUnreadNotifications: Long = 0,
numUnreadMentions: Long = 0, numUnreadMentions: Long = 0,
historyVisibility: RoomHistoryVisibility = RoomHistoryVisibility.Joined,
) = MatrixRoomInfo( ) = MatrixRoomInfo(
id = id, id = id,
name = name, name = name,
@ -90,4 +92,5 @@ fun aRoomInfo(
numUnreadMessages = numUnreadMessages, numUnreadMessages = numUnreadMessages,
numUnreadNotifications = numUnreadNotifications, numUnreadNotifications = numUnreadNotifications,
numUnreadMentions = numUnreadMentions, numUnreadMentions = numUnreadMentions,
historyVisibility = historyVisibility,
) )

View file

@ -15,6 +15,7 @@ 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.MatrixRoomInfo
import io.element.android.libraries.matrix.api.room.RoomMember import io.element.android.libraries.matrix.api.room.RoomMember
import io.element.android.libraries.matrix.api.room.RoomNotificationMode import io.element.android.libraries.matrix.api.room.RoomNotificationMode
import io.element.android.libraries.matrix.api.room.history.RoomHistoryVisibility
import io.element.android.libraries.matrix.api.room.join.JoinRule import io.element.android.libraries.matrix.api.room.join.JoinRule
import io.element.android.libraries.matrix.api.room.message.RoomMessage import io.element.android.libraries.matrix.api.room.message.RoomMessage
import io.element.android.libraries.matrix.api.roomlist.RoomSummary import io.element.android.libraries.matrix.api.roomlist.RoomSummary
@ -71,6 +72,7 @@ fun aRoomSummary(
numUnreadMessages: Long = 0, numUnreadMessages: Long = 0,
numUnreadNotifications: Long = 0, numUnreadNotifications: Long = 0,
numUnreadMentions: Long = 0, numUnreadMentions: Long = 0,
historyVisibility: RoomHistoryVisibility = RoomHistoryVisibility.Joined,
lastMessage: RoomMessage? = aRoomMessage(), lastMessage: RoomMessage? = aRoomMessage(),
) = RoomSummary( ) = RoomSummary(
info = MatrixRoomInfo( info = MatrixRoomInfo(
@ -105,6 +107,7 @@ fun aRoomSummary(
numUnreadMessages = numUnreadMessages, numUnreadMessages = numUnreadMessages,
numUnreadNotifications = numUnreadNotifications, numUnreadNotifications = numUnreadNotifications,
numUnreadMentions = numUnreadMentions, numUnreadMentions = numUnreadMentions,
historyVisibility = historyVisibility,
), ),
lastMessage = lastMessage, lastMessage = lastMessage,
) )