Skip to content

Commit fb5827a

Browse files
committed
CheckEmail screen
1 parent d8a2c51 commit fb5827a

File tree

4 files changed

+703
-163
lines changed

4 files changed

+703
-163
lines changed
Lines changed: 209 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
1+
package com.firebase.ui.auth.ui.email
2+
3+
import android.annotation.SuppressLint
4+
import android.text.TextUtils
5+
import androidx.compose.foundation.layout.*
6+
import androidx.compose.foundation.rememberScrollState
7+
import androidx.compose.foundation.text.KeyboardActions
8+
import androidx.compose.foundation.text.KeyboardOptions
9+
import androidx.compose.foundation.verticalScroll
10+
import androidx.compose.material3.*
11+
import androidx.compose.runtime.*
12+
import androidx.compose.ui.Alignment
13+
import androidx.compose.ui.Modifier
14+
import androidx.compose.ui.platform.LocalContext
15+
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
16+
import androidx.compose.ui.res.stringResource
17+
import androidx.compose.ui.text.input.ImeAction
18+
import androidx.compose.ui.text.input.KeyboardType
19+
import androidx.compose.ui.text.style.TextAlign
20+
import androidx.compose.ui.unit.dp
21+
import androidx.compose.foundation.layout.systemBarsPadding
22+
import com.firebase.ui.auth.R
23+
import com.firebase.ui.auth.data.model.FlowParameters
24+
import com.firebase.ui.auth.data.model.User
25+
import com.firebase.ui.auth.ui.idp.TermsAndPrivacyText
26+
import com.google.firebase.auth.EmailAuthProvider
27+
28+
@SuppressLint("WrongConstant")
29+
@Composable
30+
fun CheckEmailScreen(
31+
modifier: Modifier = Modifier,
32+
flowParameters: FlowParameters,
33+
initialEmail: String? = null,
34+
onExistingEmailUser: (User) -> Unit,
35+
onExistingIdpUser: (User) -> Unit,
36+
onNewUser: (User) -> Unit,
37+
onDeveloperFailure: (Exception) -> Unit,
38+
) {
39+
var email by remember { mutableStateOf(initialEmail ?: "") }
40+
var isEmailError by remember { mutableStateOf(false) }
41+
var emailErrorText by remember { mutableStateOf("") }
42+
var isLoading by remember { mutableStateOf(false) }
43+
val keyboardController = LocalSoftwareKeyboardController.current
44+
val context = LocalContext.current
45+
46+
LaunchedEffect(initialEmail) {
47+
if (!initialEmail.isNullOrEmpty()) {
48+
email = initialEmail
49+
}
50+
}
51+
52+
fun validateEmail(): Boolean {
53+
return when {
54+
TextUtils.isEmpty(email) -> {
55+
isEmailError = true
56+
emailErrorText = context.getString(R.string.fui_required_field)
57+
false
58+
}
59+
!android.util.Patterns.EMAIL_ADDRESS.matcher(email).matches() -> {
60+
isEmailError = true
61+
emailErrorText = context.getString(R.string.fui_invalid_email_address)
62+
false
63+
}
64+
else -> true
65+
}
66+
}
67+
68+
fun getEmailProvider(): String {
69+
flowParameters.providers.forEach { config ->
70+
if (EmailAuthProvider.EMAIL_LINK_SIGN_IN_METHOD == config.providerId) {
71+
return EmailAuthProvider.EMAIL_LINK_SIGN_IN_METHOD
72+
}
73+
}
74+
return EmailAuthProvider.PROVIDER_ID
75+
}
76+
77+
val signIn = {
78+
if (validateEmail()) {
79+
isLoading = true
80+
val provider = getEmailProvider()
81+
val user = User.Builder(provider, email).build()
82+
onExistingEmailUser(user)
83+
}
84+
}
85+
86+
val signUp = {
87+
if (validateEmail()) {
88+
isLoading = true
89+
val provider = getEmailProvider()
90+
val user = User.Builder(provider, email).build()
91+
onNewUser(user)
92+
}
93+
}
94+
95+
Scaffold(
96+
modifier = modifier
97+
.fillMaxSize()
98+
.systemBarsPadding(),
99+
containerColor = MaterialTheme.colorScheme.background
100+
) { innerPadding ->
101+
Column(
102+
modifier = Modifier
103+
.padding(innerPadding)
104+
.fillMaxSize()
105+
.verticalScroll(rememberScrollState())
106+
.padding(horizontal = 24.dp),
107+
horizontalAlignment = Alignment.CenterHorizontally
108+
) {
109+
if (isLoading) {
110+
LinearProgressIndicator(
111+
modifier = Modifier
112+
.fillMaxWidth()
113+
.height(4.dp)
114+
)
115+
Spacer(Modifier.height(16.dp))
116+
} else {
117+
Spacer(Modifier.height(24.dp))
118+
}
119+
120+
Text(
121+
text = stringResource(R.string.fui_email_link_confirm_email_message),
122+
style = MaterialTheme.typography.titleLarge,
123+
textAlign = TextAlign.Start,
124+
modifier = Modifier.fillMaxWidth()
125+
)
126+
127+
Spacer(Modifier.height(32.dp))
128+
129+
OutlinedTextField(
130+
value = email,
131+
onValueChange = {
132+
email = it
133+
isEmailError = false
134+
},
135+
label = { Text(stringResource(R.string.fui_email_hint)) },
136+
isError = isEmailError,
137+
supportingText = if (isEmailError) {
138+
{ Text(emailErrorText) }
139+
} else null,
140+
keyboardOptions = KeyboardOptions(
141+
keyboardType = KeyboardType.Email,
142+
imeAction = ImeAction.Done
143+
),
144+
keyboardActions = KeyboardActions(
145+
onDone = {
146+
keyboardController?.hide()
147+
signIn()
148+
}
149+
),
150+
shape = MaterialTheme.shapes.medium,
151+
colors = OutlinedTextFieldDefaults.colors(
152+
focusedBorderColor = MaterialTheme.colorScheme.primary,
153+
unfocusedBorderColor = MaterialTheme.colorScheme.outline,
154+
focusedLabelColor = MaterialTheme.colorScheme.primary,
155+
unfocusedLabelColor = MaterialTheme.colorScheme.onSurfaceVariant,
156+
cursorColor = MaterialTheme.colorScheme.primary,
157+
errorBorderColor = MaterialTheme.colorScheme.error,
158+
errorLabelColor = MaterialTheme.colorScheme.error,
159+
errorSupportingTextColor = MaterialTheme.colorScheme.error
160+
),
161+
modifier = Modifier
162+
.fillMaxWidth()
163+
.padding(bottom = if (isEmailError) 8.dp else 0.dp)
164+
)
165+
166+
Spacer(Modifier.height(24.dp))
167+
168+
Row(
169+
modifier = Modifier.fillMaxWidth(),
170+
horizontalArrangement = Arrangement.End,
171+
verticalAlignment = Alignment.CenterVertically
172+
) {
173+
OutlinedButton(
174+
onClick = signUp,
175+
enabled = !isLoading,
176+
modifier = Modifier
177+
.height(48.dp)
178+
) {
179+
Text(stringResource(R.string.fui_title_register_email))
180+
}
181+
182+
Spacer(Modifier.width(8.dp))
183+
184+
Button(
185+
onClick = signIn,
186+
enabled = !isLoading,
187+
modifier = Modifier
188+
.height(48.dp)
189+
) {
190+
Text(stringResource(R.string.fui_sign_in_default))
191+
}
192+
}
193+
194+
Spacer(Modifier.weight(1f))
195+
196+
if (flowParameters.isPrivacyPolicyUrlProvided() &&
197+
flowParameters.isTermsOfServiceUrlProvided()
198+
) {
199+
TermsAndPrivacyText(
200+
tosUrl = flowParameters.termsOfServiceUrl!!,
201+
ppUrl = flowParameters.privacyPolicyUrl!!,
202+
modifier = Modifier
203+
.fillMaxWidth()
204+
.padding(vertical = 16.dp)
205+
)
206+
}
207+
}
208+
}
209+
}

0 commit comments

Comments
 (0)