diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenter.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenter.kt index 1b63f50134..b8d5916d57 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenter.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomPresenter.kt @@ -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.createroom.CreateRoomParameters 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.roomAliasFromName +import io.element.android.libraries.matrix.api.roomdirectory.RoomVisibility import io.element.android.libraries.matrix.ui.media.AvatarAction import io.element.android.libraries.mediapickers.api.PickerProvider import io.element.android.libraries.mediaupload.api.MediaPreProcessor @@ -191,7 +191,7 @@ class ConfigureRoomPresenter @Inject constructor( topic = config.topic, isEncrypted = false, isDirect = false, - visibility = RoomVisibility.PUBLIC, + visibility = RoomVisibility.Public, joinRuleOverride = config.roomVisibility.roomAccess.toJoinRule(), preset = RoomPreset.PUBLIC_CHAT, invite = config.invites.map { it.userId }, @@ -204,7 +204,7 @@ class ConfigureRoomPresenter @Inject constructor( topic = config.topic, isEncrypted = config.roomVisibility is RoomVisibilityState.Private, isDirect = false, - visibility = RoomVisibility.PRIVATE, + visibility = RoomVisibility.Private, preset = RoomPreset.PRIVATE_CHAT, invite = config.invites.map { it.userId }, avatar = avatarUrl, diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/RoomAccess.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/RoomAccess.kt index e85fec13f1..ef35b654cc 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/RoomAccess.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/RoomAccess.kt @@ -7,16 +7,16 @@ 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 { Anyone, Knocking } -fun RoomAccess.toJoinRule(): JoinRuleOverride { +fun RoomAccess.toJoinRule(): JoinRule? { return when (this) { - RoomAccess.Anyone -> JoinRuleOverride.None - RoomAccess.Knocking -> JoinRuleOverride.Knock + RoomAccess.Anyone -> null + RoomAccess.Knocking -> JoinRule.Knock } } diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/createroom/CreateRoomParameters.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/createroom/CreateRoomParameters.kt index abf00887d0..431a49fbea 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/createroom/CreateRoomParameters.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/createroom/CreateRoomParameters.kt @@ -8,6 +8,8 @@ package io.element.android.libraries.matrix.api.createroom 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 data class CreateRoomParameters( @@ -19,6 +21,6 @@ data class CreateRoomParameters( val preset: RoomPreset, val invite: List? = null, val avatar: String? = null, - val joinRuleOverride: JoinRuleOverride = JoinRuleOverride.None, + val joinRuleOverride: JoinRule? = null, val roomAliasName: Optional = Optional.empty(), ) diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/createroom/JoinRuleOverride.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/createroom/JoinRuleOverride.kt deleted file mode 100644 index fee17adc26..0000000000 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/createroom/JoinRuleOverride.kt +++ /dev/null @@ -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 -} diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/createroom/RoomVisibility.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/createroom/RoomVisibility.kt deleted file mode 100644 index e677d4292a..0000000000 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/createroom/RoomVisibility.kt +++ /dev/null @@ -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, -} diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/MatrixRoom.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/MatrixRoom.kt index bb86684be0..9275907f66 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/MatrixRoom.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/MatrixRoom.kt @@ -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.poll.PollKind 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.location.AssetType 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.roomdirectory.RoomVisibility 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.item.event.EventOrTransactionId @@ -402,4 +404,32 @@ interface MatrixRoom : Closeable { suspend fun withdrawVerificationAndResend(userIds: List, sendHandle: SendHandle): Result 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 + ): Result + + /** + * Update the room's visibility in the room directory. + */ + suspend fun updateRoomVisibility(roomVisibility: RoomVisibility): Result + + /** + * Update room history visibility for this room. + */ + suspend fun updateHistoryVisibility(historyVisibility: RoomHistoryVisibility): Result + + /** + * 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 } diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/MatrixRoomInfo.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/MatrixRoomInfo.kt index 41456bd4ee..ff525c403d 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/MatrixRoomInfo.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/MatrixRoomInfo.kt @@ -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.RoomId 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.user.MatrixUser import kotlinx.collections.immutable.ImmutableList @@ -71,6 +72,7 @@ data class MatrixRoomInfo( val heroes: ImmutableList, val pinnedEventIds: ImmutableList, val creator: UserId?, + val historyVisibility: RoomHistoryVisibility, ) { val aliases: List get() = listOfNotNull(canonicalAlias) + alternativeAliases diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/history/RoomHistoryVisibility.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/history/RoomHistoryVisibility.kt new file mode 100644 index 0000000000..09faa9fb00 --- /dev/null +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/history/RoomHistoryVisibility.kt @@ -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 +} diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/roomdirectory/RoomVisibility.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/roomdirectory/RoomVisibility.kt new file mode 100644 index 0000000000..f29c2aac59 --- /dev/null +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/roomdirectory/RoomVisibility.kt @@ -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 +} diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt index 4f470d556e..8bc6976924 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClient.kt @@ -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.toRoomIdOrAlias 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.RoomVisibility 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.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.RoomMembershipObserver 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.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.RoomSummary 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.RustRoomFactory 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.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.RustRoomListService 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.Companion.seconds 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.RoomVisibility as RustRoomVisibility import org.matrix.rustcomponents.sdk.SyncService as ClientSyncService class RustMatrixClient( @@ -310,36 +310,23 @@ class RustMatrixClient( topic = createRoomParams.topic, isEncrypted = createRoomParams.isEncrypted, isDirect = createRoomParams.isDirect, - visibility = when (createRoomParams.visibility) { - RoomVisibility.PUBLIC -> RustRoomVisibility.Public - RoomVisibility.PRIVATE -> RustRoomVisibility.Private - }, - preset = when (createRoomParams.visibility) { - RoomVisibility.PRIVATE -> { - if (createRoomParams.isDirect) { - RustRoomPreset.TRUSTED_PRIVATE_CHAT - } else { - RustRoomPreset.PRIVATE_CHAT - } - } - RoomVisibility.PUBLIC -> { - RustRoomPreset.PUBLIC_CHAT - } + visibility = createRoomParams.visibility.map(), + preset = when (createRoomParams.preset) { + RoomPreset.PRIVATE_CHAT -> RustRoomPreset.PRIVATE_CHAT + RoomPreset.TRUSTED_PRIVATE_CHAT -> RustRoomPreset.TRUSTED_PRIVATE_CHAT + RoomPreset.PUBLIC_CHAT -> RustRoomPreset.PUBLIC_CHAT }, invite = createRoomParams.invite?.map { it.value }, avatar = createRoomParams.avatar, 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. RoomMember.Role.MODERATOR.powerLevel.toInt() } else { null } ), - joinRuleOverride = when (createRoomParams.joinRuleOverride) { - JoinRuleOverride.Knock -> RustJoinRule.Knock - JoinRuleOverride.None -> null - }, + joinRuleOverride = createRoomParams.joinRuleOverride?.map(), canonicalAlias = createRoomParams.roomAliasName.getOrNull(), ) val roomId = RoomId(innerClient.createRoom(rustParams)) @@ -358,7 +345,7 @@ class RustMatrixClient( name = null, isEncrypted = true, isDirect = true, - visibility = RoomVisibility.PRIVATE, + visibility = RoomVisibility.Private, preset = RoomPreset.TRUSTED_PRIVATE_CHAT, invite = listOf(userId), ) diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/MatrixRoomInfoMapper.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/MatrixRoomInfoMapper.kt index 4072981a77..0be4ccbc67 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/MatrixRoomInfoMapper.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/MatrixRoomInfoMapper.kt @@ -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.RoomNotificationMode 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.member.RoomMemberMapper import kotlinx.collections.immutable.ImmutableMap @@ -60,6 +61,7 @@ class MatrixRoomInfoMapper { numUnreadMessages = it.numUnreadMessages.toLong(), numUnreadMentions = it.numUnreadMentions.toLong(), numUnreadNotifications = it.numUnreadNotifications.toLong(), + historyVisibility = it.historyVisibility.map(), ) } } diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustMatrixRoom.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustMatrixRoom.kt index 7217b25dcd..0823e8396c 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustMatrixRoom.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustMatrixRoom.kt @@ -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.StateEventType 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.location.AssetType 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.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.Timeline 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.mapper.map 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.member.RoomMemberListFetcher 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.roomdirectory.map 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.util.MessageEventContent @@ -775,6 +779,30 @@ class RustMatrixRoom( } } + override suspend fun updateCanonicalAlias(canonicalAlias: RoomAlias?, alternativeAliases: List): Result = withContext(roomDispatcher) { + runCatching { + innerRoom.updateCanonicalAlias(canonicalAlias?.value, alternativeAliases.map { it.value }) + } + } + + override suspend fun updateRoomVisibility(roomVisibility: RoomVisibility): Result = withContext(roomDispatcher) { + runCatching { + innerRoom.updateRoomVisibility(roomVisibility.map()) + } + } + + override suspend fun updateHistoryVisibility(historyVisibility: RoomHistoryVisibility): Result = withContext(roomDispatcher) { + runCatching { + innerRoom.updateHistoryVisibility(historyVisibility.map()) + } + } + + override suspend fun getRoomVisibility(): Result = withContext(roomDispatcher) { + runCatching { + innerRoom.getRoomVisibility().map() + } + } + private fun createTimeline( timeline: InnerTimeline, mode: Timeline.Mode, diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/history/RoomHistoryVisibilityMapper.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/history/RoomHistoryVisibilityMapper.kt new file mode 100644 index 0000000000..60ff7cc698 --- /dev/null +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/history/RoomHistoryVisibilityMapper.kt @@ -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) + } +} diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/join/AllowRule.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/join/AllowRule.kt index 8c2269e0d5..ae74e1edc0 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/join/AllowRule.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/join/AllowRule.kt @@ -17,3 +17,10 @@ fun RustAllowRule.map(): AllowRule { 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) + } +} diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/join/JoinRule.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/join/JoinRule.kt index dc652346bc..bc10a369a4 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/join/JoinRule.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/join/JoinRule.kt @@ -21,3 +21,15 @@ fun RustJoinRule.map(): JoinRule { 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() }) + } +} diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomdirectory/RoomVisibilityMapper.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomdirectory/RoomVisibilityMapper.kt new file mode 100644 index 0000000000..bfbc48d3b9 --- /dev/null +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomdirectory/RoomVisibilityMapper.kt @@ -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) + } +} diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/room/MatrixRoomInfoMapperTest.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/room/MatrixRoomInfoMapperTest.kt index 16a9df1d56..0639f8e9e4 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/room/MatrixRoomInfoMapperTest.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/room/MatrixRoomInfoMapperTest.kt @@ -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.MatrixRoomInfo 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.user.MatrixUser 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.JoinRule as RustJoinRule import org.matrix.rustcomponents.sdk.RoomNotificationMode as RustRoomNotificationMode +import org.matrix.rustcomponents.sdk.RoomHistoryVisibility as RustRoomHistoryVisibility class MatrixRoomInfoMapperTest { @Test @@ -72,6 +74,7 @@ class MatrixRoomInfoMapperTest { numUnreadMentions = 14uL, pinnedEventIds = listOf(AN_EVENT_ID.value), roomCreator = A_USER_ID, + historyVisibility = RustRoomHistoryVisibility.Joined, ) ) ).isEqualTo( @@ -113,6 +116,7 @@ class MatrixRoomInfoMapperTest { numUnreadMessages = 12L, numUnreadNotifications = 13L, numUnreadMentions = 14L, + historyVisibility = RoomHistoryVisibility.Joined, ) ) } @@ -188,6 +192,7 @@ class MatrixRoomInfoMapperTest { numUnreadMessages = 12L, numUnreadNotifications = 13L, numUnreadMentions = 14L, + historyVisibility = RoomHistoryVisibility.Joined, ) ) } 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 62d19bd66c..551bb93795 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 @@ -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.StateEventType 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.location.AssetType 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.roomdirectory.RoomVisibility 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.item.event.EventOrTransactionId @@ -145,6 +147,10 @@ class FakeMatrixRoom( private val subscribeToSyncLambda: () -> Unit = { lambdaError() }, private val ignoreDeviceTrustAndResendResult: (Map>, SendHandle) -> Result = { _, _ -> lambdaError() }, private val withdrawVerificationAndResendResult: (List, SendHandle) -> Result = { _, _ -> lambdaError() }, + private val updateCanonicalAliasResult: (RoomAlias?, List) -> Result = { _, _ -> lambdaError() }, + private val updateRoomVisibilityResult: (RoomVisibility) -> Result = { lambdaError() }, + private val updateRoomHistoryVisibilityResult: (RoomHistoryVisibility) -> Result = { lambdaError() }, + private val roomVisibilityResult: () -> Result = { lambdaError() }, ) : MatrixRoom { private val _roomInfoFlow: MutableSharedFlow = MutableSharedFlow(replay = 1) override val roomInfoFlow: Flow = _roomInfoFlow @@ -582,6 +588,22 @@ class FakeMatrixRoom( return withdrawVerificationAndResendResult(userIds, sendHandle) } + override suspend fun updateCanonicalAlias(canonicalAlias: RoomAlias?, alternativeAliases: List): Result = simulateLongTask { + updateCanonicalAliasResult(canonicalAlias, alternativeAliases) + } + + override suspend fun updateRoomVisibility(roomVisibility: RoomVisibility): Result = simulateLongTask { + updateRoomVisibilityResult(roomVisibility) + } + + override suspend fun updateHistoryVisibility(historyVisibility: RoomHistoryVisibility): Result = simulateLongTask { + updateRoomHistoryVisibilityResult(historyVisibility) + } + + override suspend fun getRoomVisibility(): Result = simulateLongTask { + roomVisibilityResult() + } + fun givenRoomMembersState(state: MatrixRoomMembersState) { membersStateFlow.value = state } diff --git a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/RoomInfoFixture.kt b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/RoomInfoFixture.kt index 6920f9f8a0..ed62d96d98 100644 --- a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/RoomInfoFixture.kt +++ b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/RoomInfoFixture.kt @@ -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.RoomMember 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.user.MatrixUser import io.element.android.libraries.matrix.test.AN_AVATAR_URL @@ -58,6 +59,7 @@ fun aRoomInfo( numUnreadMessages: Long = 0, numUnreadNotifications: Long = 0, numUnreadMentions: Long = 0, + historyVisibility: RoomHistoryVisibility = RoomHistoryVisibility.Joined, ) = MatrixRoomInfo( id = id, name = name, @@ -90,4 +92,5 @@ fun aRoomInfo( numUnreadMessages = numUnreadMessages, numUnreadNotifications = numUnreadNotifications, numUnreadMentions = numUnreadMentions, + historyVisibility = historyVisibility, ) diff --git a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/RoomSummaryFixture.kt b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/RoomSummaryFixture.kt index c741f031b8..df34bcc734 100644 --- a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/RoomSummaryFixture.kt +++ b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/RoomSummaryFixture.kt @@ -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.RoomMember 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.message.RoomMessage import io.element.android.libraries.matrix.api.roomlist.RoomSummary @@ -71,6 +72,7 @@ fun aRoomSummary( numUnreadMessages: Long = 0, numUnreadNotifications: Long = 0, numUnreadMentions: Long = 0, + historyVisibility: RoomHistoryVisibility = RoomHistoryVisibility.Joined, lastMessage: RoomMessage? = aRoomMessage(), ) = RoomSummary( info = MatrixRoomInfo( @@ -105,6 +107,7 @@ fun aRoomSummary( numUnreadMessages = numUnreadMessages, numUnreadNotifications = numUnreadNotifications, numUnreadMentions = numUnreadMentions, + historyVisibility = historyVisibility, ), lastMessage = lastMessage, )