Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: Migrate :core:designsystem to KMP #2290

Merged
merged 10 commits into from
Jan 30, 2025
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions core/database/schemas/com.mifos.room.db.MifosDatabase/1.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
{
"formatVersion": 1,
"database": {
"version": 1,
"identityHash": "52a9a8b64b78975c74e557a9c0411c25",
"entities": [
{
"tableName": "ColumnValue",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER, `value` TEXT, `score` INTEGER, `registeredTableName` TEXT, PRIMARY KEY(`id`))",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER"
},
{
"fieldPath": "value",
"columnName": "value",
"affinity": "TEXT"
},
{
"fieldPath": "score",
"columnName": "score",
"affinity": "INTEGER"
},
{
"fieldPath": "registeredTableName",
"columnName": "registeredTableName",
"affinity": "TEXT"
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": [
"id"
]
}
}
],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '52a9a8b64b78975c74e557a9c0411c25')"
]
}
}
68 changes: 45 additions & 23 deletions core/designsystem/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -8,38 +8,60 @@
* See https://github.com/openMF/android-client/blob/master/LICENSE.md
*/
plugins {
alias(libs.plugins.mifos.android.library)
alias(libs.plugins.mifos.android.library.compose)
alias(libs.plugins.mifos.android.library.jacoco)
alias(libs.plugins.mifos.kmp.library)
niyajali marked this conversation as resolved.
Show resolved Hide resolved
alias(libs.plugins.jetbrainsCompose)
alias(libs.plugins.compose.compiler)
alias(libs.plugins.roborazzi)
}

android {
namespace = "com.mifos.core.designsystem"

defaultConfig {
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
namespace = "com.mifos.core.designsystem"
}

dependencies {
lintPublish(projects.lint)
kotlin {
sourceSets {
androidMain.dependencies {
implementation(libs.androidx.compose.ui.tooling.preview)
implementation(libs.androidx.activity.compose)
}
androidInstrumentedTest.dependencies {
implementation(libs.androidx.compose.ui.test)
}
androidUnitTest.dependencies {
implementation(libs.androidx.compose.ui.test)
}
commonMain.dependencies {
implementation(libs.coil.kt.compose)
implementation(compose.runtime)
implementation(compose.foundation)
implementation(compose.material3)
implementation(compose.materialIconsExtended)
implementation(compose.ui)
implementation(compose.uiUtil)
implementation(compose.components.resources)
implementation(compose.components.uiToolingPreview)
api(libs.back.handler)
api(libs.window.size)
}

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.util)
api(libs.androidx.activity.compose)
nativeMain.dependencies {
implementation(compose.runtime)
}

// coil
implementation(libs.coil.kt.compose)
jsMain.dependencies {
implementation(compose.runtime)
}

testImplementation(libs.androidx.compose.ui.test)
testImplementation(libs.androidx.compose.ui.test.manifest)
testImplementation(libs.hilt.android.testing)
testImplementation(projects.core.testing)

androidTestImplementation(libs.androidx.compose.ui.test)
androidTestImplementation(projects.core.testing)
wasmJsMain.dependencies {
implementation(compose.runtime)
}
}
}

compose.resources {
publicResClass = true
generateResClass = always
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,20 +22,24 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalLifecycleOwner
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver
import androidx.lifecycle.compose.LocalLifecycleOwner

// TODO:: Support for compose multiplatform
@Suppress("LongMethod", "CyclomaticComplexMethod")
@Composable
fun PermissionBox(
title: String,
confirmButtonText: String,
dismissButtonText: String,
requiredPermissions: List<String>,
title: Int,
confirmButtonText: Int,
dismissButtonText: Int,
description: Int? = null,
modifier: Modifier = Modifier,
description: String? = null,
onGranted: @Composable (() -> Unit)? = null,
) {
val context = LocalContext.current
Expand All @@ -56,7 +60,8 @@ fun PermissionBox(
requiredPermissions.all {
(context as? Activity)?.let { it1 ->
ActivityCompat.shouldShowRequestPermissionRationale(
it1, it,
it1,
it,
)
} == true
}
Expand All @@ -66,10 +71,10 @@ fun PermissionBox(
}

val decideCurrentPermissionStatus: (Boolean, Boolean) -> String =
{ permissionGranted, shouldShowPermissionRationale ->
if (permissionGranted) {
{ granted, rationale ->
if (granted) {
"Granted"
} else if (shouldShowPermissionRationale) {
} else if (rationale) {
"Rejected"
} else {
"Denied"
Expand All @@ -85,62 +90,67 @@ fun PermissionBox(
)
}

val multiplePermissionLauncher = rememberLauncherForActivityResult(
contract = ActivityResultContracts.RequestMultiplePermissions(),
onResult = { permissionResults ->
val isGranted =
requiredPermissions.all { permissionResults[it] ?: false }
val multiplePermissionLauncher =
rememberLauncherForActivityResult(
contract = ActivityResultContracts.RequestMultiplePermissions(),
onResult = { permissionResults ->
val isGranted =
requiredPermissions.all { permissionResults[it] ?: false }

permissionGranted = isGranted
permissionGranted = isGranted

if (!isGranted) {
shouldShowPermissionRationale =
requiredPermissions.all {
(context as? Activity)?.let { it1 ->
if (!isGranted) {
shouldShowPermissionRationale =
requiredPermissions.all {
ActivityCompat.shouldShowRequestPermissionRationale(
it1, it,
context as Activity,
it,
)
} == false
}
}
shouldDirectUserToApplicationSettings =
!shouldShowPermissionRationale &&
!permissionGranted
currentPermissionStatus =
decideCurrentPermissionStatus(
permissionGranted,
shouldShowPermissionRationale,
)
},
)

DisposableEffect(
key1 = lifecycleOwner,
effect = {
val observer =
LifecycleEventObserver { _, event ->
if (event == Lifecycle.Event.ON_START &&
!permissionGranted &&
!shouldShowPermissionRationale
) {
multiplePermissionLauncher.launch(requiredPermissions.toTypedArray())
}
}
lifecycleOwner.lifecycle.addObserver(observer)
onDispose {
lifecycleOwner.lifecycle.removeObserver(observer)
}
shouldDirectUserToApplicationSettings =
!shouldShowPermissionRationale && !permissionGranted
currentPermissionStatus = decideCurrentPermissionStatus(
permissionGranted,
shouldShowPermissionRationale,
)
},
)

DisposableEffect(key1 = lifecycleOwner, effect = {
val observer = LifecycleEventObserver { _, event ->
if (event == Lifecycle.Event.ON_START &&
!permissionGranted &&
!shouldShowPermissionRationale
) {
multiplePermissionLauncher.launch(requiredPermissions.toTypedArray())
}
}
lifecycleOwner.lifecycle.addObserver(observer)
onDispose {
lifecycleOwner.lifecycle.removeObserver(observer)
}
})

if (shouldShowPermissionRationale) {
MifosDialogBox(
showDialogState = shouldShowPermissionRationale,
onDismiss = { shouldShowPermissionRationale = false },
title = title,
message = description,
confirmButtonText = confirmButtonText,
onConfirm = {
shouldShowPermissionRationale = false
multiplePermissionLauncher.launch(requiredPermissions.toTypedArray())
},
dismissButtonText = dismissButtonText,
)
}
MifosDialogBox(
showDialogState = shouldShowPermissionRationale,
onDismiss = { shouldShowPermissionRationale = false },
title = title,
confirmButtonText = confirmButtonText,
onConfirm = {
shouldShowPermissionRationale = false
multiplePermissionLauncher.launch(requiredPermissions.toTypedArray())
},
dismissButtonText = dismissButtonText,
message = description,
modifier = modifier,
)

if (shouldDirectUserToApplicationSettings) {
Intent(
Expand All @@ -152,6 +162,8 @@ fun PermissionBox(
}

if (permissionGranted) {
onGranted?.invoke()
if (onGranted != null) {
onGranted()
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Copyright 2025 Mifos Initiative
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*
* See https://github.com/openMF/android-client/blob/master/LICENSE.md
*/
package com.mifos.core.designsystem.theme

import android.os.Build
import androidx.compose.material3.ColorScheme
import androidx.compose.material3.dynamicDarkColorScheme
import androidx.compose.material3.dynamicLightColorScheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.platform.LocalContext

@Composable
actual fun colorScheme(useDarkTheme: Boolean, dynamicColor: Boolean): ColorScheme {
return when {
dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
val context = LocalContext.current
if (useDarkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context)
}

useDarkTheme -> darkScheme
else -> lightScheme
}
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
*
* See https://github.com/openMF/android-client/blob/master/LICENSE.md
*/
package com.mifos.core.designsystem.component

import androidx.compose.runtime.MutableState
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateOf
Expand Down
Loading
Loading