Take into account homeserver capabilities (#6507)

* Take into account homeserver capabilities: add `HomeserverCapabilitiesProvider` to check if the HS allows changing the user's display name or avatar. Also, modify the edit user profile screen to reflect these values.

* Add `/myavatar` command. Filter both `/nick` and `/myavatar` commands based on the homeserver capabilities.

* Update screenshots

* Assume the use can change their display name and avatar url if the capabilities check fails: if they try to change those, the HS will return an error anyway.

* Disable also `/myroomname` and `/myroomavatar` based on the HS capabilities.

---------

Co-authored-by: ElementBot <android@element.io>
This commit is contained in:
Jorge Martin Espinosa 2026-04-15 14:29:41 +02:00 committed by GitHub
parent 80470b3792
commit 66513bc905
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
26 changed files with 363 additions and 14 deletions

View file

@ -0,0 +1,28 @@
/*
* Copyright (c) 2026 Element Creations 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
import io.element.android.libraries.core.extensions.runCatchingExceptions
import io.element.android.libraries.matrix.api.HomeserverCapabilitiesProvider
import org.matrix.rustcomponents.sdk.HomeserverCapabilities
class RustHomeserverCapabilitiesProvider(
private val homeserverCapabilities: HomeserverCapabilities,
) : HomeserverCapabilitiesProvider {
override suspend fun refresh(): Result<Unit> = runCatchingExceptions {
homeserverCapabilities.refresh()
}
override suspend fun canChangeDisplayName(): Result<Boolean> = runCatchingExceptions {
homeserverCapabilities.canChangeDisplayname()
}
override suspend fun canChangeAvatarUrl(): Result<Boolean> = runCatchingExceptions {
homeserverCapabilities.canChangeAvatar()
}
}

View file

@ -17,6 +17,7 @@ import io.element.android.libraries.core.data.tryOrNull
import io.element.android.libraries.core.extensions.mapFailure
import io.element.android.libraries.core.extensions.runCatchingExceptions
import io.element.android.libraries.featureflag.api.FeatureFlagService
import io.element.android.libraries.matrix.api.HomeserverCapabilitiesProvider
import io.element.android.libraries.matrix.api.MatrixClient
import io.element.android.libraries.matrix.api.analytics.SdkStoreSizes
import io.element.android.libraries.matrix.api.core.DeviceId
@ -835,6 +836,10 @@ class RustMatrixClient(
val request = PerformDatabaseVacuumRequestBuilder(sessionId)
sessionCoroutineScope.launch { workManagerScheduler.submit(request) }
}
override fun homeserverCapabilities(): HomeserverCapabilitiesProvider {
return RustHomeserverCapabilitiesProvider(innerClient.homeserverCapabilities())
}
}
private fun defaultRoomCreationPowerLevels(isPublic: Boolean, isSpace: Boolean) = PowerLevels(

View file

@ -13,6 +13,7 @@ import dev.zacsweers.metro.ContributesTo
import dev.zacsweers.metro.Provides
import io.element.android.libraries.di.SessionScope
import io.element.android.libraries.di.annotations.SessionCoroutineScope
import io.element.android.libraries.matrix.api.HomeserverCapabilitiesProvider
import io.element.android.libraries.matrix.api.MatrixClient
import io.element.android.libraries.matrix.api.core.SessionId
import io.element.android.libraries.matrix.api.encryption.EncryptionService
@ -90,4 +91,9 @@ object SessionMatrixModule {
fun providesSpaceService(matrixClient: MatrixClient): SpaceService {
return matrixClient.spaceService
}
@Provides
fun providesHomeserverCapabilitiesProvider(matrixClient: MatrixClient): HomeserverCapabilitiesProvider {
return matrixClient.homeserverCapabilities()
}
}