Fix dumb mistake with google sign in.

This commit is contained in:
Thomas Andres Gomez 2021-05-14 12:06:24 +02:00
parent 1e58752008
commit 4b5893cf43
7 changed files with 67 additions and 43 deletions

View file

@ -102,6 +102,8 @@ dependencies {
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
implementation 'com.google.code.gson:gson:2.8.6'
//Logging Network Calls
implementation 'com.squareup.okhttp3:logging-interceptor:4.8.1'
// Room
implementation "androidx.room:room-runtime:2.3.0"

View file

@ -1,26 +1,38 @@
package com.pixelized.biblib.network.client
import com.google.gson.Gson
import com.pixelized.biblib.utils.injection.inject
import com.pixelized.biblib.network.client.IBibLibClient.Companion.BASE_URL
import com.pixelized.biblib.utils.injection.inject
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
class BibLibClient : IBibLibClient {
private val gson by inject<Gson>()
private val interceptor = BearerInterceptor()
private val bearerInterceptor = BearerInterceptor()
private val httpInterceptor = HttpLoggingInterceptor().apply {
this.level = HttpLoggingInterceptor.Level.BODY
}
private val retrofit: Retrofit = Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create(gson))
.client(OkHttpClient.Builder().addInterceptor(interceptor).build())
.client(
OkHttpClient.Builder()
.addInterceptor(bearerInterceptor)
.addInterceptor(httpInterceptor)
.build()
)
.baseUrl(BASE_URL)
.build()
override val service: IBibLibWebServiceAPI = retrofit.create(IBibLibWebServiceAPI::class.java)
override var token: String?
get() = interceptor.token
set(value) { interceptor.token = value }
get() = bearerInterceptor.token
set(value) {
bearerInterceptor.token = value
}
// endregion
}

View file

@ -21,7 +21,6 @@ class BookRepository : IBookRepository {
database.bookDao().getBook().map { it.toBook() }
override suspend fun update(data: List<Book>) {
Log.d("pouet", "BookRepository#update(): $data")
val authors = mutableSetOf<AuthorDbo>()
val genres = mutableSetOf<GenreDbo>()
val series = mutableSetOf<SeriesDbo>()

View file

@ -3,6 +3,7 @@ package com.pixelized.biblib.ui.composable.screen
import android.content.Intent
import android.net.Uri
import android.util.Log
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.animation.expandVertically
@ -51,6 +52,7 @@ import com.pixelized.biblib.ui.viewmodel.credential.CredentialViewModel
import com.pixelized.biblib.ui.viewmodel.credential.ICredentialViewModel
import com.pixelized.biblib.ui.viewmodel.navigation.INavigationViewModel
import com.pixelized.biblib.ui.viewmodel.navigation.NavigationViewModel
import kotlinx.coroutines.delay
private const val LE_LOAD_BOOK = "LE_LOAD_BOOK"
@ -62,6 +64,10 @@ fun LoginScreenComposable(
authenticationViewModel: IAuthenticationViewModel = viewModel<AuthenticationViewModel>(),
bookViewModel: IBooksViewModel = viewModel<BooksViewModel>()
) {
LaunchedEffect("merde") {
authenticationViewModel.clearState()
}
Box(
modifier = Modifier
.fillMaxWidth()
@ -105,11 +111,11 @@ private fun LoginScreenDialogComposable(
authenticationViewModel: IAuthenticationViewModel,
booksViewModel: IBooksViewModel,
) {
val authState = authenticationViewModel.state.observeAsState()
val bookState = booksViewModel.state.observeAsState()
val authState by authenticationViewModel.state.observeAsState()
val bookState by booksViewModel.state.observeAsState()
val visible = authState.value is IAuthenticationViewModel.State.Error
|| bookState.value is IBooksViewModel.State.Error
val visible = authState !is IAuthenticationViewModel.State.Initial
|| bookState !is IBooksViewModel.State.Initial
CrossFadeOverlay(
modifier = Modifier.clickable {
@ -121,19 +127,19 @@ private fun LoginScreenDialogComposable(
) {
AnimatedVisibility(
modifier = Modifier.align(Alignment.Center),
visible = authState.value is IAuthenticationViewModel.State.Error,
visible = authState is IAuthenticationViewModel.State.Error,
initiallyVisible = false,
enter = expandVertically(Alignment.CenterVertically),
exit = shrinkVertically(Alignment.CenterVertically),
) {
ErrorCard(
message = stringResource(id = R.string.error_authentication),
exception = (authState.value as? IAuthenticationViewModel.State.Error)?.exception
exception = (authState as? IAuthenticationViewModel.State.Error)?.exception
)
}
AnimatedVisibility(
modifier = Modifier.align(Alignment.Center),
visible = authState.value is IAuthenticationViewModel.State.Loading,
visible = authState is IAuthenticationViewModel.State.Loading,
initiallyVisible = false,
enter = expandVertically(Alignment.CenterVertically),
exit = shrinkVertically(Alignment.CenterVertically),
@ -144,7 +150,7 @@ private fun LoginScreenDialogComposable(
}
AnimatedVisibility(
modifier = Modifier.align(Alignment.Center),
visible = (authState.value as? IAuthenticationViewModel.State.Finished)?.logged
visible = (authState as? IAuthenticationViewModel.State.Finished)?.logged
?: false,
initiallyVisible = false,
enter = expandVertically(Alignment.CenterVertically),
@ -156,19 +162,19 @@ private fun LoginScreenDialogComposable(
}
AnimatedVisibility(
modifier = Modifier.align(Alignment.Center),
visible = bookState.value is IBooksViewModel.State.Error,
visible = bookState is IBooksViewModel.State.Error,
initiallyVisible = false,
enter = expandVertically(Alignment.CenterVertically),
exit = shrinkVertically(Alignment.CenterVertically),
) {
ErrorCard(
message = stringResource(id = R.string.error_book),
exception = (bookState.value as? IBooksViewModel.State.Error)?.exception
exception = (bookState as? IBooksViewModel.State.Error)?.exception
)
}
AnimatedVisibility(
modifier = Modifier.align(Alignment.Center),
visible = bookState.value is IBooksViewModel.State.Loading,
visible = bookState is IBooksViewModel.State.Loading,
initiallyVisible = false,
enter = expandVertically(Alignment.CenterVertically),
exit = shrinkVertically(Alignment.CenterVertically),
@ -179,7 +185,7 @@ private fun LoginScreenDialogComposable(
}
AnimatedVisibility(
modifier = Modifier.align(Alignment.Center),
visible = bookState.value is IBooksViewModel.State.Finished,
visible = bookState is IBooksViewModel.State.Finished,
initiallyVisible = false,
enter = expandVertically(Alignment.CenterVertically),
exit = shrinkVertically(Alignment.CenterVertically),
@ -197,18 +203,20 @@ private fun LoginScreenNavigationComposable(
authenticationViewModel: IAuthenticationViewModel,
bookViewModel: IBooksViewModel,
) {
val authenticationState = authenticationViewModel.state.observeAsState()
(authenticationState.value as? IAuthenticationViewModel.State.Finished)?.let {
val authenticationState by authenticationViewModel.state.observeAsState()
(authenticationState as? IAuthenticationViewModel.State.Finished)?.let {
if (it.logged) {
LaunchedEffect(LE_LOAD_BOOK) {
delay(1000)
bookViewModel.updateBooks()
}
val bookLoadingState = bookViewModel.state.observeAsState()
if (bookLoadingState.value is IBooksViewModel.State.Finished) {
navigationViewModel.navigateTo(INavigationViewModel.Screen.MainScreen)
}
}
}
val bookLoadingState by bookViewModel.state.observeAsState()
if (bookLoadingState is IBooksViewModel.State.Finished) {
navigationViewModel.navigateTo(INavigationViewModel.Screen.MainScreen)
}
}
@Composable
@ -379,15 +387,11 @@ private fun CredentialRemember(
@Composable
fun LoginScreenComposablePreview() {
BibLibTheme {
val navigationViewModel = INavigationViewModel.Mock()
val credentialViewModel = ICredentialViewModel.Mock()
val authenticationViewModel = IAuthenticationViewModel.Mock()
val bookViewModel = IBooksViewModel.Mock()
LoginScreenComposable(
navigationViewModel,
credentialViewModel,
authenticationViewModel,
bookViewModel,
navigationViewModel = INavigationViewModel.Mock(),
credentialViewModel = ICredentialViewModel.Mock(),
authenticationViewModel = IAuthenticationViewModel.Mock(),
bookViewModel = IBooksViewModel.Mock(),
)
}
}

View file

@ -11,13 +11,13 @@ import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.google.android.gms.auth.api.signin.GoogleSignIn
import com.google.android.gms.auth.api.signin.GoogleSignInAccount
import com.google.android.gms.common.api.ApiException
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.googleSignIn.IGoogleSingInRepository
import com.pixelized.biblib.ui.viewmodel.authentication.IAuthenticationViewModel.State
import com.pixelized.biblib.utils.exception.MissingGoogleTokenException
import com.pixelized.biblib.utils.exception.MissingTokenException
import com.pixelized.biblib.utils.injection.inject
import kotlinx.coroutines.Dispatchers
@ -77,15 +77,19 @@ class AuthenticationViewModel : ViewModel(), IAuthenticationViewModel {
launcher = rememberLauncherForActivityResult(
ActivityResultContracts.StartActivityForResult()
) {
try {
val task = GoogleSignIn.getSignedInAccountFromIntent(it.data)
val account: GoogleSignInAccount? = task.getResult(ApiException::class.java)
val idToken = account?.idToken ?: throw MissingTokenException()
client.token = idToken
_state.postValue(State.Finished(true))
} catch (exception: Exception) {
Log.e("AuthenticationViewModel", exception.message, exception)
_state.postValue(State.Error(exception))
viewModelScope.launch(Dispatchers.IO) {
try {
val task = GoogleSignIn.getSignedInAccountFromIntent(it.data)
val account = task.getResult(ApiException::class.java)
val googleToken = account?.idToken ?: throw MissingGoogleTokenException()
val response = client.service.loginWithGoogle(googleToken)
val token = response.token ?: throw MissingTokenException()
client.token = token
_state.postValue(State.Finished(true))
} catch (exception: Exception) {
Log.e("AuthenticationViewModel", exception.message, exception)
_state.postValue(State.Error(exception))
}
}
}
}

View file

@ -24,7 +24,7 @@ class BooksViewModel : ViewModel(), IBooksViewModel {
private val client: IBibLibClient by inject()
private val apiCache: IAPICacheRepository by inject()
private val _state = MutableLiveData<IBooksViewModel.State>()
private val _state = MutableLiveData<IBooksViewModel.State>(IBooksViewModel.State.Initial)
override val state: LiveData<IBooksViewModel.State> get() = _state
private val source

View file

@ -0,0 +1,3 @@
package com.pixelized.biblib.utils.exception
class MissingGoogleTokenException: RuntimeException("Google login response miss token data.")