Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c4fd7e79 authored by Franciszek Juras's avatar Franciszek Juras Committed by Istvan Nagy
Browse files

Change User switcher dropdown into pill on Bouncer

Test: manual - Pill present instead of dropdown on Bouncer
Bug: 425357051
Flag: com.android.systemui.disable_user_switcher_dropdown_on_bouncer
Change-Id: I4a4674ec0c94670358ee7f0d45946436c87e8e74
parent e022b0fe
Loading
Loading
Loading
Loading
+7 −0
Original line number Original line Diff line number Diff line
@@ -10,6 +10,13 @@ flag {
    bug: "416223998"
    bug: "416223998"
}
}


flag {
    name: "disable_user_switcher_dropdown_on_bouncer"
    namespace: "desktop_users_and_accounts"
    description: "Show pill with current user's name instead of user switcher dropdown"
    bug: "425357051"
}

flag {
flag {
    name: "sign_out_button_on_keyguard_status_bar"
    name: "sign_out_button_on_keyguard_status_bar"
    namespace: "desktop_users_and_accounts"
    namespace: "desktop_users_and_accounts"
+80 −40
Original line number Original line Diff line number Diff line
@@ -48,6 +48,7 @@ import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.widthIn
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.KeyboardArrowDown
import androidx.compose.material.icons.filled.KeyboardArrowDown
@@ -104,6 +105,7 @@ import com.android.compose.animation.scene.rememberMutableSceneTransitionLayoutS
import com.android.compose.animation.scene.transitions
import com.android.compose.animation.scene.transitions
import com.android.compose.modifiers.thenIf
import com.android.compose.modifiers.thenIf
import com.android.compose.windowsizeclass.LocalWindowSizeClass
import com.android.compose.windowsizeclass.LocalWindowSizeClass
import com.android.systemui.Flags
import com.android.systemui.bouncer.shared.model.BouncerActionButtonModel
import com.android.systemui.bouncer.shared.model.BouncerActionButtonModel
import com.android.systemui.bouncer.ui.BouncerDialogFactory
import com.android.systemui.bouncer.ui.BouncerDialogFactory
import com.android.systemui.bouncer.ui.viewmodel.AuthMethodBouncerViewModel
import com.android.systemui.bouncer.ui.viewmodel.AuthMethodBouncerViewModel
@@ -898,6 +900,7 @@ private fun Dialog(
@Composable
@Composable
private fun UserSwitcher(viewModel: BouncerOverlayContentViewModel, modifier: Modifier = Modifier) {
private fun UserSwitcher(viewModel: BouncerOverlayContentViewModel, modifier: Modifier = Modifier) {
    val isUserSwitcherVisible by viewModel.isUserSwitcherVisible.collectAsStateWithLifecycle()
    val isUserSwitcherVisible by viewModel.isUserSwitcherVisible.collectAsStateWithLifecycle()
    val dropdownItems by viewModel.userSwitcherDropdown.collectAsStateWithLifecycle(emptyList())
    if (!isUserSwitcherVisible) {
    if (!isUserSwitcherVisible) {
        // Take up the same space as the user switcher normally would, but with nothing inside it.
        // Take up the same space as the user switcher normally would, but with nothing inside it.
        Box(modifier = modifier)
        Box(modifier = modifier)
@@ -905,10 +908,8 @@ private fun UserSwitcher(viewModel: BouncerOverlayContentViewModel, modifier: Mo
    }
    }


    val selectedUserImage by viewModel.selectedUserImage.collectAsStateWithLifecycle(null)
    val selectedUserImage by viewModel.selectedUserImage.collectAsStateWithLifecycle(null)
    val dropdownItems by viewModel.userSwitcherDropdown.collectAsStateWithLifecycle(emptyList())
    val userSwitcherIconSize = dimensionResource(R.dimen.bouncer_user_switcher_icon_size)
    val userSwitcherIconSize = dimensionResource(R.dimen.bouncer_user_switcher_icon_size)
    val dropDownWidth = userSwitcherIconSize + UserSwitcherDropdownExtraWidth
    val maxUserSwitcherWidth = userSwitcherIconSize + UserSwitcherDropdownExtraWidth

    Column(
    Column(
        horizontalAlignment = Alignment.CenterHorizontally,
        horizontalAlignment = Alignment.CenterHorizontally,
        verticalArrangement = Arrangement.Center,
        verticalArrangement = Arrangement.Center,
@@ -921,19 +922,59 @@ private fun UserSwitcher(viewModel: BouncerOverlayContentViewModel, modifier: Mo
                modifier = Modifier.size(userSwitcherIconSize).sysuiResTag("user_icon"),
                modifier = Modifier.size(userSwitcherIconSize).sysuiResTag("user_icon"),
            )
            )
        }
        }
        if (Flags.disableUserSwitcherDropdownOnBouncer() && dropdownItems.size <= 1) {
            Spacer(modifier = Modifier.height(24.dp))
            UserNamePill(viewModel = viewModel, maxWidth = maxUserSwitcherWidth)
        } else {
            Spacer(modifier = Modifier.height(40.dp))
            UserSwitcherDropdown(viewModel = viewModel, width = maxUserSwitcherWidth)
        }
    }
}

/**
 * Displays the current user's name in a stylized pill shape. This is used when the user switcher
 * dropdown is disabled.
 */
@Composable
private fun UserNamePill(viewModel: BouncerOverlayContentViewModel, maxWidth: Dp) {
    val selectedUserName by viewModel.selectedUserName.collectAsStateWithLifecycle()
    val context = LocalContext.current
    selectedUserName.loadText(context)?.let { userName ->
        Text(
            text = userName,
            style = MaterialTheme.typography.titleMedium,
            color = MaterialTheme.colorScheme.onSurface,
            maxLines = 1,
            overflow = TextOverflow.Ellipsis,
            modifier =
                Modifier.widthIn(max = maxWidth)
                    .background(
                        color = MaterialTheme.colorScheme.surfaceContainer,
                        shape = RoundedCornerShape(percent = 50),
                    )
                    .padding(horizontal = 24.dp, vertical = 16.dp),
        )
    }
}


/**
 * Displays the current user's name and an arrow, which can be clicked to expand a dropdown menu for
 * switching users.
 */
@Composable
private fun UserSwitcherDropdown(viewModel: BouncerOverlayContentViewModel, width: Dp) {
    val dropdownItems by viewModel.userSwitcherDropdown.collectAsStateWithLifecycle(emptyList())
    val (isDropdownExpanded, setDropdownExpanded) = remember { mutableStateOf(false) }
    val (isDropdownExpanded, setDropdownExpanded) = remember { mutableStateOf(false) }


    dropdownItems.firstOrNull()?.let { firstDropdownItem ->
    dropdownItems.firstOrNull()?.let { firstDropdownItem ->
            Spacer(modifier = Modifier.height(40.dp))

        Box {
        Box {
            PlatformButton(
            PlatformButton(
                modifier =
                modifier =
                    Modifier
                    Modifier
                        // Remove the built-in padding applied inside PlatformButton:
                        // Remove the built-in padding applied inside PlatformButton:
                        .padding(vertical = 0.dp)
                        .padding(vertical = 0.dp)
                            .width(dropDownWidth)
                        .width(width)
                        .height(UserSwitcherDropdownHeight),
                        .height(UserSwitcherDropdownHeight),
                colors =
                colors =
                    ButtonDefaults.buttonColors(
                    ButtonDefaults.buttonColors(
@@ -945,7 +986,7 @@ private fun UserSwitcher(viewModel: BouncerOverlayContentViewModel, modifier: Mo
                val context = LocalContext.current
                val context = LocalContext.current
                Text(
                Text(
                    text = checkNotNull(firstDropdownItem.text.loadText(context)),
                    text = checkNotNull(firstDropdownItem.text.loadText(context)),
                        style = MaterialTheme.typography.labelMedium,
                    style = MaterialTheme.typography.headlineSmall,
                    maxLines = 1,
                    maxLines = 1,
                    overflow = TextOverflow.Ellipsis,
                    overflow = TextOverflow.Ellipsis,
                )
                )
@@ -962,13 +1003,12 @@ private fun UserSwitcher(viewModel: BouncerOverlayContentViewModel, modifier: Mo
            UserSwitcherDropdownMenu(
            UserSwitcherDropdownMenu(
                isExpanded = isDropdownExpanded,
                isExpanded = isDropdownExpanded,
                items = dropdownItems,
                items = dropdownItems,
                    dropDownWidth = dropDownWidth,
                dropDownWidth = width,
                onDismissed = { setDropdownExpanded(false) },
                onDismissed = { setDropdownExpanded(false) },
            )
            )
        }
        }
    }
    }
}
}
}


/**
/**
 * Renders the dropdown menu that displays the actual users and/or user actions that can be
 * Renders the dropdown menu that displays the actual users and/or user actions that can be
+7 −0
Original line number Original line Diff line number Diff line
@@ -84,6 +84,9 @@ constructor(
    private val _selectedUserImage = MutableStateFlow<Bitmap?>(null)
    private val _selectedUserImage = MutableStateFlow<Bitmap?>(null)
    val selectedUserImage: StateFlow<Bitmap?> = _selectedUserImage.asStateFlow()
    val selectedUserImage: StateFlow<Bitmap?> = _selectedUserImage.asStateFlow()


    private val _selectedUserName = MutableStateFlow<Text?>(null)
    val selectedUserName: StateFlow<Text?> = _selectedUserName.asStateFlow()

    val message: BouncerMessageViewModel by lazy { bouncerMessageViewModelFactory.create() }
    val message: BouncerMessageViewModel by lazy { bouncerMessageViewModelFactory.create() }


    private val _userSwitcherDropdown =
    private val _userSwitcherDropdown =
@@ -212,6 +215,10 @@ constructor(
                    .collect { _selectedUserImage.value = it }
                    .collect { _selectedUserImage.value = it }
            }
            }


            launch {
                userSwitcher.selectedUser.map { it.name }.collect { _selectedUserName.value = it }
            }

            launch {
            launch {
                combine(userSwitcher.users, userSwitcher.menu) { users, actions ->
                combine(userSwitcher.users, userSwitcher.menu) { users, actions ->
                        users.map { user ->
                        users.map { user ->