mirror of
https://github.com/bitwarden/android.git
synced 2026-03-12 05:04:17 -05:00
PM-17388 Update existing and v3 email verification screen to match design audit (#4645)
This commit is contained in:
@@ -83,9 +83,6 @@ fun NavGraphBuilder.authGraph(
|
||||
)
|
||||
checkEmailDestination(
|
||||
onNavigateBack = { navController.popBackStack() },
|
||||
onNavigateBackToLanding = {
|
||||
navController.popBackStack(route = LANDING_ROUTE, inclusive = false)
|
||||
},
|
||||
)
|
||||
completeRegistrationDestination(
|
||||
onNavigateBack = { navController.popBackStack() },
|
||||
|
||||
@@ -36,7 +36,6 @@ data class CheckEmailArgs(
|
||||
*/
|
||||
fun NavGraphBuilder.checkEmailDestination(
|
||||
onNavigateBack: () -> Unit,
|
||||
onNavigateBackToLanding: () -> Unit,
|
||||
) {
|
||||
composableWithSlideTransitions(
|
||||
route = CHECK_EMAIL_ROUTE,
|
||||
@@ -46,7 +45,6 @@ fun NavGraphBuilder.checkEmailDestination(
|
||||
) {
|
||||
CheckEmailScreen(
|
||||
onNavigateBack = onNavigateBack,
|
||||
onNavigateBackToLanding = onNavigateBackToLanding,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@ import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.imePadding
|
||||
import androidx.compose.foundation.layout.navigationBarsPadding
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.wrapContentHeight
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
@@ -40,7 +39,7 @@ import com.x8bit.bitwarden.ui.platform.base.util.standardHorizontalMargin
|
||||
import com.x8bit.bitwarden.ui.platform.base.util.toAnnotatedString
|
||||
import com.x8bit.bitwarden.ui.platform.components.appbar.BitwardenTopAppBar
|
||||
import com.x8bit.bitwarden.ui.platform.components.button.BitwardenFilledButton
|
||||
import com.x8bit.bitwarden.ui.platform.components.button.BitwardenTextButton
|
||||
import com.x8bit.bitwarden.ui.platform.components.button.BitwardenOutlinedButton
|
||||
import com.x8bit.bitwarden.ui.platform.components.scaffold.BitwardenScaffold
|
||||
import com.x8bit.bitwarden.ui.platform.components.util.rememberVectorPainter
|
||||
import com.x8bit.bitwarden.ui.platform.composition.LocalIntentManager
|
||||
@@ -55,7 +54,6 @@ import com.x8bit.bitwarden.ui.platform.theme.BitwardenTheme
|
||||
@Composable
|
||||
fun CheckEmailScreen(
|
||||
onNavigateBack: () -> Unit,
|
||||
onNavigateBackToLanding: () -> Unit,
|
||||
intentManager: IntentManager = LocalIntentManager.current,
|
||||
viewModel: CheckEmailViewModel = hiltViewModel(),
|
||||
) {
|
||||
@@ -70,8 +68,6 @@ fun CheckEmailScreen(
|
||||
is CheckEmailEvent.NavigateToEmailApp -> {
|
||||
intentManager.startDefaultEmailApplication()
|
||||
}
|
||||
|
||||
CheckEmailEvent.NavigateBackToLanding -> onNavigateBackToLanding()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,16 +97,15 @@ fun CheckEmailScreen(
|
||||
email = state.email,
|
||||
onOpenEmailAppClick = handler.onOpenEmailAppClick,
|
||||
onChangeEmailClick = handler.onChangeEmailClick,
|
||||
modifier = Modifier.standardHorizontalMargin(),
|
||||
)
|
||||
} else {
|
||||
CheckEmailLegacyContent(
|
||||
email = state.email,
|
||||
onOpenEmailAppClick = handler.onOpenEmailAppClick,
|
||||
onChangeEmailClick = handler.onChangeEmailClick,
|
||||
onLoginClick = handler.onLoginClick,
|
||||
)
|
||||
}
|
||||
Spacer(modifier = Modifier.height(12.dp))
|
||||
Spacer(modifier = Modifier.navigationBarsPadding())
|
||||
}
|
||||
}
|
||||
@@ -133,9 +128,11 @@ private fun CheckEmailContent(
|
||||
Image(
|
||||
painter = rememberVectorPainter(id = R.drawable.open_email),
|
||||
contentDescription = null,
|
||||
contentScale = ContentScale.Fit,
|
||||
contentScale = ContentScale.FillHeight,
|
||||
modifier = Modifier
|
||||
.size(100.dp),
|
||||
.standardHorizontalMargin()
|
||||
.size(100.dp)
|
||||
.fillMaxWidth(),
|
||||
)
|
||||
Spacer(modifier = Modifier.height(32.dp))
|
||||
Text(
|
||||
@@ -144,9 +141,9 @@ private fun CheckEmailContent(
|
||||
style = BitwardenTheme.typography.titleMedium,
|
||||
color = BitwardenTheme.colorScheme.text.primary,
|
||||
modifier = Modifier
|
||||
.padding(horizontal = 8.dp)
|
||||
.wrapContentHeight()
|
||||
.fillMaxWidth(),
|
||||
.fillMaxWidth()
|
||||
.standardHorizontalMargin(),
|
||||
)
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
|
||||
@@ -163,9 +160,9 @@ private fun CheckEmailContent(
|
||||
textAlign = TextAlign.Center,
|
||||
style = BitwardenTheme.typography.bodyMedium,
|
||||
modifier = Modifier
|
||||
.padding(horizontal = 8.dp)
|
||||
.fillMaxWidth()
|
||||
.wrapContentHeight(),
|
||||
.wrapContentHeight()
|
||||
.standardHorizontalMargin(),
|
||||
)
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
@Suppress("MaxLineLength")
|
||||
@@ -175,9 +172,9 @@ private fun CheckEmailContent(
|
||||
color = BitwardenTheme.colorScheme.text.primary,
|
||||
textAlign = TextAlign.Center,
|
||||
modifier = Modifier
|
||||
.padding(horizontal = 8.dp)
|
||||
.fillMaxWidth()
|
||||
.wrapContentHeight(),
|
||||
.wrapContentHeight()
|
||||
.standardHorizontalMargin(),
|
||||
)
|
||||
Spacer(modifier = Modifier.height(32.dp))
|
||||
BitwardenFilledButton(
|
||||
@@ -185,12 +182,16 @@ private fun CheckEmailContent(
|
||||
onClick = onOpenEmailAppClick,
|
||||
modifier = Modifier
|
||||
.testTag("OpenEmailApp")
|
||||
.fillMaxWidth(),
|
||||
.fillMaxWidth()
|
||||
.standardHorizontalMargin(),
|
||||
)
|
||||
Spacer(modifier = Modifier.height(12.dp))
|
||||
BitwardenTextButton(
|
||||
BitwardenOutlinedButton(
|
||||
label = stringResource(R.string.change_email_address),
|
||||
onClick = onChangeEmailClick,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.standardHorizontalMargin(),
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -201,7 +202,6 @@ private fun CheckEmailLegacyContent(
|
||||
email: String,
|
||||
onOpenEmailAppClick: () -> Unit,
|
||||
onChangeEmailClick: () -> Unit,
|
||||
onLoginClick: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
Column(
|
||||
@@ -216,7 +216,7 @@ private fun CheckEmailLegacyContent(
|
||||
contentDescription = null,
|
||||
contentScale = ContentScale.FillHeight,
|
||||
modifier = Modifier
|
||||
.padding(horizontal = 16.dp)
|
||||
.standardHorizontalMargin()
|
||||
.height(112.dp)
|
||||
.fillMaxWidth(),
|
||||
)
|
||||
@@ -227,7 +227,7 @@ private fun CheckEmailLegacyContent(
|
||||
style = BitwardenTheme.typography.headlineSmall,
|
||||
color = BitwardenTheme.colorScheme.text.primary,
|
||||
modifier = Modifier
|
||||
.padding(horizontal = 24.dp)
|
||||
.standardHorizontalMargin()
|
||||
.wrapContentHeight()
|
||||
.fillMaxWidth(),
|
||||
)
|
||||
@@ -236,7 +236,7 @@ private fun CheckEmailLegacyContent(
|
||||
@Suppress("MaxLineLength")
|
||||
val descriptionAnnotatedString =
|
||||
R.string.follow_the_instructions_in_the_email_sent_to_x_to_continue_creating_your_account.toAnnotatedString(
|
||||
email,
|
||||
args = arrayOf(email),
|
||||
emphasisHighlightStyle = SpanStyle(
|
||||
color = BitwardenTheme.colorScheme.text.primary,
|
||||
fontSize = BitwardenTheme.typography.bodyMedium.fontSize,
|
||||
@@ -247,8 +247,8 @@ private fun CheckEmailLegacyContent(
|
||||
text = descriptionAnnotatedString,
|
||||
textAlign = TextAlign.Center,
|
||||
modifier = Modifier
|
||||
.padding(horizontal = 24.dp)
|
||||
.fillMaxWidth()
|
||||
.standardHorizontalMargin()
|
||||
.wrapContentHeight(),
|
||||
)
|
||||
Spacer(modifier = Modifier.height(32.dp))
|
||||
@@ -257,27 +257,18 @@ private fun CheckEmailLegacyContent(
|
||||
onClick = onOpenEmailAppClick,
|
||||
modifier = Modifier
|
||||
.testTag("OpenEmailApp")
|
||||
.padding(horizontal = 16.dp)
|
||||
.standardHorizontalMargin()
|
||||
.fillMaxWidth(),
|
||||
)
|
||||
Spacer(modifier = Modifier.height(32.dp))
|
||||
Column(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
Text(
|
||||
text = R.string.no_email_go_back_to_edit_your_email_address.toAnnotatedString {
|
||||
onChangeEmailClick()
|
||||
},
|
||||
)
|
||||
Spacer(modifier = Modifier.height(32.dp))
|
||||
Text(
|
||||
text = R.string.or_log_in_you_may_already_have_an_account
|
||||
.toAnnotatedString {
|
||||
onLoginClick()
|
||||
},
|
||||
)
|
||||
}
|
||||
Spacer(modifier = Modifier.height(12.dp))
|
||||
|
||||
BitwardenOutlinedButton(
|
||||
label = stringResource(R.string.change_email_address),
|
||||
onClick = onChangeEmailClick,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.standardHorizontalMargin(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -289,7 +280,6 @@ private fun CheckEmailScreenNewUi_preview() {
|
||||
email = "email@fake.com",
|
||||
onOpenEmailAppClick = { },
|
||||
onChangeEmailClick = { },
|
||||
modifier = Modifier.standardHorizontalMargin(),
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -302,7 +292,6 @@ private fun CheckEmailScreenLegacy_preview() {
|
||||
email = "email@fake.com",
|
||||
onOpenEmailAppClick = { },
|
||||
onChangeEmailClick = { },
|
||||
onLoginClick = {},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,15 +53,9 @@ class CheckEmailViewModel @Inject constructor(
|
||||
is CheckEmailAction.Internal.OnboardingFeatureFlagUpdated -> {
|
||||
handleOnboardingFeatureFlagUpdated(action)
|
||||
}
|
||||
|
||||
CheckEmailAction.LoginClick -> handleLoginClick()
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleLoginClick() {
|
||||
sendEvent(CheckEmailEvent.NavigateBackToLanding)
|
||||
}
|
||||
|
||||
private fun handleOnboardingFeatureFlagUpdated(
|
||||
action: CheckEmailAction.Internal.OnboardingFeatureFlagUpdated,
|
||||
) {
|
||||
@@ -100,11 +94,6 @@ sealed class CheckEmailEvent {
|
||||
* Navigate to email app.
|
||||
*/
|
||||
data object NavigateToEmailApp : CheckEmailEvent()
|
||||
|
||||
/**
|
||||
* Navigate back to Landing
|
||||
*/
|
||||
data object NavigateBackToLanding : CheckEmailEvent()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -126,11 +115,6 @@ sealed class CheckEmailAction {
|
||||
*/
|
||||
data object OpenEmailClick : CheckEmailAction()
|
||||
|
||||
/**
|
||||
* User clicked log in.
|
||||
*/
|
||||
data object LoginClick : CheckEmailAction()
|
||||
|
||||
/**
|
||||
* Denotes an internal action.
|
||||
*/
|
||||
|
||||
@@ -12,7 +12,6 @@ class CheckEmailHandler(
|
||||
val onOpenEmailAppClick: () -> Unit,
|
||||
val onChangeEmailClick: () -> Unit,
|
||||
val onBackClick: () -> Unit,
|
||||
val onLoginClick: () -> Unit,
|
||||
) {
|
||||
@Suppress("UndocumentedPublicClass")
|
||||
companion object {
|
||||
@@ -22,7 +21,6 @@ class CheckEmailHandler(
|
||||
fun create(viewModel: CheckEmailViewModel) = CheckEmailHandler(
|
||||
onChangeEmailClick = { viewModel.trySendAction(CheckEmailAction.ChangeEmailClick) },
|
||||
onOpenEmailAppClick = { viewModel.trySendAction(CheckEmailAction.OpenEmailClick) },
|
||||
onLoginClick = { viewModel.trySendAction(CheckEmailAction.LoginClick) },
|
||||
onBackClick = { viewModel.trySendAction(CheckEmailAction.BackClick) },
|
||||
)
|
||||
}
|
||||
|
||||
@@ -940,7 +940,7 @@ Do you want to switch to this account?</string>
|
||||
<string name="user_verification_direction">User verification</string>
|
||||
<string name="create_account_on">Create account on</string>
|
||||
<string name="create_account_on_with_colon">Create account on:</string>
|
||||
<string name="follow_the_instructions_in_the_email_sent_to_x_to_continue_creating_your_account">Follow the instructions in the email sent to %1$s to continue creating your account.</string>
|
||||
<string name="follow_the_instructions_in_the_email_sent_to_x_to_continue_creating_your_account">Follow the instructions in the email sent to <annotation emphasis="bold"><annotation arg="0">%1$s</annotation></annotation> to continue creating your account.</string>
|
||||
<string name="we_sent_an_email_to">We sent an email to <annotation emphasis="bold"><annotation arg="0">%1$s</annotation></annotation>.</string>
|
||||
<string name="by_continuing_you_agree_to_the_terms_of_service_and_privacy_policy">By continuing, you agree to the <annotation link="termsOfService">Terms of Service</annotation> and <annotation link="privacyPolicy">Privacy Policy</annotation></string>
|
||||
<string name="set_password">Set password</string>
|
||||
|
||||
@@ -7,7 +7,6 @@ import androidx.compose.ui.test.performScrollTo
|
||||
import com.x8bit.bitwarden.data.platform.repository.util.bufferedMutableSharedFlow
|
||||
import com.x8bit.bitwarden.ui.platform.base.BaseComposeTest
|
||||
import com.x8bit.bitwarden.ui.platform.manager.intent.IntentManager
|
||||
import com.x8bit.bitwarden.ui.util.assertLinkAnnotationIsAppliedAndInvokeClickAction
|
||||
import io.mockk.every
|
||||
import io.mockk.just
|
||||
import io.mockk.mockk
|
||||
@@ -23,7 +22,6 @@ class CheckEmailScreenTest : BaseComposeTest() {
|
||||
every { startDefaultEmailApplication() } just runs
|
||||
}
|
||||
private var onNavigateBackCalled = false
|
||||
private var onNavigateToLandingCalled = false
|
||||
|
||||
private val mutableStateFlow = MutableStateFlow(DEFAULT_STATE)
|
||||
private val mutableEventFlow = bufferedMutableSharedFlow<CheckEmailEvent>()
|
||||
@@ -37,7 +35,6 @@ class CheckEmailScreenTest : BaseComposeTest() {
|
||||
composeTestRule.setContent {
|
||||
CheckEmailScreen(
|
||||
onNavigateBack = { onNavigateBackCalled = true },
|
||||
onNavigateBackToLanding = { onNavigateToLandingCalled = true },
|
||||
viewModel = viewModel,
|
||||
intentManager = intentManager,
|
||||
)
|
||||
@@ -66,12 +63,6 @@ class CheckEmailScreenTest : BaseComposeTest() {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `login button click should send LoginTap action`() {
|
||||
mutableEventFlow.tryEmit(CheckEmailEvent.NavigateBackToLanding)
|
||||
assertTrue(onNavigateToLandingCalled)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `NavigateBack should call onNavigateBack`() {
|
||||
mutableEventFlow.tryEmit(CheckEmailEvent.NavigateBack)
|
||||
@@ -86,28 +77,6 @@ class CheckEmailScreenTest : BaseComposeTest() {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `go back and update email text click should send ChangeEmailClick action`() {
|
||||
mutableStateFlow.value = DEFAULT_STATE.copy(showNewOnboardingUi = false)
|
||||
val mainString = "No email? Go back to edit your email address."
|
||||
composeTestRule.assertLinkAnnotationIsAppliedAndInvokeClickAction(
|
||||
mainString = mainString,
|
||||
)
|
||||
|
||||
verify { viewModel.trySendAction(CheckEmailAction.ChangeEmailClick) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `already have account text click should send ChangeEmailClick action`() {
|
||||
mutableStateFlow.value = DEFAULT_STATE.copy(showNewOnboardingUi = false)
|
||||
val mainString = "Or log in, you may already have an account."
|
||||
composeTestRule.assertLinkAnnotationIsAppliedAndInvokeClickAction(
|
||||
mainString = mainString,
|
||||
)
|
||||
|
||||
verify { viewModel.trySendAction(CheckEmailAction.LoginClick) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `change email button click should send ChangeEmailClick action`() {
|
||||
mutableStateFlow.value = DEFAULT_STATE.copy(showNewOnboardingUi = true)
|
||||
|
||||
@@ -84,18 +84,6 @@ class CheckEmailViewModelTest : BaseViewModelTest() {
|
||||
assertEquals(expectedState, viewModel.stateFlow.value)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `OnLoginClick action should send NavigateToLanding event`() = runTest {
|
||||
val viewModel = createViewModel()
|
||||
viewModel.eventFlow.test {
|
||||
viewModel.trySendAction(CheckEmailAction.LoginClick)
|
||||
assertEquals(
|
||||
CheckEmailEvent.NavigateBackToLanding,
|
||||
awaitItem(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun createViewModel(state: CheckEmailState? = null): CheckEmailViewModel =
|
||||
CheckEmailViewModel(
|
||||
featureFlagManager = featureFlagManager,
|
||||
|
||||
Reference in New Issue
Block a user