From a33c21a02e01fae2ea39d7ac48b60136bd7307d3 Mon Sep 17 00:00:00 2001 From: Thomas Andres Gomez Date: Sat, 8 May 2021 22:17:50 +0200 Subject: [PATCH] Add success dialog on authentication success. --- .idea/misc.xml | 10 +++ .../items/dialog/CrossFadeOverlay.kt | 2 +- .../ui/composable/items/dialog/SuccesCard.kt | 73 +++++++++++++++++++ .../screen/LoginScreenComposable.kt | 45 ++++++------ app/src/main/res/values/strings.xml | 1 + 5 files changed, 106 insertions(+), 25 deletions(-) create mode 100644 app/src/main/java/com/pixelized/biblib/ui/composable/items/dialog/SuccesCard.kt diff --git a/.idea/misc.xml b/.idea/misc.xml index c49fbeb..bb4ff27 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -123,6 +123,16 @@ + + + + + + + + + + diff --git a/app/src/main/java/com/pixelized/biblib/ui/composable/items/dialog/CrossFadeOverlay.kt b/app/src/main/java/com/pixelized/biblib/ui/composable/items/dialog/CrossFadeOverlay.kt index 33829b5..914a2b1 100644 --- a/app/src/main/java/com/pixelized/biblib/ui/composable/items/dialog/CrossFadeOverlay.kt +++ b/app/src/main/java/com/pixelized/biblib/ui/composable/items/dialog/CrossFadeOverlay.kt @@ -18,7 +18,7 @@ fun CrossFadeOverlay( visible: Boolean, content: @Composable BoxScope.() -> Unit ) { - Crossfade(targetState = visible, animationSpec = tween(500)) { + Crossfade(targetState = visible) { if (it) { Box( modifier = modifier diff --git a/app/src/main/java/com/pixelized/biblib/ui/composable/items/dialog/SuccesCard.kt b/app/src/main/java/com/pixelized/biblib/ui/composable/items/dialog/SuccesCard.kt new file mode 100644 index 0000000..e074f41 --- /dev/null +++ b/app/src/main/java/com/pixelized/biblib/ui/composable/items/dialog/SuccesCard.kt @@ -0,0 +1,73 @@ +package com.pixelized.biblib.ui.composable.items.dialog + +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.material.Card +import androidx.compose.material.Icon +import androidx.compose.material.MaterialTheme +import androidx.compose.material.Text +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.sharp.Done +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.pixelized.biblib.R +import com.pixelized.biblib.ui.theme.BibLibTheme + + +@Composable +fun SuccessCard( + modifier: Modifier = Modifier, + message: String? = null, +) { + Card(elevation = 8.dp, modifier = modifier) { + Column( + modifier = Modifier + .width(250.dp) + .padding(32.dp) + ) { + Icon( + modifier = Modifier + .width(64.dp) + .height(64.dp) + .align(Alignment.CenterHorizontally), + tint = MaterialTheme.colors.primary, + imageVector = Icons.Sharp.Done, + contentDescription = "error" + ) + val typography = MaterialTheme.typography + if (message != null) { + Text( + modifier = Modifier + .align(Alignment.CenterHorizontally) + .padding(top = 16.dp), + style = typography.body1, + textAlign = TextAlign.Center, + text = message + ) + } + } + } +} + +@Preview +@Composable +private fun SuccessLightPreview() { + BibLibTheme(darkTheme = false) { + SuccessCard(message = stringResource(id = R.string.authentication_success)) + } +} + +@Preview +@Composable +private fun SuccessDarkPreview() { + BibLibTheme(darkTheme = true) { + SuccessCard(message = stringResource(id = R.string.authentication_success)) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/pixelized/biblib/ui/composable/screen/LoginScreenComposable.kt b/app/src/main/java/com/pixelized/biblib/ui/composable/screen/LoginScreenComposable.kt index 141488e..edfbf66 100644 --- a/app/src/main/java/com/pixelized/biblib/ui/composable/screen/LoginScreenComposable.kt +++ b/app/src/main/java/com/pixelized/biblib/ui/composable/screen/LoginScreenComposable.kt @@ -37,12 +37,15 @@ import com.pixelized.biblib.R import com.pixelized.biblib.ui.composable.items.dialog.CrossFadeOverlay import com.pixelized.biblib.ui.composable.items.dialog.ErrorCard import com.pixelized.biblib.ui.composable.items.dialog.LoadingCard +import com.pixelized.biblib.ui.composable.items.dialog.SuccessCard import com.pixelized.biblib.ui.theme.BibLibTheme import com.pixelized.biblib.ui.viewmodel.authentication.AuthenticationViewModel import com.pixelized.biblib.ui.viewmodel.authentication.IAuthentication import com.pixelized.biblib.ui.viewmodel.navigation.INavigation import com.pixelized.biblib.ui.viewmodel.navigation.NavigationViewModel import com.pixelized.biblib.utils.exception.NoBearerException +import kotlinx.coroutines.delay +import kotlinx.coroutines.launch @Composable @@ -166,6 +169,7 @@ private fun LoginScreenDialogComposable( AnimatedVisibility( modifier = Modifier.align(Alignment.Center), visible = state.value is IAuthentication.State.Error, + initiallyVisible = false, enter = expandVertically(Alignment.CenterVertically), exit = shrinkVertically(Alignment.CenterVertically), ) { @@ -176,7 +180,8 @@ private fun LoginScreenDialogComposable( } AnimatedVisibility( modifier = Modifier.align(Alignment.Center), - visible = state.value is IAuthentication.State.Loading || state.value is IAuthentication.State.Connect, + visible = state.value is IAuthentication.State.Loading, + initiallyVisible = false, enter = expandVertically(Alignment.CenterVertically), exit = shrinkVertically(Alignment.CenterVertically), ) { @@ -184,6 +189,17 @@ private fun LoginScreenDialogComposable( message = stringResource(id = R.string.loading) ) } + AnimatedVisibility( + modifier = Modifier.align(Alignment.Center), + visible = state.value is IAuthentication.State.Connect, + initiallyVisible = false, + enter = expandVertically(Alignment.CenterVertically), + exit = shrinkVertically(Alignment.CenterVertically), + ) { + SuccessCard( + message = stringResource(id = R.string.authentication_success) + ) + } } } @@ -194,7 +210,10 @@ private fun LoginScreenNavigationComposable( ) { val state = authentication.state.observeAsState() if (state.value == IAuthentication.State.Connect) { - navigation.navigateTo(INavigation.Screen.MainScreen) + LaunchedEffect(key1 = "navigateTo(MainScreen)") { + delay(1000) + navigation.navigateTo(INavigation.Screen.MainScreen) + } } } @@ -283,26 +302,4 @@ fun LoginScreenComposablePreview() { val authenticationViewModel = IAuthentication.Mock() LoginScreenComposable(navigationViewModel, authenticationViewModel) } -} - -@Preview(name = "Loading") -@Composable -fun LoginScreenComposableWaitingPreview() { - BibLibTheme { - val navigationViewModel = INavigation.Mock() - val state = IAuthentication.State.Loading - val authenticationViewModel = IAuthentication.Mock(state) - LoginScreenComposable(navigationViewModel, authenticationViewModel) - } -} - -@Preview(name = "Error") -@Composable -fun LoginScreenComposableErrorPreview() { - BibLibTheme { - val navigationViewModel = INavigation.Mock() - val state = IAuthentication.State.Error(NoBearerException()) - val authenticationViewModel = IAuthentication.Mock(state) - LoginScreenComposable(navigationViewModel, authenticationViewModel) - } } \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index c92c441..5297498 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -14,6 +14,7 @@ Login Password Remember my credential + Authentication successful Rating Language