create room : start integrating the address field
This commit is contained in:
@@ -19,4 +19,6 @@ data class CreateRoomConfig(
|
||||
val avatarUri: Uri? = null,
|
||||
val invites: ImmutableList<MatrixUser> = persistentListOf(),
|
||||
val roomVisibility: RoomVisibilityState = RoomVisibilityState.Private,
|
||||
)
|
||||
) {
|
||||
val isValid = roomName.isNullOrEmpty().not() && roomVisibility.isValid()
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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<AsyncAction<RoomId>>
|
||||
) = 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 {
|
||||
|
||||
@@ -21,6 +21,4 @@ data class ConfigureRoomState(
|
||||
val cameraPermissionState: PermissionsState,
|
||||
val homeserverName: String,
|
||||
val eventSink: (ConfigureRoomEvents) -> Unit
|
||||
) {
|
||||
val isCreateButtonEnabled: Boolean = config.roomName.isNullOrEmpty().not()
|
||||
}
|
||||
)
|
||||
|
||||
@@ -26,7 +26,8 @@ open class ConfigureRoomStateProvider : PreviewParameterProvider<ConfigureRoomSt
|
||||
invites = aMatrixUserList().toImmutableList(),
|
||||
roomVisibility = RoomVisibilityState.Public(
|
||||
roomAddress = RoomAddress.AutoFilled("Room 101"),
|
||||
roomAccess = RoomAccess.Knocking
|
||||
roomAccess = RoomAccess.Knocking,
|
||||
roomAddressErrorState = RoomAddressErrorState.None,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -78,7 +78,7 @@ fun ConfigureRoomView(
|
||||
modifier = modifier.clearFocusOnTap(focusManager),
|
||||
topBar = {
|
||||
ConfigureRoomToolbar(
|
||||
isNextActionEnabled = state.isCreateButtonEnabled,
|
||||
isNextActionEnabled = state.config.isValid,
|
||||
onBackClick = onBackClick,
|
||||
onNextClick = {
|
||||
focusManager.clearFocus()
|
||||
@@ -138,7 +138,7 @@ fun ConfigureRoomView(
|
||||
state.eventSink(ConfigureRoomEvents.RoomAccessChanged(it))
|
||||
},
|
||||
)
|
||||
RoomAddress(
|
||||
RoomAddressField(
|
||||
modifier = Modifier.padding(horizontal = 16.dp),
|
||||
address = state.config.roomVisibility.roomAddress,
|
||||
homeserverName = state.homeserverName,
|
||||
@@ -310,7 +310,7 @@ private fun RoomAccessOptions(
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun RoomAddress(
|
||||
private fun RoomAddressField(
|
||||
address: RoomAddress,
|
||||
homeserverName: String,
|
||||
onAddressChange: (String) -> 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 = "#",
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
@@ -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<String> {
|
||||
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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<UserId>? = null,
|
||||
val avatar: String? = null,
|
||||
val joinRuleOverride: JoinRuleOverride = JoinRuleOverride.None,
|
||||
val canonicalAlias: Optional<String> = Optional.empty(),
|
||||
)
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user