Remove UserStatus feature flag.

This commit is contained in:
Benoit Marty
2026-08-24 14:25:03 +02:00
committed by Benoit Marty
parent 0cd6e70777
commit e50dee8b9c
4 changed files with 7 additions and 43 deletions
@@ -30,8 +30,6 @@ import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.core.extensions.runCatchingExceptions import io.element.android.libraries.core.extensions.runCatchingExceptions
import io.element.android.libraries.core.log.logger.LoggerTag import io.element.android.libraries.core.log.logger.LoggerTag
import io.element.android.libraries.core.meta.BuildMeta import io.element.android.libraries.core.meta.BuildMeta
import io.element.android.libraries.featureflag.api.FeatureFlagService
import io.element.android.libraries.featureflag.api.FeatureFlags
import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.MatrixClient
import io.element.android.libraries.matrix.api.encryption.EncryptionService import io.element.android.libraries.matrix.api.encryption.EncryptionService
import io.element.android.libraries.matrix.api.encryption.RecoveryState import io.element.android.libraries.matrix.api.encryption.RecoveryState
@@ -67,7 +65,6 @@ class LoggedInPresenter(
private val buildMeta: BuildMeta, private val buildMeta: BuildMeta,
private val networkMonitor: NetworkMonitor, private val networkMonitor: NetworkMonitor,
private val localNetworkPermissionAdvisor: LocalNetworkPermissionAdvisor, private val localNetworkPermissionAdvisor: LocalNetworkPermissionAdvisor,
private val featureFlagService: FeatureFlagService,
permissionsPresenterFactory: PermissionsPresenter.Factory, permissionsPresenterFactory: PermissionsPresenter.Factory,
) : Presenter<LoggedInState> { ) : Presenter<LoggedInState> {
private val localNetworkPermissionsPresenter: PermissionsPresenter = private val localNetworkPermissionsPresenter: PermissionsPresenter =
@@ -124,13 +121,9 @@ class LoggedInPresenter(
} }
LaunchedEffect(Unit) { LaunchedEffect(Unit) {
// Keep automatic call status (m.call) in sync with the feature flag and homeserver support. // Keep automatic call status (m.call) in sync with homeserver support.
featureFlagService.isFeatureEnabledFlow(FeatureFlags.UserStatus) val enabled = matrixClient.isUserStatusSupported().getOrDefault(false)
.onEach { isUserStatusEnabled -> matrixClient.enableAutomaticCallStatus(enabled)
val enabled = isUserStatusEnabled && matrixClient.isUserStatusSupported().getOrDefault(false)
matrixClient.enableAutomaticCallStatus(enabled)
}
.launchIn(this)
} }
val networkConnectivity by networkMonitor.connectivity.collectAsState() val networkConnectivity by networkMonitor.connectivity.collectAsState()
@@ -17,9 +17,6 @@ import im.vector.app.features.analytics.plan.UserProperties
import io.element.android.features.networkmonitor.api.NetworkStatus import io.element.android.features.networkmonitor.api.NetworkStatus
import io.element.android.features.networkmonitor.test.FakeNetworkMonitor import io.element.android.features.networkmonitor.test.FakeNetworkMonitor
import io.element.android.libraries.core.meta.BuildMeta import io.element.android.libraries.core.meta.BuildMeta
import io.element.android.libraries.featureflag.api.FeatureFlagService
import io.element.android.libraries.featureflag.api.FeatureFlags
import io.element.android.libraries.featureflag.test.FakeFeatureFlagService
import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.MatrixClient
import io.element.android.libraries.matrix.api.core.SessionId import io.element.android.libraries.matrix.api.core.SessionId
import io.element.android.libraries.matrix.api.encryption.EncryptionService import io.element.android.libraries.matrix.api.encryption.EncryptionService
@@ -131,7 +128,6 @@ class LoggedInPresenterTest {
buildMeta = buildMeta, buildMeta = buildMeta,
networkMonitor = networkMonitor, networkMonitor = networkMonitor,
localNetworkPermissionAdvisor = FakeLocalNetworkPermissionAdvisor(), localNetworkPermissionAdvisor = FakeLocalNetworkPermissionAdvisor(),
featureFlagService = FakeFeatureFlagService(),
permissionsPresenterFactory = FakePermissionsPresenterFactory(), permissionsPresenterFactory = FakePermissionsPresenterFactory(),
).test { ).test {
encryptionService.emitRecoveryState(RecoveryState.UNKNOWN) encryptionService.emitRecoveryState(RecoveryState.UNKNOWN)
@@ -362,9 +358,6 @@ class LoggedInPresenterTest {
} }
createLoggedInPresenter( createLoggedInPresenter(
matrixClient = matrixClient, matrixClient = matrixClient,
featureFlagService = FakeFeatureFlagService(
initialState = mapOf(FeatureFlags.UserStatus.key to true),
),
).test { ).test {
cancelAndConsumeRemainingEvents() cancelAndConsumeRemainingEvents()
assert(enableAutomaticCallStatusLambda) assert(enableAutomaticCallStatusLambda)
@@ -374,7 +367,7 @@ class LoggedInPresenterTest {
} }
@Test @Test
fun `present - reacts to user status flag being toggled at runtime`() = runTest { fun `present - enables automatic call status when server supports it`() = runTest {
val enableAutomaticCallStatusLambda = lambdaRecorder<Boolean, Unit> { } val enableAutomaticCallStatusLambda = lambdaRecorder<Boolean, Unit> { }
val matrixClient = FakeMatrixClient( val matrixClient = FakeMatrixClient(
accountManagementUrlResult = { Result.success(null) }, accountManagementUrlResult = { Result.success(null) },
@@ -382,23 +375,13 @@ class LoggedInPresenterTest {
).apply { ).apply {
isUserStatusSupportedResult = Result.success(true) isUserStatusSupportedResult = Result.success(true)
} }
val featureFlagService = FakeFeatureFlagService(
initialState = mapOf(FeatureFlags.UserStatus.key to false),
)
createLoggedInPresenter( createLoggedInPresenter(
matrixClient = matrixClient, matrixClient = matrixClient,
featureFlagService = featureFlagService,
).test { ).test {
awaitItem()
// Turning the flag on at runtime enables it.
featureFlagService.setFeatureEnabled(FeatureFlags.UserStatus, true)
cancelAndConsumeRemainingEvents() cancelAndConsumeRemainingEvents()
assert(enableAutomaticCallStatusLambda) assert(enableAutomaticCallStatusLambda)
.isCalledExactly(2) .isCalledOnce()
.withSequence( .with(value(true))
listOf(value(false)),
listOf(value(true)),
)
} }
} }
@@ -418,7 +401,6 @@ class LoggedInPresenterTest {
), ),
buildMeta: BuildMeta = aBuildMeta(), buildMeta: BuildMeta = aBuildMeta(),
networkMonitor: FakeNetworkMonitor = FakeNetworkMonitor(), networkMonitor: FakeNetworkMonitor = FakeNetworkMonitor(),
featureFlagService: FeatureFlagService = FakeFeatureFlagService(),
): LoggedInPresenter { ): LoggedInPresenter {
return LoggedInPresenter( return LoggedInPresenter(
matrixClient = matrixClient, matrixClient = matrixClient,
@@ -430,7 +412,6 @@ class LoggedInPresenterTest {
buildMeta = buildMeta, buildMeta = buildMeta,
networkMonitor = networkMonitor, networkMonitor = networkMonitor,
localNetworkPermissionAdvisor = FakeLocalNetworkPermissionAdvisor(), localNetworkPermissionAdvisor = FakeLocalNetworkPermissionAdvisor(),
featureFlagService = featureFlagService,
permissionsPresenterFactory = FakePermissionsPresenterFactory(), permissionsPresenterFactory = FakePermissionsPresenterFactory(),
) )
} }
@@ -76,10 +76,7 @@ class PreferencesRootPresenter(
}.collectAsState(initial = false) }.collectAsState(initial = false)
val isUserStatusSupported by produceState(false) { val isUserStatusSupported by produceState(false) {
featureFlagService.isFeatureEnabledFlow(FeatureFlags.UserStatus) value = matrixClient.isUserStatusSupported().getOrDefault(false)
.collect { isUserStatusEnabled ->
value = isUserStatusEnabled && matrixClient.isUserStatusSupported().getOrDefault(false)
}
} }
val userStatusState = if (isUserStatusSupported) userStatusPresenter.present() else null val userStatusState = if (isUserStatusSupported) userStatusPresenter.present() else null
@@ -152,13 +152,6 @@ enum class FeatureFlags(
defaultValue = { false }, defaultValue = { false },
isFinished = false, isFinished = false,
), ),
UserStatus(
key = "feature.user_status",
title = "User status",
description = "Allow users to set a status (e.g. In a meeting, Away) visible to their contacts.",
defaultValue = { false },
isFinished = false,
),
MessageSearch( MessageSearch(
key = "feature.message_search", key = "feature.message_search",
title = "Message search", title = "Message search",