use local state to track email/authProvider signin

This commit is contained in:
Satindar Dhillon
2022-08-23 11:50:20 -07:00
parent 9e14b49c07
commit 9fb4ae35cf
9 changed files with 118 additions and 111 deletions

View File

@ -10,7 +10,7 @@ import androidx.core.view.ViewCompat
import androidx.core.view.WindowCompat
import androidx.core.view.WindowInsetsCompat
import app.omnivore.omnivore.ui.auth.LoginViewModel
import app.omnivore.omnivore.ui.main.ScreenMain
import app.omnivore.omnivore.ui.root.RootView
import dagger.hilt.android.AndroidEntryPoint
@AndroidEntryPoint
@ -22,7 +22,7 @@ class MainActivity : ComponentActivity() {
setContent {
OmnivoreTheme {
ScreenMain(viewModel = viewModel)
RootView(viewModel = viewModel)
}
}

View File

@ -4,5 +4,4 @@ sealed class Routes(val route: String) {
object Root : Routes("Root")
object Home : Routes("Home")
object Welcome : Routes("Welcome")
object EmailLogin : Routes("EmailLogin")
}

View File

@ -5,6 +5,7 @@ import android.widget.Toast
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.text.ClickableText
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material3.*
@ -14,29 +15,30 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.PasswordVisualTransformation
import androidx.compose.ui.unit.dp
import androidx.navigation.NavHostController
import kotlinx.coroutines.launch
@Composable
fun EmailLoginViewContainer(viewModel: LoginViewModel, navController: NavHostController) {
Column(
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier
.background(MaterialTheme.colorScheme.background)
.fillMaxSize()
.navigationBarsPadding()
) {
EmailLoginView(viewModel)
}
}
//@Composable
//fun EmailLoginViewContainer(viewModel: LoginViewModel, navController: NavHostController) {
// Column(
// verticalArrangement = Arrangement.Center,
// horizontalAlignment = Alignment.CenterHorizontally,
// modifier = Modifier
// .background(MaterialTheme.colorScheme.background)
// .fillMaxSize()
// .navigationBarsPadding()
// ) {
// EmailLoginView(viewModel)
// }
//}
@SuppressLint("CoroutineCreationDuringComposition")
@Composable
fun EmailLoginView(viewModel: LoginViewModel) {
fun EmailLoginView(viewModel: LoginViewModel, onAuthProviderButtonTap: () -> Unit) {
var email by rememberSaveable { mutableStateOf("") }
var password by rememberSaveable { mutableStateOf("") }
val focusManager = LocalFocusManager.current
@ -79,6 +81,11 @@ fun EmailLoginView(viewModel: LoginViewModel) {
SnackbarHost(hostState = snackBarHostState)
}
ClickableText(
text = AnnotatedString("Continue with Google/Apple ->"),
onClick = { onAuthProviderButtonTap() }
)
}
}

View File

@ -15,6 +15,11 @@ import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.launch
import javax.inject.Inject
enum class RegistrationState {
AuthProviderButtons,
EmailSignIn
}
@HiltViewModel
class LoginViewModel @Inject constructor(
private val datastoreRepo: DatastoreRepository

View File

@ -8,8 +8,8 @@ import androidx.compose.foundation.layout.*
import androidx.compose.foundation.text.ClickableText
import androidx.compose.material.ExperimentalMaterialApi
import androidx.compose.material3.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.runtime.*
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
@ -24,21 +24,22 @@ import app.omnivore.omnivore.Routes
import com.google.android.gms.common.GoogleApiAvailability
@Composable
fun WelcomeScreen(viewModel: LoginViewModel, navController: NavHostController) {
fun WelcomeScreen(viewModel: LoginViewModel) {
// val systemUiController = rememberSystemUiController()
// systemUiController.isSystemBarsVisible = false
Surface(modifier = Modifier.fillMaxSize(), color = Color(0xFFFBEAA8 )) {
WelcomeScreenContent(viewModel = viewModel, navController = navController)
WelcomeScreenContent(viewModel = viewModel)
}
}
@OptIn(ExperimentalMaterialApi::class)
@Composable
fun WelcomeScreenContent(viewModel: LoginViewModel, navController: NavHostController) {
val isGoogleAuthAvailable: Boolean = GoogleApiAvailability
.getInstance()
.isGooglePlayServicesAvailable(LocalContext.current) == 0
fun WelcomeScreenContent(viewModel: LoginViewModel) {
var registrationState by rememberSaveable { mutableStateOf(RegistrationState.AuthProviderButtons) }
val onRegistrationStateChange = { state: RegistrationState ->
registrationState = state
}
Column(
verticalArrangement = Arrangement.SpaceAround,
@ -55,43 +56,74 @@ fun WelcomeScreenContent(viewModel: LoginViewModel, navController: NavHostContro
contentDescription = "Omnivore Icon with Name"
)
Spacer(modifier = Modifier.height(50.dp))
Text(
text = stringResource(id = R.string.welcome_title),
style = MaterialTheme.typography.headlineLarge
)
MoreInfoButton()
Spacer(modifier = Modifier.height(50.dp))
Row(
horizontalArrangement = Arrangement.Center
) {
Spacer(modifier = Modifier.weight(1.0F))
Column(
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
if (isGoogleAuthAvailable) {
GoogleAuthButton(viewModel)
}
LoadingButtonWithIcon(
text = "Continue with Apple",
loadingText = "Signing in...",
icon = painterResource(id = R.drawable.ic_logo_apple),
modifier = Modifier.padding(vertical = 6.dp),
onClick = {}
when(registrationState) {
RegistrationState.EmailSignIn -> {
EmailLoginView(
viewModel = viewModel,
onAuthProviderButtonTap = {
onRegistrationStateChange(RegistrationState.AuthProviderButtons)
}
)
}
RegistrationState.AuthProviderButtons -> {
AuthProviderView(
viewModel = viewModel,
onEmailButtonTap = { onRegistrationStateChange(RegistrationState.EmailSignIn) }
)
ContinueWithEmailButton(navController)
}
Spacer(modifier = Modifier.weight(1.0F))
}
Spacer(modifier = Modifier.weight(1.0F))
}
}
@Composable
fun AuthProviderView(
viewModel: LoginViewModel,
onEmailButtonTap: () -> Unit
) {
val isGoogleAuthAvailable: Boolean = GoogleApiAvailability
.getInstance()
.isGooglePlayServicesAvailable(LocalContext.current) == 0
Text(
text = stringResource(id = R.string.welcome_title),
style = MaterialTheme.typography.headlineLarge
)
MoreInfoButton()
Spacer(modifier = Modifier.height(50.dp))
Row(
horizontalArrangement = Arrangement.Center
) {
Spacer(modifier = Modifier.weight(1.0F))
Column(
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
if (isGoogleAuthAvailable) {
GoogleAuthButton(viewModel)
}
LoadingButtonWithIcon(
text = "Continue with Apple",
loadingText = "Signing in...",
icon = painterResource(id = R.drawable.ic_logo_apple),
modifier = Modifier.padding(vertical = 6.dp),
onClick = {}
)
ClickableText(
text = AnnotatedString("Continue with Email ->"),
onClick = { onEmailButtonTap() }
)
}
Spacer(modifier = Modifier.weight(1.0F))
}
}
@Composable
fun MoreInfoButton() {
val context = LocalContext.current
@ -107,12 +139,3 @@ fun MoreInfoButton() {
)
}
@Composable
fun ContinueWithEmailButton(navController: NavHostController) {
ClickableText(
text = AnnotatedString("Continue with Email ->"),
onClick = {
navController.navigate(Routes.EmailLogin.route)
}
)
}

View File

@ -14,7 +14,7 @@ import androidx.navigation.NavHostController
import app.omnivore.omnivore.ui.auth.LoginViewModel
@Composable
fun HomeView(viewModel: LoginViewModel, navController: NavHostController) {
fun HomeView(viewModel: LoginViewModel) {
Column(
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally,

View File

@ -1,45 +0,0 @@
package app.omnivore.omnivore.ui.main
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState
import androidx.navigation.NavHostController
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import app.omnivore.omnivore.Routes
import app.omnivore.omnivore.ui.auth.EmailLoginViewContainer
import app.omnivore.omnivore.ui.auth.LoginViewModel
import app.omnivore.omnivore.ui.auth.WelcomeScreen
import app.omnivore.omnivore.ui.home.HomeView
@Composable
fun ScreenMain(viewModel: LoginViewModel) {
val navController = rememberNavController()
NavHost(navController = navController, startDestination = Routes.Root.route) {
composable(Routes.Root.route) {
RootView(viewModel = viewModel, navController = navController)
}
composable(Routes.Welcome.route) {
WelcomeScreen(viewModel = viewModel, navController = navController)
}
composable(Routes.Home.route) {
HomeView(viewModel = viewModel, navController = navController)
}
composable(Routes.EmailLogin.route) {
EmailLoginViewContainer(viewModel = viewModel, navController = navController)
}
}
}
@Composable
fun RootView(viewModel: LoginViewModel, navController: NavHostController) {
val hasAuthToken: Boolean by viewModel.hasAuthTokenLiveData.observeAsState(false)
if (hasAuthToken) {
HomeView(viewModel = viewModel, navController = navController)
} else {
WelcomeScreen(viewModel = viewModel, navController = navController)
}
}

View File

@ -0,0 +1,19 @@
package app.omnivore.omnivore.ui.root
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState
import app.omnivore.omnivore.ui.auth.LoginViewModel
import app.omnivore.omnivore.ui.auth.WelcomeScreen
import app.omnivore.omnivore.ui.home.HomeView
@Composable
fun RootView(viewModel: LoginViewModel) {
val hasAuthToken: Boolean by viewModel.hasAuthTokenLiveData.observeAsState(false)
if (hasAuthToken) {
HomeView(viewModel = viewModel)
} else {
WelcomeScreen(viewModel = viewModel)
}
}

View File

@ -1,8 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="Theme.Omnivore" parent="android:Theme.Material.Light">
<style name="Theme.Omnivore" parent="android:Theme.Material.Light.NoActionBar">
</style>
<style name="Theme.AppCompat.Translucent" parent="Theme.AppCompat.NoActionBar">