Finaly fix the book loading issue. (I Hope)

This commit is contained in:
Thomas Andres Gomez 2022-07-06 09:31:11 +02:00
parent c7603ca71e
commit 3cf90ee701
9 changed files with 66 additions and 18 deletions

View file

@ -43,6 +43,7 @@ android {
buildTypes { buildTypes {
debug { debug {
applicationIdSuffix ".debug"
signingConfig signingConfigs.pixelized signingConfig signingConfigs.pixelized
minifyEnabled false minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'

View file

@ -7,6 +7,10 @@ import com.pixelized.biblib.database.relation.BookRelation
@Dao @Dao
interface BookDao { interface BookDao {
@Query("SELECT COUNT(${BookDbo.ID}) FROM ${BookDbo.TABLE}")
fun count(): Int
@Transaction @Transaction
@Query("SELECT * FROM ${BookDbo.TABLE}") @Query("SELECT * FROM ${BookDbo.TABLE}")
fun getAll(): List<BookRelation> fun getAll(): List<BookRelation>

View file

@ -17,6 +17,9 @@ class BookRepository @Inject constructor(
override fun getAll(): List<Book> = override fun getAll(): List<Book> =
database.bookDao().getAll().map { it.toBook() } database.bookDao().getAll().map { it.toBook() }
override fun getBookCount(): Int =
database.bookDao().count()
override fun getNewsSource(): DataSource.Factory<Int, Book> = override fun getNewsSource(): DataSource.Factory<Int, Book> =
database.bookDao().getNews().map { it.toBook() } database.bookDao().getNews().map { it.toBook() }

View file

@ -1,23 +1,41 @@
package com.pixelized.biblib.repository.book package com.pixelized.biblib.repository.book
import android.util.Log
import com.pixelized.biblib.network.client.IBibLibClient import com.pixelized.biblib.network.client.IBibLibClient
import com.pixelized.biblib.network.data.response.BookListResponse
import com.pixelized.biblib.network.factory.BookFactory import com.pixelized.biblib.network.factory.BookFactory
import com.pixelized.biblib.repository.apiCache.IAPICacheRepository import com.pixelized.biblib.repository.apiCache.IAPICacheRepository
import com.pixelized.biblib.utils.exception.BookFetchException
import com.pixelized.biblib.utils.exception.NewBookFetchException
suspend fun updateBooks( suspend fun updateBooks(
client: IBibLibClient, client: IBibLibClient,
cache: IAPICacheRepository, cache: IAPICacheRepository,
repository: IBookRepository, repository: IBookRepository,
): Boolean { ) {
return loadNewBooks(client, cache) || loadAllBooks(client, cache, repository) if (loadNewBooks(client, cache) || repository.getBookCount() <= 0) {
loadAllBooks(client, cache, repository)
}
} }
/**
* This method will fetch all new book from [client] and save them into the [cache]
* @param client the client used to fetch the data.
* @param cache the cache used to save the data.
* @return return true if the data have been loaded and book need to be updated.
*/
suspend fun loadNewBooks( suspend fun loadNewBooks(
client: IBibLibClient, client: IBibLibClient,
cache: IAPICacheRepository, cache: IAPICacheRepository,
): Boolean { ): Boolean {
val cached = cache.new val cached = cache.new
val updated = client.service.new() val updated = client.service.new()
if (updated.isError) {
Log.e("loadNewBooks", updated.message ?: "")
throw NewBookFetchException(updated.message)
}
return if (cached != updated) { return if (cached != updated) {
cache.new = updated cache.new = updated
true true
@ -26,12 +44,26 @@ suspend fun loadNewBooks(
} }
} }
/**
* This method will fetch all book from [client] and save them into the [repository]
* @param client the client used to fetch the data.
* @param cache the cache used to read the new book data.
* @param repository the repository to save the book data.
* @return this method will return true the books have been correctly fetch, otherwise false.
*/
suspend fun loadAllBooks( suspend fun loadAllBooks(
client: IBibLibClient, client: IBibLibClient,
cache: IAPICacheRepository, cache: IAPICacheRepository,
repository: IBookRepository, repository: IBookRepository,
): Boolean { ): Boolean {
client.service.list().let { response -> val response: BookListResponse = client.service.list().also { response ->
if (response.isError) {
Log.e("loadAllBooks", response.message ?: "")
throw BookFetchException(response.message)
}
val newIds = cache.new?.data?.map { it.book_id } ?: listOf() val newIds = cache.new?.data?.map { it.book_id } ?: listOf()
val factory = BookFactory() val factory = BookFactory()
val books = response.data?.mapNotNull { dto -> val books = response.data?.mapNotNull { dto ->
@ -45,5 +77,5 @@ suspend fun loadAllBooks(
} }
books?.let { data -> repository.update(data) } books?.let { data -> repository.update(data) }
} }
return true return response.isError.not()
} }

View file

@ -7,6 +7,8 @@ interface IBookRepository {
fun getAll(): List<Book> fun getAll(): List<Book>
fun getBookCount(): Int
fun getNewsSource(): DataSource.Factory<Int, Book> fun getNewsSource(): DataSource.Factory<Int, Book>
fun getBooksSource(): DataSource.Factory<Int, Book> fun getBooksSource(): DataSource.Factory<Int, Book>

View file

@ -14,15 +14,13 @@ import com.google.android.gms.auth.api.signin.GoogleSignIn
import com.google.android.gms.common.api.ApiException import com.google.android.gms.common.api.ApiException
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.network.data.query.AuthLoginQuery
import com.pixelized.biblib.network.data.response.BookListResponse
import com.pixelized.biblib.network.factory.BookFactory
import com.pixelized.biblib.repository.apiCache.IAPICacheRepository import com.pixelized.biblib.repository.apiCache.IAPICacheRepository
import com.pixelized.biblib.repository.book.IBookRepository import com.pixelized.biblib.repository.book.IBookRepository
import com.pixelized.biblib.repository.book.updateBooks import com.pixelized.biblib.repository.book.updateBooks
import com.pixelized.biblib.repository.credential.CredentialRepository_Factory
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.repository.googleSignIn.IGoogleSingInRepository
import com.pixelized.biblib.ui.composable.StateUio import com.pixelized.biblib.ui.composable.StateUio
import com.pixelized.biblib.utils.exception.BookFetchException
import com.pixelized.biblib.utils.exception.MissingGoogleTokenException import com.pixelized.biblib.utils.exception.MissingGoogleTokenException
import com.pixelized.biblib.utils.exception.MissingTokenException import com.pixelized.biblib.utils.exception.MissingTokenException
import dagger.hilt.android.lifecycle.HiltViewModel import dagger.hilt.android.lifecycle.HiltViewModel
@ -58,8 +56,7 @@ class AuthenticationViewModel @Inject constructor(
val idToken = response.token ?: throw MissingTokenException() val idToken = response.token ?: throw MissingTokenException()
client.token = idToken client.token = idToken
credentialRepository.bearer = response.token credentialRepository.bearer = response.token
// update book if needed updateBooks() // update book if needed
updateBooks()
_authenticationProcess.value = StateUio.Success(Unit) _authenticationProcess.value = StateUio.Success(Unit)
} catch (exception: Exception) { } catch (exception: Exception) {
Log.e("AuthenticationViewModel", exception.message, exception) Log.e("AuthenticationViewModel", exception.message, exception)
@ -86,8 +83,7 @@ class AuthenticationViewModel @Inject constructor(
val response = client.service.loginWithGoogle(token = googleToken) val response = client.service.loginWithGoogle(token = googleToken)
val token = response.token ?: throw MissingTokenException() val token = response.token ?: throw MissingTokenException()
client.token = token client.token = token
// update book if needed updateBooks() // update book if needed
updateBooks()
_authenticationProcess.value = StateUio.Success(Unit) _authenticationProcess.value = StateUio.Success(Unit)
} catch (exception: Exception) { } catch (exception: Exception) {
Log.e("AuthenticationViewModel", exception.message, exception) Log.e("AuthenticationViewModel", exception.message, exception)
@ -106,7 +102,7 @@ class AuthenticationViewModel @Inject constructor(
////////////////////////////////////// //////////////////////////////////////
// region: Books update // region: Books update
private suspend fun updateBooks(): Boolean = updateBooks( private suspend fun updateBooks() = updateBooks(
client = client, client = client,
cache = apiCache, cache = apiCache,
repository = bookRepository, repository = bookRepository,

View file

@ -7,7 +7,6 @@ import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
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.network.data.query.AuthLoginQuery
import com.pixelized.biblib.network.factory.BookFactory
import com.pixelized.biblib.repository.apiCache.IAPICacheRepository import com.pixelized.biblib.repository.apiCache.IAPICacheRepository
import com.pixelized.biblib.repository.book.IBookRepository import com.pixelized.biblib.repository.book.IBookRepository
import com.pixelized.biblib.repository.book.updateBooks import com.pixelized.biblib.repository.book.updateBooks
@ -39,10 +38,15 @@ class LauncherViewModel @Inject constructor(
viewModelScope.launch(Dispatchers.IO) { viewModelScope.launch(Dispatchers.IO) {
// Try to Authenticate // Try to Authenticate
if (autoLoginWithGoogle() || autologinWithCredential()) { if (autoLoginWithGoogle() || autologinWithCredential()) {
startDestination = try {
// Update book // Update book
updateBooks() updateBooks()
// Change the start destination // Change the start destination
startDestination = Screen.Home Screen.Home
} catch (exception: Exception) {
// Force the authentication process.
Screen.Authentication
}
} }
delay(1000) delay(1000)
// Update loading state. // Update loading state.
@ -100,7 +104,7 @@ class LauncherViewModel @Inject constructor(
////////////////////////////////////// //////////////////////////////////////
// region: Books update // region: Books update
private suspend fun updateBooks(): Boolean = updateBooks( private suspend fun updateBooks() = updateBooks(
client = client, client = client,
cache = apiCache, cache = apiCache,
repository = bookRepository, repository = bookRepository,

View file

@ -0,0 +1,3 @@
package com.pixelized.biblib.utils.exception
class BookFetchException(message: String?): RuntimeException("New Book fetch failed.\n$message")

View file

@ -0,0 +1,3 @@
package com.pixelized.biblib.utils.exception
class NewBookFetchException(message: String?): RuntimeException("New Book fetch failed.\n$message")