diff --git a/.idea/misc.xml b/.idea/misc.xml
index 72c05e7..2c29f05 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -88,6 +88,8 @@
+
+
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index af5b706..a2bb010 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -3,21 +3,24 @@
package="com.pixelized.biblib">
+
+
-
diff --git a/app/src/main/java/com/pixelized/biblib/BibLibApplication.kt b/app/src/main/java/com/pixelized/biblib/BibLibApplication.kt
new file mode 100644
index 0000000..fc1db66
--- /dev/null
+++ b/app/src/main/java/com/pixelized/biblib/BibLibApplication.kt
@@ -0,0 +1,22 @@
+package com.pixelized.biblib
+
+import android.app.Application
+import com.google.gson.Gson
+import com.google.gson.GsonBuilder
+import com.pixelized.biblib.injection.Bob
+import com.pixelized.biblib.network.client.BibLibClient
+import com.pixelized.biblib.network.client.IBibLibClient
+import com.pixelized.biblib.utils.BitmapCache
+
+class BibLibApplication : Application() {
+
+ override fun onCreate() {
+ super.onCreate()
+
+ Bob[BitmapCache::class] = BitmapCache(this)
+
+ Bob[Gson::class] = GsonBuilder().create()
+
+ Bob[IBibLibClient::class] = BibLibClient()
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/pixelized/biblib/data/network/query/AuthLoginQuery.kt b/app/src/main/java/com/pixelized/biblib/data/network/query/AuthLoginQuery.kt
new file mode 100644
index 0000000..5cdca94
--- /dev/null
+++ b/app/src/main/java/com/pixelized/biblib/data/network/query/AuthLoginQuery.kt
@@ -0,0 +1,10 @@
+package com.pixelized.biblib.data.network.query
+
+import com.google.gson.annotations.SerializedName
+
+data class AuthLoginQuery(
+ @SerializedName("username")
+ val username: String?,
+ @SerializedName("password")
+ val password: String?,
+)
\ No newline at end of file
diff --git a/app/src/main/java/com/pixelized/biblib/data/network/response/AuthLoginResponse.kt b/app/src/main/java/com/pixelized/biblib/data/network/response/AuthLoginResponse.kt
new file mode 100644
index 0000000..c54b0e6
--- /dev/null
+++ b/app/src/main/java/com/pixelized/biblib/data/network/response/AuthLoginResponse.kt
@@ -0,0 +1,8 @@
+package com.pixelized.biblib.data.network.response
+
+import com.google.gson.annotations.SerializedName
+
+data class AuthLoginResponse(
+ @SerializedName("id_token")
+ val token: String? = null,
+) : ErrorResponse()
\ No newline at end of file
diff --git a/app/src/main/java/com/pixelized/biblib/data/network/response/ErrorResponse.kt b/app/src/main/java/com/pixelized/biblib/data/network/response/ErrorResponse.kt
new file mode 100644
index 0000000..daf1121
--- /dev/null
+++ b/app/src/main/java/com/pixelized/biblib/data/network/response/ErrorResponse.kt
@@ -0,0 +1,25 @@
+package com.pixelized.biblib.data.network.response
+
+import com.google.gson.annotations.SerializedName
+
+open class ErrorResponse(
+ @SerializedName("error")
+ val error: Error? = null,
+ @SerializedName("message")
+ val message: String? = null,
+) {
+ val isError: Boolean get() = error != null
+
+ class Error(
+ @SerializedName("expose")
+ val expose: Boolean? = null,
+ @SerializedName("statusCode")
+ val statusCode: Int? = null,
+ @SerializedName("status")
+ val status: Int? = null,
+ @SerializedName("body")
+ val body: String? = null,
+ @SerializedName("type")
+ val type: String? = null,
+ )
+}
diff --git a/app/src/main/java/com/pixelized/biblib/data/ui/BookThumbnailUio.kt b/app/src/main/java/com/pixelized/biblib/data/ui/BookThumbnailUio.kt
index 17bffe4..a255ad0 100644
--- a/app/src/main/java/com/pixelized/biblib/data/ui/BookThumbnailUio.kt
+++ b/app/src/main/java/com/pixelized/biblib/data/ui/BookThumbnailUio.kt
@@ -1,6 +1,6 @@
package com.pixelized.biblib.data.ui
-import com.pixelized.biblib.utils.Constant.THUMBNAIL_URL
+import com.pixelized.biblib.network.client.IBibLibClient.Companion.THUMBNAIL_URL
import java.net.URL
data class BookThumbnailUio(
diff --git a/app/src/main/java/com/pixelized/biblib/data/ui/BookUio.kt b/app/src/main/java/com/pixelized/biblib/data/ui/BookUio.kt
index ea24150..a4562d1 100644
--- a/app/src/main/java/com/pixelized/biblib/data/ui/BookUio.kt
+++ b/app/src/main/java/com/pixelized/biblib/data/ui/BookUio.kt
@@ -1,6 +1,6 @@
package com.pixelized.biblib.data.ui
-import com.pixelized.biblib.utils.Constant
+import com.pixelized.biblib.network.client.IBibLibClient.Companion.COVER_URL
import java.net.URL
data class BookUio(
@@ -14,5 +14,5 @@ data class BookUio(
val series: String?,
val description: String,
) {
- val cover: URL = URL("${Constant.COVER_URL}/$id.jpg")
+ val cover: URL = URL("${COVER_URL}/$id.jpg")
}
diff --git a/app/src/main/java/com/pixelized/biblib/injection/Bob.kt b/app/src/main/java/com/pixelized/biblib/injection/Bob.kt
new file mode 100644
index 0000000..994951b
--- /dev/null
+++ b/app/src/main/java/com/pixelized/biblib/injection/Bob.kt
@@ -0,0 +1,21 @@
+package com.pixelized.biblib.injection
+
+import com.pixelized.biblib.utils.exception.InjectionException
+import kotlin.reflect.KClass
+
+@Suppress("UNCHECKED_CAST")
+object Bob {
+ private val components = hashMapOf, Any>()
+
+ operator fun set(clazz: KClass, component: O) {
+ components[clazz] = component
+ }
+
+ operator fun get(clazz: KClass<*>): T {
+ return components[clazz] as? T ?: throw InjectionException(clazz)
+ }
+}
+
+inline fun get(): T = Bob[T::class]
+
+inline fun inject(): Lazy = lazy { Bob[T::class] }
\ No newline at end of file
diff --git a/app/src/main/java/com/pixelized/biblib/network/client/BearerInterceptor.kt b/app/src/main/java/com/pixelized/biblib/network/client/BearerInterceptor.kt
new file mode 100644
index 0000000..cafa7b6
--- /dev/null
+++ b/app/src/main/java/com/pixelized/biblib/network/client/BearerInterceptor.kt
@@ -0,0 +1,23 @@
+package com.pixelized.biblib.network.client
+
+import okhttp3.Interceptor
+import okhttp3.Response
+
+class BearerInterceptor : Interceptor {
+ private val bearer get() = "$BEARER $token"
+ var token: String? = null
+
+ override fun intercept(chain: Interceptor.Chain): Response {
+ var request = chain.request()
+ if (request.header(NO_AUTHORIZATION) == null && token.isNullOrEmpty().not()) {
+ request = request.newBuilder().addHeader(AUTHORIZATION, bearer).build()
+ }
+ return chain.proceed(request)
+ }
+
+ companion object {
+ private const val NO_AUTHORIZATION = "No-Authentication"
+ private const val AUTHORIZATION = "Authorization"
+ private const val BEARER = "Bearer"
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/pixelized/biblib/network/client/BibLibClient.kt b/app/src/main/java/com/pixelized/biblib/network/client/BibLibClient.kt
new file mode 100644
index 0000000..574a662
--- /dev/null
+++ b/app/src/main/java/com/pixelized/biblib/network/client/BibLibClient.kt
@@ -0,0 +1,30 @@
+package com.pixelized.biblib.network.client
+
+import com.google.gson.Gson
+import com.pixelized.biblib.injection.inject
+import com.pixelized.biblib.network.client.IBibLibClient.Companion.BASE_URL
+import okhttp3.OkHttpClient
+import retrofit2.Retrofit
+import retrofit2.converter.gson.GsonConverterFactory
+
+class BibLibClient : IBibLibClient {
+ private val gson by inject()
+ private val interceptor = BearerInterceptor()
+ private val retrofit: Retrofit = Retrofit.Builder()
+ .addConverterFactory(GsonConverterFactory.create(gson))
+ .client(OkHttpClient.Builder().addInterceptor(interceptor).build())
+ .baseUrl(BASE_URL)
+ .build()
+
+ override val service: IBibLibWebServiceAPI = retrofit.create(IBibLibWebServiceAPI::class.java)
+
+ // endregion
+ ///////////////////////////////////
+ // region BibLib webservice Auth
+
+ override fun updateBearerToken(token: String?) {
+ interceptor.token = token
+ }
+
+ // endregion
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/pixelized/biblib/network/client/IBibLibClient.kt b/app/src/main/java/com/pixelized/biblib/network/client/IBibLibClient.kt
new file mode 100644
index 0000000..7fdc9fa
--- /dev/null
+++ b/app/src/main/java/com/pixelized/biblib/network/client/IBibLibClient.kt
@@ -0,0 +1,15 @@
+package com.pixelized.biblib.network.client
+
+interface IBibLibClient {
+
+ val service: IBibLibWebServiceAPI
+
+ fun updateBearerToken(token: String?)
+
+ companion object {
+ const val BASE_URL = "https://bib.bibulle.fr"
+ const val THUMBNAIL_URL = "$BASE_URL/api/book/thumbnail"
+ const val COVER_URL = "$BASE_URL/api/book/cover"
+ const val REGISTER_URL = "$BASE_URL/signup"
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/pixelized/biblib/network/client/IBibLibWebServiceAPI.kt b/app/src/main/java/com/pixelized/biblib/network/client/IBibLibWebServiceAPI.kt
new file mode 100644
index 0000000..f3fbb54
--- /dev/null
+++ b/app/src/main/java/com/pixelized/biblib/network/client/IBibLibWebServiceAPI.kt
@@ -0,0 +1,43 @@
+package com.pixelized.biblib.network.client
+
+import com.pixelized.biblib.data.network.query.AuthLoginQuery
+import com.pixelized.biblib.data.network.response.AuthLoginResponse
+import retrofit2.http.Body
+import retrofit2.http.GET
+import retrofit2.http.POST
+import retrofit2.http.Query
+
+interface IBibLibWebServiceAPI {
+ @POST("/authent/login")
+ suspend fun login(@Body query: AuthLoginQuery): AuthLoginResponse
+
+ @GET("/authent/google-id-token")
+ suspend fun loginWithGoogle(@Query("id_token") token: String): AuthLoginResponse
+
+// @GET("/authent/user")
+// suspend fun user(): UserResponse
+//
+// @GET("/api/book/new")
+// suspend fun new(): BookListResponse
+//
+// @GET("/api/book")
+// suspend fun list(): BookListResponse
+//
+// @GET("/api/book/{id}")
+// suspend fun detail(@Path("id") bookId: Int): BookDetailResponse
+//
+// @GET("/api/book/{id}/send/kindle")
+// suspend fun send(@Path("id") bookId: Int, @Query("mail") mail: String): LinkedTreeMap
+//
+// @GET("/api/book/{id}/epub/url")
+// suspend fun epub(@Path("id") bookId: Int): TokenResponse
+//
+// @GET("/api/book/{id}/mobi/url")
+// suspend fun mobi(@Path("id") bookId: Int): TokenResponse
+//
+// @GET("/api/book/{id}/epub")
+// fun downloadEpub(@Path("id") bookId: Int, @Query("token") token: String): Call
+//
+// @GET("/api/book/{id}/mobi")
+// fun downloadMobi(@Path("id") bookId: Int, @Query("token") token: String): Call
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/pixelized/biblib/ui/MainActivity.kt b/app/src/main/java/com/pixelized/biblib/ui/MainActivity.kt
index 58de05a..4521eba 100644
--- a/app/src/main/java/com/pixelized/biblib/ui/MainActivity.kt
+++ b/app/src/main/java/com/pixelized/biblib/ui/MainActivity.kt
@@ -5,28 +5,37 @@ import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.viewModels
import androidx.compose.animation.Crossfade
-import androidx.compose.animation.core.tween
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState
import androidx.lifecycle.viewmodel.compose.viewModel
+import com.google.android.gms.auth.api.signin.GoogleSignIn
+import com.google.android.gms.auth.api.signin.GoogleSignInOptions
+import com.pixelized.biblib.R
import com.pixelized.biblib.ui.composable.screen.LoginScreenComposable
import com.pixelized.biblib.ui.composable.screen.MainScreenComposable
import com.pixelized.biblib.ui.composable.screen.SplashScreenComposable
import com.pixelized.biblib.ui.theme.BibLibTheme
-import com.pixelized.biblib.ui.viewmodel.AuthenticationViewModel
import com.pixelized.biblib.ui.viewmodel.NavigationViewModel
import com.pixelized.biblib.ui.viewmodel.NavigationViewModel.Screen
-import com.pixelized.biblib.utils.BitmapCache
class MainActivity : ComponentActivity() {
private val navigationViewModel: NavigationViewModel by viewModels()
+ private val googleSignInOption by lazy {
+ GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
+ .requestIdToken(getString(R.string.biblib_server_id))
+ .requestEmail()
+ .build()
+ }
+
+ val googleSignIn by lazy {
+ GoogleSignIn.getClient(this, googleSignInOption)
+ }
+
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
- BitmapCache.init(this)
-
setContent {
BibLibTheme {
ContentComposable()
diff --git a/app/src/main/java/com/pixelized/biblib/ui/composable/screen/LoginScreenComposable.kt b/app/src/main/java/com/pixelized/biblib/ui/composable/screen/LoginScreenComposable.kt
index 64a2ccc..92c64c9 100644
--- a/app/src/main/java/com/pixelized/biblib/ui/composable/screen/LoginScreenComposable.kt
+++ b/app/src/main/java/com/pixelized/biblib/ui/composable/screen/LoginScreenComposable.kt
@@ -1,5 +1,10 @@
package com.pixelized.biblib.ui.composable.screen
+import android.util.Log
+import android.widget.Toast
+import androidx.activity.ComponentActivity
+import androidx.activity.compose.rememberLauncherForActivityResult
+import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.foundation.Image
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
@@ -19,6 +24,7 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
+import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
@@ -28,7 +34,11 @@ import androidx.compose.ui.text.input.VisualTransformation
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
+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.R
+import com.pixelized.biblib.ui.MainActivity
import com.pixelized.biblib.ui.theme.BibLibTheme
import com.pixelized.biblib.ui.viewmodel.AuthenticationViewModel
import com.pixelized.biblib.ui.viewmodel.NavigationViewModel
@@ -43,10 +53,35 @@ fun LoginScreenComposablePreview() {
@Composable
fun LoginScreenComposable(
-
+ navigationViewModel: NavigationViewModel = viewModel(),
+ authenticationViewModel: AuthenticationViewModel = viewModel(),
) {
- val navigationViewModel = viewModel()
- val authenticationViewModel = viewModel()
+ // TODO : c'est de la merde ça
+ val activity = LocalContext.current as MainActivity
+ val result = remember { mutableStateOf(null) }
+ val launcher =
+ rememberLauncherForActivityResult(ActivityResultContracts.StartActivityForResult()) {
+ try {
+ val task = GoogleSignIn.getSignedInAccountFromIntent(it.data)
+ val account: GoogleSignInAccount? = task.getResult(ApiException::class.java)
+
+ val idToken = account?.idToken
+// if (idToken != null) {
+// viewModel.loginWithGoogle(idToken).observeLogin()
+// } else {
+// Toast.makeText(requireActivity(), "GoogleSignIn missing Token", Toast.LENGTH_SHORT).show()
+// }
+ Log.e("AuthLoginFragment", "idToken: $idToken")
+ } catch (exception: Exception) {
+// Toast.makeText(requireActivity(), "GoogleSignIn exception: ${exception.message}", Toast.LENGTH_SHORT).show()
+ Log.e("AuthLoginFragment", exception.message, exception)
+ }
+// // Here we just update the state, but you could imagine
+// // pre-processing the result, or updating a MutableSharedFlow that
+// // your composable collects
+// result.value = it
+ }
+
val typography = MaterialTheme.typography
Column(
@@ -102,14 +137,12 @@ fun LoginScreenComposable(
modifier = Modifier.padding(end = 8.dp),
colors = outlinedButtonColors(),
onClick = {
- // TODO:
- navigationViewModel.navigateTo(NavigationViewModel.Screen.MainScreen)
+ authenticationViewModel.register()
}) {
Text(text = stringResource(id = R.string.action_register))
}
Button(onClick = {
- // TODO:
- navigationViewModel.navigateTo(NavigationViewModel.Screen.MainScreen)
+ authenticationViewModel.login()
}) {
Text(text = stringResource(id = R.string.action_login))
}
@@ -121,8 +154,7 @@ fun LoginScreenComposable(
modifier = Modifier.fillMaxWidth(),
colors = outlinedButtonColors(),
onClick = {
- // TODO:
- navigationViewModel.navigateTo(NavigationViewModel.Screen.MainScreen)
+ launcher.launch(activity.googleSignIn.signInIntent)
}) {
Image(
modifier = Modifier.padding(end = 8.dp),
@@ -189,7 +221,7 @@ private fun PasswordField(
private fun CredentialRemember(viewModel: AuthenticationViewModel, modifier: Modifier = Modifier) {
val credential = viewModel.rememberCredential.observeAsState()
Row(modifier = modifier.clickable {
- viewModel.updateRememberCredential(credential = credential.value?.not() ?: false)
+ viewModel.updateRememberCredential(rememberCredential = credential.value?.not() ?: false)
}) {
Checkbox(
modifier = Modifier.align(Alignment.CenterVertically),
diff --git a/app/src/main/java/com/pixelized/biblib/ui/viewmodel/AuthenticationViewModel.kt b/app/src/main/java/com/pixelized/biblib/ui/viewmodel/AuthenticationViewModel.kt
index 1c2b63d..2c1ce03 100644
--- a/app/src/main/java/com/pixelized/biblib/ui/viewmodel/AuthenticationViewModel.kt
+++ b/app/src/main/java/com/pixelized/biblib/ui/viewmodel/AuthenticationViewModel.kt
@@ -1,10 +1,24 @@
package com.pixelized.biblib.ui.viewmodel
+import android.app.Application
+import android.content.Context
+import android.content.SharedPreferences
+import android.util.Log
+import androidx.core.content.edit
+import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
-import androidx.lifecycle.ViewModel
+import androidx.lifecycle.viewModelScope
+import androidx.lifecycle.viewmodel.compose.viewModel
+import com.pixelized.biblib.data.network.query.AuthLoginQuery
+import com.pixelized.biblib.injection.inject
+import com.pixelized.biblib.network.client.IBibLibClient
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
-class AuthenticationViewModel: ViewModel() {
+class AuthenticationViewModel(application: Application) : AndroidViewModel(application) {
+ private val preferences = application.getSharedPreferences(SHARED_PREF, Context.MODE_PRIVATE)
+ private val client: IBibLibClient by inject()
private val _login = MutableLiveData()
val login: LiveData get() = _login
@@ -12,9 +26,17 @@ class AuthenticationViewModel: ViewModel() {
private val _password = MutableLiveData()
val password: LiveData get() = _password
- private val _rememberCredential = MutableLiveData(false)
+ private val _rememberCredential = MutableLiveData()
val rememberCredential: LiveData get() = _rememberCredential
+ init {
+ viewModelScope.launch(Dispatchers.Main) {
+ _login.value = preferences.login
+ _password.value = preferences.password
+ _rememberCredential.value = preferences.rememberCredential
+ }
+ }
+
fun updateLogin(login: String) {
_login.postValue(login)
}
@@ -23,7 +45,54 @@ class AuthenticationViewModel: ViewModel() {
_password.postValue(password)
}
- fun updateRememberCredential(credential: Boolean) {
- _rememberCredential.postValue(credential)
+ fun updateRememberCredential(rememberCredential: Boolean) {
+ _rememberCredential.postValue(rememberCredential)
+ viewModelScope.launch {
+ preferences.rememberCredential = rememberCredential
+ if (rememberCredential.not()) {
+ preferences.login = null
+ preferences.password = null
+ }
+ }
+ }
+
+ fun register() {
+
+ }
+
+ fun login() {
+ viewModelScope.launch(Dispatchers.IO) {
+ if (rememberCredential.value == true) {
+ preferences.login = login.value
+ preferences.password = password.value
+ }
+ // TODO : validation !
+ val query = AuthLoginQuery(
+ username = login.value,
+ password = password.value
+ )
+ // TODO : Repository (token management & co)
+ val response = client.service.login(query)
+ Log.e("pouet", response.toString())
+ }
+ }
+
+ private var SharedPreferences.login: String?
+ get() = getString(REMEMBER_USER, null)
+ set(value) = edit { putString(REMEMBER_USER, value) }
+
+ private var SharedPreferences.password: String?
+ get() = getString(REMEMBER_PASSWORD, null)
+ set(value) = edit { putString(REMEMBER_PASSWORD, value) }
+
+ private var SharedPreferences.rememberCredential: Boolean
+ get() = getBoolean(REMEMBER_CREDENTIAL, false)
+ set(value) = edit { putBoolean(REMEMBER_CREDENTIAL, value) }
+
+ companion object {
+ const val SHARED_PREF = "BIB_LIB_SHARED_PREF"
+ const val REMEMBER_CREDENTIAL = "REMEMBER_CREDENTIAL"
+ const val REMEMBER_USER = "REMEMBER_USER"
+ const val REMEMBER_PASSWORD = "REMEMBER_PASSWORD"
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/pixelized/biblib/utils/BitmapCache.kt b/app/src/main/java/com/pixelized/biblib/utils/BitmapCache.kt
index eca63f5..84f2255 100644
--- a/app/src/main/java/com/pixelized/biblib/utils/BitmapCache.kt
+++ b/app/src/main/java/com/pixelized/biblib/utils/BitmapCache.kt
@@ -1,6 +1,6 @@
package com.pixelized.biblib.utils
-import android.content.Context
+import android.app.Application
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.util.Log
@@ -12,12 +12,11 @@ import java.io.File
import java.io.IOException
import java.net.URL
-object BitmapCache {
- private val scope = CoroutineScope(Dispatchers.IO)
+class BitmapCache(application: Application) {
private var cache: File? = null
- fun init(context: Context) {
- cache = context.cacheDir
+ init {
+ cache = application.cacheDir
}
fun writeToDisk(url: URL, bitmap: Bitmap) {
diff --git a/app/src/main/java/com/pixelized/biblib/utils/exception/InjectionException.kt b/app/src/main/java/com/pixelized/biblib/utils/exception/InjectionException.kt
new file mode 100644
index 0000000..3379876
--- /dev/null
+++ b/app/src/main/java/com/pixelized/biblib/utils/exception/InjectionException.kt
@@ -0,0 +1,5 @@
+package com.pixelized.biblib.utils.exception
+
+import kotlin.reflect.KClass
+
+class InjectionException(clazz: KClass<*>) : RuntimeException("InjectionException occur for class:${clazz}")
\ No newline at end of file
diff --git a/app/src/main/java/com/pixelized/biblib/utils/exception/NoBearerException.kt b/app/src/main/java/com/pixelized/biblib/utils/exception/NoBearerException.kt
new file mode 100644
index 0000000..238368a
--- /dev/null
+++ b/app/src/main/java/com/pixelized/biblib/utils/exception/NoBearerException.kt
@@ -0,0 +1,3 @@
+package com.pixelized.biblib.utils.exception
+
+class NoBearerException : RuntimeException("Bearer token is null")
\ No newline at end of file
diff --git a/app/src/main/java/com/pixelized/biblib/utils/extention/UrlEx.kt b/app/src/main/java/com/pixelized/biblib/utils/extention/UrlEx.kt
index 2116e4c..43af27f 100644
--- a/app/src/main/java/com/pixelized/biblib/utils/extention/UrlEx.kt
+++ b/app/src/main/java/com/pixelized/biblib/utils/extention/UrlEx.kt
@@ -5,18 +5,19 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.ui.graphics.asImageBitmap
import androidx.compose.ui.graphics.painter.BitmapPainter
import androidx.compose.ui.graphics.painter.Painter
+import com.pixelized.biblib.injection.get
import com.pixelized.biblib.utils.BitmapCache
import java.net.URL
-
fun URL.toImage(placeHolder: Painter): State {
- val cached = BitmapCache.readFromDisk(this)?.let { BitmapPainter(it.asImageBitmap()) }
- val state = mutableStateOf(cached ?: placeHolder)
+ val cache: BitmapCache = get()
+ val resource = cache.readFromDisk(this)?.let { BitmapPainter(it.asImageBitmap()) }
+ val state = mutableStateOf(resource ?: placeHolder)
- if (cached == null) {
- BitmapCache.download(url = this) { downloaded ->
+ if (resource == null) {
+ cache.download(url = this) { downloaded ->
if (downloaded != null) {
- BitmapCache.writeToDisk(this, downloaded)
+ cache.writeToDisk(this, downloaded)
state.value = BitmapPainter(downloaded.asImageBitmap())
}
}
diff --git a/app/src/main/res/values/biblib_server.xml b/app/src/main/res/values/biblib_server.xml
new file mode 100644
index 0000000..f4d220f
--- /dev/null
+++ b/app/src/main/res/values/biblib_server.xml
@@ -0,0 +1,4 @@
+
+
+ 725701605591-rr2dqeabon4kjpfevoruru65eo3rukmv.apps.googleusercontent.com
+
\ No newline at end of file