BIT-732: Add account swither to login screen (#333)

This commit is contained in:
Brian Yencho
2023-12-06 11:37:29 -06:00
committed by Álison Fernandes
parent 2e2fede945
commit b0e3aca323
4 changed files with 139 additions and 2 deletions

View File

@@ -18,7 +18,10 @@ import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.material3.rememberTopAppBarState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
@@ -36,16 +39,19 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.x8bit.bitwarden.R
import com.x8bit.bitwarden.ui.platform.base.util.EventsEffect
import com.x8bit.bitwarden.ui.platform.base.util.IntentHandler
import com.x8bit.bitwarden.ui.platform.components.BitwardenAccountSwitcher
import com.x8bit.bitwarden.ui.platform.components.BitwardenBasicDialog
import com.x8bit.bitwarden.ui.platform.components.BitwardenFilledButton
import com.x8bit.bitwarden.ui.platform.components.BitwardenLoadingDialog
import com.x8bit.bitwarden.ui.platform.components.BitwardenOutlinedButtonWithIcon
import com.x8bit.bitwarden.ui.platform.components.BitwardenOverflowActionItem
import com.x8bit.bitwarden.ui.platform.components.BitwardenPasswordField
import com.x8bit.bitwarden.ui.platform.components.BitwardenPlaceholderAccountActionItem
import com.x8bit.bitwarden.ui.platform.components.BitwardenScaffold
import com.x8bit.bitwarden.ui.platform.components.BitwardenTopAppBar
import com.x8bit.bitwarden.ui.platform.components.OverflowMenuItemData
import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.toImmutableList
/**
* The top level composable for the Login screen.
@@ -73,6 +79,8 @@ fun LoginScreen(
}
}
val isAccountButtonVisible = state.accountSummaries.isNotEmpty()
var isAccountMenuVisible by rememberSaveable { mutableStateOf(false) }
val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(rememberTopAppBarState())
BitwardenScaffold(
modifier = Modifier
@@ -88,6 +96,11 @@ fun LoginScreen(
{ viewModel.trySendAction(LoginAction.CloseButtonClick) }
},
actions = {
if (isAccountButtonVisible) {
BitwardenPlaceholderAccountActionItem(
onClick = { isAccountMenuVisible = !isAccountMenuVisible },
)
}
BitwardenOverflowActionItem(
menuItemDataList = persistentListOf(
OverflowMenuItemData(
@@ -126,6 +139,23 @@ fun LoginScreen(
.padding(innerPadding)
.fillMaxSize(),
)
BitwardenAccountSwitcher(
isVisible = isAccountMenuVisible,
accountSummaries = state.accountSummaries.toImmutableList(),
onAccountSummaryClick = remember(viewModel) {
{ viewModel.trySendAction(LoginAction.SwitchAccountClick(it)) }
},
onAddAccountClick = {
// Not available
},
onDismissRequest = { isAccountMenuVisible = false },
isAddAccountAvailable = false,
topAppBarScrollBehavior = scrollBehavior,
modifier = Modifier
.padding(innerPadding)
.fillMaxSize(),
)
}
}

View File

@@ -17,7 +17,9 @@ import com.x8bit.bitwarden.ui.platform.base.util.Text
import com.x8bit.bitwarden.ui.platform.base.util.asText
import com.x8bit.bitwarden.ui.platform.components.BasicDialogState
import com.x8bit.bitwarden.ui.platform.components.LoadingDialogState
import com.x8bit.bitwarden.ui.platform.components.model.AccountSummary
import com.x8bit.bitwarden.ui.platform.util.labelOrBaseUrlHost
import com.x8bit.bitwarden.ui.vault.feature.vault.util.toAccountSummaries
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
@@ -46,6 +48,7 @@ class LoginViewModel @Inject constructor(
loadingDialogState = LoadingDialogState.Hidden,
errorDialogState = BasicDialogState.Hidden,
captchaToken = LoginArgs(savedStateHandle).captchaToken,
accountSummaries = authRepository.userStateFlow.value?.toAccountSummaries().orEmpty(),
),
) {
@@ -67,6 +70,7 @@ class LoginViewModel @Inject constructor(
override fun handleAction(action: LoginAction) {
when (action) {
is LoginAction.SwitchAccountClick -> handleSwitchAccountClicked(action)
is LoginAction.CloseButtonClick -> handleCloseButtonClicked()
LoginAction.LoginButtonClick -> handleLoginButtonClicked()
LoginAction.MasterPasswordHintClick -> handleMasterPasswordHintClicked()
@@ -84,6 +88,10 @@ class LoginViewModel @Inject constructor(
}
}
private fun handleSwitchAccountClicked(action: LoginAction.SwitchAccountClick) {
authRepository.switchAccount(userId = action.account.userId)
}
private fun handleReceiveLoginResult(action: LoginAction.Internal.ReceiveLoginResult) {
when (val loginResult = action.loginResult) {
is LoginResult.CaptchaRequired -> {
@@ -201,6 +209,7 @@ data class LoginState(
val isLoginButtonEnabled: Boolean,
val loadingDialogState: LoadingDialogState,
val errorDialogState: BasicDialogState,
val accountSummaries: List<AccountSummary>,
) : Parcelable
/**
@@ -227,6 +236,13 @@ sealed class LoginEvent {
* Models actions for the login screen.
*/
sealed class LoginAction {
/**
* Indicates the user has clicked on the given [account] information in order to switch to it.
*/
data class SwitchAccountClick(
val account: AccountSummary,
) : LoginAction()
/**
* Indicates that the top-bar close button was clicked.
*/