Gate user status behind UserStatus feature flag

This commit is contained in:
ganfra
2026-06-17 17:20:58 +02:00
parent 1cfd3e4dfb
commit dd24e14cf6
5 changed files with 40 additions and 14 deletions
@@ -62,20 +62,20 @@ class PreferencesRootPresenter(
) : Presenter<PreferencesRootState> { ) : Presenter<PreferencesRootState> {
@Composable @Composable
override fun present(): PreferencesRootState { override fun present(): PreferencesRootState {
val userStatusState = userStatusPresenter.present()
val coroutineScope = rememberCoroutineScope() val coroutineScope = rememberCoroutineScope()
val matrixUser = matrixClient.userProfile.collectAsState() val matrixUser = matrixClient.userProfile.collectAsState()
LaunchedEffect(Unit) { LaunchedEffect(Unit) {
// Force a refresh of the profile // Force a refresh of the profile
matrixClient.getUserProfile() matrixClient.getUserProfile()
} }
val isMultiAccountEnabled by remember { val isMultiAccountEnabled by remember {
featureFlagService.isFeatureEnabledFlow(FeatureFlags.MultiAccount) featureFlagService.isFeatureEnabledFlow(FeatureFlags.MultiAccount)
}.collectAsState(initial = false) }.collectAsState(initial = false)
val showLinkNewDevice by remember { val showLinkNewDevice by remember {
featureFlagService.isFeatureEnabledFlow(FeatureFlags.QrCodeLogin) featureFlagService.isFeatureEnabledFlow(FeatureFlags.QrCodeLogin)
}.collectAsState(initial = false) }.collectAsState(initial = false)
val isUserStatusEnabled by featureFlagService.isFeatureEnabledFlow(FeatureFlags.UserStatus).collectAsState(initial = false)
val userStatusState = if (isUserStatusEnabled) userStatusPresenter.present() else null
val otherSessions by remember { val otherSessions by remember {
sessionStore.sessionsFlow().map { list -> sessionStore.sessionsFlow().map { list ->
@@ -17,7 +17,7 @@ import kotlinx.collections.immutable.ImmutableList
data class PreferencesRootState( data class PreferencesRootState(
val myUser: MatrixUser, val myUser: MatrixUser,
val userStatusState: UserStatusState, val userStatusState: UserStatusState?,
val version: String, val version: String,
val deviceId: DeviceId?, val deviceId: DeviceId?,
val isMultiAccountEnabled: Boolean, val isMultiAccountEnabled: Boolean,
@@ -88,7 +88,7 @@ fun aPreferencesRootState(
nbOfBlockedUsers: Int = 0, nbOfBlockedUsers: Int = 0,
showLabsItem: Boolean = false, showLabsItem: Boolean = false,
directLogoutState: DirectLogoutState = aDirectLogoutState(), directLogoutState: DirectLogoutState = aDirectLogoutState(),
userStatusState: UserStatusState = aUserStatusState(), userStatusState: UserStatusState? = aUserStatusState(),
snackbarMessage: SnackbarMessage? = null, snackbarMessage: SnackbarMessage? = null,
eventSink: (PreferencesRootEvent) -> Unit = {}, eventSink: (PreferencesRootEvent) -> Unit = {},
) = PreferencesRootState( ) = PreferencesRootState(
@@ -25,6 +25,7 @@ import io.element.android.compound.tokens.generated.CompoundIcons
import io.element.android.features.preferences.impl.R import io.element.android.features.preferences.impl.R
import io.element.android.features.preferences.impl.user.UserPreferences import io.element.android.features.preferences.impl.user.UserPreferences
import io.element.android.features.preferences.impl.userstatus.UserStatusRow import io.element.android.features.preferences.impl.userstatus.UserStatusRow
import io.element.android.features.preferences.impl.userstatus.UserStatusState
import io.element.android.libraries.architecture.coverage.ExcludeFromCoverage import io.element.android.libraries.architecture.coverage.ExcludeFromCoverage
import io.element.android.libraries.designsystem.components.avatar.AvatarSize import io.element.android.libraries.designsystem.components.avatar.AvatarSize
import io.element.android.libraries.designsystem.components.list.ListItemContent import io.element.android.libraries.designsystem.components.list.ListItemContent
@@ -82,15 +83,14 @@ fun PreferencesRootView(
}, },
matrixUser = state.myUser, matrixUser = state.myUser,
) )
HorizontalDivider()
UserStatusRow( if (state.userStatusState != null) {
state = state.userStatusState, UserStatusSection(state.userStatusState)
modifier = Modifier.fillMaxWidth(), }
)
HorizontalDivider()
if (state.isMultiAccountEnabled) { if (state.isMultiAccountEnabled) {
MultiAccountSection( MultiAccountSection(
state = state, state = state,
showTopDivider = state.userStatusState == null,
onAddAccountClick = onAddAccountClick, onAddAccountClick = onAddAccountClick,
) )
} }
@@ -135,14 +135,33 @@ fun PreferencesRootView(
} }
@Composable @Composable
private fun ColumnScope.MultiAccountSection( private fun ColumnScope.UserStatusSection(userStatusState: UserStatusState) {
state: PreferencesRootState,
onAddAccountClick: () -> Unit,
) {
HorizontalDivider( HorizontalDivider(
thickness = 8.dp, thickness = 8.dp,
color = ElementTheme.colors.bgSubtleSecondary, color = ElementTheme.colors.bgSubtleSecondary,
) )
UserStatusRow(
state = userStatusState,
modifier = Modifier.fillMaxWidth(),
)
HorizontalDivider(
thickness = 8.dp,
color = ElementTheme.colors.bgSubtleSecondary,
)
}
@Composable
private fun ColumnScope.MultiAccountSection(
state: PreferencesRootState,
showTopDivider: Boolean,
onAddAccountClick: () -> Unit,
) {
if(showTopDivider) {
HorizontalDivider(
thickness = 8.dp,
color = ElementTheme.colors.bgSubtleSecondary,
)
}
state.otherSessions.forEach { matrixUser -> state.otherSessions.forEach { matrixUser ->
MatrixUserRow( MatrixUserRow(
modifier = Modifier modifier = Modifier
@@ -137,4 +137,11 @@ 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,
),
} }