feat: Groovy to Kotlin DSL

This commit is contained in:
Rajan Maurya 2024-01-31 09:23:13 -05:00 committed by Rajan Maurya
parent 21dc95fe9a
commit f3027c3aa6
47 changed files with 1391 additions and 441 deletions

47
.gitignore vendored
View File

@ -6,7 +6,46 @@
.DS_Store
/build
/captures
.idea/
app/src/main/res/raw/third_party_licenses
app/src/main/res/raw/third_party_license_metadata
app/release/
.externalNativeBuild
.idea
/*.iml
# files for the dex VM
*.dex
# Java class files
*.class
# generated files
bin/
gen/
out/
build/
# Eclipse project files
.classpath
.project
# Windows thumbnail db
.DS_Store
# IDEA/Android Studio project files, because
# the project can be imported from settings.gradle.kts
*.iml
.idea/*
!.idea/copyright
# Keep the code styles.
!/.idea/codeStyles
/.idea/codeStyles/*
!/.idea/codeStyles/Project.xml
!/.idea/codeStyles/codeStyleConfig.xml
# Gradle cache
.gradle
# Android Studio captures folder
captures/
/app/app-release.apk
app/app.iml
app/manifest-merger-release-report.txt

View File

@ -1,210 +0,0 @@
apply plugin: 'com.android.application'
apply plugin: 'com.google.firebase.crashlytics'
apply plugin: 'com.google.android.gms.oss-licenses-plugin'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-parcelize'
apply plugin: 'kotlin-kapt'
apply plugin: 'com.google.dagger.hilt.android'
apply from: '../config/quality/quality.gradle'
android {
compileSdkVersion rootProject.ext.compileSdkVersion
defaultConfig {
applicationId "org.mifos.mobile"
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 1
versionName "1.0"
// A test runner provided by https://code.google.com/p/android-test-kit/
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables.useSupportLibrary = true
ndk {
abiFilters "armeabi-v7a", "x86", "x86_64", "arm64-v8a"
}
multiDexEnabled true
}
signingConfigs {
release {
storeFile file("../default_key_store.jks")
storePassword "mifos1234"
keyAlias "mifos-mobile"
keyPassword "mifos1234"
}
}
buildTypes {
release {
minifyEnabled false
signingConfig signingConfigs.release
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
sourceSets {
def commonTestDir = 'src/commonTest/java'
main {
java.srcDir commonTestDir
}
androidTest {
java.srcDir commonTestDir
}
test {
java.srcDir commonTestDir
}
}
compileOptions {
incremental = false
coreLibraryDesugaringEnabled true
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = "1.8"
}
lintOptions {
abortOnError false
disable 'InvalidPackage'
}
buildFeatures {
compose true
}
composeOptions {
kotlinCompilerExtensionVersion "1.4.4"
}
buildFeatures {
viewBinding = true
}
kapt {
correctErrorTypes = true
}
}
dependencies {
implementation project(':ui')
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation "androidx.lifecycle:lifecycle-extensions:$rootProject.lifecycleExtensionsVersion"
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$rootProject.lifecycleVersion"
kapt "com.github.Raizlabs.DBFlow:dbflow-processor:$rootProject.dbflowVersion"
implementation "com.github.Raizlabs.DBFlow:dbflow-core:$rootProject.dbflowVersion"
implementation "com.github.Raizlabs.DBFlow:dbflow:$rootProject.dbflowVersion"
implementation "androidx.appcompat:appcompat:$rootProject.supportLibraryVersion"
implementation "com.google.android.material:material:$rootProject.designLibraryVersion"
implementation "androidx.preference:preference:1.0.0"
implementation "com.google.android.gms:play-services-maps:$rootProject.playServicesVersion"
implementation "com.google.firebase:firebase-messaging:$rootProject.firebaseMessagingVersion"
implementation "androidx.recyclerview:recyclerview:$rootProject.recyclerViewVersion"
implementation "androidx.vectordrawable:vectordrawable:$rootProject.vectorDrawablesVersion"
implementation "com.google.android.gms:play-services-oss-licenses:$rootProject.oss_licenses"
implementation "com.isseiaoki:simplecropview:$rootProject.cropviewVersion"
implementation "androidx.activity:activity-ktx:$activity_version"
implementation "androidx.fragment:fragment-ktx:$fragment_version"
//Country Code picker
implementation "com.hbb20:ccp:$rootProject.countryCodePicker"
implementation 'com.github.ParveshSandila:CountryCodeChooser:1.0'
//Square dependencies
implementation("com.squareup.retrofit2:retrofit:$rootProject.retrofitVersion") {
// exclude Retrofits OkHttp peer-dependency module and define your own module import
exclude module: 'okhttp'
}
implementation "com.squareup.retrofit2:converter-gson:$rootProject.retrofitVersion"
implementation "com.squareup.retrofit2:adapter-rxjava2:$rootProject.retrofitVersion"
implementation "com.squareup.okhttp3:okhttp:$rootProject.okHttp3Version"
implementation "com.squareup.okhttp3:logging-interceptor:$rootProject.okHttp3Version"
//rxjava Dependencies
implementation "io.reactivex.rxjava2:rxandroid:$rootProject.rxandroidVersion"
implementation "io.reactivex.rxjava2:rxjava:$rootProject.rxjavaVersion"
//Butter Knife
implementation "com.jakewharton:butterknife:$butterKnifeVersion"
kapt "com.jakewharton:butterknife-compiler:$butterKnifeVersion"
// Firebase Crashlytics dependency
implementation "com.google.firebase:firebase-crashlytics:$firebaseCrashlyticsVersion"
//Annotation library
implementation "androidx.annotation:annotation:$rootProject.annotationLibraryVersion"
//qr code
implementation "com.google.zxing:core:$rootProject.zxingcoreVersion"
implementation "me.dm7.barcodescanner:zxing:$rootProject.zxingbarcodescannerVersion"
//sweet error dependency
implementation "com.github.therajanmaurya:Sweet-Error:$rootProject.sweeterrorVersion"
//mifos passcode
implementation "com.mifos.mobile:mifos-passcode:$mifosPasscodeVersion"
//multidex
implementation "androidx.multidex:multidex:$rootProject.multiDexVersion"
//TableView
implementation "com.evrencoskun.library:tableview:$rootProject.tableViewVersion"
//Biometric Authentication
implementation "androidx.biometric:biometric:$rootProject.biometric"
// Coroutines
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$rootProject.coroutines"
testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:$rootProject.coroutinesTest"
// Unit tests dependencies
testImplementation "junit:junit:$rootProject.jUnitVersion"
testImplementation "org.mockito:mockito-core:$rootProject.mockitoVersion"
implementation "org.mockito:mockito-core:$rootProject.mockitoVersion"
implementation "org.mockito:mockito-android:$rootProject.mockitoVersion"
androidTestImplementation "junit:junit:$rootProject.jUnitVersion"
androidTestImplementation "org.mockito:mockito-core:$rootProject.mockitoVersion"
androidTestImplementation "org.mockito:mockito-android:$rootProject.mockitoVersion"
androidTestImplementation "androidx.annotation:annotation:1.0.0"
implementation "androidx.arch.core:core-testing:$rootProject.archCoreVersion"
androidTestImplementation("androidx.test.espresso:espresso-contrib:$rootProject.espressoVersion") {
exclude group: 'com.android.support', module: 'appcompat'
exclude group: 'com.android.support', module: 'support-v4'
exclude group: 'com.android.support', module: 'recyclerview-v7'
exclude group: 'com.android.support', module: 'design'
exclude group: 'com.android.support', module: 'support-annotations'
}
androidTestImplementation "androidx.test.espresso:espresso-core:$rootProject.espressoVersion"
androidTestImplementation "androidx.test:runner:$rootProject.runnerVersion"
androidTestImplementation "androidx.test:rules:$rootProject.rulesVersion"
implementation 'com.github.rahul-gill.mifos-ui-library:uihouse:alpha-2.1'
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5'
// Hilt
implementation("com.google.dagger:hilt-android:2.48")
kapt("com.google.dagger:hilt-android-compiler:2.47")
// Compose BOM
implementation platform('androidx.compose:compose-bom:2023.08.00')
// Jetpack Compose
implementation "androidx.compose.material:material:$rootProject.composeVersion"
implementation "androidx.compose.compiler:compiler:$rootProject.composeCompiler"
implementation "androidx.compose.ui:ui-tooling-preview:$rootProject.composeVersion"
implementation "androidx.activity:activity-compose:$rootProject.composeActivity"
debugImplementation "androidx.compose.ui:ui-tooling:$rootProject.composeVersion"
implementation "androidx.compose.material3:material3:$rootProject.materialVersion"
implementation "androidx.lifecycle:lifecycle-viewmodel-compose:$rootProject.lifecycleVersion"
implementation "androidx.compose.material:material-icons-extended:$rootProject.composeVersion"
}
apply plugin: 'com.google.gms.google-services'

174
app/build.gradle.kts Normal file
View File

@ -0,0 +1,174 @@
plugins {
alias(libs.plugins.mifos.android.application)
alias(libs.plugins.mifos.android.application.compose)
alias(libs.plugins.mifos.android.hilt)
alias(libs.plugins.mifos.android.application.firebase)
id("com.google.android.gms.oss-licenses-plugin")
id("kotlin-parcelize")
alias(libs.plugins.roborazzi)
}
apply(from = "../config/quality/quality.gradle")
android {
namespace = "org.mifos.mobile"
defaultConfig {
applicationId = "org.mifos.mobile"
versionCode = 1
versionName = "1.0"
vectorDrawables.useSupportLibrary = true
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
ndk {
abiFilters.addAll(arrayOf("armeabi-v7a", "x86", "x86_64", "arm64-v8a"))
}
multiDexEnabled = true
}
signingConfigs {
create("release") {
storeFile = file("../default_key_store.jks")
storePassword = "mifos1234"
keyAlias = "mifos-mobile"
keyPassword = "mifos1234"
}
}
buildTypes {
release {
isMinifyEnabled = false
isDebuggable = false
signingConfig = signingConfigs.getByName("release")
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
}
}
sourceSets {
val commonTestDir = "src/commonTest/java"
getByName("main"){
java.srcDir(commonTestDir)
}
getByName("androidTest"){
java.srcDir(commonTestDir)
}
getByName("test"){
java.srcDir(commonTestDir)
}
}
buildFeatures {
dataBinding = true
viewBinding = true
compose = true
buildConfig = true
}
lint {
abortOnError = false
disable.add("InvalidPackage")
}
}
dependencies {
implementation(projects.ui)
implementation("androidx.legacy:legacy-support-v4:1.0.0")
implementation(libs.androidx.lifecycle.ktx)
implementation(libs.androidx.lifecycle.extensions)
implementation(libs.androidx.appcompat)
implementation(libs.material)
implementation(libs.androidx.preference)
implementation(libs.play.services.maps)
// DBFlow
implementation(libs.dbflow)
kapt(libs.dbflow.processor)
implementation(libs.dbflow.core)
implementation("androidx.recyclerview:recyclerview:1.2.1")
implementation("androidx.vectordrawable:vectordrawable:1.1.0")
implementation(libs.google.oss.licenses)
implementation("com.isseiaoki:simplecropview:1.1.8")
implementation(libs.androidx.activity.ktx)
implementation(libs.androidx.fragment.ktx)
//Country Code picker
implementation("com.hbb20:ccp:2.7.2")
implementation("com.github.ParveshSandila:CountryCodeChooser:1.0")
//Square dependencies
implementation(libs.squareup.retrofit2) {
// exclude Retrofits OkHttp peer-dependency module and define your own module import
exclude(module = "okhttp")
}
implementation(libs.squareup.retrofit.adapter.rxjava)
implementation(libs.squareup.retrofit.converter.gson)
implementation(libs.squareup.okhttp)
implementation(libs.squareup.logging.interceptor)
//rxjava Dependencies
implementation(libs.reactivex.rxjava2.android)
implementation(libs.reactivex.rxjava2)
//Butter Knife
implementation(libs.jakewharton.butterknife)
implementation(libs.jakewharton.compiler)
//Annotation library
implementation("androidx.annotation:annotation:1.1.0")
//qr code
implementation("com.google.zxing:core:3.5.2")
implementation("me.dm7.barcodescanner:zxing:1.9.13")
//sweet error dependency
implementation("com.github.therajanmaurya:Sweet-Error:1.0.0")
//mifos passcode
implementation("com.mifos.mobile:mifos-passcode:1.0.0")
//multidex
implementation("androidx.multidex:multidex:2.0.1")
//TableView
implementation("com.evrencoskun.library:tableview:0.8.9.4")
//Biometric Authentication
implementation("androidx.biometric:biometric:1.1.0")
// Coroutines
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4")
testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.7.3")
// Unit tests dependencies
testImplementation(libs.junit)
testImplementation("org.mockito:mockito-core:5.4.0")
implementation("org.mockito:mockito-core:5.4.0")
implementation("org.mockito:mockito-android:5.4.0")
androidTestImplementation((libs.junit))
androidTestImplementation("org.mockito:mockito-core:5.4.0")
androidTestImplementation("org.mockito:mockito-android:5.4.0")
androidTestImplementation("androidx.annotation:annotation:1.0.0")
implementation("androidx.arch.core:core-testing:2.2.0")
androidTestImplementation("androidx.test.espresso:espresso-contrib:3.5.1") {
}
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
androidTestImplementation("androidx.test:runner:1.6.0-alpha04")
androidTestImplementation("androidx.test:rules:1.6.0-alpha01")
implementation("com.github.rahul-gill.mifos-ui-library:uihouse:alpha-2.1")
// Jetpack Compose
api(libs.androidx.activity.compose)
api(libs.androidx.compose.material3)
api(libs.androidx.compose.foundation)
api(libs.androidx.compose.foundation.layout)
api(libs.androidx.compose.material.iconsExtended)
api(libs.androidx.compose.runtime)
api(libs.androidx.compose.ui.tooling.preview)
api(libs.androidx.compose.ui.util)
debugApi(libs.androidx.compose.ui.tooling)
}

View File

@ -2,7 +2,7 @@
# By default, the flags in this file are appended to flags specified
# in /Users/ishan/Library/Android/sdk/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
# directive in build.gradle.kts.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html

View File

@ -20,10 +20,10 @@ class SelfServiceInterceptor(private val preferencesHelper: PreferencesHelper) :
override fun intercept(chain: Interceptor.Chain): Response {
val chainRequest = chain.request()
val builder = chainRequest.newBuilder()
.header(HEADER_TENANT, preferencesHelper.tenant)
.header(HEADER_TENANT, preferencesHelper.tenant!!)
.header(CONTENT_TYPE, "application/json")
if (!TextUtils.isEmpty(preferencesHelper.token)) {
builder.header(HEADER_AUTH, preferencesHelper.token)
builder.header(HEADER_AUTH, preferencesHelper.token!!)
}
val request = builder.build()
return chain.proceed(request)

View File

@ -3,16 +3,13 @@ package org.mifos.mobile.ui.about
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material3.*
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import org.mifos.mobile.core.ui.component.AboutUsItemCard
import org.mifos.mobile.core.ui.component.MifosItemCard
import org.mifos.mobile.ui.enums.AboutUsListItemId
import java.util.*
@Composable
fun AboutUsScreen(viewModel: AboutUsViewModel) {

View File

@ -437,8 +437,7 @@ class HomeActivity :
val resultCode = apiAvailability.isGooglePlayServicesAvailable(this)
if (resultCode != ConnectionResult.SUCCESS) {
if (apiAvailability.isUserResolvableError(resultCode)) {
apiAvailability.getErrorDialog(this, resultCode, PLAY_SERVICES_RESOLUTION_REQUEST)
.show()
apiAvailability.getErrorDialog(this, resultCode, PLAY_SERVICES_RESOLUTION_REQUEST)?.show()
} else {
Log.i(HomeActivity::class.java.name, "This device is not supported.")
finish()

View File

@ -31,6 +31,7 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.input.pointer.pointerInput
@ -46,6 +47,7 @@ import org.mifos.mobile.R
import org.mifos.mobile.core.ui.component.MifosMobileIcon
import org.mifos.mobile.core.ui.component.MifosOutlinedTextField
@OptIn(ExperimentalComposeUiApi::class)
@Composable
fun LoginScreen(
login: (username: String, password: String) -> Unit,

View File

@ -29,6 +29,7 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.input.pointer.pointerInput
@ -49,6 +50,7 @@ import org.mifos.mobile.core.ui.component.MifosOutlinedTextField
* @since 28/12/2023
*/
@OptIn(ExperimentalComposeUiApi::class)
@Composable
fun RegistrationScreen(
register: (accountNumber: String, username: String, firstName: String, lastName: String, phoneNumber: String, email: String, password: String, authMode: String, countryCode: String) -> Unit,

View File

@ -11,7 +11,7 @@ import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.Divider
import androidx.compose.material3.Divider
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color

View File

@ -20,12 +20,12 @@ import android.content.Intent
import android.util.Log
import androidx.localbroadcastmanager.content.LocalBroadcastManager
import com.google.android.gms.tasks.OnCompleteListener
import com.google.firebase.iid.FirebaseInstanceId
import com.google.firebase.messaging.FirebaseMessaging
import org.mifos.mobile.utils.Constants
class RegistrationIntentService : IntentService(TAG) {
override fun onHandleIntent(intent: Intent?) {
FirebaseInstanceId.getInstance().instanceId
FirebaseMessaging.getInstance().token
.addOnCompleteListener(
OnCompleteListener { task ->
if (!task.isSuccessful) {
@ -34,7 +34,7 @@ class RegistrationIntentService : IntentService(TAG) {
}
// Get new Instance ID token
val token = task.result?.token
val token = task.result
sendRegistrationToServer(token)
},
)

38
build-logic/README.md Normal file
View File

@ -0,0 +1,38 @@
# Convention Plugins
The `build-logic` folder defines project-specific convention plugins, used to keep a single
source of truth for common module configurations.
This approach is heavily based on
[https://developer.squareup.com/blog/herding-elephants/](https://developer.squareup.com/blog/herding-elephants/)
and
[https://github.com/jjohannes/idiomatic-gradle](https://github.com/jjohannes/idiomatic-gradle).
By setting up convention plugins in `build-logic`, we can avoid duplicated build script setup,
messy `subproject` configurations, without the pitfalls of the `buildSrc` directory.
`build-logic` is an included build, as configured in the root
[`settings.gradle.kts`](../settings.gradle.kts).
Inside `build-logic` is a `convention` module, which defines a set of plugins that all normal
modules can use to configure themselves.
`build-logic` also includes a set of `Kotlin` files used to share logic between plugins themselves,
which is most useful for configuring Android components (libraries vs applications) with shared
code.
These plugins are *additive* and *composable*, and try to only accomplish a single responsibility.
Modules can then pick and choose the configurations they need.
If there is one-off logic for a module without shared code, it's preferable to define that directly
in the module's `build.gradle`, as opposed to creating a convention plugin with module-specific
setup.
Current list of convention plugins:
- [`mifos.android.application`](convention/src/main/kotlin/AndroidApplicationConventionPlugin.kt),
[`mifos.android.library`](convention/src/main/kotlin/AndroidLibraryConventionPlugin.kt),
[`mifos.android.test`](convention/src/main/kotlin/AndroidTestConventionPlugin.kt):
Configures common Android and Kotlin options.
- [`mifos.android.application.compose`](convention/src/main/kotlin/AndroidApplicationComposeConventionPlugin.kt),
[`mifos.android.library.compose`](convention/src/main/kotlin/AndroidLibraryComposeConventionPlugin.kt):
Configures Jetpack Compose options

View File

@ -0,0 +1,86 @@
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
`kotlin-dsl`
}
group = "org.mifos.mobile.buildlogic"
// Configure the build-logic plugins to target JDK 17
// This matches the JDK used to build the project, and is not related to what is running on device.
java {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
tasks.withType<KotlinCompile>().configureEach {
kotlinOptions {
jvmTarget = JavaVersion.VERSION_17.toString()
}
}
dependencies {
compileOnly(libs.android.gradlePlugin)
compileOnly(libs.android.tools.common)
compileOnly(libs.firebase.crashlytics.gradlePlugin)
compileOnly(libs.firebase.performance.gradlePlugin)
compileOnly(libs.kotlin.gradlePlugin)
compileOnly(libs.ksp.gradlePlugin)
compileOnly(libs.room.gradlePlugin)
implementation(libs.truth)
}
tasks {
validatePlugins {
enableStricterValidation = true
failOnWarning = true
}
}
gradlePlugin {
plugins {
register("androidApplicationCompose") {
id = "mifos.android.application.compose"
implementationClass = "AndroidApplicationComposeConventionPlugin"
}
register("androidApplication") {
id = "mifos.android.application"
implementationClass = "AndroidApplicationConventionPlugin"
}
register("androidHilt") {
id = "mifos.android.hilt"
implementationClass = "AndroidHiltConventionPlugin"
}
register("androidLibraryCompose") {
id = "mifos.android.library.compose"
implementationClass = "AndroidLibraryComposeConventionPlugin"
}
register("androidLibrary") {
id = "mifos.android.library"
implementationClass = "AndroidLibraryConventionPlugin"
}
register("androidFeature") {
id = "mifos.android.feature"
implementationClass = "AndroidFeatureConventionPlugin"
}
register("androidTest") {
id = "mifos.android.test"
implementationClass = "AndroidTestConventionPlugin"
}
register("androidRoom") {
id = "mifos.android.room"
implementationClass = "AndroidRoomConventionPlugin"
}
register("androidFirebase") {
id = "mifos.android.application.firebase"
implementationClass = "AndroidApplicationFirebaseConventionPlugin"
}
register("androidLint") {
id = "mifos.android.lint"
implementationClass = "AndroidLintConventionPlugin"
}
register("jvmLibrary") {
id = "mifos.jvm.library"
implementationClass = "JvmLibraryConventionPlugin"
}
}
}

View File

@ -0,0 +1,16 @@
import com.android.build.api.dsl.ApplicationExtension
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.kotlin.dsl.getByType
import org.mifos.mobile.configureAndroidCompose
class AndroidApplicationComposeConventionPlugin : Plugin<Project> {
override fun apply(target: Project) {
with(target) {
pluginManager.apply("com.android.application")
val extension = extensions.getByType<ApplicationExtension>()
configureAndroidCompose(extension)
}
}
}

View File

@ -0,0 +1,32 @@
import com.android.build.api.dsl.ApplicationExtension
import com.android.build.api.variant.ApplicationAndroidComponentsExtension
import com.android.build.gradle.BaseExtension
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.kotlin.dsl.configure
import org.gradle.kotlin.dsl.getByType
import org.mifos.mobile.configureBadgingTasks
import org.mifos.mobile.configureKotlinAndroid
import org.mifos.mobile.configurePrintApksTask
class AndroidApplicationConventionPlugin : Plugin<Project> {
override fun apply(target: Project) {
with(target) {
with(pluginManager) {
apply("com.android.application")
apply("org.jetbrains.kotlin.android")
apply("mifos.android.lint")
apply("com.dropbox.dependency-guard")
}
extensions.configure<ApplicationExtension> {
configureKotlinAndroid(this)
defaultConfig.targetSdk = 34
}
extensions.configure<ApplicationAndroidComponentsExtension> {
configurePrintApksTask(this)
configureBadgingTasks(extensions.getByType<BaseExtension>(), this)
}
}
}
}

View File

@ -0,0 +1,39 @@
import com.android.build.api.dsl.ApplicationExtension
import com.google.firebase.crashlytics.buildtools.gradle.CrashlyticsExtension
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.kotlin.dsl.configure
import org.gradle.kotlin.dsl.dependencies
import org.mifos.mobile.libs
class AndroidApplicationFirebaseConventionPlugin : Plugin<Project> {
override fun apply(target: Project) {
with(target) {
with(pluginManager) {
apply("com.google.gms.google-services")
apply("com.google.firebase.firebase-perf")
apply("com.google.firebase.crashlytics")
}
dependencies {
val bom = libs.findLibrary("firebase-bom").get()
add("implementation", platform(bom))
"implementation"(libs.findLibrary("firebase.analytics").get())
"implementation"(libs.findLibrary("firebase.performance").get())
"implementation"(libs.findLibrary("firebase.crashlytics").get())
"implementation"(libs.findLibrary("firebase.cloud.messaging").get())
}
extensions.configure<ApplicationExtension> {
buildTypes.configureEach {
// Disable the Crashlytics mapping file upload. This feature should only be
// enabled if a Firebase backend is available and configured in
// google-services.json.
configure<CrashlyticsExtension> {
mappingFileUploadEnabled = false
}
}
}
}
}
}

View File

@ -0,0 +1,32 @@
import com.android.build.gradle.LibraryExtension
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.kotlin.dsl.configure
import org.gradle.kotlin.dsl.dependencies
import org.mifos.mobile.libs
class AndroidFeatureConventionPlugin : Plugin<Project> {
override fun apply(target: Project) {
with(target) {
pluginManager.apply {
apply("mifos.android.library")
apply("mifos.android.hilt")
}
extensions.configure<LibraryExtension> {
defaultConfig {
// set custom test runner
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
}
dependencies {
add("implementation", project(":ui"))
//add("implementation", project(":core:designsystem"))
add("implementation", libs.findLibrary("androidx.hilt.navigation.compose").get())
add("implementation", libs.findLibrary("androidx.lifecycle.runtimeCompose").get())
add("implementation", libs.findLibrary("androidx.lifecycle.viewModelCompose").get())
}
}
}
}

View File

@ -0,0 +1,25 @@
import org.mifos.mobile.libs
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.kotlin.dsl.dependencies
class AndroidHiltConventionPlugin : Plugin<Project> {
override fun apply(target: Project) {
with(target) {
with(pluginManager) {
apply("dagger.hilt.android.plugin")
// KAPT must go last to avoid build warnings.
// See: https://stackoverflow.com/questions/70550883/warning-the-following-options-were-not-recognized-by-any-processor-dagger-f
apply("org.jetbrains.kotlin.kapt")
}
dependencies {
"implementation"(libs.findLibrary("hilt.android").get())
"kapt"(libs.findLibrary("hilt.compiler").get())
"kaptAndroidTest"(libs.findLibrary("hilt.compiler").get())
"kaptTest"(libs.findLibrary("hilt.compiler").get())
}
}
}
}

View File

@ -0,0 +1,17 @@
import com.android.build.gradle.LibraryExtension
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.kotlin.dsl.getByType
import org.mifos.mobile.configureAndroidCompose
class AndroidLibraryComposeConventionPlugin : Plugin<Project> {
override fun apply(target: Project) {
with(target) {
pluginManager.apply("com.android.library")
val extension = extensions.getByType<LibraryExtension>()
configureAndroidCompose(extension)
}
}
}

View File

@ -0,0 +1,37 @@
import com.android.build.api.variant.LibraryAndroidComponentsExtension
import com.android.build.gradle.LibraryExtension
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.kotlin.dsl.configure
import org.gradle.kotlin.dsl.dependencies
import org.gradle.kotlin.dsl.kotlin
import org.mifos.mobile.configureKotlinAndroid
import org.mifos.mobile.configurePrintApksTask
import org.mifos.mobile.disableUnnecessaryAndroidTests
class AndroidLibraryConventionPlugin : Plugin<Project> {
override fun apply(target: Project) {
with(target) {
with(pluginManager) {
apply("com.android.library")
apply("org.jetbrains.kotlin.android")
apply("mifos.android.lint")
}
extensions.configure<LibraryExtension> {
configureKotlinAndroid(this)
defaultConfig.targetSdk = 34
// The resource prefix is derived from the module name,
// so resources inside ":core:module1" must be prefixed with "core_module1_"
resourcePrefix = path.split("""\W""".toRegex()).drop(1).distinct().joinToString(separator = "_").lowercase() + "_"
}
extensions.configure<LibraryAndroidComponentsExtension> {
configurePrintApksTask(this)
disableUnnecessaryAndroidTests(target)
}
dependencies {
add("testImplementation", kotlin("test"))
}
}
}
}

View File

@ -0,0 +1,30 @@
import com.android.build.api.dsl.ApplicationExtension
import com.android.build.api.dsl.LibraryExtension
import com.android.build.api.dsl.Lint
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.kotlin.dsl.configure
class AndroidLintConventionPlugin : Plugin<Project> {
override fun apply(target: Project) {
with(target) {
when {
pluginManager.hasPlugin("com.android.application") ->
configure<ApplicationExtension> { lint(Lint::configure) }
pluginManager.hasPlugin("com.android.library") ->
configure<LibraryExtension> { lint(Lint::configure) }
else -> {
pluginManager.apply("com.android.lint")
configure<Lint>(Lint::configure)
}
}
}
}
}
private fun Lint.configure() {
xmlReport = true
checkDependencies = true
}

View File

@ -0,0 +1,29 @@
import androidx.room.gradle.RoomExtension
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.kotlin.dsl.configure
import org.gradle.kotlin.dsl.dependencies
import org.mifos.mobile.libs
class AndroidRoomConventionPlugin : Plugin<Project> {
override fun apply(target: Project) {
with(target) {
pluginManager.apply("androidx.room")
pluginManager.apply("com.google.devtools.ksp")
extensions.configure<RoomExtension> {
// The schemas directory contains a schema file for each version of the Room database.
// This is required to enable Room auto migrations.
// See https://developer.android.com/reference/kotlin/androidx/room/AutoMigration.
schemaDirectory("$projectDir/schemas")
}
dependencies {
add("implementation", libs.findLibrary("room.runtime").get())
add("implementation", libs.findLibrary("room.ktx").get())
add("ksp", libs.findLibrary("room.compiler").get())
}
}
}
}

View File

@ -0,0 +1,21 @@
import com.android.build.gradle.TestExtension
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.kotlin.dsl.configure
import org.mifos.mobile.configureKotlinAndroid
class AndroidTestConventionPlugin : Plugin<Project> {
override fun apply(target: Project) {
with(target) {
with(pluginManager) {
apply("com.android.test")
apply("org.jetbrains.kotlin.android")
}
extensions.configure<TestExtension> {
configureKotlinAndroid(this)
defaultConfig.targetSdk = 34
}
}
}
}

View File

@ -0,0 +1,15 @@
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.mifos.mobile.configureKotlinJvm
class JvmLibraryConventionPlugin : Plugin<Project> {
override fun apply(target: Project) {
with(target) {
with(pluginManager) {
apply("org.jetbrains.kotlin.jvm")
apply("mifos.android.lint")
}
configureKotlinJvm()
}
}
}

View File

@ -0,0 +1,69 @@
package org.mifos.mobile
import com.android.build.api.dsl.CommonExtension
import org.gradle.api.Project
import org.gradle.kotlin.dsl.dependencies
import org.gradle.kotlin.dsl.withType
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
/**
* Configure Compose-specific options
*/
internal fun Project.configureAndroidCompose(
commonExtension: CommonExtension<*, *, *, *, *>,
) {
commonExtension.apply {
buildFeatures {
compose = true
}
composeOptions {
kotlinCompilerExtensionVersion = libs.findVersion("androidxComposeCompiler").get().toString()
}
dependencies {
val bom = libs.findLibrary("androidx-compose-bom").get()
add("implementation", platform(bom))
add("androidTestImplementation", platform(bom))
}
testOptions {
unitTests {
// For Robolectric
isIncludeAndroidResources = true
}
}
}
tasks.withType<KotlinCompile>().configureEach {
kotlinOptions {
freeCompilerArgs = freeCompilerArgs + buildComposeMetricsParameters()
}
}
}
private fun Project.buildComposeMetricsParameters(): List<String> {
val metricParameters = mutableListOf<String>()
val enableMetricsProvider = project.providers.gradleProperty("enableComposeCompilerMetrics")
val relativePath = projectDir.relativeTo(rootDir)
val buildDir = layout.buildDirectory.get().asFile
val enableMetrics = (enableMetricsProvider.orNull == "true")
if (enableMetrics) {
val metricsFolder = buildDir.resolve("compose-metrics").resolve(relativePath)
metricParameters.add("-P")
metricParameters.add(
"plugin:androidx.compose.compiler.plugins.kotlin:metricsDestination=" + metricsFolder.absolutePath
)
}
val enableReportsProvider = project.providers.gradleProperty("enableComposeCompilerReports")
val enableReports = (enableReportsProvider.orNull == "true")
if (enableReports) {
val reportsFolder = buildDir.resolve("compose-reports").resolve(relativePath)
metricParameters.add("-P")
metricParameters.add(
"plugin:androidx.compose.compiler.plugins.kotlin:reportsDestination=" + reportsFolder.absolutePath
)
}
return metricParameters.toList()
}

View File

@ -0,0 +1,19 @@
package org.mifos.mobile
import com.android.build.api.variant.LibraryAndroidComponentsExtension
import org.gradle.api.Project
/**
* Disable unnecessary Android instrumented tests for the [project] if there is no `androidTest` folder.
* Otherwise, these projects would be compiled, packaged, installed and ran only to end-up with the following message:
*
* > Starting 0 tests on AVD
*
* Note: this could be improved by checking other potential sourceSets based on buildTypes and flavors.
*/
internal fun LibraryAndroidComponentsExtension.disableUnnecessaryAndroidTests(
project: Project,
) = beforeVariants {
it.enableAndroidTest = it.enableAndroidTest
&& project.projectDir.resolve("src/androidTest").exists()
}

View File

@ -0,0 +1,144 @@
package org.mifos.mobile
import com.android.build.api.artifact.SingleArtifact
import com.android.build.api.variant.ApplicationAndroidComponentsExtension
import com.android.build.gradle.BaseExtension
import com.android.SdkConstants
import com.google.common.truth.Truth.assertWithMessage
import org.gradle.api.DefaultTask
import org.gradle.api.Project
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.provider.Property
import org.gradle.api.tasks.CacheableTask
import org.gradle.api.tasks.Copy
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.InputFile
import org.gradle.api.tasks.OutputDirectory
import org.gradle.api.tasks.OutputFile
import org.gradle.api.tasks.PathSensitive
import org.gradle.api.tasks.PathSensitivity
import org.gradle.api.tasks.TaskAction
import org.gradle.configurationcache.extensions.capitalized
import org.gradle.kotlin.dsl.register
import org.gradle.language.base.plugins.LifecycleBasePlugin
import org.gradle.process.ExecOperations
import java.io.File
import javax.inject.Inject
@CacheableTask
abstract class GenerateBadgingTask : DefaultTask() {
@get:OutputFile
abstract val badging: RegularFileProperty
@get:PathSensitive(PathSensitivity.NONE)
@get:InputFile
abstract val apk: RegularFileProperty
@get:PathSensitive(PathSensitivity.NONE)
@get:InputFile
abstract val aapt2Executable: RegularFileProperty
@get:Inject
abstract val execOperations: ExecOperations
@TaskAction
fun taskAction() {
execOperations.exec {
commandLine(
aapt2Executable.get().asFile.absolutePath,
"dump",
"badging",
apk.get().asFile.absolutePath,
)
standardOutput = badging.asFile.get().outputStream()
}
}
}
@CacheableTask
abstract class CheckBadgingTask : DefaultTask() {
// In order for the task to be up-to-date when the inputs have not changed,
// the task must declare an output, even if it's not used. Tasks with no
// output are always run regardless of whether the inputs changed
@get:OutputDirectory
abstract val output: DirectoryProperty
@get:PathSensitive(PathSensitivity.NONE)
@get:InputFile
abstract val goldenBadging: RegularFileProperty
@get:PathSensitive(PathSensitivity.NONE)
@get:InputFile
abstract val generatedBadging: RegularFileProperty
@get:Input
abstract val updateBadgingTaskName: Property<String>
override fun getGroup(): String = LifecycleBasePlugin.VERIFICATION_GROUP
@TaskAction
fun taskAction() {
assertWithMessage(
"Generated badging is different from golden badging! " +
"If this change is intended, run ./gradlew ${updateBadgingTaskName.get()}",
)
.that(generatedBadging.get().asFile.readText())
.isEqualTo(goldenBadging.get().asFile.readText())
}
}
fun Project.configureBadgingTasks(
baseExtension: BaseExtension,
componentsExtension: ApplicationAndroidComponentsExtension,
) {
// Registers a callback to be called, when a new variant is configured
componentsExtension.onVariants { variant ->
// Registers a new task to verify the app bundle.
val capitalizedVariantName = variant.name.capitalized()
val generateBadgingTaskName = "generate${capitalizedVariantName}Badging"
val generateBadging =
tasks.register<GenerateBadgingTask>(generateBadgingTaskName) {
apk.set(
variant.artifacts.get(SingleArtifact.APK_FROM_BUNDLE),
)
aapt2Executable.set(
File(
baseExtension.sdkDirectory,
"${SdkConstants.FD_BUILD_TOOLS}/" +
"${baseExtension.buildToolsVersion}/" +
SdkConstants.FN_AAPT2,
),
)
badging.set(
project.layout.buildDirectory.file(
"outputs/apk_from_bundle/${variant.name}/${variant.name}-badging.txt",
),
)
}
val updateBadgingTaskName = "update${capitalizedVariantName}Badging"
tasks.register<Copy>(updateBadgingTaskName) {
from(generateBadging.get().badging)
into(project.layout.projectDirectory)
}
val checkBadgingTaskName = "check${capitalizedVariantName}Badging"
tasks.register<CheckBadgingTask>(checkBadgingTaskName) {
goldenBadging.set(
project.layout.projectDirectory.file("${variant.name}-badging.txt"),
)
generatedBadging.set(
generateBadging.get().badging,
)
this.updateBadgingTaskName.set(updateBadgingTaskName)
output.set(
project.layout.buildDirectory.dir("intermediates/$checkBadgingTaskName"),
)
}
}
}

View File

@ -0,0 +1,75 @@
package org.mifos.mobile
import com.android.build.api.dsl.CommonExtension
import org.gradle.api.JavaVersion
import org.gradle.api.Project
import org.gradle.api.plugins.JavaPluginExtension
import org.gradle.kotlin.dsl.configure
import org.gradle.kotlin.dsl.dependencies
import org.gradle.kotlin.dsl.provideDelegate
import org.gradle.kotlin.dsl.withType
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
/**
* Configure base Kotlin with Android options
*/
internal fun Project.configureKotlinAndroid(
commonExtension: CommonExtension<*, *, *, *, *>,
) {
commonExtension.apply {
compileSdk = 34
defaultConfig {
minSdk = 24
}
compileOptions {
// Up to Java 11 APIs are available through desugaring
// https://developer.android.com/studio/write/java11-minimal-support-table
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
isCoreLibraryDesugaringEnabled = true
}
}
configureKotlin()
dependencies {
add("coreLibraryDesugaring", libs.findLibrary("android.desugarJdkLibs").get())
}
}
/**
* Configure base Kotlin options for JVM (non-Android)
*/
internal fun Project.configureKotlinJvm() {
extensions.configure<JavaPluginExtension> {
// Up to Java 11 APIs are available through desugaring
// https://developer.android.com/studio/write/java11-minimal-support-table
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
configureKotlin()
}
/**
* Configure base Kotlin options
*/
private fun Project.configureKotlin() {
// Use withType to workaround https://youtrack.jetbrains.com/issue/KT-55947
tasks.withType<KotlinCompile>().configureEach {
kotlinOptions {
// Set JVM target to 11
jvmTarget = JavaVersion.VERSION_17.toString()
// Treat all Kotlin warnings as errors (disabled by default)
// Override by setting warningsAsErrors=true in your ~/.gradle/gradle.properties
val warningsAsErrors: String? by project
allWarningsAsErrors = warningsAsErrors.toBoolean()
freeCompilerArgs = freeCompilerArgs + listOf(
// Enable experimental coroutines APIs, including Flow
"-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi",
)
}
}
}

View File

@ -0,0 +1,87 @@
package org.mifos.mobile
import com.android.build.api.artifact.SingleArtifact
import com.android.build.api.variant.AndroidComponentsExtension
import com.android.build.api.variant.BuiltArtifactsLoader
import com.android.build.api.variant.HasAndroidTest
import org.gradle.api.DefaultTask
import org.gradle.api.Project
import org.gradle.api.file.Directory
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.provider.ListProperty
import org.gradle.api.provider.Property
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.InputDirectory
import org.gradle.api.tasks.InputFiles
import org.gradle.api.tasks.Internal
import org.gradle.api.tasks.PathSensitive
import org.gradle.api.tasks.PathSensitivity
import org.gradle.api.tasks.TaskAction
import org.gradle.work.DisableCachingByDefault
import java.io.File
internal fun Project.configurePrintApksTask(extension: AndroidComponentsExtension<*, *, *>) {
extension.onVariants { variant ->
if (variant is HasAndroidTest) {
val loader = variant.artifacts.getBuiltArtifactsLoader()
val artifact = variant.androidTest?.artifacts?.get(SingleArtifact.APK)
val javaSources = variant.androidTest?.sources?.java?.all
val kotlinSources = variant.androidTest?.sources?.kotlin?.all
val testSources = if (javaSources != null && kotlinSources != null) {
javaSources.zip(kotlinSources) { javaDirs, kotlinDirs ->
javaDirs + kotlinDirs
}
} else javaSources ?: kotlinSources
if (artifact != null && testSources != null) {
tasks.register(
"${variant.name}PrintTestApk",
PrintApkLocationTask::class.java
) {
apkFolder.set(artifact)
builtArtifactsLoader.set(loader)
variantName.set(variant.name)
sources.set(testSources)
}
}
}
}
}
@DisableCachingByDefault(because = "Prints output")
internal abstract class PrintApkLocationTask : DefaultTask() {
@get:PathSensitive(PathSensitivity.RELATIVE)
@get:InputDirectory
abstract val apkFolder: DirectoryProperty
@get:PathSensitive(PathSensitivity.RELATIVE)
@get:InputFiles
abstract val sources: ListProperty<Directory>
@get:Internal
abstract val builtArtifactsLoader: Property<BuiltArtifactsLoader>
@get:Input
abstract val variantName: Property<String>
@TaskAction
fun taskAction() {
val hasFiles = sources.orNull?.any { directory ->
directory.asFileTree.files.any {
it.isFile && "build${File.separator}generated" !in it.parentFile.path
}
} ?: throw RuntimeException("Cannot check androidTest sources")
// Don't print APK location if there are no androidTest source files
if (!hasFiles) return
val builtArtifacts = builtArtifactsLoader.get().load(apkFolder.get())
?: throw RuntimeException("Cannot load APKs")
if (builtArtifacts.elements.size != 1)
throw RuntimeException("Expected one APK !")
val apk = File(builtArtifacts.elements.single().outputFile).toPath()
println(apk)
}
}

View File

@ -0,0 +1,9 @@
package org.mifos.mobile
import org.gradle.api.Project
import org.gradle.api.artifacts.VersionCatalog
import org.gradle.api.artifacts.VersionCatalogsExtension
import org.gradle.kotlin.dsl.getByType
val Project.libs
get(): VersionCatalog = extensions.getByType<VersionCatalogsExtension>().named("libs")

View File

@ -0,0 +1,4 @@
# Gradle properties are not passed to included builds https://github.com/gradle/gradle/issues/2534
org.gradle.parallel=true
org.gradle.caching=true
org.gradle.configureondemand=true

View File

@ -0,0 +1,30 @@
/*
* Copyright 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
dependencyResolutionManagement {
repositories {
google()
mavenCentral()
}
versionCatalogs {
create("libs") {
from(files("../gradle/libs.versions.toml"))
}
}
}
rootProject.name = "build-logic"
include(":convention")

View File

@ -1,98 +0,0 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
google()
mavenCentral()
maven {
url "https://plugins.gradle.org/m2/"
}
jcenter()
}
ext {
gradleVersion = '7.2.0'
crashlyticsGradleVersion = '2.9.9'
ossLicensesVersion = '0.10.5'
googleServicesVersion = '4.3.15'
kotlinGradlePluginversion = '1.6.21'
}
dependencies {
classpath "com.android.tools.build:gradle:$gradleVersion"
classpath "com.google.firebase:firebase-crashlytics-gradle:$crashlyticsGradleVersion"
classpath 'com.google.android.gms:oss-licenses-plugin:0.10.6'
classpath "com.google.gms:google-services:$googleServicesVersion"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinGradlePluginversion"
classpath "com.github.spotbugs.snom:spotbugs-gradle-plugin:5.1.2"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
plugins {
id("com.google.dagger.hilt.android") version "2.48" apply false
id 'org.jetbrains.kotlin.android' version '1.8.10' apply false
}
allprojects {
repositories {
google()
jcenter()
mavenCentral()
maven { url "https://www.jitpack.io" }
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
ext {
// Sdk and tools
minSdkVersion = 24
targetSdkVersion = 34
compileSdkVersion = 34
// App dependencies
countryCodePicker = '2.7.2'
supportLibraryVersion = '1.4.2'
designLibraryVersion = '1.9.0'
recyclerViewVersion = '1.2.1'
vectorDrawablesVersion = '1.1.0'
lifecycleVersion = '2.4.1'
lifecycleExtensionsVersion = '2.2.0'
retrofitVersion = '2.9.0'
coroutinesTest = '1.7.3'
okHttp3Version = '3.14.9'
butterKnifeVersion = '8.0.1'
dbflowVersion = '4.2.4'
playServicesVersion = '17.0.1'
firebaseMessagingVersion = '21.1.0'
oss_licenses = '17.0.0'
kotlinVersion = '1.6.10'
tableViewVersion = '0.8.9.4'
biometric = '1.1.0'
archCoreVersion = '2.2.0'
coroutines = '1.6.4'
jUnitVersion = '4.13.2'
mockitoVersion = '5.4.0'
runnerVersion = '1.6.0-alpha04'
rulesVersion = '1.6.0-alpha01'
espressoVersion = '3.5.1'
zxingcoreVersion = '3.5.2'
zxingbarcodescannerVersion = '1.9.13'
rxjavaVersion = '2.2.21'
rxandroidVersion = '2.1.1'
sweeterrorVersion = '1.0.0'
mifosPasscodeVersion = '1.0.0'
cropviewVersion = '1.1.8'
multiDexVersion = '2.0.1'
annotationLibraryVersion ='1.1.0'
firebaseCrashlyticsVersion = '18.4.1'
activity_version = '1.5.0'
fragment_version = '1.5.0'
composeVersion = '1.6.0-alpha05'
composeCompiler = '1.3.2'
composeActivity = '1.7.2'
materialVersion = '1.1.0'
lifecycleVersion = '2.6.1'
}

32
build.gradle.kts Normal file
View File

@ -0,0 +1,32 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
google()
mavenCentral()
}
dependencies {
classpath(libs.google.oss.licenses.plugin) {
exclude(group = "com.google.protobuf")
}
}
}
plugins {
alias(libs.plugins.android.application) apply false
alias(libs.plugins.android.library) apply false
alias(libs.plugins.android.test) apply false
alias(libs.plugins.kotlin.jvm) apply false
alias(libs.plugins.kotlin.serialization) apply false
alias(libs.plugins.kotlin.parcelize) apply false
alias(libs.plugins.dependencyGuard) apply false
alias(libs.plugins.firebase.crashlytics) apply false
alias(libs.plugins.firebase.perf) apply false
alias(libs.plugins.gms) apply false
alias(libs.plugins.hilt) apply false
alias(libs.plugins.ksp) apply false
alias(libs.plugins.roborazzi) apply false
alias(libs.plugins.secrets) apply false
alias(libs.plugins.room) apply false
alias(libs.plugins.kotlin.android) apply false
alias(libs.plugins.spotbugs) apply false
}

View File

@ -32,7 +32,7 @@ task checkstyle(type: Checkstyle, group: 'Verification', description: 'Runs code
include '**/*.java'
reports {
xml.enabled = true
//xml.enabled = true
xml {
destination file("$reportsDir/checkstyle/checkstyle.xml")
}
@ -41,37 +41,36 @@ task checkstyle(type: Checkstyle, group: 'Verification', description: 'Runs code
classpath = files( )
}
tasks.matching {task -> task.name.startsWith('spotbugs')}.forEach {
check.dependsOn it
it.dependsOn(['compileDebugSources','compileReleaseSources'])
it.group('Verification')
it.description('Inspect java bytecode for bugs')
it.ignoreFailures = false
it.effort = "max"
it.reportLevel = "high"
it.excludeFilter = new File("$qualityConfigDir/findbugs/android-exclude-filter.xml")
it.classes = files("$project.rootDir/app/build/intermediates/javac")
it.source 'src'
it.include '**/*.java'
it.exclude '**/gen/**'
it.reports {
xml.enabled = false
html.enabled = true
xml {
destination file("$reportsDir/findbugs/findbugs.xml")
}
html {
destination file("$reportsDir/findbugs/findbugs.html")
}
}
it.classpath = files()
}
// TODO un comment after fixing the plugin
//tasks.matching {task -> task.name.startsWith('spotbugs')}.forEach {
// check.dependsOn it
// it.dependsOn(['compileDebugSources','compileReleaseSources'])
// it.group('Verification')
// it.description('Inspect java bytecode for bugs')
//
// it.ignoreFailures = false
// it.effort = "max"
// it.reportLevel = "high"
// it.excludeFilter = new File("$qualityConfigDir/findbugs/android-exclude-filter.xml")
// it.classes = files("$project.rootDir/app/build/intermediates/javac")
//
// it.source 'src'
// it.include '**/*.java'
// it.exclude '**/gen/**'
//
// it.reports {
// // xml.enabled = false
// // html.enabled = true
// xml {
// destination file("$reportsDir/findbugs/findbugs.xml")
// }
// html {
// destination file("$reportsDir/findbugs/findbugs.html")
// }
// }
//
// it.classpath = files()
//}
task pmd(type: Pmd, group: 'Verification', description: 'Inspect sourcecode for bugs') {
@ -84,8 +83,8 @@ task pmd(type: Pmd, group: 'Verification', description: 'Inspect sourcecode for
exclude '**/gen/**'
reports {
xml.enabled = true
html.enabled = true
// xml.enabled = true
// html.enabled = true
xml {
destination file("$reportsDir/pmd/pmd.xml")
}

View File

@ -9,20 +9,40 @@
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
# Default value: -Xmx10248m -XX:MaxPermSize=256m
# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
org.gradle.jvmargs=-Xmx6g -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 -XX:+UseParallelGC -XX:MaxMetaspaceSize=1g
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
org.gradle.parallel=true
# When set to true the Gradle daemon is used to run the build. For local developer builds this is our favorite property.
# The developer environment is optimized for speed and feedback so we nearly always run Gradle jobs with the daemon.
org.gradle.daemon=true
# Not encouraged by Gradle and can produce weird results. Wait for isolated projects instead.
org.gradle.configureondemand=false
# Enable caching between builds.
org.gradle.caching=true
# Enable configuration caching between builds.
org.gradle.configuration-cache=true
# This option is set because of https://github.com/google/play-services-plugins/issues/246
# to generate the Configuration Cache regardless of incompatible tasks.
# See https://github.com/android/nowinandroid/issues/1022 before using it.
org.gradle.configuration-cache.problems=warn
# AndroidX package structure to make it clearer which packages are bundled with the
# Android operating system, and which are packaged with your app"s APK
# https://developer.android.com/topic/libraries/support-library/androidx-rn
android.useAndroidX=true
android.enableJetifier=true
# Remove after jetpack compose implementation
android.enableJetifier=true
android.nonTransitiveRClass=false
android.nonFinalResIds=false
# Kotlin code style for this project: "official" or "obsolete":
kotlin.code.style=official
# Disable build features that are enabled by default,
# https://developer.android.com/build/releases/gradle-plugin#default-changes
android.defaults.buildfeatures.resvalues=false
android.defaults.buildfeatures.shaders=false

148
gradle/libs.versions.toml Normal file
View File

@ -0,0 +1,148 @@
[versions]
appcompatVersion = "1.6.1"
compileSdk = "34"
constraintlayoutVersion = "2.1.4"
coreKtxVersion = "1.12.0"
minSdk = "24"
targetSdk = "34"
androidGradlePlugin = "8.2.1"
androidTools = "31.2.1"
androidxActivity = "1.7.2"
androidxComposeBom = "2023.10.01"
androidxComposeCompiler = "1.5.8"
androidxCore = "1.10.1"
androidxHilt = "1.1.0-alpha01"
androidxLifecycle = "2.6.1"
hilt = "2.50"
junit = "4.13.2"
kotlin = "1.9.22"
ksp = "1.9.21-1.0.16"
firebaseCrashlyticsPlugin = "2.9.2"
gmsPlugin = "4.3.14"
butterknifePlugin = "10.2.3"
secrets = "2.0.1"
lifecycleVersion = "2.6.2"
lifecycleExtensionsVersion = "2.2.0"
activityVersion = "1.5.0"
fragmentVersion = "1.5.0"
retrofitVersion = "2.9.0"
okHttp3Version = "3.14.9"
butterKnifeVersion = "10.2.3"
rxandroidVersion = "2.1.1"
rxjavaVersion = "2.2.21"
junitVersion = "4.12"
firebasePerfPlugin = "1.4.2"
truth = "1.1.5"
dependencyGuard = "0.4.3"
room = "2.6.1"
roborazzi = "1.6.0"
googleOss = "17.0.1"
googleOssPlugin = "0.10.6"
firebaseBom = "32.7.1"
androidDesugarJdkLibs = "2.0.4"
androidx-test-ext-junit = "1.1.5"
espresso-core = "3.5.1"
material = "1.11.0"
dbflowVersion = "4.2.4"
preference = "1.0.0"
playServicesVersion = "17.0.1"
spotbugs = "4.8.0"
[libraries]
androidx-activity-ktx = { module = "androidx.activity:activity-ktx", version.ref = "activityVersion" }
androidx-appcompat = { module = "androidx.appcompat:appcompat", version.ref = "appcompatVersion" }
androidx-constraintlayout = { module = "androidx.constraintlayout:constraintlayout", version.ref = "constraintlayoutVersion" }
androidx-core-ktx = { module = "androidx.core:core-ktx", version.ref = "coreKtxVersion" }
androidx-fragment-ktx = { module = "androidx.fragment:fragment-ktx", version.ref = "fragmentVersion" }
android-desugarJdkLibs = { group = "com.android.tools", name = "desugar_jdk_libs", version.ref = "androidDesugarJdkLibs" }
androidx-compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "androidxComposeBom" }
androidx-activity-compose = { module = "androidx.activity:activity-compose", version.ref = "androidxActivity" }
androidx-compose-compiler = { module = "androidx.compose.compiler:compiler", version.ref = "androidxComposeCompiler" }
androidx-compose-foundation = { group = "androidx.compose.foundation", name = "foundation" }
androidx-compose-foundation-layout = { group = "androidx.compose.foundation", name = "foundation-layout" }
androidx-compose-material3 = { group = "androidx.compose.material3", name = "material3"}
androidx-compose-material-iconsExtended = { group = "androidx.compose.material", name = "material-icons-extended" }
androidx-compose-ui = { group = "androidx.compose.ui", name = "ui"}
androidx-compose-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4"}
androidx-compose-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest"}
androidx-compose-ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling"}
androidx-compose-runtime = { group = "androidx.compose.runtime", name = "runtime" }
hilt-android = { group = "com.google.dagger", name = "hilt-android", version.ref = "hilt" }
hilt-compiler = { group = "com.google.dagger", name = "hilt-android-compiler", version.ref = "hilt" }
androidx-compose-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-tooling-preview"}
androidx-compose-ui-util = { group = "androidx.compose.ui", name = "ui-util"}
androidx-hilt-navigation-compose = { module = "androidx.hilt:hilt-navigation-compose", version.ref = "androidxHilt" }
androidx-lifecycle-runtimeCompose = { group = "androidx.lifecycle", name = "lifecycle-runtime-compose", version.ref = "androidxLifecycle" }
androidx-lifecycle-viewModelCompose = { group = "androidx.lifecycle", name = "lifecycle-viewmodel-compose", version.ref = "androidxLifecycle" }
androidx-lifecycle-ktx = { module = "androidx.lifecycle:lifecycle-viewmodel-ktx", version.ref = "lifecycleVersion" }
androidx-lifecycle-extensions = { module = "androidx.lifecycle:lifecycle-extensions", version.ref = "lifecycleExtensionsVersion" }
jakewharton-butterknife = { module = "com.jakewharton:butterknife", version.ref = "butterKnifeVersion" }
jakewharton-compiler = { module = "com.jakewharton:butterknife-compiler", version.ref = "butterKnifeVersion" }
squareup-retrofit2 = { module = "com.squareup.retrofit2:retrofit", version.ref = "retrofitVersion" }
squareup-retrofit-adapter-rxjava = { module = "com.squareup.retrofit2:adapter-rxjava2", version.ref = "retrofitVersion" }
squareup-retrofit-converter-gson = { module = "com.squareup.retrofit2:converter-gson", version.ref = "retrofitVersion" }
squareup-okhttp = { module = "com.squareup.okhttp3:okhttp", version.ref = "okHttp3Version" }
squareup-logging-interceptor = { module = "com.squareup.okhttp3:logging-interceptor", version.ref = "okHttp3Version" }
reactivex-rxjava2-android = { module = "io.reactivex.rxjava2:rxandroid", version.ref = "rxandroidVersion" }
reactivex-rxjava2 = { module = "io.reactivex.rxjava2:rxjava", version.ref = "rxjavaVersion" }
truth = { group = "com.google.truth", name = "truth", version.ref = "truth" }
junit = { module = "junit:junit", version.ref = "junitVersion"}
google-oss-licenses = { group = "com.google.android.gms", name = "play-services-oss-licenses", version.ref = "googleOss" }
google-oss-licenses-plugin = { group = "com.google.android.gms", name = "oss-licenses-plugin", version.ref = "googleOssPlugin" }
jetbrains-kotlin-jdk7 = { module = "org.jetbrains.kotlin:kotlin-stdlib-jdk7", version.ref = "kotlin" }
firebase-bom = { group = "com.google.firebase", name = "firebase-bom", version.ref = "firebaseBom" }
firebase-analytics = { group = "com.google.firebase", name = "firebase-analytics-ktx" }
firebase-cloud-messaging = { group = "com.google.firebase", name = "firebase-messaging-ktx" }
firebase-crashlytics = { group = "com.google.firebase", name = "firebase-crashlytics-ktx" }
firebase-performance = { group = "com.google.firebase", name = "firebase-perf-ktx" }
dbflow-processor = { group = "com.github.Raizlabs.DBFlow", name = "dbflow-processor", version.ref = "dbflowVersion" }
dbflow-core = { group = "com.github.Raizlabs.DBFlow", name = "dbflow-core", version.ref = "dbflowVersion" }
dbflow = { group = "com.github.Raizlabs.DBFlow", name = "dbflow", version.ref = "dbflowVersion" }
androidx-preference = { group = "androidx.preference", name = "preference", version.ref = "preference" }
play-services-maps = { group = "com.google.android.gms", name = "play-services-maps", version.ref = "playServicesVersion" }
# Dependencies of the included build-logic
android-gradlePlugin = { group = "com.android.tools.build", name = "gradle", version.ref = "androidGradlePlugin" }
android-tools-common = { group = "com.android.tools", name = "common", version.ref = "androidTools" }
firebase-crashlytics-gradlePlugin = { group = "com.google.firebase", name = "firebase-crashlytics-gradle", version.ref = "firebaseCrashlyticsPlugin" }
firebase-performance-gradlePlugin = { group = "com.google.firebase", name = "perf-plugin", version.ref = "firebasePerfPlugin" }
kotlin-gradlePlugin = { group = "org.jetbrains.kotlin", name = "kotlin-gradle-plugin", version.ref = "kotlin" }
ksp-gradlePlugin = { group = "com.google.devtools.ksp", name = "com.google.devtools.ksp.gradle.plugin", version.ref = "ksp" }
room-gradlePlugin = { group = "androidx.room", name = "room-gradle-plugin", version.ref = "room" }
work-testing = { group = "androidx.work", name = "work-testing", version = "2.8.1" }
androidx-test-ext-junit = { group = "androidx.test.ext", name = "junit", version.ref = "androidx-test-ext-junit" }
espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espresso-core" }
material = { group = "com.google.android.material", name = "material", version.ref = "material" }
[plugins]
android-application = { id = "com.android.application", version.ref = "androidGradlePlugin" }
android-library = { id = "com.android.library", version.ref = "androidGradlePlugin" }
gms = { id = "com.google.gms.google-services", version.ref = "gmsPlugin" }
hilt = { id = "com.google.dagger.hilt.android", version.ref = "hilt" }
firebase-crashlytics = { id = "com.google.firebase.crashlytics", version.ref = "firebaseCrashlyticsPlugin" }
firebase-perf = { id = "com.google.firebase.firebase-perf", version.ref = "firebasePerfPlugin" }
dependencyGuard = { id = "com.dropbox.dependency-guard", version.ref = "dependencyGuard" }
secrets = { id = "com.google.android.libraries.mapsplatform.secrets-gradle-plugin", version.ref = "secrets" }
kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }
kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }
android-test = { id = "com.android.test", version.ref = "androidGradlePlugin" }
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
kotlin-kapt = { id = "org.jetbrains.kotlin.kapt", version.ref = "kotlin" }
kotlin-parcelize = { id = "org.jetbrains.kotlin.plugin.parcelize", version.ref = "kotlin" }
roborazzi = { id = "io.github.takahirom.roborazzi", version.ref = "roborazzi" }
ksp = { id = "com.google.devtools.ksp", version.ref = "ksp"}
room = { id = "androidx.room", version.ref = "room" }
spotbugs = { id = "com.github.spotbugs", version.ref = "spotbugs" }
# Plugins defined by this project
mifos-android-application = { id = "mifos.android.application", version = "unspecified" }
mifos-android-application-compose = { id = "mifos.android.application.compose", version = "unspecified" }
mifos-android-application-firebase = { id = "mifos.android.application.firebase", version = "unspecified" }
mifos-android-feature = { id = "mifos.android.feature", version = "unspecified" }
mifos-android-hilt = { id = "mifos.android.hilt", version = "unspecified" }
mifos-android-library = { id = "mifos.android.library", version = "unspecified" }
mifos-android-library-compose = { id = "mifos.android.library.compose", version = "unspecified" }
mifos-android-lint = { id = "mifos.android.lint", version = "unspecified" }
mifos-android-room = { id = "mifos.android.room", version = "unspecified" }
mifos-android-test = { id = "mifos.android.test", version = "unspecified" }
mifos-jvm-library = { id = "mifos.jvm.library", version = "unspecified" }

View File

@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip

View File

@ -1,2 +0,0 @@
include ':app'
include ':ui'

24
settings.gradle.kts Normal file
View File

@ -0,0 +1,24 @@
pluginManagement {
includeBuild("build-logic")
repositories {
gradlePluginPortal()
google()
mavenCentral()
maven("https://www.jitpack.io")
maven("https://plugins.gradle.org/m2/")
}
}
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
maven("https://www.jitpack.io")
maven("https://plugins.gradle.org/m2/")
}
}
rootProject.name = "mifos-mobile"
enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")
include(":app")
include(":ui")

View File

@ -1,59 +0,0 @@
plugins {
id 'com.android.library'
id 'org.jetbrains.kotlin.android'
}
android {
namespace 'org.mifos.mobile.core'
compileSdk 32
defaultConfig {
minSdk 21
targetSdk 32
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles "consumer-rules.pro"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
buildFeatures {
compose true
}
composeOptions {
kotlinCompilerExtensionVersion "1.4.4"
}
}
dependencies {
implementation 'androidx.core:core-ktx:1.12.0'
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'com.google.android.material:material:1.9.0'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
// Jetpack Compose
implementation "androidx.compose.material:material:$rootProject.composeVersion"
implementation "androidx.compose.compiler:compiler:$rootProject.composeCompiler"
implementation "androidx.compose.ui:ui-tooling-preview:$rootProject.composeVersion"
implementation "androidx.activity:activity-compose:$rootProject.composeActivity"
debugImplementation "androidx.compose.ui:ui-tooling:$rootProject.composeVersion"
implementation "androidx.compose.material3:material3:$rootProject.materialVersion"
implementation "androidx.lifecycle:lifecycle-viewmodel-compose:$rootProject.lifecycleVersion"
}

30
ui/build.gradle.kts Normal file
View File

@ -0,0 +1,30 @@
plugins {
alias(libs.plugins.mifos.android.library)
alias(libs.plugins.mifos.android.library.compose)
}
android {
defaultConfig {
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
namespace = "org.mifos.mobile.core"
}
dependencies {
api(libs.androidx.compose.foundation)
api(libs.androidx.compose.foundation.layout)
api(libs.androidx.compose.material.iconsExtended)
api(libs.androidx.compose.material3)
api(libs.androidx.compose.runtime)
api(libs.androidx.compose.ui.tooling.preview)
api(libs.androidx.compose.ui.util)
debugApi(libs.androidx.compose.ui.tooling)
implementation("androidx.core:core-ktx:1.12.0")
implementation("androidx.appcompat:appcompat:1.6.1")
implementation("com.google.android.material:material:1.9.0")
testImplementation("junit:junit:4.13.2")
androidTestImplementation("androidx.test.ext:junit:1.1.5")
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
}

View File

@ -1,6 +1,6 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
# proguardFiles setting in build.gradle.kts.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html

View File

@ -3,11 +3,10 @@ package org.mifos.mobile.core.ui.component
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.material.Icon
import androidx.compose.material.Text
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier

View File

@ -2,7 +2,7 @@ package org.mifos.mobile.core.ui.component
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material.icons.filled.ArrowBack
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
@ -28,7 +28,7 @@ fun MifosTopBar(
onClick = { navigateBack.invoke() }
) {
Icon(
imageVector = Icons.AutoMirrored.Filled.ArrowBack,
imageVector = Icons.Filled.ArrowBack,
contentDescription = "Back Arrow",
tint = if (isSystemInDarkTheme()) Color.White else Color.Black,
)

View File

@ -6,8 +6,8 @@ import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.material.Icon
import androidx.compose.material.Text
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier

View File

@ -6,8 +6,8 @@ import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material.Divider
import androidx.compose.material.Icon
import androidx.compose.material3.Divider
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier