mirror of
https://github.com/bitwarden/android.git
synced 2025-03-16 19:28:44 +03:00
PM-11192 update check email screen to new design (#3788)
This commit is contained in:
parent
8d08b5f7c5
commit
86dabea39f
9 changed files with 275 additions and 154 deletions
|
@ -80,9 +80,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,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,9 +9,9 @@ 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
|
||||
import androidx.compose.foundation.text.ClickableText
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
|
@ -23,7 +23,6 @@ import androidx.compose.runtime.getValue
|
|||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.ColorFilter
|
||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.platform.testTag
|
||||
|
@ -31,23 +30,22 @@ import androidx.compose.ui.res.stringResource
|
|||
import androidx.compose.ui.text.SpanStyle
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.hilt.navigation.compose.hiltViewModel
|
||||
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.createAnnotatedString
|
||||
import com.x8bit.bitwarden.ui.platform.base.util.standardHorizontalMargin
|
||||
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.scaffold.BitwardenScaffold
|
||||
import com.x8bit.bitwarden.ui.platform.components.util.rememberVectorPainter
|
||||
import com.x8bit.bitwarden.ui.platform.composition.LocalIntentManager
|
||||
import com.x8bit.bitwarden.ui.platform.manager.intent.IntentManager
|
||||
|
||||
/**
|
||||
* Constant string to be used in string annotation tag field
|
||||
*/
|
||||
private const val TAG_URL = "URL"
|
||||
import com.x8bit.bitwarden.ui.platform.theme.BitwardenTheme
|
||||
|
||||
/**
|
||||
* Top level composable for the check email screen.
|
||||
|
@ -57,7 +55,6 @@ private const val TAG_URL = "URL"
|
|||
@Composable
|
||||
fun CheckEmailScreen(
|
||||
onNavigateBack: () -> Unit,
|
||||
onNavigateBackToLanding: () -> Unit,
|
||||
intentManager: IntentManager = LocalIntentManager.current,
|
||||
viewModel: CheckEmailViewModel = hiltViewModel(),
|
||||
) {
|
||||
|
@ -71,10 +68,6 @@ fun CheckEmailScreen(
|
|||
is CheckEmailEvent.NavigateToEmailApp -> {
|
||||
intentManager.startDefaultEmailApplication()
|
||||
}
|
||||
|
||||
is CheckEmailEvent.NavigateBackToLanding -> {
|
||||
onNavigateBackToLanding.invoke()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -87,10 +80,10 @@ fun CheckEmailScreen(
|
|||
BitwardenTopAppBar(
|
||||
title = stringResource(id = R.string.create_account),
|
||||
scrollBehavior = scrollBehavior,
|
||||
navigationIcon = rememberVectorPainter(id = R.drawable.ic_close),
|
||||
navigationIconContentDescription = stringResource(id = R.string.close),
|
||||
navigationIcon = rememberVectorPainter(id = R.drawable.ic_back),
|
||||
navigationIconContentDescription = stringResource(id = R.string.back),
|
||||
onNavigationIconClick = remember(viewModel) {
|
||||
{ viewModel.trySendAction(CheckEmailAction.CloseClick) }
|
||||
{ viewModel.trySendAction(CheckEmailAction.BackClick) }
|
||||
},
|
||||
)
|
||||
},
|
||||
|
@ -102,105 +95,118 @@ fun CheckEmailScreen(
|
|||
.fillMaxSize()
|
||||
.verticalScroll(rememberScrollState()),
|
||||
) {
|
||||
Spacer(modifier = Modifier.height(32.dp))
|
||||
Image(
|
||||
painter = rememberVectorPainter(id = R.drawable.email_check),
|
||||
colorFilter = ColorFilter.tint(MaterialTheme.colorScheme.primary),
|
||||
contentDescription = null,
|
||||
contentScale = ContentScale.FillHeight,
|
||||
modifier = Modifier
|
||||
.padding(horizontal = 16.dp)
|
||||
.height(112.dp)
|
||||
.fillMaxWidth(),
|
||||
)
|
||||
Spacer(modifier = Modifier.height(32.dp))
|
||||
Text(
|
||||
text = stringResource(id = R.string.check_your_email),
|
||||
textAlign = TextAlign.Center,
|
||||
style = MaterialTheme.typography.headlineSmall,
|
||||
color = MaterialTheme.colorScheme.onSurface,
|
||||
modifier = Modifier
|
||||
.padding(horizontal = 24.dp)
|
||||
.wrapContentHeight()
|
||||
.fillMaxWidth(),
|
||||
)
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
|
||||
@Suppress("MaxLineLength")
|
||||
val descriptionAnnotatedString = createAnnotatedString(
|
||||
mainString = stringResource(
|
||||
id = R.string.follow_the_instructions_in_the_email_sent_to_x_to_continue_creating_your_account,
|
||||
state.email,
|
||||
),
|
||||
highlights = listOf(state.email),
|
||||
highlightStyle = SpanStyle(
|
||||
color = MaterialTheme.colorScheme.onSurface,
|
||||
fontSize = MaterialTheme.typography.bodyMedium.fontSize,
|
||||
fontWeight = FontWeight.Bold,
|
||||
),
|
||||
tag = "EMAIL",
|
||||
)
|
||||
Text(
|
||||
text = descriptionAnnotatedString,
|
||||
textAlign = TextAlign.Center,
|
||||
modifier = Modifier
|
||||
.padding(horizontal = 24.dp)
|
||||
.fillMaxWidth()
|
||||
.wrapContentHeight(),
|
||||
)
|
||||
Spacer(modifier = Modifier.height(32.dp))
|
||||
BitwardenFilledButton(
|
||||
label = stringResource(id = R.string.open_email_app),
|
||||
onClick = remember(viewModel) {
|
||||
{ viewModel.trySendAction(CheckEmailAction.OpenEmailClick) }
|
||||
CheckEmailContent(
|
||||
email = state.email,
|
||||
onOpenEmailAppClick = remember(viewModel) {
|
||||
{
|
||||
viewModel.trySendAction(CheckEmailAction.OpenEmailClick)
|
||||
}
|
||||
},
|
||||
modifier = Modifier
|
||||
.testTag("OpenEmailApp")
|
||||
.padding(horizontal = 16.dp)
|
||||
.fillMaxWidth(),
|
||||
onChangeEmailClick = remember(viewModel) {
|
||||
{
|
||||
viewModel.trySendAction(CheckEmailAction.ChangeEmailClick)
|
||||
}
|
||||
},
|
||||
modifier = Modifier.standardHorizontalMargin(),
|
||||
)
|
||||
Spacer(modifier = Modifier.height(32.dp))
|
||||
Column(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
val goBackAnnotatedString = createAnnotatedString(
|
||||
mainString = stringResource(
|
||||
id = R.string.no_email_go_back_to_edit_your_email_address,
|
||||
),
|
||||
highlights = listOf(stringResource(id = R.string.go_back)),
|
||||
tag = TAG_URL,
|
||||
)
|
||||
ClickableText(
|
||||
text = goBackAnnotatedString,
|
||||
onClick = {
|
||||
goBackAnnotatedString
|
||||
.getStringAnnotations(TAG_URL, it, it)
|
||||
.firstOrNull()?.let {
|
||||
viewModel.trySendAction(CheckEmailAction.CloseClick)
|
||||
}
|
||||
},
|
||||
)
|
||||
Spacer(modifier = Modifier.height(32.dp))
|
||||
val logInAnnotatedString = createAnnotatedString(
|
||||
mainString = stringResource(
|
||||
id = R.string.or_log_in_you_may_already_have_an_account,
|
||||
),
|
||||
highlights = listOf(stringResource(id = R.string.log_in)),
|
||||
tag = TAG_URL,
|
||||
)
|
||||
ClickableText(
|
||||
text = logInAnnotatedString,
|
||||
onClick = {
|
||||
logInAnnotatedString
|
||||
.getStringAnnotations(TAG_URL, it, it)
|
||||
.firstOrNull()?.let {
|
||||
viewModel.trySendAction(CheckEmailAction.LoginClick)
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
Spacer(modifier = Modifier.navigationBarsPadding())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("LongMethod")
|
||||
@Composable
|
||||
private fun CheckEmailContent(
|
||||
email: String,
|
||||
onOpenEmailAppClick: () -> Unit,
|
||||
onChangeEmailClick: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
Column(
|
||||
modifier = modifier
|
||||
.fillMaxWidth(),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
Spacer(modifier = Modifier.height(32.dp))
|
||||
Image(
|
||||
painter = rememberVectorPainter(id = R.drawable.open_email),
|
||||
contentDescription = null,
|
||||
contentScale = ContentScale.Fit,
|
||||
modifier = Modifier
|
||||
.size(100.dp),
|
||||
)
|
||||
Spacer(modifier = Modifier.height(32.dp))
|
||||
Text(
|
||||
text = stringResource(id = R.string.check_your_email),
|
||||
textAlign = TextAlign.Center,
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
color = MaterialTheme.colorScheme.onSurface,
|
||||
modifier = Modifier
|
||||
.padding(horizontal = 8.dp)
|
||||
.wrapContentHeight()
|
||||
.fillMaxWidth(),
|
||||
)
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
|
||||
val descriptionAnnotatedString = createAnnotatedString(
|
||||
mainString = stringResource(
|
||||
id = R.string.we_sent_an_email_to,
|
||||
email,
|
||||
),
|
||||
highlights = listOf(email),
|
||||
highlightStyle = SpanStyle(
|
||||
color = MaterialTheme.colorScheme.onSurface,
|
||||
fontSize = MaterialTheme.typography.bodyMedium.fontSize,
|
||||
fontWeight = FontWeight.Bold,
|
||||
),
|
||||
tag = "EMAIL",
|
||||
)
|
||||
Text(
|
||||
text = descriptionAnnotatedString,
|
||||
textAlign = TextAlign.Center,
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
modifier = Modifier
|
||||
.padding(horizontal = 8.dp)
|
||||
.fillMaxWidth()
|
||||
.wrapContentHeight(),
|
||||
)
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
@Suppress("MaxLineLength")
|
||||
Text(
|
||||
text = stringResource(R.string.select_the_link_in_the_email_to_verify_your_email_address_and_continue_creating_your_account),
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = MaterialTheme.colorScheme.onSurface,
|
||||
textAlign = TextAlign.Center,
|
||||
modifier = Modifier
|
||||
.padding(horizontal = 8.dp)
|
||||
.fillMaxWidth()
|
||||
.wrapContentHeight(),
|
||||
)
|
||||
Spacer(modifier = Modifier.height(32.dp))
|
||||
BitwardenFilledButton(
|
||||
label = stringResource(id = R.string.open_email_app),
|
||||
onClick = onOpenEmailAppClick,
|
||||
modifier = Modifier
|
||||
.testTag("OpenEmailApp")
|
||||
.fillMaxWidth(),
|
||||
)
|
||||
Spacer(modifier = Modifier.height(12.dp))
|
||||
BitwardenTextButton(
|
||||
label = stringResource(R.string.change_email_address),
|
||||
onClick = onChangeEmailClick,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(showBackground = true)
|
||||
@Composable
|
||||
private fun CheckEmailScreenPreview() {
|
||||
BitwardenTheme {
|
||||
CheckEmailContent(
|
||||
email = "email@fake.com",
|
||||
onOpenEmailAppClick = { },
|
||||
onChangeEmailClick = { },
|
||||
modifier = Modifier.standardHorizontalMargin(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,11 +33,17 @@ class CheckEmailViewModel @Inject constructor(
|
|||
|
||||
override fun handleAction(action: CheckEmailAction) {
|
||||
when (action) {
|
||||
CheckEmailAction.CloseClick -> sendEvent(CheckEmailEvent.NavigateBack)
|
||||
CheckEmailAction.LoginClick -> sendEvent(CheckEmailEvent.NavigateBackToLanding)
|
||||
CheckEmailAction.OpenEmailClick -> sendEvent(CheckEmailEvent.NavigateToEmailApp)
|
||||
CheckEmailAction.BackClick -> handleBackClick()
|
||||
CheckEmailAction.OpenEmailClick -> handleOpenEmailClick()
|
||||
CheckEmailAction.ChangeEmailClick -> handleChangeEmailClick()
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleOpenEmailClick() = sendEvent(CheckEmailEvent.NavigateToEmailApp)
|
||||
|
||||
private fun handleBackClick() = sendEvent(CheckEmailEvent.NavigateBack)
|
||||
|
||||
private fun handleChangeEmailClick() = sendEvent(CheckEmailEvent.NavigateBack)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -62,11 +68,6 @@ sealed class CheckEmailEvent {
|
|||
* Navigate to email app.
|
||||
*/
|
||||
data object NavigateToEmailApp : CheckEmailEvent()
|
||||
|
||||
/**
|
||||
* Navigate to landing screen.
|
||||
*/
|
||||
data object NavigateBackToLanding : CheckEmailEvent()
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -76,12 +77,12 @@ sealed class CheckEmailAction {
|
|||
/**
|
||||
* User clicked close.
|
||||
*/
|
||||
data object CloseClick : CheckEmailAction()
|
||||
data object BackClick : CheckEmailAction()
|
||||
|
||||
/**
|
||||
* User clicked log in.
|
||||
* User clicked change email.
|
||||
*/
|
||||
data object LoginClick : CheckEmailAction()
|
||||
data object ChangeEmailClick : CheckEmailAction()
|
||||
|
||||
/**
|
||||
* User clicked open email.
|
||||
|
|
54
app/src/main/res/drawable-night/open_email.xml
Normal file
54
app/src/main/res/drawable-night/open_email.xml
Normal file
|
@ -0,0 +1,54 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="197dp"
|
||||
android:height="164dp"
|
||||
android:viewportWidth="197"
|
||||
android:viewportHeight="164">
|
||||
<path
|
||||
android:pathData="M89.79,9.59C85.92,6.59 80.54,6.55 76.62,9.48L64.3,18.71C63.41,19.37 62.16,19.19 61.5,18.31C60.84,17.42 61.02,16.17 61.9,15.51L74.23,6.28C79.58,2.27 86.95,2.33 92.24,6.42L94.8,8.41C95.67,9.08 95.83,10.34 95.15,11.21C94.48,12.09 93.22,12.25 92.35,11.57L89.79,9.59ZM21.6,48.19C22.26,49.08 22.08,50.33 21.2,50.99L8.35,60.62C5.61,62.67 4,65.89 4,69.31V148.26C4,154.26 8.86,159.12 14.86,159.12H152.88C158.88,159.12 163.75,154.26 163.75,148.26V103.35C163.75,102.24 164.64,101.35 165.75,101.35C166.85,101.35 167.75,102.24 167.75,103.35V148.26C167.75,156.46 161.09,163.12 152.88,163.12H14.86C6.65,163.12 0,156.46 0,148.26V69.31C0,64.63 2.21,60.22 5.95,57.41L18.8,47.79C19.69,47.13 20.94,47.31 21.6,48.19ZM165.75,60.87C166.85,60.87 167.75,61.77 167.75,62.87V84.94C167.75,86.05 166.85,86.94 165.75,86.94C164.64,86.94 163.75,86.05 163.75,84.94V62.87C163.75,61.77 164.64,60.87 165.75,60.87Z"
|
||||
android:fillColor="#E2E3E4"
|
||||
android:fillType="evenOdd"/>
|
||||
<path
|
||||
android:pathData="M25.44,19.61C24.18,19.61 23.16,20.63 23.16,21.89V78.03C23.16,79.13 22.26,80.03 21.16,80.03C20.05,80.03 19.16,79.13 19.16,78.03V21.89C19.16,18.42 21.97,15.61 25.44,15.61H84.36C85.47,15.61 86.36,16.5 86.36,17.61C86.36,18.71 85.47,19.61 84.36,19.61H25.44Z"
|
||||
android:fillColor="#6FD9E2"
|
||||
android:fillType="evenOdd"/>
|
||||
<path
|
||||
android:pathData="M34.33,36.2C34.33,35.1 35.23,34.2 36.33,34.2H64.99C66.1,34.2 66.99,35.1 66.99,36.2C66.99,37.31 66.1,38.2 64.99,38.2H36.33C35.23,38.2 34.33,37.31 34.33,36.2Z"
|
||||
android:fillColor="#6FD9E2"
|
||||
android:fillType="evenOdd"/>
|
||||
<path
|
||||
android:pathData="M34.33,53.32C34.33,52.22 35.23,51.32 36.33,51.32H64.16C65.26,51.32 66.16,52.22 66.16,53.32C66.16,54.42 65.26,55.32 64.16,55.32H36.33C35.23,55.32 34.33,54.42 34.33,53.32Z"
|
||||
android:fillColor="#6FD9E2"
|
||||
android:fillType="evenOdd"/>
|
||||
<path
|
||||
android:pathData="M34.33,70.44C34.33,69.33 35.23,68.44 36.33,68.44H68.75C69.85,68.44 70.75,69.33 70.75,70.44C70.75,71.54 69.85,72.44 68.75,72.44H36.33C35.23,72.44 34.33,71.54 34.33,70.44Z"
|
||||
android:fillColor="#6FD9E2"
|
||||
android:fillType="evenOdd"/>
|
||||
<path
|
||||
android:pathData="M34.33,87.56C34.33,86.46 35.23,85.56 36.33,85.56H78.76C79.87,85.56 80.76,86.46 80.76,87.56C80.76,88.67 79.87,89.56 78.76,89.56H36.33C35.23,89.56 34.33,88.67 34.33,87.56Z"
|
||||
android:fillColor="#6FD9E2"
|
||||
android:fillType="evenOdd"/>
|
||||
<path
|
||||
android:pathData="M53.59,108.05C57.97,103.8 63.83,101.42 69.93,101.42H95.35C101.26,101.42 106.95,103.65 111.28,107.66L163.62,156.15L160.9,159.09L108.56,110.6C104.97,107.27 100.25,105.42 95.35,105.42H69.93C64.87,105.42 60.01,107.39 56.38,110.92L6.87,159.06L4.08,156.19L53.59,108.05Z"
|
||||
android:fillColor="#E2E3E4"
|
||||
android:fillType="evenOdd"/>
|
||||
<path
|
||||
android:pathData="M123.04,93.78C123.59,94.74 123.26,95.96 122.3,96.51L106.02,105.89C105.06,106.44 103.84,106.11 103.29,105.15C102.75,104.19 103.08,102.96 104.04,102.41L120.32,93.04C121.27,92.49 122.49,92.82 123.04,93.78Z"
|
||||
android:fillColor="#E2E3E4"
|
||||
android:fillType="evenOdd"/>
|
||||
<path
|
||||
android:pathData="M1.85,67.55C1.29,68.5 1.6,69.73 2.55,70.29L61.83,105.83C62.77,106.4 64,106.09 64.56,105.14C65.13,104.19 64.82,102.96 63.87,102.39L4.59,66.86C3.64,66.29 2.42,66.6 1.85,67.55Z"
|
||||
android:fillColor="#E2E3E4"
|
||||
android:fillType="evenOdd"/>
|
||||
<path
|
||||
android:pathData="M75.87,48.27C75.87,23.81 95.62,4 119.97,4C144.31,4 164.06,23.81 164.06,48.27C164.06,72.72 144.31,92.53 119.97,92.53C95.62,92.53 75.87,72.72 75.87,48.27ZM119.97,-0C93.4,-0 71.87,21.62 71.87,48.27C71.87,74.92 93.4,96.53 119.97,96.53C146.54,96.53 168.06,74.92 168.06,48.27C168.06,21.62 146.54,-0 119.97,-0Z"
|
||||
android:fillColor="#E2E3E4"
|
||||
android:fillType="evenOdd"/>
|
||||
<path
|
||||
android:pathData="M118.72,88.06C118.72,88.65 119.2,89.13 119.79,89.13C142.52,89.13 160.96,70.84 160.96,48.27C160.96,47.68 160.48,47.2 159.89,47.2C159.3,47.2 158.82,47.68 158.82,48.27C158.82,69.64 141.35,86.99 119.79,86.99C119.2,86.99 118.72,87.47 118.72,88.06ZM79.69,49.34C80.28,49.34 80.76,48.86 80.76,48.27C80.76,26.89 98.23,9.55 119.79,9.55C120.38,9.55 120.86,9.07 120.86,8.48C120.86,7.89 120.38,7.41 119.79,7.41C97.06,7.41 78.62,25.69 78.62,48.27C78.62,48.86 79.1,49.34 79.69,49.34Z"
|
||||
android:fillColor="#E2E3E4"
|
||||
android:fillType="evenOdd"/>
|
||||
<path
|
||||
android:pathData="M188.81,111.53C190.12,112.85 190.12,114.98 188.81,116.29L187.81,117.29C186.5,118.61 184.38,118.61 183.07,117.29L149.62,83.71C148.84,82.93 147.57,82.93 146.79,83.71C146.01,84.5 146.01,85.77 146.79,86.55L180.25,120.13C183.11,123.01 187.76,123.01 190.63,120.13L191.63,119.13C194.5,116.25 194.5,111.58 191.63,108.7L158.18,75.12C157.4,74.34 156.13,74.34 155.35,75.12C154.57,75.9 154.57,77.17 155.35,77.96L188.81,111.53Z"
|
||||
android:fillColor="#E2E3E4"
|
||||
android:fillType="evenOdd"/>
|
||||
</vector>
|
54
app/src/main/res/drawable/open_email.xml
Normal file
54
app/src/main/res/drawable/open_email.xml
Normal file
|
@ -0,0 +1,54 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="197dp"
|
||||
android:height="164dp"
|
||||
android:viewportWidth="197"
|
||||
android:viewportHeight="164">
|
||||
<path
|
||||
android:pathData="M89.79,9.59C85.92,6.59 80.54,6.55 76.62,9.48L64.3,18.71C63.41,19.37 62.16,19.19 61.5,18.31C60.84,17.42 61.02,16.17 61.9,15.51L74.23,6.28C79.58,2.27 86.95,2.33 92.24,6.42L94.8,8.41C95.67,9.08 95.83,10.34 95.15,11.21C94.48,12.09 93.22,12.25 92.35,11.57L89.79,9.59ZM21.6,48.19C22.26,49.08 22.08,50.33 21.2,50.99L8.35,60.62C5.61,62.67 4,65.89 4,69.31V148.26C4,154.26 8.86,159.12 14.86,159.12H152.88C158.88,159.12 163.75,154.26 163.75,148.26V103.35C163.75,102.24 164.64,101.35 165.75,101.35C166.85,101.35 167.75,102.24 167.75,103.35V148.26C167.75,156.46 161.09,163.12 152.88,163.12H14.86C6.65,163.12 0,156.46 0,148.26V69.31C0,64.63 2.21,60.22 5.95,57.41L18.8,47.79C19.69,47.13 20.94,47.31 21.6,48.19ZM165.75,60.87C166.85,60.87 167.75,61.77 167.75,62.87V84.94C167.75,86.05 166.85,86.94 165.75,86.94C164.64,86.94 163.75,86.05 163.75,84.94V62.87C163.75,61.77 164.64,60.87 165.75,60.87Z"
|
||||
android:fillColor="#020F66"
|
||||
android:fillType="evenOdd"/>
|
||||
<path
|
||||
android:pathData="M25.44,19.61C24.18,19.61 23.16,20.63 23.16,21.89V78.03C23.16,79.13 22.26,80.03 21.16,80.03C20.05,80.03 19.16,79.13 19.16,78.03V21.89C19.16,18.42 21.97,15.61 25.44,15.61H84.36C85.47,15.61 86.36,16.5 86.36,17.61C86.36,18.71 85.47,19.61 84.36,19.61H25.44Z"
|
||||
android:fillColor="#10949D"
|
||||
android:fillType="evenOdd"/>
|
||||
<path
|
||||
android:pathData="M34.33,36.2C34.33,35.1 35.23,34.2 36.33,34.2H64.99C66.1,34.2 66.99,35.1 66.99,36.2C66.99,37.31 66.1,38.2 64.99,38.2H36.33C35.23,38.2 34.33,37.31 34.33,36.2Z"
|
||||
android:fillColor="#10949D"
|
||||
android:fillType="evenOdd"/>
|
||||
<path
|
||||
android:pathData="M34.33,53.32C34.33,52.22 35.23,51.32 36.33,51.32H64.16C65.26,51.32 66.16,52.22 66.16,53.32C66.16,54.43 65.26,55.32 64.16,55.32H36.33C35.23,55.32 34.33,54.43 34.33,53.32Z"
|
||||
android:fillColor="#10949D"
|
||||
android:fillType="evenOdd"/>
|
||||
<path
|
||||
android:pathData="M34.33,70.44C34.33,69.33 35.23,68.44 36.33,68.44H68.75C69.85,68.44 70.75,69.33 70.75,70.44C70.75,71.54 69.85,72.44 68.75,72.44H36.33C35.23,72.44 34.33,71.54 34.33,70.44Z"
|
||||
android:fillColor="#10949D"
|
||||
android:fillType="evenOdd"/>
|
||||
<path
|
||||
android:pathData="M34.33,87.56C34.33,86.46 35.23,85.56 36.33,85.56H78.76C79.87,85.56 80.76,86.46 80.76,87.56C80.76,88.67 79.87,89.56 78.76,89.56H36.33C35.23,89.56 34.33,88.67 34.33,87.56Z"
|
||||
android:fillColor="#10949D"
|
||||
android:fillType="evenOdd"/>
|
||||
<path
|
||||
android:pathData="M53.59,108.05C57.97,103.8 63.83,101.42 69.93,101.42H95.35C101.26,101.42 106.95,103.65 111.28,107.66L163.62,156.15L160.9,159.09L108.56,110.6C104.97,107.27 100.25,105.42 95.35,105.42H69.93C64.87,105.42 60.01,107.39 56.38,110.92L6.87,159.05L4.08,156.19L53.59,108.05Z"
|
||||
android:fillColor="#020F66"
|
||||
android:fillType="evenOdd"/>
|
||||
<path
|
||||
android:pathData="M123.04,93.78C123.59,94.74 123.26,95.96 122.3,96.51L106.02,105.89C105.06,106.44 103.84,106.11 103.29,105.15C102.75,104.19 103.08,102.96 104.04,102.41L120.32,93.04C121.27,92.49 122.49,92.82 123.04,93.78Z"
|
||||
android:fillColor="#020F66"
|
||||
android:fillType="evenOdd"/>
|
||||
<path
|
||||
android:pathData="M1.85,67.55C1.29,68.5 1.6,69.73 2.55,70.29L61.83,105.83C62.77,106.4 64,106.09 64.56,105.14C65.13,104.19 64.82,102.96 63.87,102.39L4.59,66.86C3.64,66.29 2.42,66.6 1.85,67.55Z"
|
||||
android:fillColor="#020F66"
|
||||
android:fillType="evenOdd"/>
|
||||
<path
|
||||
android:pathData="M75.87,48.27C75.87,23.81 95.62,4 119.97,4C144.31,4 164.06,23.81 164.06,48.27C164.06,72.72 144.31,92.53 119.97,92.53C95.62,92.53 75.87,72.72 75.87,48.27ZM119.97,-0C93.4,-0 71.87,21.62 71.87,48.27C71.87,74.92 93.4,96.53 119.97,96.53C146.54,96.53 168.06,74.92 168.06,48.27C168.06,21.62 146.54,-0 119.97,-0Z"
|
||||
android:fillColor="#020F66"
|
||||
android:fillType="evenOdd"/>
|
||||
<path
|
||||
android:pathData="M118.72,88.06C118.72,88.65 119.2,89.13 119.79,89.13C142.52,89.13 160.96,70.84 160.96,48.27C160.96,47.68 160.48,47.2 159.89,47.2C159.3,47.2 158.82,47.68 158.82,48.27C158.82,69.64 141.35,86.99 119.79,86.99C119.2,86.99 118.72,87.47 118.72,88.06ZM79.69,49.34C80.28,49.34 80.76,48.86 80.76,48.27C80.76,26.89 98.23,9.55 119.79,9.55C120.38,9.55 120.86,9.07 120.86,8.48C120.86,7.89 120.38,7.41 119.79,7.41C97.06,7.41 78.62,25.69 78.62,48.27C78.62,48.86 79.1,49.34 79.69,49.34Z"
|
||||
android:fillColor="#020F66"
|
||||
android:fillType="evenOdd"/>
|
||||
<path
|
||||
android:pathData="M188.81,111.53C190.12,112.85 190.12,114.98 188.81,116.29L187.81,117.29C186.5,118.61 184.38,118.61 183.07,117.29L149.62,83.71C148.84,82.93 147.57,82.93 146.79,83.71C146.01,84.5 146.01,85.77 146.79,86.55L180.25,120.13C183.11,123.01 187.76,123.01 190.63,120.13L191.63,119.13C194.5,116.25 194.5,111.58 191.63,108.7L158.18,75.12C157.4,74.34 156.13,74.34 155.35,75.12C154.57,75.9 154.57,77.17 155.35,77.96L188.81,111.53Z"
|
||||
android:fillColor="#020F66"
|
||||
android:fillType="evenOdd"/>
|
||||
</vector>
|
|
@ -930,6 +930,7 @@ Do you want to switch to this account?</string>
|
|||
<string name="user_verification_direction">User verification</string>
|
||||
<string name="creating_on">Creating 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="we_sent_an_email_to">We sent an email to %1$s.</string>
|
||||
<string name="by_continuing_you_agree_to_the_terms_of_service_and_privacy_policy">By continuing, you agree to the Terms of Service and Privacy Policy</string>
|
||||
<string name="set_password">Set password</string>
|
||||
<string name="unsubscribe">Unsubscribe</string>
|
||||
|
@ -979,4 +980,6 @@ Do you want to switch to this account?</string>
|
|||
<string name="learn_about_other_ways_to_prevent_account_lockout">Learn about other ways to prevent account lockout</string>
|
||||
<string name="help_with_server_geolocations">Help with server geolocations.</string>
|
||||
<string name="email_address_required">Email address (required)</string>
|
||||
<string name="select_the_link_in_the_email_to_verify_your_email_address_and_continue_creating_your_account">"Select the link in the email to verify your email address and continue creating your account. "</string>
|
||||
<string name="change_email_address">Change email address</string>
|
||||
</resources>
|
||||
|
|
|
@ -3,6 +3,7 @@ package com.x8bit.bitwarden.ui.auth.feature.checkemail
|
|||
import androidx.compose.ui.test.onNodeWithContentDescription
|
||||
import androidx.compose.ui.test.onNodeWithText
|
||||
import androidx.compose.ui.test.performClick
|
||||
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
|
||||
|
@ -21,8 +22,6 @@ class CheckEmailScreenTest : BaseComposeTest() {
|
|||
every { startDefaultEmailApplication() } just runs
|
||||
}
|
||||
private var onNavigateBackCalled = false
|
||||
private var onNavigateBackToLandingCalled = false
|
||||
private var onNavigateToEmailAppCalled = false
|
||||
|
||||
private val mutableStateFlow = MutableStateFlow(DEFAULT_STATE)
|
||||
private val mutableEventFlow = bufferedMutableSharedFlow<CheckEmailEvent>()
|
||||
|
@ -36,7 +35,6 @@ class CheckEmailScreenTest : BaseComposeTest() {
|
|||
composeTestRule.setContent {
|
||||
CheckEmailScreen(
|
||||
onNavigateBack = { onNavigateBackCalled = true },
|
||||
onNavigateBackToLanding = { onNavigateBackToLandingCalled = true },
|
||||
viewModel = viewModel,
|
||||
intentManager = intentManager,
|
||||
)
|
||||
|
@ -44,27 +42,27 @@ class CheckEmailScreenTest : BaseComposeTest() {
|
|||
}
|
||||
|
||||
@Test
|
||||
fun `close button click should send CloseTap action`() {
|
||||
composeTestRule.onNodeWithContentDescription("Close").performClick()
|
||||
fun `close button click should send BackClick action`() {
|
||||
composeTestRule
|
||||
.onNodeWithContentDescription("Back")
|
||||
.performClick()
|
||||
verify {
|
||||
viewModel.trySendAction(CheckEmailAction.CloseClick)
|
||||
viewModel.trySendAction(CheckEmailAction.BackClick)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `open email app button click should send OpenEmailTap action`() {
|
||||
composeTestRule.onNodeWithText("Open email app").performClick()
|
||||
fun `open email app button click should send OpenEmailClcik action`() {
|
||||
composeTestRule
|
||||
.onNodeWithText("Open email app")
|
||||
.performScrollTo()
|
||||
.performClick()
|
||||
|
||||
verify {
|
||||
viewModel.trySendAction(CheckEmailAction.OpenEmailClick)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `login button click should send LoginTap action`() {
|
||||
mutableEventFlow.tryEmit(CheckEmailEvent.NavigateBackToLanding)
|
||||
TestCase.assertTrue(onNavigateBackToLandingCalled)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `NavigateBack should call onNavigateBack`() {
|
||||
mutableEventFlow.tryEmit(CheckEmailEvent.NavigateBack)
|
||||
|
@ -79,6 +77,16 @@ class CheckEmailScreenTest : BaseComposeTest() {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `change email button click should send ChangeEmailClick action`() {
|
||||
composeTestRule
|
||||
.onNodeWithText("Change email address")
|
||||
.performScrollTo()
|
||||
.performClick()
|
||||
|
||||
verify { viewModel.trySendAction(CheckEmailAction.ChangeEmailClick) }
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val EMAIL = "test@gmail.com"
|
||||
private val DEFAULT_STATE = CheckEmailState(
|
||||
|
|
|
@ -31,7 +31,7 @@ class CheckEmailViewModelTest : BaseViewModelTest() {
|
|||
fun `CloseTap should emit NavigateBack`() = runTest {
|
||||
val viewModel = createViewModel()
|
||||
viewModel.eventFlow.test {
|
||||
viewModel.trySendAction(CheckEmailAction.CloseClick)
|
||||
viewModel.trySendAction(CheckEmailAction.BackClick)
|
||||
assertEquals(
|
||||
CheckEmailEvent.NavigateBack,
|
||||
awaitItem(),
|
||||
|
@ -39,18 +39,6 @@ class CheckEmailViewModelTest : BaseViewModelTest() {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `LoginTap should emit NavigateBackToLanding`() = runTest {
|
||||
val viewModel = createViewModel()
|
||||
viewModel.eventFlow.test {
|
||||
viewModel.trySendAction(CheckEmailAction.LoginClick)
|
||||
assertEquals(
|
||||
CheckEmailEvent.NavigateBackToLanding,
|
||||
awaitItem(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `OpenEmailTap should emit NavigateToEmailApp`() = runTest {
|
||||
val viewModel = createViewModel()
|
||||
|
@ -63,6 +51,18 @@ class CheckEmailViewModelTest : BaseViewModelTest() {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `ChangeEmailTap should emit NavigateBack`() = runTest {
|
||||
val viewModel = createViewModel()
|
||||
viewModel.eventFlow.test {
|
||||
viewModel.trySendAction(CheckEmailAction.ChangeEmailClick)
|
||||
assertEquals(
|
||||
CheckEmailEvent.NavigateBack,
|
||||
awaitItem(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun createViewModel(state: CheckEmailState? = null): CheckEmailViewModel =
|
||||
CheckEmailViewModel(
|
||||
savedStateHandle = SavedStateHandle().also {
|
||||
|
|
Loading…
Add table
Reference in a new issue