Skip to content

Commit 39714e7

Browse files
authored
Merge pull request #451 from urnetwork/bugfix-reset-password-alert
bugfix broken snackbar when triggering reset password email
2 parents e476967 + fe0bdfc commit 39714e7

21 files changed

Lines changed: 103 additions & 119 deletions

File tree

app/app/src/main/java/com/bringyour/network/ui/profile/ProfileScreen.kt

Lines changed: 70 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.bringyour.network.ui.profile
22

3+
import android.widget.Toast
34
import androidx.compose.foundation.clickable
45
import androidx.compose.foundation.layout.Arrangement
56
import androidx.compose.foundation.layout.Column
@@ -9,7 +10,6 @@ import androidx.compose.foundation.layout.fillMaxWidth
910
import androidx.compose.foundation.layout.height
1011
import androidx.compose.foundation.layout.imePadding
1112
import androidx.compose.foundation.layout.padding
12-
import androidx.compose.foundation.layout.width
1313
import androidx.compose.foundation.text.KeyboardOptions
1414
import androidx.compose.material.icons.Icons
1515
import androidx.compose.material.icons.automirrored.filled.KeyboardArrowLeft
@@ -33,6 +33,7 @@ import androidx.compose.runtime.rememberCoroutineScope
3333
import androidx.compose.runtime.setValue
3434
import androidx.compose.ui.Alignment
3535
import androidx.compose.ui.Modifier
36+
import androidx.compose.ui.platform.LocalContext
3637
import androidx.compose.ui.res.stringResource
3738
import androidx.compose.ui.text.TextStyle
3839
import androidx.compose.ui.text.input.ImeAction
@@ -47,14 +48,14 @@ import com.bringyour.network.R
4748
import com.bringyour.network.ui.account.AccountViewModel
4849
import com.bringyour.network.ui.components.AccountSwitcher
4950
import com.bringyour.network.ui.components.LoginMode
50-
import com.bringyour.network.ui.components.SnackBarType
51-
import com.bringyour.network.ui.components.URSnackBar
5251
import com.bringyour.network.ui.components.URTextInput
5352
import com.bringyour.network.ui.components.overlays.OverlayMode
5453
import com.bringyour.network.ui.shared.viewmodels.OverlayViewModel
54+
import com.bringyour.network.ui.shared.viewmodels.ResetPasswordFunction
5555
import com.bringyour.network.ui.shared.viewmodels.ResetPasswordViewModel
5656
import com.bringyour.network.ui.theme.Black
5757
import com.bringyour.network.ui.theme.BlueMedium
58+
import com.bringyour.network.ui.theme.TextMuted
5859
import com.bringyour.network.ui.theme.TopBarTitleTextStyle
5960
import com.bringyour.network.ui.theme.URNetworkTheme
6061
import kotlinx.coroutines.Job
@@ -93,10 +94,6 @@ fun ProfileScreen(
9394
loginMode = accountViewModel.loginMode,
9495
isSendingResetPassLink = resetPasswordViewModel.isSendingResetPassLink,
9596
sendResetLink = resetPasswordViewModel.sendResetLink,
96-
passwordResetError = resetPasswordViewModel.passwordResetError,
97-
markPasswordResetAsSent = resetPasswordViewModel.markPasswordResetAsSent,
98-
setPasswordResetError = resetPasswordViewModel.setPasswordResetError,
99-
setMarkPasswordResetAsSent = resetPasswordViewModel.setMarkPasswordResetAsSent,
10097
networkName = networkUser?.networkName ?: "",
10198
networkNameTextFieldValue = profileViewModel.networkNameTextFieldValue,
10299
setNetworkName = profileViewModel.setNetworkNameTextFieldValue,
@@ -122,11 +119,7 @@ fun ProfileScreen(
122119
navController: NavController,
123120
loginMode: LoginMode,
124121
isSendingResetPassLink: Boolean,
125-
sendResetLink: (String) -> Unit,
126-
passwordResetError: String?,
127-
markPasswordResetAsSent: Boolean,
128-
setPasswordResetError: (String?) -> Unit,
129-
setMarkPasswordResetAsSent: (Boolean) -> Unit,
122+
sendResetLink: ResetPasswordFunction,
130123
networkName: String,
131124
networkNameTextFieldValue: TextFieldValue,
132125
setNetworkName: (TextFieldValue) -> Unit,
@@ -144,17 +137,32 @@ fun ProfileScreen(
144137
launchOverlay: (OverlayMode) -> Unit
145138
) {
146139

140+
val context = LocalContext.current
141+
var lastResetTime by remember { mutableStateOf(0L) }
142+
var cooldownTrigger by remember { mutableStateOf(0) }
143+
val cooldownPeriod = 15_000L // 15 seconds
144+
145+
// disable send reset email for 15 seconds after successfully sending
146+
LaunchedEffect(lastResetTime) {
147+
if (lastResetTime > 0L) {
148+
delay(cooldownPeriod)
149+
cooldownTrigger++ // trigger recomposition
150+
}
151+
}
152+
147153
val resendBtnEnabled by remember {
148154
derivedStateOf {
149-
passwordResetError == null &&
150-
userAuth != null &&
155+
cooldownTrigger
156+
userAuth != null &&
151157
!isSendingResetPassLink &&
152-
!markPasswordResetAsSent
158+
(System.currentTimeMillis() - lastResetTime > cooldownPeriod)
153159
}
154160
}
155161

156162
var debounceJob by remember { mutableStateOf<Job?>(null) }
157163
val coroutineScope = rememberCoroutineScope()
164+
val resetPasswordErr = stringResource(id = R.string.something_went_wrong)
165+
val resetPasswordEmailSentMsg = stringResource(id = R.string.reset_password_email_sent, userAuth ?: "unknown")
158166

159167
Scaffold(
160168
topBar = {
@@ -273,81 +281,55 @@ fun ProfileScreen(
273281
isPassword = true,
274282
)
275283

276-
Text(
277-
stringResource(id = R.string.change_password),
278-
modifier = Modifier.clickable {
279-
if (resendBtnEnabled && userAuth != null) {
280-
sendResetLink(userAuth)
281-
}
282-
},
283-
style = TextStyle(
284-
color = BlueMedium
284+
if (userAuth != null) {
285+
286+
Text(
287+
stringResource(id = R.string.change_password),
288+
modifier = Modifier
289+
.clickable(enabled = resendBtnEnabled) {
290+
sendResetLink(
291+
userAuth,
292+
{
293+
lastResetTime = System.currentTimeMillis()
294+
Toast.makeText(
295+
context,
296+
resetPasswordEmailSentMsg,
297+
Toast.LENGTH_LONG
298+
).show()
299+
},
300+
{
301+
Toast.makeText(
302+
context,
303+
resetPasswordErr,
304+
Toast.LENGTH_SHORT
305+
).show()
306+
}
307+
)
308+
}
309+
,
310+
style = TextStyle(
311+
color = if (resendBtnEnabled) BlueMedium else TextMuted
312+
)
285313
)
286-
)
287-
}
288-
URSnackBar(
289-
type = if (markPasswordResetAsSent) SnackBarType.SUCCESS else SnackBarType.ERROR,
290-
isVisible = markPasswordResetAsSent || passwordResetError != null,
291-
onDismiss = {
292-
if (passwordResetError != null) {
293-
setPasswordResetError(null)
294-
}
295-
if (markPasswordResetAsSent) {
296-
setMarkPasswordResetAsSent(false)
297-
}
298-
}
299-
) {
300-
if (markPasswordResetAsSent) {
301-
Column() {
302-
Text("Verification email sent to $userAuth")
303-
}
304-
} else {
305-
Column() {
306-
Text(stringResource(id = R.string.something_went_wrong))
307-
Text(stringResource(id = R.string.please_wait))
308-
}
309-
}
310-
}
311314

312-
URSnackBar(
313-
type = if (markPasswordResetAsSent) SnackBarType.SUCCESS else SnackBarType.ERROR,
314-
isVisible = markPasswordResetAsSent || passwordResetError != null,
315-
onDismiss = {
316-
if (passwordResetError != null) {
317-
setPasswordResetError(null)
318-
}
319-
if (markPasswordResetAsSent) {
320-
setMarkPasswordResetAsSent(false)
321-
}
322-
}
323-
) {
324-
if (markPasswordResetAsSent) {
325-
Column() {
326-
Text("Verification email sent to $userAuth")
327-
}
328-
} else {
329-
Column() {
330-
Text(stringResource(id = R.string.something_went_wrong))
331-
Text(stringResource(id = R.string.please_wait))
332-
}
333-
}
334-
}
335-
}
336-
URSnackBar(
337-
type = SnackBarType.ERROR,
338-
isVisible = errorUpdatingProfile,
339-
onDismiss = {
340-
if (errorUpdatingProfile) {
341-
setErrorUpdatingProfile(false)
342315
}
343316
}
344-
) {
345-
346-
Column() {
347-
Text(stringResource(id = R.string.something_went_wrong))
348-
Text(stringResource(id = R.string.please_wait))
349-
}
350317
}
318+
// URSnackBar(
319+
// type = SnackBarType.ERROR,
320+
// isVisible = errorUpdatingProfile,
321+
// onDismiss = {
322+
// if (errorUpdatingProfile) {
323+
// setErrorUpdatingProfile(false)
324+
// }
325+
// }
326+
// ) {
327+
//
328+
// Column() {
329+
// Text(stringResource(id = R.string.something_went_wrong))
330+
// Text(stringResource(id = R.string.please_wait))
331+
// }
332+
// }
351333
}
352334

353335
@Preview
@@ -359,11 +341,7 @@ fun ProfileScreenPreview() {
359341
navController,
360342
loginMode = LoginMode.Authenticated,
361343
isSendingResetPassLink = false,
362-
sendResetLink = {},
363-
passwordResetError = null,
364-
markPasswordResetAsSent = false,
365-
setPasswordResetError = {},
366-
setMarkPasswordResetAsSent = {},
344+
sendResetLink = {_, _, _ ->},
367345
userAuth = "hello@bringyour.com",
368346
networkName = "my_network",
369347
networkNameTextFieldValue = TextFieldValue("my_network"),
@@ -392,11 +370,7 @@ fun ProfileScreenEditingPreview() {
392370
navController,
393371
loginMode = LoginMode.Authenticated,
394372
isSendingResetPassLink = false,
395-
sendResetLink = {},
396-
passwordResetError = null,
397-
markPasswordResetAsSent = false,
398-
setPasswordResetError = {},
399-
setMarkPasswordResetAsSent = {},
373+
sendResetLink = {_, _, _ ->},
400374
userAuth = "hello@bringyour.com",
401375
networkName = "my_network",
402376
networkNameTextFieldValue = TextFieldValue("my_network"),
@@ -425,11 +399,7 @@ fun ProfileScreenErrorUpdatingPreview() {
425399
navController,
426400
loginMode = LoginMode.Authenticated,
427401
isSendingResetPassLink = false,
428-
sendResetLink = {},
429-
passwordResetError = null,
430-
markPasswordResetAsSent = false,
431-
setPasswordResetError = {},
432-
setMarkPasswordResetAsSent = {},
402+
sendResetLink = {_, _, _ ->},
433403
userAuth = "hello@bringyour.com",
434404
networkName = "my_network",
435405
networkNameTextFieldValue = TextFieldValue("my_network"),
Lines changed: 14 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,24 @@
11
package com.bringyour.network.ui.shared.viewmodels
22

3+
import android.util.Log
34
import androidx.compose.runtime.getValue
45
import androidx.compose.runtime.mutableStateOf
56
import androidx.compose.runtime.setValue
67
import androidx.lifecycle.ViewModel
78
import androidx.lifecycle.viewModelScope
89
import com.bringyour.sdk.AuthPasswordResetArgs
910
import com.bringyour.network.DeviceManager
11+
import com.bringyour.network.TAG
1012
import dagger.hilt.android.lifecycle.HiltViewModel
1113
import kotlinx.coroutines.launch
1214
import javax.inject.Inject
1315

16+
typealias ResetPasswordFunction = (
17+
userAuth: String,
18+
onSuccess: () -> Unit,
19+
onError: () -> Unit,
20+
) -> Unit
21+
1422
@HiltViewModel
1523
class ResetPasswordViewModel @Inject constructor(
1624
private val deviceManager: DeviceManager,
@@ -19,38 +27,25 @@ class ResetPasswordViewModel @Inject constructor(
1927
var isSendingResetPassLink by mutableStateOf(false)
2028
private set
2129

22-
var passwordResetError by mutableStateOf<String?>(null)
23-
private set
24-
25-
var markPasswordResetAsSent by mutableStateOf(false)
26-
private set
27-
28-
val sendResetLink: (String) -> Unit = { userAuth ->
30+
val sendResetLink: ResetPasswordFunction = { userAuth, onSuccess, onErr ->
2931

3032
val args = AuthPasswordResetArgs()
3133
args.userAuth = userAuth.trim()
3234

3335
val byDevice = deviceManager.device
3436
byDevice?.api?.authPasswordReset(args) { _, err ->
3537
viewModelScope.launch {
36-
isSendingResetPassLink = false
3738

3839
if (err != null) {
39-
setPasswordResetError(err.message)
40+
Log.i(TAG, "authPasswordReset error: ${err.message}")
41+
onErr()
4042
} else {
41-
setPasswordResetError(null)
42-
markPasswordResetAsSent = true
43+
onSuccess()
4344
}
45+
46+
isSendingResetPassLink = false
4447
}
4548
}
4649
}
4750

48-
val setPasswordResetError: (String?) -> Unit = {
49-
passwordResetError = it
50-
}
51-
52-
val setMarkPasswordResetAsSent: (Boolean) -> Unit = {
53-
markPasswordResetAsSent = it
54-
}
55-
5651
}

app/app/src/main/res/values-ar/strings.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -487,4 +487,5 @@
487487
<string name="step_into_the_internet">" ادخل إلى الإنترنت\n كما يجب أن يكون."</string>
488488
<string name="auth_code_error">حدث خطأ أثناء التحقق من الرمز. يرجى المحاولة مرة أخرى أو إنشاء رمز جديد.</string>
489489
<string name="auth_code_login_button_text">تسجيل الدخول برمز المصادقة</string>
490+
<string name="reset_password_email_sent">تم إرسال بريد إعادة تعيين كلمة المرور إلى %s</string>
490491
</resources>

app/app/src/main/res/values-cs/strings.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -499,4 +499,5 @@
499499
<string name="step_into_the_internet">Vstupte do internetu\njaký by měl být.</string>
500500
<string name="auth_code_error">Chyba při ověřování kódu. Zkuste to prosím znovu nebo vygenerujte nový kód.</string>
501501
<string name="auth_code_login_button_text">Přihlásit se ověřovacím kódem</string>
502+
<string name="reset_password_email_sent">E-mail pro reset hesla byl odeslán na %s</string>
502503
</resources>

app/app/src/main/res/values-de/strings.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,4 +354,5 @@
354354
<string name="step_into_the_internet">Tauche ins Internet ein\nwie es sein sollte.</string>
355355
<string name="auth_code_error">Fehler bei der Code-Authentifizierung. Bitte versuchen Sie es erneut oder generieren Sie einen neuen Code.</string>
356356
<string name="auth_code_login_button_text">Mit Authentifizierungscode anmelden</string>
357+
<string name="reset_password_email_sent">" E-Mail zum Zurücksetzen des Passworts wurde an %s gesendet"</string>
357358
</resources>

app/app/src/main/res/values-el/strings.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,4 +353,5 @@
353353
<string name="step_into_the_internet">Μπείτε στο διαδίκτυο\nόπως θα έπρεπε να είναι.</string>
354354
<string name="auth_code_error">Σφάλμα κατά τον έλεγχο ταυτοποίησης του κωδικού. Δοκιμάστε ξανά ή δημιουργήστε νέο κωδικό.</string>
355355
<string name="auth_code_login_button_text">Σύνδεση με κωδικό ταυτοποίησης</string>
356+
<string name="reset_password_email_sent">Το email επαναφοράς κωδικού στάλθηκε στο %s</string>
356357
</resources>

app/app/src/main/res/values-es-rMX/strings.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,4 +353,5 @@
353353
<string name="step_into_the_internet">Entra a Internet\ncomo debería ser.</string>
354354
<string name="auth_code_error">Error al autenticar el código. Por favor, inténtalo de nuevo o genera un nuevo código.</string>
355355
<string name="auth_code_login_button_text">Iniciar sesión con código de autenticación</string>
356+
<string name="reset_password_email_sent">Correo de restablecimiento de contraseña enviado a %s</string>
356357
</resources>

app/app/src/main/res/values-es/strings.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,4 +353,5 @@
353353
<string name="step_into_the_internet">Entra a Internet\ncomo debería ser.</string>
354354
<string name="auth_code_error">Error al autenticar el código. Por favor, inténtalo de nuevo o genera un nuevo código.</string>
355355
<string name="auth_code_login_button_text">Iniciar sesión con código de autenticación</string>
356+
<string name="reset_password_email_sent">Correo de restablecimiento de contraseña enviado a %s</string>
356357
</resources>

app/app/src/main/res/values-fr/strings.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,4 +355,5 @@
355355
<string name="step_into_the_internet">Entrez dans Internet\ncomme il devrait être.</string>
356356
<string name="auth_code_error">Erreur lors de l’authentification du code. Veuillez réessayer ou générer un nouveau code.</string>
357357
<string name="auth_code_login_button_text">Se connecter avec le code d’authentification</string>
358+
<string name="reset_password_email_sent">E-mail de réinitialisation du mot de passe envoyé à %s</string>
358359
</resources>

app/app/src/main/res/values-hi/strings.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,4 +353,5 @@
353353
<string name="step_into_the_internet">इंटरनेट में कदम रखें\nजैसा कि होना चाहिए।</string>
354354
<string name="auth_code_error">कोड प्रमाणित करने में त्रुटि। कृपया पुनः प्रयास करें या नया कोड जनरेट करें।</string>
355355
<string name="auth_code_login_button_text">ऑथ कोड से लॉगिन करें</string>
356+
<string name="reset_password_email_sent">पासवर्ड रीसेट ईमेल %s पर भेजा गया है</string>
356357
</resources>

0 commit comments

Comments
 (0)