11package com.bringyour.network.ui.profile
22
3+ import android.widget.Toast
34import androidx.compose.foundation.clickable
45import androidx.compose.foundation.layout.Arrangement
56import androidx.compose.foundation.layout.Column
@@ -9,7 +10,6 @@ import androidx.compose.foundation.layout.fillMaxWidth
910import androidx.compose.foundation.layout.height
1011import androidx.compose.foundation.layout.imePadding
1112import androidx.compose.foundation.layout.padding
12- import androidx.compose.foundation.layout.width
1313import androidx.compose.foundation.text.KeyboardOptions
1414import androidx.compose.material.icons.Icons
1515import androidx.compose.material.icons.automirrored.filled.KeyboardArrowLeft
@@ -33,6 +33,7 @@ import androidx.compose.runtime.rememberCoroutineScope
3333import androidx.compose.runtime.setValue
3434import androidx.compose.ui.Alignment
3535import androidx.compose.ui.Modifier
36+ import androidx.compose.ui.platform.LocalContext
3637import androidx.compose.ui.res.stringResource
3738import androidx.compose.ui.text.TextStyle
3839import androidx.compose.ui.text.input.ImeAction
@@ -47,14 +48,14 @@ import com.bringyour.network.R
4748import com.bringyour.network.ui.account.AccountViewModel
4849import com.bringyour.network.ui.components.AccountSwitcher
4950import com.bringyour.network.ui.components.LoginMode
50- import com.bringyour.network.ui.components.SnackBarType
51- import com.bringyour.network.ui.components.URSnackBar
5251import com.bringyour.network.ui.components.URTextInput
5352import com.bringyour.network.ui.components.overlays.OverlayMode
5453import com.bringyour.network.ui.shared.viewmodels.OverlayViewModel
54+ import com.bringyour.network.ui.shared.viewmodels.ResetPasswordFunction
5555import com.bringyour.network.ui.shared.viewmodels.ResetPasswordViewModel
5656import com.bringyour.network.ui.theme.Black
5757import com.bringyour.network.ui.theme.BlueMedium
58+ import com.bringyour.network.ui.theme.TextMuted
5859import com.bringyour.network.ui.theme.TopBarTitleTextStyle
5960import com.bringyour.network.ui.theme.URNetworkTheme
6061import 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" ),
0 commit comments