Change transition betweens screen. skip login is unneeded.
This commit is contained in:
parent
4ede938017
commit
e9cb8cd0ac
7 changed files with 72 additions and 35 deletions
|
|
@ -18,4 +18,8 @@ class GoogleSingInRepository(application: Application) : IGoogleSingInRepository
|
||||||
override val client: GoogleSignInClient by lazy {
|
override val client: GoogleSignInClient by lazy {
|
||||||
GoogleSignIn.getClient(application, option)
|
GoogleSignIn.getClient(application, option)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override val lastGoogleToken: String? by lazy {
|
||||||
|
GoogleSignIn.getLastSignedInAccount(application)?.idToken
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -6,4 +6,5 @@ import com.google.android.gms.auth.api.signin.GoogleSignInOptions
|
||||||
interface IGoogleSingInRepository {
|
interface IGoogleSingInRepository {
|
||||||
val option: GoogleSignInOptions
|
val option: GoogleSignInOptions
|
||||||
val client: GoogleSignInClient
|
val client: GoogleSignInClient
|
||||||
|
val lastGoogleToken: String?
|
||||||
}
|
}
|
||||||
|
|
@ -4,10 +4,7 @@ import android.os.Bundle
|
||||||
import androidx.activity.ComponentActivity
|
import androidx.activity.ComponentActivity
|
||||||
import androidx.activity.compose.setContent
|
import androidx.activity.compose.setContent
|
||||||
import androidx.activity.viewModels
|
import androidx.activity.viewModels
|
||||||
import androidx.compose.animation.AnimatedVisibility
|
|
||||||
import androidx.compose.animation.Crossfade
|
import androidx.compose.animation.Crossfade
|
||||||
import androidx.compose.animation.ExperimentalAnimationApi
|
|
||||||
import androidx.compose.animation.slideInHorizontally
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.livedata.observeAsState
|
import androidx.compose.runtime.livedata.observeAsState
|
||||||
|
|
@ -39,7 +36,6 @@ class MainActivity : ComponentActivity() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(ExperimentalAnimationApi::class)
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ContentComposable() {
|
fun ContentComposable() {
|
||||||
val navigationViewModel = viewModel<NavigationViewModel>()
|
val navigationViewModel = viewModel<NavigationViewModel>()
|
||||||
|
|
@ -49,13 +45,7 @@ fun ContentComposable() {
|
||||||
when (it) {
|
when (it) {
|
||||||
is Screen.SplashScreen -> SplashScreenComposable()
|
is Screen.SplashScreen -> SplashScreenComposable()
|
||||||
is Screen.LoginScreen -> LoginScreenComposable()
|
is Screen.LoginScreen -> LoginScreenComposable()
|
||||||
is Screen.MainScreen -> AnimatedVisibility(
|
is Screen.MainScreen -> MainScreenComposable()
|
||||||
visible = true,
|
|
||||||
initiallyVisible = false,
|
|
||||||
enter = slideInHorizontally(initialOffsetX = { width -> width / 2 })
|
|
||||||
) {
|
|
||||||
MainScreenComposable()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,18 @@
|
||||||
package com.pixelized.biblib.ui.composable.screen
|
package com.pixelized.biblib.ui.composable.screen
|
||||||
|
|
||||||
import androidx.compose.animation.*
|
import androidx.compose.animation.*
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.material.*
|
import androidx.compose.material.*
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.sharp.ArrowBack
|
import androidx.compose.material.icons.sharp.ArrowBack
|
||||||
import androidx.compose.material.icons.sharp.LocalLibrary
|
import androidx.compose.material.icons.sharp.LocalLibrary
|
||||||
import androidx.compose.runtime.*
|
import androidx.compose.runtime.*
|
||||||
import androidx.compose.runtime.livedata.observeAsState
|
import androidx.compose.runtime.livedata.observeAsState
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
|
import androidx.compose.ui.unit.IntSize
|
||||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||||
import com.pixelized.biblib.R
|
import com.pixelized.biblib.R
|
||||||
import com.pixelized.biblib.ui.composable.pages.DetailPageComposable
|
import com.pixelized.biblib.ui.composable.pages.DetailPageComposable
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,8 @@ fun SplashScreenComposable(
|
||||||
val duration = 1000
|
val duration = 1000
|
||||||
val typography = MaterialTheme.typography
|
val typography = MaterialTheme.typography
|
||||||
initialisation.LoadApplication {
|
initialisation.LoadApplication {
|
||||||
|
val visible = it !is IInitialisation.State.Finished
|
||||||
|
|
||||||
Box(
|
Box(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxHeight()
|
.fillMaxHeight()
|
||||||
|
|
@ -53,7 +55,7 @@ fun SplashScreenComposable(
|
||||||
.align(Alignment.Center)
|
.align(Alignment.Center)
|
||||||
) {
|
) {
|
||||||
AnimatedVisibility(
|
AnimatedVisibility(
|
||||||
visible = it != IInitialisation.State.Finished,
|
visible = visible,
|
||||||
initiallyVisible = false,
|
initiallyVisible = false,
|
||||||
enter = fadeIn(animationSpec = tween(duration))
|
enter = fadeIn(animationSpec = tween(duration))
|
||||||
+ slideInVertically(
|
+ slideInVertically(
|
||||||
|
|
@ -73,7 +75,7 @@ fun SplashScreenComposable(
|
||||||
}
|
}
|
||||||
AnimatedVisibility(
|
AnimatedVisibility(
|
||||||
modifier = Modifier.align(Alignment.End),
|
modifier = Modifier.align(Alignment.End),
|
||||||
visible = it != IInitialisation.State.Finished,
|
visible = visible,
|
||||||
initiallyVisible = false,
|
initiallyVisible = false,
|
||||||
enter = fadeIn(animationSpec = tween(duration))
|
enter = fadeIn(animationSpec = tween(duration))
|
||||||
+ slideInVertically(
|
+ slideInVertically(
|
||||||
|
|
@ -95,7 +97,7 @@ fun SplashScreenComposable(
|
||||||
|
|
||||||
AnimatedVisibility(
|
AnimatedVisibility(
|
||||||
modifier = Modifier.align(Alignment.BottomEnd),
|
modifier = Modifier.align(Alignment.BottomEnd),
|
||||||
visible = it != IInitialisation.State.Finished,
|
visible = visible,
|
||||||
enter = fadeIn(animationSpec = tween(duration)),
|
enter = fadeIn(animationSpec = tween(duration)),
|
||||||
exit = fadeOut(animationSpec = tween(duration)),
|
exit = fadeOut(animationSpec = tween(duration)),
|
||||||
) {
|
) {
|
||||||
|
|
@ -111,10 +113,14 @@ fun SplashScreenComposable(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (it == IInitialisation.State.Finished) {
|
if (it is IInitialisation.State.Finished) {
|
||||||
LaunchedEffect(key1 = "navigateTo(INavigation.Screen.LoginScreen)") {
|
LaunchedEffect(key1 = "SplashScreen.navigateTo()") {
|
||||||
delay(1000)
|
delay(1000)
|
||||||
navigation.navigateTo(INavigation.Screen.LoginScreen)
|
if (it.needLogin) {
|
||||||
|
navigation.navigateTo(INavigation.Screen.LoginScreen)
|
||||||
|
} else {
|
||||||
|
navigation.navigateTo(INavigation.Screen.MainScreen)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,17 +8,9 @@ interface IInitialisation {
|
||||||
fun LoadApplication(content: @Composable (State) -> Unit)
|
fun LoadApplication(content: @Composable (State) -> Unit)
|
||||||
|
|
||||||
sealed class State {
|
sealed class State {
|
||||||
abstract fun proceed(): State
|
object Initial : State()
|
||||||
|
object Loading : State()
|
||||||
object Initial : State() {
|
class Finished(val needLogin: Boolean) : State()
|
||||||
override fun proceed() = Loading
|
|
||||||
}
|
|
||||||
object Loading : State() {
|
|
||||||
override fun proceed() = Finished
|
|
||||||
}
|
|
||||||
object Finished : State() {
|
|
||||||
override fun proceed() = Finished
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class Mock(private val state: State = State.Loading) : IInitialisation {
|
class Mock(private val state: State = State.Loading) : IInitialisation {
|
||||||
|
|
|
||||||
|
|
@ -3,13 +3,16 @@ package com.pixelized.biblib.ui.viewmodel.initialisation
|
||||||
import androidx.compose.runtime.*
|
import androidx.compose.runtime.*
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import com.pixelized.biblib.network.client.IBibLibClient
|
import com.pixelized.biblib.network.client.IBibLibClient
|
||||||
|
import com.pixelized.biblib.network.data.query.AuthLoginQuery
|
||||||
import com.pixelized.biblib.repository.credential.ICredentialRepository
|
import com.pixelized.biblib.repository.credential.ICredentialRepository
|
||||||
|
import com.pixelized.biblib.repository.googlesignin.IGoogleSingInRepository
|
||||||
import com.pixelized.biblib.ui.viewmodel.initialisation.IInitialisation.State.*
|
import com.pixelized.biblib.ui.viewmodel.initialisation.IInitialisation.State.*
|
||||||
import com.pixelized.biblib.utils.injection.inject
|
import com.pixelized.biblib.utils.injection.inject
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
|
|
||||||
class InitialisationViewModel : ViewModel(), IInitialisation {
|
class InitialisationViewModel : ViewModel(), IInitialisation {
|
||||||
private val credentialRepository: ICredentialRepository by inject()
|
private val credentialRepository: ICredentialRepository by inject()
|
||||||
|
private val googleSignIn: IGoogleSingInRepository by inject()
|
||||||
private val client: IBibLibClient by inject()
|
private val client: IBibLibClient by inject()
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
|
|
@ -20,15 +23,52 @@ class InitialisationViewModel : ViewModel(), IInitialisation {
|
||||||
state.value = Loading
|
state.value = Loading
|
||||||
delay(2000)
|
delay(2000)
|
||||||
|
|
||||||
val bearerToken = credentialRepository.bearer
|
val loggedIn = loginWithGoogle() || loginWithCredential()
|
||||||
if (bearerToken != null) {
|
state.value = Finished(needLogin = loggedIn.not())
|
||||||
client.updateBearerToken(bearerToken)
|
|
||||||
state.value = Finished
|
|
||||||
} else {
|
|
||||||
state.value = Finished
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
content(state.value)
|
content(state.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private suspend fun loginWithGoogle(): Boolean {
|
||||||
|
val googleToken = googleSignIn.lastGoogleToken
|
||||||
|
return if (googleToken != null) {
|
||||||
|
try {
|
||||||
|
client.service.loginWithGoogle(googleToken).let { response ->
|
||||||
|
if (response.token != null) {
|
||||||
|
client.updateBearerToken(response.token)
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private suspend fun loginWithCredential(): Boolean {
|
||||||
|
val login = credentialRepository.login
|
||||||
|
val password = credentialRepository.password
|
||||||
|
return if (login != null && password != null) {
|
||||||
|
try {
|
||||||
|
val query = AuthLoginQuery(login, password)
|
||||||
|
client.service.login(query).let { response ->
|
||||||
|
if (response.token != null) {
|
||||||
|
client.updateBearerToken(response.token)
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue