mirror of
https://github.com/bitwarden/android.git
synced 2026-08-01 18:53:39 -05:00
PM-39888: feat: ViewModel controls Environment Selector options (#7135)
This commit is contained in:
@@ -235,6 +235,7 @@ private fun LandingScreenContent(
|
||||
EnvironmentSelector(
|
||||
labelText = stringResource(id = BitwardenString.logging_in_on_with_colon),
|
||||
dialogTitle = stringResource(id = BitwardenString.logging_in_on),
|
||||
options = state.environmentTypeOptions,
|
||||
selectedOption = state.selectedEnvironmentType,
|
||||
onOptionSelected = onEnvironmentTypeSelect,
|
||||
isHelpEnabled = false,
|
||||
|
||||
@@ -21,6 +21,8 @@ import com.x8bit.bitwarden.data.vault.repository.VaultRepository
|
||||
import com.x8bit.bitwarden.ui.platform.model.SnackbarRelay
|
||||
import com.x8bit.bitwarden.ui.vault.feature.vault.util.toAccountSummaries
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
@@ -283,6 +285,12 @@ data class LandingState(
|
||||
val dialog: DialogState?,
|
||||
val accountSummaries: List<AccountSummary>,
|
||||
) : Parcelable {
|
||||
/**
|
||||
* The selectable environments.
|
||||
*/
|
||||
val environmentTypeOptions: ImmutableList<Environment.Type>
|
||||
get() = Environment.Type.entries.toImmutableList()
|
||||
|
||||
/**
|
||||
* Determines whether the app bar should be visible based on the presence of account summaries.
|
||||
*/
|
||||
|
||||
+25
-26
@@ -129,11 +129,7 @@ fun StartRegistrationScreen(
|
||||
},
|
||||
) {
|
||||
StartRegistrationContent(
|
||||
emailInput = state.emailInput,
|
||||
selectedEnvironmentType = state.selectedEnvironmentType,
|
||||
nameInput = state.nameInput,
|
||||
isReceiveMarketingEmailsToggled = state.isReceiveMarketingEmailsToggled,
|
||||
isContinueButtonEnabled = state.isContinueButtonEnabled,
|
||||
state = state,
|
||||
handler = handler,
|
||||
)
|
||||
}
|
||||
@@ -165,11 +161,7 @@ private fun StartRegistrationDialogs(
|
||||
@Suppress("LongMethod")
|
||||
@Composable
|
||||
private fun StartRegistrationContent(
|
||||
emailInput: String,
|
||||
selectedEnvironmentType: Environment.Type,
|
||||
nameInput: String,
|
||||
isReceiveMarketingEmailsToggled: Boolean,
|
||||
isContinueButtonEnabled: Boolean,
|
||||
state: StartRegistrationState,
|
||||
handler: StartRegistrationHandler,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
@@ -195,7 +187,7 @@ private fun StartRegistrationContent(
|
||||
|
||||
BitwardenTextField(
|
||||
label = stringResource(id = BitwardenString.email_address_required),
|
||||
value = emailInput,
|
||||
value = state.emailInput,
|
||||
onValueChange = handler.onEmailInputChange,
|
||||
keyboardType = KeyboardType.Email,
|
||||
textFieldTestTag = "EmailAddressEntry",
|
||||
@@ -204,7 +196,8 @@ private fun StartRegistrationContent(
|
||||
EnvironmentSelector(
|
||||
labelText = stringResource(id = BitwardenString.create_account_on_with_colon),
|
||||
dialogTitle = stringResource(id = BitwardenString.create_account_on),
|
||||
selectedOption = selectedEnvironmentType,
|
||||
options = state.environmentTypeOptions,
|
||||
selectedOption = state.selectedEnvironmentType,
|
||||
onOptionSelected = handler.onEnvironmentTypeSelect,
|
||||
onHelpClick = handler.onServerGeologyHelpClick,
|
||||
modifier = Modifier
|
||||
@@ -222,7 +215,7 @@ private fun StartRegistrationContent(
|
||||
|
||||
BitwardenTextField(
|
||||
label = stringResource(id = BitwardenString.name),
|
||||
value = nameInput,
|
||||
value = state.nameInput,
|
||||
onValueChange = handler.onNameInputChange,
|
||||
textFieldTestTag = "NameEntry",
|
||||
cardStyle = CardStyle.Full,
|
||||
@@ -231,10 +224,10 @@ private fun StartRegistrationContent(
|
||||
.standardHorizontalMargin(),
|
||||
)
|
||||
|
||||
if (selectedEnvironmentType != Environment.Type.SELF_HOSTED) {
|
||||
if (state.selectedEnvironmentType != Environment.Type.SELF_HOSTED) {
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
ReceiveMarketingEmailsSwitch(
|
||||
isChecked = isReceiveMarketingEmailsToggled,
|
||||
isChecked = state.isReceiveMarketingEmailsToggled,
|
||||
onCheckedChange = handler.onReceiveMarketingEmailsToggle,
|
||||
onUnsubscribeClick = handler.onUnsubscribeMarketingEmailsClick,
|
||||
modifier = Modifier
|
||||
@@ -248,7 +241,7 @@ private fun StartRegistrationContent(
|
||||
BitwardenFilledButton(
|
||||
label = stringResource(id = BitwardenString.continue_text),
|
||||
onClick = handler.onContinueClick,
|
||||
isEnabled = isContinueButtonEnabled,
|
||||
isEnabled = state.isContinueButtonEnabled,
|
||||
modifier = Modifier
|
||||
.testTag("ContinueButton")
|
||||
.standardHorizontalMargin()
|
||||
@@ -365,11 +358,14 @@ private fun ReceiveMarketingEmailsSwitch(
|
||||
private fun StartRegistrationContentFilledOut_preview() {
|
||||
BitwardenTheme {
|
||||
StartRegistrationContent(
|
||||
emailInput = "e@mail.com",
|
||||
selectedEnvironmentType = Environment.Type.US,
|
||||
nameInput = "Test User",
|
||||
isReceiveMarketingEmailsToggled = true,
|
||||
isContinueButtonEnabled = true,
|
||||
state = StartRegistrationState(
|
||||
emailInput = "e@mail.com",
|
||||
selectedEnvironmentType = Environment.Type.US,
|
||||
nameInput = "Test User",
|
||||
isReceiveMarketingEmailsToggled = true,
|
||||
isContinueButtonEnabled = true,
|
||||
dialog = null,
|
||||
),
|
||||
handler = StartRegistrationHandler(
|
||||
onEmailInputChange = {},
|
||||
onNameInputChange = {},
|
||||
@@ -391,11 +387,14 @@ private fun StartRegistrationContentFilledOut_preview() {
|
||||
private fun StartRegistrationContentEmpty_preview() {
|
||||
BitwardenTheme {
|
||||
StartRegistrationContent(
|
||||
emailInput = "",
|
||||
selectedEnvironmentType = Environment.Type.US,
|
||||
nameInput = "",
|
||||
isReceiveMarketingEmailsToggled = false,
|
||||
isContinueButtonEnabled = false,
|
||||
state = StartRegistrationState(
|
||||
emailInput = "",
|
||||
selectedEnvironmentType = Environment.Type.US,
|
||||
nameInput = "",
|
||||
isReceiveMarketingEmailsToggled = false,
|
||||
isContinueButtonEnabled = false,
|
||||
dialog = null,
|
||||
),
|
||||
handler = StartRegistrationHandler(
|
||||
onEmailInputChange = {},
|
||||
onNameInputChange = {},
|
||||
|
||||
+21
-12
@@ -4,7 +4,6 @@ import android.os.Parcelable
|
||||
import androidx.lifecycle.SavedStateHandle
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.bitwarden.data.repository.model.Environment
|
||||
import com.bitwarden.data.repository.model.Environment.Type
|
||||
import com.bitwarden.ui.platform.base.BackgroundEvent
|
||||
import com.bitwarden.ui.platform.base.BaseViewModel
|
||||
import com.bitwarden.ui.platform.base.util.isValidEmail
|
||||
@@ -19,6 +18,8 @@ import com.x8bit.bitwarden.data.auth.repository.model.SendVerificationEmailResul
|
||||
import com.x8bit.bitwarden.data.platform.repository.EnvironmentRepository
|
||||
import com.x8bit.bitwarden.ui.platform.model.SnackbarRelay
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
@@ -40,15 +41,17 @@ class StartRegistrationViewModel @Inject constructor(
|
||||
private val authRepository: AuthRepository,
|
||||
private val environmentRepository: EnvironmentRepository,
|
||||
) : BaseViewModel<StartRegistrationState, StartRegistrationEvent, StartRegistrationAction>(
|
||||
initialState = savedStateHandle[KEY_STATE]
|
||||
?: StartRegistrationState(
|
||||
initialState = savedStateHandle[KEY_STATE] ?: run {
|
||||
val environmentType = environmentRepository.environment.type
|
||||
StartRegistrationState(
|
||||
emailInput = "",
|
||||
nameInput = "",
|
||||
isReceiveMarketingEmailsToggled = environmentRepository.environment.type == Type.US,
|
||||
isReceiveMarketingEmailsToggled = environmentType == Environment.Type.US,
|
||||
isContinueButtonEnabled = false,
|
||||
selectedEnvironmentType = environmentRepository.environment.type,
|
||||
selectedEnvironmentType = environmentType,
|
||||
dialog = null,
|
||||
),
|
||||
)
|
||||
},
|
||||
) {
|
||||
|
||||
init {
|
||||
@@ -115,9 +118,9 @@ class StartRegistrationViewModel @Inject constructor(
|
||||
|
||||
private fun handleEnvironmentTypeSelect(action: StartRegistrationAction.EnvironmentTypeSelect) {
|
||||
val environment = when (action.environmentType) {
|
||||
Type.US -> Environment.Us
|
||||
Type.EU -> Environment.Eu
|
||||
Type.SELF_HOSTED -> {
|
||||
Environment.Type.US -> Environment.Us
|
||||
Environment.Type.EU -> Environment.Eu
|
||||
Environment.Type.SELF_HOSTED -> {
|
||||
// Launch the self-hosted screen and select the full environment details there.
|
||||
sendEvent(StartRegistrationEvent.NavigateToEnvironment)
|
||||
return
|
||||
@@ -286,9 +289,15 @@ data class StartRegistrationState(
|
||||
val nameInput: String,
|
||||
val isReceiveMarketingEmailsToggled: Boolean,
|
||||
val isContinueButtonEnabled: Boolean,
|
||||
val selectedEnvironmentType: Type,
|
||||
val selectedEnvironmentType: Environment.Type,
|
||||
val dialog: StartRegistrationDialog?,
|
||||
) : Parcelable
|
||||
) : Parcelable {
|
||||
/**
|
||||
* The selectable environments.
|
||||
*/
|
||||
val environmentTypeOptions: ImmutableList<Environment.Type>
|
||||
get() = Environment.Type.entries.toImmutableList()
|
||||
}
|
||||
|
||||
/**
|
||||
* Models dialogs that can be displayed on the start registration screen.
|
||||
@@ -397,7 +406,7 @@ sealed class StartRegistrationAction {
|
||||
* Indicates that the selection from the region drop down has changed.
|
||||
*/
|
||||
data class EnvironmentTypeSelect(
|
||||
val environmentType: Type,
|
||||
val environmentType: Environment.Type,
|
||||
) : StartRegistrationAction()
|
||||
|
||||
/**
|
||||
|
||||
+3
-1
@@ -29,6 +29,7 @@ import com.bitwarden.ui.platform.resource.BitwardenDrawable
|
||||
import com.bitwarden.ui.platform.resource.BitwardenString
|
||||
import com.bitwarden.ui.platform.theme.BitwardenTheme
|
||||
import com.x8bit.bitwarden.ui.platform.util.displayLabel
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
|
||||
/**
|
||||
* A dropdown selector UI component specific to region url selection.
|
||||
@@ -39,6 +40,7 @@ import com.x8bit.bitwarden.ui.platform.util.displayLabel
|
||||
*
|
||||
* @param labelText The text displayed near the selector button.
|
||||
* @param dialogTitle The title displayed in the selection dialog.
|
||||
* @param options The options displayed in the selection dialog.
|
||||
* @param selectedOption The currently selected environment option.
|
||||
* @param onOptionSelected A callback that gets invoked when an environment option is selected
|
||||
* and passes the selected option as an argument.
|
||||
@@ -51,13 +53,13 @@ import com.x8bit.bitwarden.ui.platform.util.displayLabel
|
||||
fun EnvironmentSelector(
|
||||
labelText: String,
|
||||
dialogTitle: String,
|
||||
options: ImmutableList<Environment.Type>,
|
||||
selectedOption: Environment.Type,
|
||||
onOptionSelected: (Environment.Type) -> Unit,
|
||||
onHelpClick: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
isHelpEnabled: Boolean = true,
|
||||
) {
|
||||
val options = Environment.Type.entries.toTypedArray()
|
||||
var shouldShowDialog by rememberSaveable { mutableStateOf(false) }
|
||||
|
||||
Row(
|
||||
|
||||
Reference in New Issue
Block a user