From 2c107eeab31e5e612f3e2616576ede514e123ccf Mon Sep 17 00:00:00 2001 From: ganfra Date: Wed, 30 Oct 2024 18:20:57 +0100 Subject: [PATCH] create room : start integrating the address field --- .../createroom/impl/CreateRoomConfig.kt | 4 +++- .../createroom/impl/CreateRoomDataStore.kt | 3 ++- .../configureroom/ConfigureRoomPresenter.kt | 16 ++++++++++------ .../impl/configureroom/ConfigureRoomState.kt | 4 +--- .../ConfigureRoomStateProvider.kt | 3 ++- .../impl/configureroom/ConfigureRoomView.kt | 13 +++++-------- .../impl/configureroom/RoomAddress.kt | 6 +++--- .../configureroom/RoomAddressErrorState.kt | 17 +++++++++++++++++ .../impl/configureroom/RoomVisibilityState.kt | 19 ++++++++++++++++++- .../api/createroom/CreateRoomParameters.kt | 2 ++ .../libraries/matrix/impl/RustMatrixClient.kt | 3 ++- 11 files changed, 65 insertions(+), 25 deletions(-) create mode 100644 features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/RoomAddressErrorState.kt diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/CreateRoomConfig.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/CreateRoomConfig.kt index a83673886d..ab6e116598 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/CreateRoomConfig.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/CreateRoomConfig.kt @@ -19,4 +19,6 @@ data class CreateRoomConfig( val avatarUri: Uri? = null, val invites: ImmutableList = persistentListOf(), val roomVisibility: RoomVisibilityState = RoomVisibilityState.Private, -) +) { + val isValid = roomName.isNullOrEmpty().not() && roomVisibility.isValid() +} diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/CreateRoomDataStore.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/CreateRoomDataStore.kt index 17d7d5cc3d..1c08068d67 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/CreateRoomDataStore.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/CreateRoomDataStore.kt @@ -11,6 +11,7 @@ import android.net.Uri import io.element.android.features.createroom.impl.configureroom.RoomAccess import io.element.android.features.createroom.impl.configureroom.RoomAccessItem import io.element.android.features.createroom.impl.configureroom.RoomAddress +import io.element.android.features.createroom.impl.configureroom.RoomAddressErrorState import io.element.android.features.createroom.impl.configureroom.RoomVisibilityItem import io.element.android.features.createroom.impl.configureroom.RoomVisibilityState import io.element.android.features.createroom.impl.di.CreateRoomScope @@ -23,7 +24,6 @@ import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.getAndUpdate import java.io.File -import java.text.Normalizer import javax.inject.Inject @SingleIn(CreateRoomScope::class) @@ -86,6 +86,7 @@ class CreateRoomDataStore @Inject constructor( RoomVisibilityItem.Private -> RoomVisibilityState.Private RoomVisibilityItem.Public -> RoomVisibilityState.Public( roomAddress = RoomAddress.AutoFilled(config.roomName.orEmpty()), + roomAddressErrorState = RoomAddressErrorState.None, roomAccess = RoomAccess.Anyone, ) } 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 13a4952308..7addc8aca9 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 @@ -22,7 +22,7 @@ import io.element.android.features.createroom.impl.CreateRoomConfig import io.element.android.features.createroom.impl.CreateRoomDataStore import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.Presenter -import io.element.android.libraries.architecture.runCatchingUpdatingState +import io.element.android.libraries.architecture.runUpdatingState import io.element.android.libraries.core.mimetype.MimeTypes import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.core.RoomId @@ -39,7 +39,7 @@ import io.element.android.services.analytics.api.AnalyticsService import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch -import java.util.Optional +import timber.log.Timber import javax.inject.Inject class ConfigureRoomPresenter @Inject constructor( @@ -132,7 +132,7 @@ class ConfigureRoomPresenter @Inject constructor( config: CreateRoomConfig, createRoomAction: MutableState> ) = launch { - suspend { + runUpdatingState(createRoomAction) { val avatarUrl = config.avatarUri?.let { uploadAvatar(it) } val params = CreateRoomParameters( name = config.roomName, @@ -144,13 +144,17 @@ class ConfigureRoomPresenter @Inject constructor( preset = if (config.roomVisibility is RoomVisibilityState.Public) RoomPreset.PUBLIC_CHAT else RoomPreset.PRIVATE_CHAT, invite = config.invites.map { it.userId }, avatar = avatarUrl, + canonicalAlias = config.roomVisibility.roomAddress() ) - matrixClient.createRoom(params).getOrThrow() - .also { + matrixClient.createRoom(params) + .onFailure { failure -> + Timber.e(failure, "Failed to create room") + } + .onSuccess { dataStore.clearCachedData() analyticsService.capture(CreatedRoom(isDM = false)) } - }.runCatchingUpdatingState(createRoomAction) + } } private suspend fun uploadAvatar(avatarUri: Uri): String { diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomState.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomState.kt index b59ae887e5..2bbcd521ac 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomState.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomState.kt @@ -21,6 +21,4 @@ data class ConfigureRoomState( val cameraPermissionState: PermissionsState, val homeserverName: String, val eventSink: (ConfigureRoomEvents) -> Unit -) { - val isCreateButtonEnabled: Boolean = config.roomName.isNullOrEmpty().not() -} +) diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomStateProvider.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomStateProvider.kt index af32ac8b13..42ace6c73a 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomStateProvider.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/ConfigureRoomStateProvider.kt @@ -26,7 +26,8 @@ open class ConfigureRoomStateProvider : PreviewParameterProvider Unit, @@ -326,13 +326,10 @@ private fun RoomAddress( color = MaterialTheme.colorScheme.primary, text = "Room address", ) - + TextField( modifier = Modifier.fillMaxWidth(), - value = when (address) { - is RoomAddress.AutoFilled -> address.address - is RoomAddress.Edited -> address.address - }, + value = address.value, leadingIcon = { Text( text = "#", diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/RoomAddress.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/RoomAddress.kt index a26888e08d..5c10cfb7b5 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/RoomAddress.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/RoomAddress.kt @@ -7,7 +7,7 @@ package io.element.android.features.createroom.impl.configureroom -sealed interface RoomAddress { - data class AutoFilled(val address: String) : RoomAddress - data class Edited(val address: String) : RoomAddress +sealed class RoomAddress(open val value: String) { + data class AutoFilled(override val value: String) : RoomAddress(value) + data class Edited(override val value: String) : RoomAddress(value) } diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/RoomAddressErrorState.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/RoomAddressErrorState.kt new file mode 100644 index 0000000000..f2cadfd6bb --- /dev/null +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/RoomAddressErrorState.kt @@ -0,0 +1,17 @@ +/* + * Copyright 2024 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only + * Please see LICENSE in the repository root for full details. + */ + +package io.element.android.features.createroom.impl.configureroom + +/** + * Represents the error state of a room address. + */ +sealed interface RoomAddressErrorState { + data object InvalidCharacters : RoomAddressErrorState + data object AlreadyExists : RoomAddressErrorState + data object None : RoomAddressErrorState +} diff --git a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/RoomVisibilityState.kt b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/RoomVisibilityState.kt index ad61fadb3a..cc5af7836e 100644 --- a/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/RoomVisibilityState.kt +++ b/features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/configureroom/RoomVisibilityState.kt @@ -7,11 +7,28 @@ package io.element.android.features.createroom.impl.configureroom +import java.util.Optional + sealed interface RoomVisibilityState { data object Private : RoomVisibilityState data class Public( val roomAddress: RoomAddress, - val roomAccess: RoomAccess + val roomAddressErrorState: RoomAddressErrorState, + val roomAccess: RoomAccess, ) : RoomVisibilityState + + fun roomAddress(): Optional { + return when (this) { + is Private -> Optional.empty() + is Public -> Optional.of(roomAddress.value) + } + } + + fun isValid(): Boolean { + return when (this) { + is Private -> true + is Public -> roomAddressErrorState is RoomAddressErrorState.None && roomAddress.value.isNotEmpty() + } + } } 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 4c74153a31..2e13623c96 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,7 @@ package io.element.android.libraries.matrix.api.createroom import io.element.android.libraries.matrix.api.core.UserId +import java.util.Optional data class CreateRoomParameters( val name: String?, @@ -19,4 +20,5 @@ data class CreateRoomParameters( val invite: List? = null, val avatar: String? = null, val joinRuleOverride: JoinRuleOverride = JoinRuleOverride.None, + val canonicalAlias: Optional = Optional.empty(), ) 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 c73b3c50a6..3417c9b377 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 @@ -324,7 +324,8 @@ class RustMatrixClient( joinRuleOverride = when (createRoomParams.joinRuleOverride) { JoinRuleOverride.Knock -> RustJoinRule.Knock JoinRuleOverride.None -> null - } + }, + canonicalAlias = createRoomParams.canonicalAlias.getOrNull(), ) val roomId = RoomId(client.createRoom(rustParams)) // Wait to receive the room back from the sync but do not returns failure if it fails.