Small refactor and add FireBase Crashlitycs.

This commit is contained in:
Thomas Andres Gomez 2023-04-06 10:35:10 +02:00
parent 9c8d05e578
commit f6496e485d
9 changed files with 131 additions and 88 deletions

View file

@ -2,6 +2,8 @@ plugins {
id 'com.android.application' id 'com.android.application'
id 'kotlin-android' id 'kotlin-android'
id 'kotlin-kapt' id 'kotlin-kapt'
id 'com.google.gms.google-services'
id 'com.google.firebase.crashlytics'
id 'dagger.hilt.android.plugin' id 'dagger.hilt.android.plugin'
id 'org.jetbrains.kotlin.android' id 'org.jetbrains.kotlin.android'
} }
@ -130,7 +132,7 @@ dependencies {
implementation "com.github.skydoves:landscapist-glide:1.5.2" implementation "com.github.skydoves:landscapist-glide:1.5.2"
kapt 'com.github.bumptech.glide:compiler:4.13.2' // this have to be align with landscapist-glide kapt 'com.github.bumptech.glide:compiler:4.13.2' // this have to be align with landscapist-glide
// Reorder element in laylist // Reorder element in lazylist
implementation "org.burnoutcrew.composereorderable:reorderable:0.9.6" implementation "org.burnoutcrew.composereorderable:reorderable:0.9.6"
// Navigation // Navigation
@ -142,6 +144,10 @@ dependencies {
// Google sign in. // Google sign in.
implementation "com.google.android.gms:play-services-auth:20.4.1" implementation "com.google.android.gms:play-services-auth:20.4.1"
// Firebase
implementation platform('com.google.firebase:firebase-bom:31.3.0')
implementation 'com.google.firebase:firebase-crashlytics'
// RetroFit & Gson for webservice call // RetroFit & Gson for webservice call
implementation 'com.squareup.retrofit2:retrofit:2.9.0' implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0' implementation 'com.squareup.retrofit2:converter-gson:2.9.0'

View file

@ -0,0 +1,68 @@
{
"project_info": {
"project_number": "837508873287",
"project_id": "biblib-2b8e6",
"storage_bucket": "biblib-2b8e6.appspot.com"
},
"client": [
{
"client_info": {
"mobilesdk_app_id": "1:837508873287:android:52368b2f6ecf2304c90562",
"android_client_info": {
"package_name": "com.pixelized.biblib"
}
},
"oauth_client": [
{
"client_id": "837508873287-kar6b3a5phks9n5f4ieoib48cfb3r437.apps.googleusercontent.com",
"client_type": 3
}
],
"api_key": [
{
"current_key": "AIzaSyAU-JemDic4WFaIq6nTp48uf_P1-pxgARo"
}
],
"services": {
"appinvite_service": {
"other_platform_oauth_client": [
{
"client_id": "837508873287-kar6b3a5phks9n5f4ieoib48cfb3r437.apps.googleusercontent.com",
"client_type": 3
}
]
}
}
},
{
"client_info": {
"mobilesdk_app_id": "1:837508873287:android:200c71bdf4129685c90562",
"android_client_info": {
"package_name": "com.pixelized.biblib.debug"
}
},
"oauth_client": [
{
"client_id": "837508873287-kar6b3a5phks9n5f4ieoib48cfb3r437.apps.googleusercontent.com",
"client_type": 3
}
],
"api_key": [
{
"current_key": "AIzaSyAU-JemDic4WFaIq6nTp48uf_P1-pxgARo"
}
],
"services": {
"appinvite_service": {
"other_platform_oauth_client": [
{
"client_id": "837508873287-kar6b3a5phks9n5f4ieoib48cfb3r437.apps.googleusercontent.com",
"client_type": 3
}
]
}
}
}
],
"configuration_version": "1"
}

View file

@ -2,7 +2,6 @@ package com.pixelized.biblib.ui.screen.home.common.item
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.content.res.Configuration import android.content.res.Configuration
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.* import androidx.compose.foundation.layout.*
import androidx.compose.material.Card import androidx.compose.material.Card
@ -16,11 +15,12 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import com.pixelized.biblib.R import com.pixelized.biblib.R
import com.pixelized.biblib.ui.theme.BibLibTheme import com.pixelized.biblib.ui.theme.BibLibTheme
import com.pixelized.biblib.utils.extention.bibLib import com.pixelized.biblib.utils.extention.bibLib
import com.pixelized.biblib.utils.extention.default
import com.pixelized.biblib.utils.extention.modifier.drawDiagonalLabel import com.pixelized.biblib.utils.extention.modifier.drawDiagonalLabel
import com.pixelized.biblib.utils.extention.placeholder import com.pixelized.biblib.utils.extention.placeholder
import com.skydoves.landscapist.glide.GlideImage import com.skydoves.landscapist.glide.GlideImage
@ -36,7 +36,7 @@ data class LargeBookThumbnailUio(
fun LargeBookThumbnail( fun LargeBookThumbnail(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
thumbnail: LargeBookThumbnailUio?, thumbnail: LargeBookThumbnailUio?,
onClick: (LargeBookThumbnailUio) -> Unit = default<LargeBookThumbnailUio>(), onClick: (LargeBookThumbnailUio) -> Unit,
) { ) {
Card( Card(
modifier = modifier modifier = modifier
@ -62,7 +62,7 @@ fun LargeBookThumbnail(
private fun LargeBookThumbnailContent( private fun LargeBookThumbnailContent(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
thumbnail: LargeBookThumbnailUio, thumbnail: LargeBookThumbnailUio,
onClick: (LargeBookThumbnailUio) -> Unit = default<LargeBookThumbnailUio>(), onClick: (LargeBookThumbnailUio) -> Unit,
) { ) {
GlideImage( GlideImage(
modifier = Modifier modifier = Modifier
@ -115,27 +115,25 @@ private fun Modifier.isNew(
@Composable @Composable
@Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_NO) @Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_NO)
@Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES) @Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES)
private fun LargeBookThumbnailPreview() { private fun LargeBookThumbnailPreview(
@PreviewParameter(LargeBookThumbnailPreviewProvider::class) preview: LargeBookThumbnailUio?,
) {
BibLibTheme { BibLibTheme {
LargeBookThumbnail( LargeBookThumbnail(
modifier = Modifier.width(168.dp), modifier = Modifier.width(168.dp),
thumbnail = LargeBookThumbnailUio( thumbnail = preview,
id = 0, onClick = { },
isNew = true,
cover = "",
),
) )
} }
} }
@Composable private class LargeBookThumbnailPreviewProvider : PreviewParameterProvider<LargeBookThumbnailUio?> {
@Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_NO) override val values: Sequence<LargeBookThumbnailUio?> = sequenceOf(
@Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES) LargeBookThumbnailUio(
private fun LargeBookThumbnailEmptyPreview() { id = 0,
BibLibTheme { isNew = true,
LargeBookThumbnail( cover = "",
modifier = Modifier.width(168.dp), ),
thumbnail = null, null
) )
}
} }

View file

@ -23,7 +23,6 @@ import androidx.constraintlayout.compose.Dimension
import com.pixelized.biblib.R import com.pixelized.biblib.R
import com.pixelized.biblib.ui.theme.BibLibTheme import com.pixelized.biblib.ui.theme.BibLibTheme
import com.pixelized.biblib.utils.extention.bibLib import com.pixelized.biblib.utils.extention.bibLib
import com.pixelized.biblib.utils.extention.default
import com.pixelized.biblib.utils.extention.modifier.drawDiagonalLabel import com.pixelized.biblib.utils.extention.modifier.drawDiagonalLabel
import com.pixelized.biblib.utils.extention.placeholder import com.pixelized.biblib.utils.extention.placeholder
import com.skydoves.landscapist.glide.GlideImage import com.skydoves.landscapist.glide.GlideImage
@ -43,7 +42,7 @@ data class SmallBookThumbnailUio(
fun SmallBookThumbnail( fun SmallBookThumbnail(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
thumbnail: SmallBookThumbnailUio?, thumbnail: SmallBookThumbnailUio?,
onClick: (SmallBookThumbnailUio) -> Unit = default<SmallBookThumbnailUio>(), onClick: (SmallBookThumbnailUio) -> Unit,
) { ) {
if (thumbnail != null) { if (thumbnail != null) {
SmallBookThumbnailContent( SmallBookThumbnailContent(
@ -62,7 +61,7 @@ fun SmallBookThumbnail(
private fun SmallBookThumbnailContent( private fun SmallBookThumbnailContent(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
thumbnail: SmallBookThumbnailUio, thumbnail: SmallBookThumbnailUio,
onClick: (SmallBookThumbnailUio) -> Unit = default<SmallBookThumbnailUio>(), onClick: (SmallBookThumbnailUio) -> Unit,
) { ) {
Card( Card(
modifier = modifier modifier = modifier
@ -248,13 +247,14 @@ private fun SmallBookThumbnailPreview() {
SmallBookThumbnail( SmallBookThumbnail(
thumbnail = SmallBookThumbnailUio( thumbnail = SmallBookThumbnailUio(
id = 0, id = 0,
genre = "Sci-Fi",
title = "Foundation", title = "Foundation",
genre = "Sci-Fi",
author = "Asimov", author = "Asimov",
date = "1951", date = "1951",
isNew = true, isNew = true,
cover = "", cover = "",
) ),
onClick = { },
) )
} }
} }
@ -266,6 +266,7 @@ private fun SmallBookThumbnailEmptyPreview() {
BibLibTheme { BibLibTheme {
SmallBookThumbnail( SmallBookThumbnail(
thumbnail = null, thumbnail = null,
onClick = { },
) )
} }
} }

View file

@ -13,10 +13,7 @@ import androidx.compose.material.Button
import androidx.compose.material.MaterialTheme import androidx.compose.material.MaterialTheme
import androidx.compose.material.RadioButton import androidx.compose.material.RadioButton
import androidx.compose.material.Text import androidx.compose.material.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.*
import androidx.compose.runtime.Immutable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.Stable
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
@ -52,8 +49,8 @@ fun DetailScreenSendOption(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
optionViewModel: BookOptionViewModel = hiltViewModel(), optionViewModel: BookOptionViewModel = hiltViewModel(),
emails: List<String>, emails: List<String>,
onHelp: (url: String) -> Unit = default<String>(), onHelp: (url: String) -> Unit,
onSend: (email: String, format: String) -> Unit = { _, _ -> }, onSend: (email: String, format: String) -> Unit,
) { ) {
LaunchedEffect(key1 = emails) { LaunchedEffect(key1 = emails) {
optionViewModel.updateEmails(amazonEmails = emails) optionViewModel.updateEmails(amazonEmails = emails)
@ -74,10 +71,10 @@ fun DetailScreenSendOption(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
emails: List<OptionUio>, emails: List<OptionUio>,
formats: List<OptionUio>, formats: List<OptionUio>,
onHelp: (url: String) -> Unit = default<String>(), onHelp: (url: String) -> Unit,
onEmail: (OptionUio) -> Unit = { }, onEmail: (OptionUio) -> Unit,
onFormat: (OptionUio) -> Unit = { }, onFormat: (OptionUio) -> Unit,
onSend: (email: String, format: String) -> Unit = { _, _ -> }, onSend: (email: String, format: String) -> Unit,
) { ) {
val amazonHelpUri = stringResource(R.string.detail_send_confirm_help_url) val amazonHelpUri = stringResource(R.string.detail_send_confirm_help_url)
@ -221,15 +218,29 @@ private fun rememberDescription(
@Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES) @Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES)
private fun DetailScreenEmailListPreview() { private fun DetailScreenEmailListPreview() {
BibLibTheme { BibLibTheme {
val emails by remember {
mutableStateOf(
listOf(
OptionUio("R.Giskard.Reventlov.Kindle@gmail.com", selected = true),
OptionUio("R.Daneel.Olivaw.Kindle@gmail.com"),
)
)
}
val formats by remember {
mutableStateOf(
listOf(
OptionUio(Format.EPUB.capitalize(), selected = true),
OptionUio(Format.MOBI.capitalize()),
)
)
}
DetailScreenSendOption( DetailScreenSendOption(
emails = listOf( emails = emails,
OptionUio("R.Giskard.Reventlov.Kindle@gmail.com", selected = true), formats = formats,
OptionUio("R.Daneel.Olivaw.Kindle@gmail.com"), onHelp = { },
), onEmail = { },
formats = listOf( onFormat = { },
OptionUio(Format.EPUB.capitalize(), selected = true), onSend = { _, _ -> },
OptionUio(Format.MOBI.capitalize()),
),
) )
} }
} }

View file

@ -1,27 +0,0 @@
package com.pixelized.biblib.utils.extention
import android.content.Context
import android.widget.Toast
import androidx.compose.runtime.Composable
import androidx.compose.ui.platform.LocalContext
fun Context.showToast(message: String, duration: Int = Toast.LENGTH_SHORT) =
Toast.makeText(this, message, duration).show()
fun Context.notImplemented() {
showToast("Not implemented yet")
}
@Deprecated("")
@Composable
fun default(): () -> Unit {
val context = LocalContext.current
return { context.notImplemented() }
}
@Deprecated("")
@Composable
fun <T> default(): (T) -> Unit {
val context = LocalContext.current
return { context.notImplemented() }
}

View file

@ -2,4 +2,4 @@ package com.pixelized.biblib.utils.extention
fun Int.toBoolean(): Boolean = this != 0 fun Int.toBoolean(): Boolean = this != 0
fun Int?.toBoolean(): Boolean? = if (this == null) null else this != 0 fun Int?.toBoolean(): Boolean? = this?.toBoolean()

View file

@ -1,14 +0,0 @@
package com.pixelized.biblib.utils.extention
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.paging.LoadState
import androidx.paging.compose.LazyPagingItems
val LazyPagingItems<*>.isLoading: Boolean
get() {
val isLoading by derivedStateOf {
loadState.refresh is LoadState.Loading || loadState.append is LoadState.Loading
}
return isLoading
}

View file

@ -1,15 +1,15 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules. // Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript { buildscript {
repositories { repositories {
google() google()
mavenCentral() mavenCentral()
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:7.4.2' classpath 'com.android.tools.build:gradle:7.4.2'
classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.8.10' classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.8.10'
classpath "com.google.dagger:hilt-android-gradle-plugin:2.43.2" classpath "com.google.dagger:hilt-android-gradle-plugin:2.43.2"
classpath 'com.google.gms:google-services:4.3.15'
classpath 'com.google.firebase:firebase-crashlytics-gradle:2.9.4'
} }
} }