feat(room address) : extract some reusable code

This commit is contained in:
ganfra 2025-01-21 21:55:06 +01:00
parent 129eb45c68
commit 9faa305262
7 changed files with 142 additions and 83 deletions

View file

@ -0,0 +1,74 @@
/*
* 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.ui.room.address
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import io.element.android.compound.theme.ElementTheme
import io.element.android.libraries.designsystem.preview.ElementPreview
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
import io.element.android.libraries.designsystem.theme.components.Text
import io.element.android.libraries.designsystem.theme.components.TextField
import io.element.android.libraries.ui.strings.CommonStrings
@Composable
fun RoomAddressField(
address: String,
homeserverName: String,
addressValidity: RoomAddressValidity,
onAddressChange: (String) -> Unit,
label: String,
supportingText: String,
modifier: Modifier = Modifier,
) {
TextField(
modifier = modifier,
value = address,
label = label,
leadingIcon = {
Text(
text = "#",
style = ElementTheme.typography.fontBodyLgMedium,
color = ElementTheme.colors.textSecondary,
)
},
trailingIcon = {
Text(
text = homeserverName,
style = ElementTheme.typography.fontBodyLgMedium,
color = ElementTheme.colors.textSecondary,
)
},
supportingText = when (addressValidity) {
RoomAddressValidity.InvalidSymbols -> {
stringResource(CommonStrings.error_room_address_invalid_symbols)
}
RoomAddressValidity.NotAvailable -> {
stringResource(CommonStrings.error_room_address_already_exists)
}
else -> supportingText
},
isError = addressValidity.isError(),
onValueChange = onAddressChange,
singleLine = true,
)
}
@PreviewsDayNight
@Composable
fun RoomAddressFieldPreview() = ElementPreview {
RoomAddressField(
address = "room",
homeserverName = "element.io",
addressValidity = RoomAddressValidity.Valid,
onAddressChange = {},
label = "Room address",
supportingText = "This is the address that people will use to join your room",
)
}

View file

@ -0,0 +1,26 @@
/*
* 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.ui.room.address
import androidx.compose.runtime.Immutable
/**
* Represents the validity state of a room address.
* ie. whether it contains invalid characters, is already taken, or is valid.
*/
@Immutable
sealed interface RoomAddressValidity {
data object Unknown : RoomAddressValidity
data object InvalidSymbols : RoomAddressValidity
data object NotAvailable : RoomAddressValidity
data object Valid : RoomAddressValidity
fun isError(): Boolean {
return this is InvalidSymbols || this is NotAvailable
}
}

View file

@ -0,0 +1,52 @@
/*
* 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.ui.room.address
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.rememberUpdatedState
import io.element.android.libraries.matrix.api.MatrixClient
import io.element.android.libraries.matrix.api.room.alias.RoomAliasHelper
import io.element.android.libraries.matrix.api.roomAliasFromName
import kotlinx.coroutines.delay
@Composable
fun RoomAddressValidityEffect(
client: MatrixClient,
roomAliasHelper: RoomAliasHelper,
newRoomAddress: String,
knownRoomAddress: String?,
onRoomAddressValidityChange: (RoomAddressValidity) -> Unit,
) {
val onChange by rememberUpdatedState(onRoomAddressValidityChange)
LaunchedEffect(newRoomAddress) {
if (newRoomAddress.isEmpty() || newRoomAddress == knownRoomAddress) {
onChange(RoomAddressValidity.Unknown)
return@LaunchedEffect
}
// debounce the room address validation
delay(300)
val roomAlias = client.roomAliasFromName(newRoomAddress).getOrNull()
if (roomAlias == null || !roomAliasHelper.isRoomAliasValid(roomAlias)) {
onChange(RoomAddressValidity.InvalidSymbols)
} else {
client.resolveRoomAlias(roomAlias)
.onSuccess { resolved ->
if (resolved.isPresent) {
onChange(RoomAddressValidity.NotAvailable)
} else {
onChange(RoomAddressValidity.Valid)
}
}
.onFailure {
onChange(RoomAddressValidity.Valid)
}
}
}
}