Add success dialog on authentication success.

This commit is contained in:
Thomas Andres Gomez 2021-05-08 22:17:50 +02:00
parent 9591b4239c
commit a33c21a02e
5 changed files with 106 additions and 25 deletions

View file

@ -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

View file

@ -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))
}
}

View file

@ -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)
}
}

View file

@ -14,6 +14,7 @@
<string name="authentication_login">Login</string>
<string name="authentication_password">Password</string>
<string name="authentication_credential_remember">Remember my credential</string>
<string name="authentication_success">Authentication successful</string>
<string name="detail_rating">Rating</string>
<string name="detail_language">Language</string>