From 3623a35d0cbbba8a3f50a11312ca0da3d012f22e Mon Sep 17 00:00:00 2001 From: revanthkumarJ Date: Thu, 16 Jan 2025 20:16:55 +0530 Subject: [PATCH 01/11] initial Setup --- core/ui/src/androidMain/AndroidManifest.xml | 13 ++ .../composeResources/values/strings.xml | 17 ++ .../core/ui/component/AboutUsItemCard.kt | 75 ++++++ .../mobile/core/ui/component/EmptyDataView.kt | 84 +++++++ .../mobile/core/ui/component/FaqItemHolder.kt | 114 +++++++++ .../mobile/core/ui/component/MFStepProcess.kt | 127 ++++++++++ .../core/ui/component/MifosAlertDialog.kt | 74 ++++++ .../mobile/core/ui/component/MifosCheckBox.kt | 54 +++++ .../ui/component/MifosDropDownTextField.kt | 218 ++++++++++++++++++ .../core/ui/component/MifosErrorComponent.kt | 206 +++++++++++++++++ .../core/ui/component/MifosHiddenTextRow.kt | 106 +++++++++ .../mobile/core/ui/component/MifosItemCard.kt | 60 +++++ .../mobile/core/ui/component/MifosLinkText.kt | 56 +++++ .../core/ui/component/MifosMobileIcon.kt | 55 +++++ .../ui/component/MifosProgressIndicator.kt | 50 ++++ .../component/MifosRadioButtonAlertDialog.kt | 99 ++++++++ .../core/ui/component/MifosRoundIcon.kt | 58 +++++ .../MifosTextButtonWithTopDrawable.kt | 83 +++++++ .../core/ui/component/MifosTextUserImage.kt | 71 ++++++ .../mobile/core/ui/component/MifosTexts.kt | 211 +++++++++++++++++ .../core/ui/component/MifosTitleSearchCard.kt | 110 +++++++++ .../core/ui/component/MifosUserImage.kt | 59 +++++ .../ui/component/MonitorListItemWithIcon.kt | 90 ++++++++ .../mobile/core/ui/component/NoInternet.kt | 101 ++++++++ .../core/ui/component/UserProfileField.kt | 118 ++++++++++ .../core/ui/component/UserProfileTopBar.kt | 94 ++++++++ .../mifos/mobile/core/ui/utils/ColorUtils.kt | 47 ++++ .../mobile/core/ui/utils/DevicePreviews.kt | 19 ++ .../mifos/mobile/core/ui/utils/ImageUtil.kt | 141 +++++++++++ .../utils/PresentOrFutureSelectableDates.kt | 34 +++ 30 files changed, 2644 insertions(+) create mode 100644 core/ui/src/androidMain/AndroidManifest.xml create mode 100644 core/ui/src/commonMain/composeResources/values/strings.xml create mode 100644 core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/AboutUsItemCard.kt create mode 100644 core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/EmptyDataView.kt create mode 100644 core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/FaqItemHolder.kt create mode 100644 core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MFStepProcess.kt create mode 100644 core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosAlertDialog.kt create mode 100644 core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosCheckBox.kt create mode 100644 core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosDropDownTextField.kt create mode 100644 core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosErrorComponent.kt create mode 100644 core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosHiddenTextRow.kt create mode 100644 core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosItemCard.kt create mode 100644 core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosLinkText.kt create mode 100644 core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosMobileIcon.kt create mode 100644 core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosProgressIndicator.kt create mode 100644 core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosRadioButtonAlertDialog.kt create mode 100644 core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosRoundIcon.kt create mode 100644 core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosTextButtonWithTopDrawable.kt create mode 100644 core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosTextUserImage.kt create mode 100644 core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosTexts.kt create mode 100644 core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosTitleSearchCard.kt create mode 100644 core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosUserImage.kt create mode 100644 core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MonitorListItemWithIcon.kt create mode 100644 core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/NoInternet.kt create mode 100644 core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/UserProfileField.kt create mode 100644 core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/UserProfileTopBar.kt create mode 100644 core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/utils/ColorUtils.kt create mode 100644 core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/utils/DevicePreviews.kt create mode 100644 core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.kt create mode 100644 core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/utils/PresentOrFutureSelectableDates.kt diff --git a/core/ui/src/androidMain/AndroidManifest.xml b/core/ui/src/androidMain/AndroidManifest.xml new file mode 100644 index 000000000..4ee22a4fb --- /dev/null +++ b/core/ui/src/androidMain/AndroidManifest.xml @@ -0,0 +1,13 @@ + + + + + \ No newline at end of file diff --git a/core/ui/src/commonMain/composeResources/values/strings.xml b/core/ui/src/commonMain/composeResources/values/strings.xml new file mode 100644 index 000000000..fd2ecc432 --- /dev/null +++ b/core/ui/src/commonMain/composeResources/values/strings.xml @@ -0,0 +1,17 @@ + + + + No Internet + Retry + No Data + Something went wrong + Core Common Working + \ No newline at end of file diff --git a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/AboutUsItemCard.kt b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/AboutUsItemCard.kt new file mode 100644 index 000000000..262f42aef --- /dev/null +++ b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/AboutUsItemCard.kt @@ -0,0 +1,75 @@ +/* + * Copyright 2024 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/mobile-mobile/blob/master/LICENSE.md + */ +package org.mifos.mobile.core.ui.component + +import androidx.compose.foundation.Image +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import org.jetbrains.compose.resources.DrawableResource +import org.jetbrains.compose.resources.StringResource +import org.jetbrains.compose.resources.painterResource +import org.jetbrains.compose.resources.stringResource +import org.mifos.mobile.core.designsystem.theme.MifosMobileTheme +import org.mifos.mobile.core.ui.utils.DevicePreviews + +@Composable +fun AboutUsItemCard( + title: String, + subtitle: StringResource?, + iconUrl: DrawableResource?, + modifier: Modifier = Modifier, +) { + Row( + modifier = modifier.padding(16.dp), + ) { + iconUrl?.let { painterResource(it) }?.let { + Image( + painter = it, + contentDescription = null, + modifier = Modifier.padding(end = 8.dp), + ) + } + Column { + Text( + text = title, + style = MaterialTheme.typography.bodyLarge, + modifier = Modifier.padding(end = 8.dp), + ) + if (subtitle != null) { + Text( + text = stringResource(subtitle), + style = MaterialTheme.typography.bodyLarge, + modifier = Modifier.padding(end = 8.dp), + ) + } + } + } +} + +@DevicePreviews +@Composable +private fun AboutUsItemCardPreview( + modifier: Modifier = Modifier, +) { + MifosMobileTheme { + AboutUsItemCard( + title = "About Us", + modifier = modifier, + subtitle = null, + iconUrl = null, + ) + } +} diff --git a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/EmptyDataView.kt b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/EmptyDataView.kt new file mode 100644 index 000000000..9af62a8c1 --- /dev/null +++ b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/EmptyDataView.kt @@ -0,0 +1,84 @@ +/* + * Copyright 2024 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/mobile-mobile/blob/master/LICENSE.md + */ +package org.mifos.mobile.core.ui.component + + +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.material3.Icon +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import org.jetbrains.compose.resources.DrawableResource +import org.jetbrains.compose.resources.StringResource +import org.jetbrains.compose.resources.painterResource +import org.jetbrains.compose.resources.stringResource +import org.mifos.mobile.core.designsystem.icons.MifosIcons +import org.mifos.mobile.core.designsystem.theme.MifosMobileTheme +import org.mifos.mobile.core.ui.utils.DevicePreviews +import mifos_mobile.core.ui.generated.resources.Res +import mifos_mobile.core.ui.generated.resources.no_internet + +@Composable +fun EmptyDataView( + error: StringResource, + modifier: Modifier = Modifier.fillMaxSize(), + icon: DrawableResource?=null, + errorString: String? = null, +) { + Column( + modifier = modifier, + verticalArrangement = Arrangement.Center, + horizontalAlignment = Alignment.CenterHorizontally, + ) { + Icon( + modifier = Modifier + .size(100.dp) + .padding(bottom = 12.dp), + painter = if (icon != null) { + painterResource(icon) + } else { + MifosIcons.Error + }, + contentDescription = null, + tint = MaterialTheme.colorScheme.onSecondary, + ) + + Text( + modifier = Modifier.padding(horizontal = 20.dp), + text = errorString ?: stringResource(error), + style = TextStyle(fontSize = 20.sp), + color = MaterialTheme.colorScheme.onSecondary, + textAlign = TextAlign.Center, + ) + } +} + +@DevicePreviews +@Composable +private fun EmptyDataViewPreview( + modifier: Modifier = Modifier, +) { + MifosMobileTheme { + EmptyDataView( + error = Res.string.no_internet, + modifier = modifier, + ) + } +} diff --git a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/FaqItemHolder.kt b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/FaqItemHolder.kt new file mode 100644 index 000000000..849ee2143 --- /dev/null +++ b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/FaqItemHolder.kt @@ -0,0 +1,114 @@ +/* + * Copyright 2024 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/mobile-mobile/blob/master/LICENSE.md + */ +package org.mifos.mobile.core.ui.component + +import androidx.compose.animation.AnimatedVisibility +import androidx.compose.animation.core.Spring +import androidx.compose.animation.core.spring +import androidx.compose.animation.expandVertically +import androidx.compose.animation.fadeIn +import androidx.compose.foundation.clickable +import androidx.compose.foundation.isSystemInDarkTheme +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.HorizontalDivider +import androidx.compose.material3.Icon +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.scale +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.unit.dp +import org.mifos.mobile.core.designsystem.icons.MifosIcons +import org.mifos.mobile.core.designsystem.theme.MifosMobileTheme +import org.mifos.mobile.core.ui.utils.DevicePreviews + +@Composable +fun FaqItemHolder( + index: Int, + isSelected: Boolean, + onItemSelected: (Int) -> Unit, + question: String?, + answer: String?, + modifier: Modifier = Modifier, +) { + Column( + modifier = modifier + .fillMaxWidth() + .padding(horizontal = 16.dp), + ) { + Row( + modifier = Modifier + .clickable { + onItemSelected.invoke(index) + } + .padding(vertical = 8.dp), + verticalAlignment = Alignment.CenterVertically, + ) { + Text( + text = question.orEmpty(), + style = MaterialTheme.typography.bodyMedium, + color = if (isSystemInDarkTheme()) Color.White else Color.Black, + modifier = Modifier + .fillMaxWidth() + .weight(1f), + ) + + Icon( + imageVector = MifosIcons.ArrowDropDown, + contentDescription = "drop down", + tint = if (isSystemInDarkTheme()) Color.White else Color.Gray, + modifier = Modifier + .scale(1f, if (isSelected) -1f else 1f), + ) + } + + AnimatedVisibility( + visible = isSelected, + enter = fadeIn() + expandVertically( + animationSpec = spring( + stiffness = Spring.StiffnessMedium, + ), + ), + ) { + Text( + text = answer.orEmpty(), + style = MaterialTheme.typography.bodyMedium, + color = if (isSystemInDarkTheme()) Color.White else Color.Black, + modifier = Modifier + .fillMaxWidth() + .padding(bottom = 8.dp), + ) + } + + HorizontalDivider() + } +} + +@DevicePreviews +@Composable +private fun FaqItemHolderPreview( + modifier: Modifier = Modifier, +) { + MifosMobileTheme { + FaqItemHolder( + index = 0, + isSelected = false, + onItemSelected = {}, + question = "What is Mifos?", + answer = "Mifos is a platform for financial inclusion.", + modifier = modifier, + ) + } +} diff --git a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MFStepProcess.kt b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MFStepProcess.kt new file mode 100644 index 000000000..8295af7ef --- /dev/null +++ b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MFStepProcess.kt @@ -0,0 +1,127 @@ +/* + * Copyright 2024 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/mobile-mobile/blob/master/LICENSE.md + */ +package org.mifos.mobile.core.ui.component + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.layout.onGloballyPositioned +import androidx.compose.ui.platform.LocalDensity +import androidx.compose.ui.unit.dp +import org.mifos.mobile.core.designsystem.theme.MifosMobileTheme +import org.mifos.mobile.core.ui.utils.DevicePreviews + +@Composable +fun MFStepProcess( + stepNumber: String, + activateColor: Color, + deactivateColor: Color, + modifier: Modifier = Modifier, + isLastStep: Boolean = false, + processState: StepProcessState = StepProcessState.INACTIVE, + content: @Composable (Modifier) -> Unit, +) { + var barHeight by remember { mutableStateOf(0.dp) } + val localDensity = LocalDensity.current + + Row(modifier) { + Column(horizontalAlignment = Alignment.CenterHorizontally) { + Column( + modifier = Modifier + .size(40.dp) + .clip(CircleShape) + .background( + color = if (processState == StepProcessState.INACTIVE) { + deactivateColor + } else { + activateColor + }, + ), + verticalArrangement = Arrangement.Center, + horizontalAlignment = Alignment.CenterHorizontally, + ) { + Text( + text = if (processState == StepProcessState.COMPLETED) "✔" else stepNumber, + color = MaterialTheme.colorScheme.onPrimary, + ) + } + if (!isLastStep) { + Box( + modifier = Modifier + .height(barHeight) + .width(4.dp) + .background( + color = if (processState == StepProcessState.INACTIVE) { + deactivateColor + } else { + activateColor + }, + ), + ) + } + } + content( + Modifier + .padding(start = 10.dp, end = 6.dp) + .onGloballyPositioned { barHeight = with(localDensity) { it.size.height.toDp() } }, + ) + } +} + +enum class StepProcessState { + COMPLETED, + ACTIVE, + INACTIVE, +} + +fun getStepState(targetStep: Int, currentStep: Int): StepProcessState { + return when { + currentStep == targetStep -> StepProcessState.ACTIVE + currentStep > targetStep -> StepProcessState.COMPLETED + else -> StepProcessState.INACTIVE + } +} + +@DevicePreviews +@Composable +private fun Preview( + modifier: Modifier = Modifier, +) { + MifosMobileTheme { + MFStepProcess( + stepNumber = "1", + activateColor = Color.Red, + deactivateColor = Color.Gray, + modifier = modifier, + isLastStep = false, + processState = StepProcessState.ACTIVE, + ) { + Text(text = "Step 1") + } + } +} diff --git a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosAlertDialog.kt b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosAlertDialog.kt new file mode 100644 index 000000000..c87a49027 --- /dev/null +++ b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosAlertDialog.kt @@ -0,0 +1,74 @@ +/* + * Copyright 2024 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/mobile-mobile/blob/master/LICENSE.md + */ +package org.mifos.mobile.core.ui.component + +import androidx.compose.material3.AlertDialog +import androidx.compose.material3.Icon +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.vector.ImageVector +import org.mifos.mobile.core.designsystem.components.MifosTextButton +import org.mifos.mobile.core.designsystem.theme.MifosMobileTheme +import org.mifos.mobile.core.ui.utils.DevicePreviews + +@Composable +fun MifosAlertDialog( + dialogTitle: String, + dialogText: String, + dismissText: String, + confirmationText: String, + onDismissRequest: () -> Unit, + onConfirmation: () -> Unit, + modifier: Modifier = Modifier, + icon: ImageVector? = null, +) { + AlertDialog( + icon = { + if (icon != null) { + Icon(imageVector = icon, contentDescription = null) + } + }, + title = { Text(text = dialogTitle) }, + text = { Text(text = dialogText) }, + modifier = modifier, + onDismissRequest = onDismissRequest, + confirmButton = { + MifosTextButton( + text = confirmationText, + onClick = onConfirmation, + ) + }, + dismissButton = { + MifosTextButton( + text = dismissText, + onClick = onDismissRequest, + ) + }, + ) +} + +@DevicePreviews +@Composable +private fun MifosAlertDialogPreview( + modifier: Modifier = Modifier, +) { + MifosMobileTheme { + MifosAlertDialog( + dialogTitle = "Dialog Title", + dialogText = "Dialog Text", + dismissText = "Dismiss", + confirmationText = "Confirm", + onDismissRequest = {}, + onConfirmation = {}, + modifier = modifier, + ) + } +} diff --git a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosCheckBox.kt b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosCheckBox.kt new file mode 100644 index 000000000..85724dbe9 --- /dev/null +++ b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosCheckBox.kt @@ -0,0 +1,54 @@ +/* + * Copyright 2024 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/mobile-mobile/blob/master/LICENSE.md + */ +package org.mifos.mobile.core.ui.component + +import androidx.compose.foundation.layout.Row +import androidx.compose.material3.Checkbox +import androidx.compose.material3.CheckboxColors +import androidx.compose.material3.CheckboxDefaults +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import org.mifos.mobile.core.designsystem.theme.MifosMobileTheme +import org.mifos.mobile.core.ui.utils.DevicePreviews + +@Composable +fun MifosCheckBox( + text: String, + checked: Boolean, + onCheckChanged: (Boolean) -> Unit, + modifier: Modifier = Modifier, + checkboxColors: CheckboxColors = CheckboxDefaults.colors(), +) { + Row( + modifier = modifier, + verticalAlignment = Alignment.CenterVertically, + ) { + Checkbox( + checked = checked, + onCheckedChange = { onCheckChanged.invoke(it) }, + colors = checkboxColors, + ) + Text(text = text) + } +} + +@DevicePreviews +@Composable +fun MifosCheckBoxPreview() { + MifosMobileTheme { + MifosCheckBox( + checked = false, + onCheckChanged = {}, + text = "", + ) + } +} diff --git a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosDropDownTextField.kt b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosDropDownTextField.kt new file mode 100644 index 000000000..582459f56 --- /dev/null +++ b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosDropDownTextField.kt @@ -0,0 +1,218 @@ +/* + * Copyright 2024 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/mobile-mobile/blob/master/LICENSE.md + */ +package org.mifos.mobile.core.ui.component + +import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.foundation.interaction.collectIsPressedAsState +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.heightIn +import androidx.compose.material3.DropdownMenu +import androidx.compose.material3.DropdownMenuItem +import androidx.compose.material3.Icon +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.OutlinedTextField +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.saveable.rememberSaveable +import androidx.compose.runtime.setValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.alpha +import androidx.compose.ui.unit.dp +import org.jetbrains.compose.resources.StringResource +import org.jetbrains.compose.resources.stringResource +import org.mifos.mobile.core.designsystem.icons.MifosIcons +import org.mifos.mobile.core.designsystem.theme.MifosMobileTheme +import org.mifos.mobile.core.ui.utils.DevicePreviews + +@Composable +fun MifosDropDownTextField( + onClick: (Int, String) -> Unit, + modifier: Modifier = Modifier, + labelResId: StringResource, + isEnabled: Boolean = true, + supportingText: String? = null, + error: Boolean = false, + optionsList: List = listOf(), + selectedOption: String? = null, +) { + var expanded by rememberSaveable { mutableStateOf(false) } + val interactionSource = remember { MutableInteractionSource() } + val isPressed by interactionSource.collectIsPressedAsState() + + LaunchedEffect(key1 = isPressed) { + if (isPressed) expanded = true && isEnabled + } + + Box( + modifier = modifier.alpha(if (!isEnabled) 0.4f else 1f), + ) { + OutlinedTextField( + value = selectedOption ?: "", + onValueChange = { }, + label = { Text(stringResource(labelResId)) }, + interactionSource = interactionSource, + modifier = Modifier + .fillMaxWidth(), + readOnly = true, + enabled = isEnabled, + textStyle = MaterialTheme.typography.labelSmall, + supportingText = { if (error) Text(text = supportingText ?: "") }, + isError = error, + trailingIcon = { + Icon( + imageVector = if (expanded) { + MifosIcons.ArrowDropUp + } else { + MifosIcons.ArrowDropDown + }, + contentDescription = null, + ) + }, + ) + + DropdownMenu( + expanded = expanded && isEnabled, + modifier = Modifier + .fillMaxWidth(0.92f) + .heightIn(max = 200.dp), + onDismissRequest = { expanded = false }, + ) { + optionsList.forEachIndexed { index, item -> + DropdownMenuItem( + onClick = { + expanded = false + onClick(index, item) + }, + text = { Text(text = item) }, + ) + } + } + } +} + +@Composable +fun MifosDropDownDoubleTextField( + onClick: (Int, Pair) -> Unit, + modifier: Modifier = Modifier, + labelResId: StringResource, + isEnabled: Boolean = true, + supportingText: String? = null, + error: Boolean = false, + optionsList: List> = listOf(), + selectedOption: String? = null, +) { + var expanded by rememberSaveable { mutableStateOf(false) } + val interactionSource = remember { MutableInteractionSource() } + val isPressed by interactionSource.collectIsPressedAsState() + + LaunchedEffect(key1 = isPressed) { + if (isPressed) expanded = true && isEnabled + } + + Box( + modifier = modifier.alpha(if (!isEnabled) 0.4f else 1f), + ) { + OutlinedTextField( + value = selectedOption ?: "", + onValueChange = { }, + label = { Text(stringResource(labelResId)) }, + interactionSource = interactionSource, + modifier = Modifier + .fillMaxWidth(), + readOnly = true, + enabled = isEnabled, + textStyle = MaterialTheme.typography.labelSmall, + supportingText = { if (error) Text(text = supportingText ?: "") }, + isError = error, + trailingIcon = { + Icon( + imageVector = if (expanded) { + MifosIcons.ArrowDropUp + } else { + MifosIcons.ArrowDropDown + }, + contentDescription = null, + ) + }, + ) + + DropdownMenu( + expanded = expanded && isEnabled, + modifier = Modifier + .fillMaxWidth(0.92f) + .heightIn(max = 200.dp), + onDismissRequest = { expanded = false }, + ) { + optionsList.forEachIndexed { index, item -> + DropdownMenuItem( + onClick = { + expanded = false + onClick(index, item) + }, + text = { + Column { + Text(text = item.first) + Text(text = item.second) + } + }, + + ) + } + } + } +} + +@DevicePreviews +@Composable +private fun MifosDropDownTextFieldPreview( + modifier: Modifier = Modifier, +) { + MifosMobileTheme { + MifosDropDownTextField( + onClick = { _, _ -> }, + modifier = modifier, + labelResId = 0, + isEnabled = true, + supportingText = null, + error = false, + optionsList = listOf("Option 1", "Option 2", "Option 3"), + selectedOption = null, + ) + } +} + +@DevicePreviews +@Composable +private fun MifosDropDownDoubleTextFieldPreview( + modifier: Modifier = Modifier, +) { + MifosMobileTheme { + MifosDropDownDoubleTextField( + onClick = { _, _ -> }, + modifier = modifier, + labelResId = 0, + isEnabled = true, + supportingText = null, + error = false, + optionsList = listOf( + Pair("Option 1", "Option 1 Description"), + Pair("Option 2", "Option 2 Description"), + Pair("Option 3", "Option 3 Description"), + ), + selectedOption = null, + ) + } +} diff --git a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosErrorComponent.kt b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosErrorComponent.kt new file mode 100644 index 000000000..896fadbea --- /dev/null +++ b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosErrorComponent.kt @@ -0,0 +1,206 @@ +/* + * Copyright 2024 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/mobile-mobile/blob/master/LICENSE.md + */ +package org.mifos.mobile.core.ui.component + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.material3.FilledTonalButton +import androidx.compose.material3.Icon +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import org.jetbrains.compose.resources.stringResource +import mifos_mobile.core.ui.generated.resources.no_internet +import mifos_mobile.core.ui.generated.resources.Res +import mifos_mobile.core.ui.generated.resources.no_data +import mifos_mobile.core.ui.generated.resources.retry +import mifos_mobile.core.ui.generated.resources.something_went_wrong +import org.mifos.mobile.core.designsystem.icons.MifosIcons +import org.mifos.mobile.core.designsystem.theme.MifosMobileTheme +import org.mifos.mobile.core.ui.utils.DevicePreviews + +@Composable +fun MifosErrorComponent( + modifier: Modifier = Modifier, + isNetworkConnected: Boolean = true, + message: String? = null, + isEmptyData: Boolean = false, + isRetryEnabled: Boolean = false, + onRetry: () -> Unit = {}, +) { + when { + !isNetworkConnected -> NoInternetComponent(isRetryEnabled = isRetryEnabled) { onRetry() } + else -> EmptyDataComponent( + modifier = modifier, + isEmptyData = isEmptyData, + message = message, + isRetryEnabled = isRetryEnabled, + onRetry = onRetry, + ) + } +} + +@Composable +fun NoInternetComponent( + modifier: Modifier = Modifier, + isRetryEnabled: Boolean = false, + onRetry: () -> Unit = {}, +) { + Column( + modifier = modifier + .fillMaxSize() + .background(MaterialTheme.colorScheme.background), + verticalArrangement = Arrangement.Center, + horizontalAlignment = Alignment.CenterHorizontally, + ) { + Icon( + modifier = Modifier + .size(100.dp) + .padding(bottom = 12.dp), + imageVector = MifosIcons.WifiOff, + contentDescription = null, + tint = MaterialTheme.colorScheme.onSecondary, + ) + + Text( + text = stringResource(Res.string.no_internet), + style = TextStyle(fontSize = 20.sp), + color = MaterialTheme.colorScheme.onSecondary, + ) + + Spacer(modifier = Modifier.height(12.dp)) + + if (isRetryEnabled) { + FilledTonalButton(onClick = { onRetry.invoke() }) { + Text(text = stringResource(Res.string.retry)) + } + } + } +} + +@Composable +fun EmptyDataComponent( + modifier: Modifier = Modifier, + isEmptyData: Boolean = false, + message: String? = null, + isRetryEnabled: Boolean = false, + onRetry: () -> Unit = {}, +) { + Column( + modifier = modifier.fillMaxSize(), + verticalArrangement = Arrangement.Center, + horizontalAlignment = Alignment.CenterHorizontally, + ) { + Icon( + modifier = Modifier + .size(100.dp) + .padding(bottom = 12.dp), + imageVector = MifosIcons.Info, + contentDescription = null, + tint = MaterialTheme.colorScheme.onSecondary, + ) + + Text( + modifier = Modifier.padding(horizontal = 20.dp), + text = message ?: if (isEmptyData) { + stringResource(Res.string.no_data) + } else { + stringResource(Res.string.something_went_wrong) + }, + style = TextStyle(fontSize = 20.sp), + color = MaterialTheme.colorScheme.onSecondary, + textAlign = TextAlign.Center, + ) + + if (isRetryEnabled) { + FilledTonalButton( + modifier = Modifier.padding(top = 8.dp), + onClick = { onRetry.invoke() }, + ) { + Text(text = stringResource(Res.string.retry)) + } + } + } +} + +@Composable +fun EmptyDataComponentWithModifiedMessageAndIcon( + message: String, + icon: ImageVector, + modifier: Modifier = Modifier, + isEmptyData: Boolean = false, +) { + Column( + modifier = modifier.fillMaxSize(), + verticalArrangement = Arrangement.Center, + horizontalAlignment = Alignment.CenterHorizontally, + ) { + Icon( + modifier = Modifier + .size(100.dp) + .padding(bottom = 12.dp), + imageVector = if (isEmptyData) icon else MifosIcons.Info, + contentDescription = null, + tint = MaterialTheme.colorScheme.onSecondary, + ) + + Text( + modifier = Modifier.padding(horizontal = 20.dp), + text = if (isEmptyData) message else stringResource(Res.string.something_went_wrong), + style = TextStyle(fontSize = 20.sp), + color = MaterialTheme.colorScheme.onSecondary, + textAlign = TextAlign.Center, + ) + } +} + +@DevicePreviews +@Composable +fun NoInternetPreview() { + MifosMobileTheme { + NoInternetComponent() + } +} + +@DevicePreviews +@Composable +fun EmptyDataPreview() { + MifosMobileTheme { + EmptyDataComponent() + } +} + +@DevicePreviews +@Composable +private fun EmptyDataComponentWithModifiedMessageAndIconPreview( + modifier: Modifier = Modifier, +) { + MifosMobileTheme { + EmptyDataComponentWithModifiedMessageAndIcon( + message = "No data found", + icon = MifosIcons.Error, + modifier = modifier, + isEmptyData = true, + ) + } +} diff --git a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosHiddenTextRow.kt b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosHiddenTextRow.kt new file mode 100644 index 000000000..c124c30d6 --- /dev/null +++ b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosHiddenTextRow.kt @@ -0,0 +1,106 @@ +/* + * Copyright 2024 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/mobile-mobile/blob/master/LICENSE.md + */ +package org.mifos.mobile.core.ui.component + +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.alpha +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.dp +import org.jetbrains.compose.resources.DrawableResource +import org.jetbrains.compose.resources.painterResource +import org.mifos.mobile.core.designsystem.theme.MifosMobileTheme +import org.mifos.mobile.core.ui.utils.DevicePreviews + +@Composable +fun MifosHiddenTextRow( + title: String, + hiddenText: String, + hiddenColor: Color, + hidingText: String, + visibilityIconId: DrawableResource, + visibilityOffIconId: DrawableResource, + onClick: () -> Unit, + modifier: Modifier = Modifier, +) { + var isHidden by remember { mutableStateOf(true) } + + Row( + modifier.clickable { onClick.invoke() }, + verticalAlignment = Alignment.CenterVertically, + ) { + Text( + text = title, + style = MaterialTheme.typography.labelMedium, + modifier = Modifier + .alpha(0.7f) + .weight(1f), + ) + Text( + text = if (isHidden) { + hidingText + } else { + hiddenText + }, + style = MaterialTheme.typography.bodyLarge, + fontWeight = FontWeight.Bold, + color = hiddenColor, + ) + IconButton( + onClick = { isHidden = !isHidden }, + modifier = Modifier + .padding(start = 6.dp) + .size(24.dp), + ) { + Icon( + painter = if (isHidden) { + painterResource(visibilityIconId) + } else { + painterResource(visibilityOffIconId) + }, + contentDescription = "Show or hide total amount", + tint = MaterialTheme.colorScheme.primary, + ) + } + } +} + +@DevicePreviews +@Composable +private fun MifosHiddenTextRowPreview( + modifier: Modifier = Modifier, +) { + MifosMobileTheme { + MifosHiddenTextRow( + title = "Title", + hiddenText = "Hidden Text", + hiddenColor = MaterialTheme.colorScheme.primary, + hidingText = "Hiding Text", + visibilityIconId = 0, + visibilityOffIconId = 0, + onClick = {}, + modifier = modifier, + ) + } +} diff --git a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosItemCard.kt b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosItemCard.kt new file mode 100644 index 000000000..72dea308b --- /dev/null +++ b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosItemCard.kt @@ -0,0 +1,60 @@ +/* + * Copyright 2024 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/mobile-mobile/blob/master/LICENSE.md + */ +package org.mifos.mobile.core.ui.component + +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.ColumnScope +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Card +import androidx.compose.material3.CardDefaults +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Shape +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.dp +import org.mifos.mobile.core.designsystem.theme.MifosMobileTheme +import org.mifos.mobile.core.ui.utils.DevicePreviews + +@Composable +fun MifosItemCard( + onClick: () -> Unit, + modifier: Modifier = Modifier, + elevation: Dp = 1.dp, + shape: Shape = RoundedCornerShape(8.dp), + content: @Composable ColumnScope.() -> Unit, +) { + Card( + shape = shape, + modifier = modifier + .fillMaxWidth() + .clickable(onClick = onClick), + elevation = CardDefaults.cardElevation( + defaultElevation = elevation, + ), + content = content, + ) +} + +@DevicePreviews +@Composable +private fun MifosItemCardPreview( + modifier: Modifier = Modifier, +) { + MifosMobileTheme { + MifosItemCard( + onClick = {}, + modifier = modifier, + ) { + Text(text = "Card Content") + } + } +} diff --git a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosLinkText.kt b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosLinkText.kt new file mode 100644 index 000000000..e09e38741 --- /dev/null +++ b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosLinkText.kt @@ -0,0 +1,56 @@ +/* + * Copyright 2024 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/mobile-mobile/blob/master/LICENSE.md + */ +package org.mifos.mobile.core.ui.component + +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.text.style.TextDecoration +import androidx.compose.ui.unit.dp +import org.mifos.mobile.core.designsystem.theme.MifosMobileTheme +import org.mifos.mobile.core.ui.utils.DevicePreviews + +@Composable +fun MifosLinkText( + text: String, + onClick: () -> Unit, + modifier: Modifier = Modifier, + isUnderlined: Boolean = true, +) { + Text( + text = text, + style = MaterialTheme.typography.bodyMedium.copy( + color = MaterialTheme.colorScheme.primary, + textDecoration = if (isUnderlined) TextDecoration.Underline else null, + ), + modifier = modifier + .padding(vertical = 2.dp) + .clickable { + onClick() + }, + ) +} + +@DevicePreviews +@Composable +private fun MifosLinkTextPreview( + modifier: Modifier = Modifier, +) { + MifosMobileTheme { + MifosLinkText( + text = "Link Text", + onClick = {}, + modifier = modifier, + ) + } +} diff --git a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosMobileIcon.kt b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosMobileIcon.kt new file mode 100644 index 000000000..6686fb984 --- /dev/null +++ b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosMobileIcon.kt @@ -0,0 +1,55 @@ +/* + * Copyright 2024 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/mobile-mobile/blob/master/LICENSE.md + */ +package org.mifos.mobile.core.ui.component + + +import androidx.compose.foundation.Image +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import mifos_mobile.core.ui.generated.resources.Res +import org.jetbrains.compose.resources.DrawableResource +import org.jetbrains.compose.resources.painterResource +import org.mifos.mobile.core.designsystem.theme.MifosMobileTheme +import org.mifos.mobile.core.ui.utils.DevicePreviews + +@Composable +fun MifosMobileIcon( + id: DrawableResource, + modifier: Modifier = Modifier, +) { + Column(modifier) { + Image( + painter = painterResource(id), + contentDescription = null, + modifier = Modifier + .fillMaxWidth() + .align(Alignment.CenterHorizontally) + .padding(0.dp, 56.dp), + ) + } +} + +@DevicePreviews +@Composable +private fun MifosMobileIconPreview( + modifier: Modifier = Modifier, +) { + MifosMobileTheme { + MifosMobileIcon( + id = Res.drawable.core_common_circular_background, + modifier = modifier, + ) + } +} diff --git a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosProgressIndicator.kt b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosProgressIndicator.kt new file mode 100644 index 000000000..a00356768 --- /dev/null +++ b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosProgressIndicator.kt @@ -0,0 +1,50 @@ +/* + * Copyright 2024 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/mobile-mobile/blob/master/LICENSE.md + */ +package org.mifos.mobile.core.ui.component + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.material3.CircularProgressIndicator +import androidx.compose.material3.MaterialTheme +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import org.mifos.mobile.core.ui.utils.DevicePreviews + +@DevicePreviews +@Composable +fun MifosProgressIndicator( + modifier: Modifier = Modifier.fillMaxSize(), +) { + Column( + modifier = modifier, + verticalArrangement = Arrangement.Center, + horizontalAlignment = Alignment.CenterHorizontally, + ) { + CircularProgressIndicator() + } +} + +@DevicePreviews +@Composable +fun MifosProgressIndicatorOverlay( + modifier: Modifier = Modifier.fillMaxSize(), +) { + Column( + modifier = modifier + .background(MaterialTheme.colorScheme.background.copy(alpha = 0.7f)), + verticalArrangement = Arrangement.Center, + horizontalAlignment = Alignment.CenterHorizontally, + ) { + CircularProgressIndicator() + } +} diff --git a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosRadioButtonAlertDialog.kt b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosRadioButtonAlertDialog.kt new file mode 100644 index 000000000..0a0faf8cf --- /dev/null +++ b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosRadioButtonAlertDialog.kt @@ -0,0 +1,99 @@ +/* + * Copyright 2024 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/mobile-mobile/blob/master/LICENSE.md + */ +package org.mifos.mobile.core.ui.component + +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.heightIn +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.itemsIndexed +import androidx.compose.material3.BasicAlertDialog +import androidx.compose.material3.Card +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.RadioButton +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import mifos_mobile.core.ui.generated.resources.Res +import mifos_mobile.core.ui.generated.resources.core_common_working +import org.jetbrains.compose.resources.StringResource +import org.jetbrains.compose.resources.stringResource +import org.mifos.mobile.core.designsystem.theme.MifosMobileTheme +import org.mifos.mobile.core.ui.utils.DevicePreviews + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun MifosRadioButtonDialog( + titleResId: StringResource, + selectedItem: String, + items: Array, + selectItem: (item: String, index: Int) -> Unit, + onDismissRequest: () -> Unit, + modifier: Modifier = Modifier, +) { + BasicAlertDialog( + onDismissRequest = onDismissRequest, + modifier = modifier, + ) { + Card { + Column(modifier = Modifier.padding(20.dp)) { + Text(text = stringResource(titleResId)) + LazyColumn( + modifier = Modifier + .fillMaxWidth() + .heightIn(max = 500.dp), + ) { + itemsIndexed(items = items) { index, item -> + Row( + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier + .clickable { + onDismissRequest.invoke() + selectItem.invoke(item, index) + } + .fillMaxWidth(), + ) { + RadioButton( + selected = (item == selectedItem), + onClick = { + onDismissRequest.invoke() + selectItem.invoke(item, index) + }, + ) + Text( + text = item, + modifier = Modifier.padding(start = 4.dp), + ) + } + } + } + } + } + } +} + +@DevicePreviews +@Composable +fun PreviewRadioButtonDialog() { + MifosMobileTheme { + MifosRadioButtonDialog( + titleResId = Res.string.core_common_working, + items = arrayOf("1", "2", "3"), + selectedItem = "1", + onDismissRequest = { }, + selectItem = { _, _ -> }, + ) + } +} diff --git a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosRoundIcon.kt b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosRoundIcon.kt new file mode 100644 index 000000000..6f63164bc --- /dev/null +++ b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosRoundIcon.kt @@ -0,0 +1,58 @@ +/* + * Copyright 2024 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/mobile-mobile/blob/master/LICENSE.md + */ +package org.mifos.mobile.core.ui.component + + +import androidx.compose.foundation.Image +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Surface +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.unit.dp +import mifos_mobile.core.ui.generated.resources.Res +import org.jetbrains.compose.resources.DrawableResource +import org.jetbrains.compose.resources.painterResource +import org.mifos.mobile.core.designsystem.theme.MifosMobileTheme +import org.mifos.mobile.core.ui.utils.DevicePreviews + +@Composable +fun MifosRoundIcon( + iconId: DrawableResource, + modifier: Modifier = Modifier, + contentDescription: String? = null, +) { + Surface( + color = MaterialTheme.colorScheme.surfaceVariant, + modifier = modifier + .clip(CircleShape), + ) { + Image( + modifier = Modifier.padding(all = 6.dp), + painter = painterResource(iconId), + contentDescription = contentDescription, + ) + } +} + +@DevicePreviews +@Composable +private fun MifosRoundIconPreview( + modifier: Modifier = Modifier, +) { + MifosMobileTheme { + MifosRoundIcon( + iconId = Res.drawable.core_common_circular_background, + modifier = modifier, + ) + } +} diff --git a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosTextButtonWithTopDrawable.kt b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosTextButtonWithTopDrawable.kt new file mode 100644 index 000000000..83a8d3c89 --- /dev/null +++ b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosTextButtonWithTopDrawable.kt @@ -0,0 +1,83 @@ +/* + * Copyright 2024 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/mobile-mobile/blob/master/LICENSE.md + */ +package org.mifos.mobile.core.ui.component + + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.height +import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.Icon +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.unit.dp +import mifos_mobile.core.ui.generated.resources.Res +import mifos_mobile.core.ui.generated.resources.core_common_working +import org.jetbrains.compose.resources.StringResource +import org.jetbrains.compose.resources.stringResource +import org.mifos.mobile.core.designsystem.components.MifosTextButton +import org.mifos.mobile.core.designsystem.icons.MifosIcons +import org.mifos.mobile.core.designsystem.theme.MifosMobileTheme +import org.mifos.mobile.core.ui.utils.DevicePreviews + +@Composable +fun MifosTextButtonWithTopDrawable( + textResourceId: StringResource, + icon: ImageVector, + onClick: () -> Unit, + contentDescription: String?, + modifier: Modifier = Modifier, +) { + MifosTextButton( + onClick = onClick, + modifier = modifier, + colors = ButtonDefaults.textButtonColors( + contentColor = MaterialTheme.colorScheme.primary, + ), + content = { + Column( + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.Center, + ) { + Icon( + imageVector = icon, + contentDescription = contentDescription, + ) + Spacer(modifier = Modifier.height(4.dp)) + Text( + text = stringResource(textResourceId), + textAlign = TextAlign.Center, + ) + } + }, + ) +} + +@DevicePreviews +@Composable +private fun MifosTextButtonWithTopDrawablePreview( + modifier: Modifier = Modifier, +) { + MifosMobileTheme { + MifosTextButtonWithTopDrawable( + textResourceId = Res.string.core_common_working, + icon = MifosIcons.Add, + onClick = {}, + contentDescription = null, + modifier = modifier, + ) + } +} diff --git a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosTextUserImage.kt b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosTextUserImage.kt new file mode 100644 index 000000000..1a2de0af7 --- /dev/null +++ b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosTextUserImage.kt @@ -0,0 +1,71 @@ +/* + * Copyright 2024 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/mobile-mobile/blob/master/LICENSE.md + */ +package org.mifos.mobile.core.ui.component + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.geometry.Size +import androidx.compose.ui.layout.onGloballyPositioned +import androidx.compose.ui.platform.LocalDensity +import org.mifos.mobile.core.designsystem.theme.MifosMobileTheme +import org.mifos.mobile.core.ui.utils.DevicePreviews +import kotlin.math.min + +@Composable +fun MifosTextUserImage( + text: String, + modifier: Modifier = Modifier, +) { + var boxSize by remember { mutableStateOf(Size.Zero) } + Box( + modifier = modifier + .clip(CircleShape) + .background(color = MaterialTheme.colorScheme.primary) + .onGloballyPositioned { coordinates -> + boxSize = Size( + coordinates.size.width.toFloat(), + coordinates.size.height.toFloat(), + ) + }, + contentAlignment = Alignment.Center, + ) { + Text( + text = text, + color = MaterialTheme.colorScheme.onPrimary, + fontSize = with(LocalDensity.current) { + (min(boxSize.width, boxSize.height) / 2).toSp() + }, + ) + } +} + +@DevicePreviews +@Composable +private fun MifosTextUserImagePreview( + modifier: Modifier = Modifier, +) { + MifosMobileTheme { + MifosTextUserImage( + text = "A", + modifier = modifier, + ) + } +} diff --git a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosTexts.kt b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosTexts.kt new file mode 100644 index 000000000..8c0d6881b --- /dev/null +++ b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosTexts.kt @@ -0,0 +1,211 @@ +/* + * Copyright 2024 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/mobile-mobile/blob/master/LICENSE.md + */ +package org.mifos.mobile.core.ui.component + +import androidx.compose.foundation.Image +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.alpha +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.dp +import mifos_mobile.core.ui.generated.resources.Res +import org.jetbrains.compose.resources.DrawableResource +import org.jetbrains.compose.resources.painterResource +import org.mifos.mobile.core.designsystem.theme.MifosMobileTheme +import org.mifos.mobile.core.ui.utils.DevicePreviews + +@Composable +fun MifosTextTitleDescSingleLine( + title: String, + description: String, + modifier: Modifier = Modifier, +) { + Row( + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.SpaceBetween, + modifier = modifier.fillMaxWidth(), + ) { + Text( + style = MaterialTheme.typography.labelMedium, + color = MaterialTheme.colorScheme.onSurface, + text = title, + modifier = Modifier + .alpha(0.7f), + ) + + Text( + style = MaterialTheme.typography.bodyMedium, + color = MaterialTheme.colorScheme.onSurface, + text = description, + ) + } +} + +@Composable +fun MifosTextTitleDescDoubleLine( + title: String, + description: String, + descriptionStyle: TextStyle, + modifier: Modifier = Modifier, +) { + Column(modifier = modifier.fillMaxWidth()) { + Text( + text = title, + style = MaterialTheme.typography.labelMedium, + color = MaterialTheme.colorScheme.onSurface, + modifier = Modifier + .alpha(0.7f) + .fillMaxWidth(), + ) + Text( + text = description, + style = descriptionStyle, + color = MaterialTheme.colorScheme.onSurface, + modifier = Modifier.fillMaxWidth(), + ) + } +} + +@Composable +fun MifosTextTitleDescDrawableSingleLine( + title: String, + description: String, + imageResId: DrawableResource, + modifier: Modifier = Modifier, + imageSize: Dp = 14.dp, + onDrawableClick: () -> Unit = {}, +) { + Row( + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.SpaceBetween, + modifier = modifier.fillMaxWidth(), + ) { + Text( + style = MaterialTheme.typography.labelMedium, + color = MaterialTheme.colorScheme.onSurface, + text = title, + modifier = Modifier + .weight(1f) + .alpha(0.7f), + ) + Text( + style = MaterialTheme.typography.bodyMedium, + color = MaterialTheme.colorScheme.onSurface, + text = description, + ) + Spacer(modifier = Modifier.width(5.dp)) + Image( + painter = painterResource(imageResId), + contentDescription = null, + modifier = Modifier + .size(imageSize) + .clickable { onDrawableClick() }, + ) + } +} + +@Composable +fun MifosTitleDescSingleLineEqual( + title: String, + description: String, + modifier: Modifier = Modifier, +) { + Row( + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.SpaceBetween, + modifier = modifier.fillMaxWidth(), + ) { + Text( + style = MaterialTheme.typography.labelMedium, + color = MaterialTheme.colorScheme.onSurface, + text = title, + modifier = Modifier + .alpha(0.7f) + .weight(1f), + ) + + Text( + style = MaterialTheme.typography.bodyMedium, + color = MaterialTheme.colorScheme.onSurface, + text = description, + modifier = Modifier.weight(1f), + ) + } +} + +@DevicePreviews +@Composable +private fun MifosTextTitleDescSingleLinePreview( + modifier: Modifier = Modifier, +) { + MifosMobileTheme { + MifosTextTitleDescSingleLine( + title = "MifosTextTitleDescSingleLine Title", + description = "MifosTextTitleDescSingleLine Description", + modifier = modifier, + ) + } +} + +@DevicePreviews +@Composable +private fun MifosTextTitleDescDoubleLinePreview( + modifier: Modifier = Modifier, +) { + MifosMobileTheme { + MifosTextTitleDescDoubleLine( + title = "MifosTextTitleDescDoubleLine Title", + description = "MifosTextTitleDescDoubleLine Description", + descriptionStyle = MaterialTheme.typography.bodyMedium, + modifier = modifier, + ) + } +} + +@DevicePreviews +@Composable +private fun MifosTextTitleDescDrawableSingleLinePreview( + modifier: Modifier = Modifier, +) { + MifosMobileTheme { + MifosTextTitleDescDrawableSingleLine( + title = "MifosTextTitleDescDrawableSingleLine Title", + description = "MifosTextTitleDescDrawableSingleLine Description", + imageResId = Res.drawable.core_common_circular_background, + modifier = modifier, + ) + } +} + +@DevicePreviews +@Composable +private fun MifosTitleDescSingleLineEqualPreview( + modifier: Modifier = Modifier, +) { + MifosMobileTheme { + MifosTitleDescSingleLineEqual( + title = "MifosTitleDescSingleLineEqual Title", + description = "MifosTitleDescSingleLineEqual Description", + modifier = modifier, + ) + } +} diff --git a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosTitleSearchCard.kt b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosTitleSearchCard.kt new file mode 100644 index 000000000..5b323f993 --- /dev/null +++ b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosTitleSearchCard.kt @@ -0,0 +1,110 @@ +/* + * Copyright 2024 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/mobile-mobile/blob/master/LICENSE.md + */ +package org.mifos.mobile.core.ui.component + + +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +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.Modifier +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.input.TextFieldValue +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import mifos_mobile.core.ui.generated.resources.Res +import org.jetbrains.compose.resources.StringResource +import org.jetbrains.compose.resources.stringResource +import org.mifos.mobile.core.designsystem.components.MifosSearchTextField +import org.mifos.mobile.core.designsystem.icons.MifosIcons +import org.mifos.mobile.core.designsystem.theme.MifosMobileTheme +import org.mifos.mobile.core.ui.utils.DevicePreviews + +@Composable +fun MifosTitleSearchCard( + titleResourceId: StringResource, + searchQuery: (String) -> Unit, + onSearchDismiss: () -> Unit, + modifier: Modifier = Modifier, +) { + var isSearching by rememberSaveable { mutableStateOf(false) } + var searchedQuery by rememberSaveable(stateSaver = TextFieldValue.Saver) { + mutableStateOf( + TextFieldValue(""), + ) + } + + if (!isSearching) { + Row( + modifier = modifier, + verticalAlignment = Alignment.CenterVertically, + ) { + Text( + text = stringResource(titleResourceId), + color = MaterialTheme.colorScheme.onSurface, + style = TextStyle(fontSize = 24.sp), + modifier = Modifier.weight(1f), + maxLines = 1, + ) + + IconButton(onClick = { isSearching = true }) { + Icon( + imageVector = MifosIcons.Search, + contentDescription = "Search Icon", + tint = MaterialTheme.colorScheme.onSurface, + ) + } + } + } else { + Row( + modifier = Modifier + .padding(horizontal = 4.dp), + verticalAlignment = Alignment.CenterVertically, + ) { + MifosSearchTextField( + modifier = Modifier.fillMaxWidth(), + value = searchedQuery, + onValueChange = { + searchedQuery = it + searchQuery(it.text) + }, + onSearchDismiss = { + searchedQuery = TextFieldValue("") + isSearching = false + onSearchDismiss.invoke() + }, + ) + } + } +} + +@DevicePreviews +@Composable +private fun MifosTitleSearchCardPreview( + modifier: Modifier = Modifier, +) { + MifosMobileTheme { + MifosTitleSearchCard( + titleResourceId = Res.string.core_common_working, + searchQuery = {}, + onSearchDismiss = {}, + modifier = modifier, + ) + } +} diff --git a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosUserImage.kt b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosUserImage.kt new file mode 100644 index 000000000..e0b4b2a4d --- /dev/null +++ b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosUserImage.kt @@ -0,0 +1,59 @@ +/* + * Copyright 2024 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/mobile-mobile/blob/master/LICENSE.md + */ +package org.mifos.mobile.core.ui.component + +import androidx.compose.foundation.Image +import androidx.compose.foundation.background +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.material3.MaterialTheme +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.layout.ContentScale +import coil3.Bitmap +import org.mifos.mobile.core.designsystem.theme.MifosMobileTheme +import org.mifos.mobile.core.ui.utils.DevicePreviews + +@Composable +fun MifosUserImage( + bitmap: Bitmap?, + modifier: Modifier = Modifier, + username: String? = null, +) { + if (bitmap == null) { + MifosTextUserImage( + text = username?.firstOrNull()?.toString() ?: "M", + modifier = modifier, + ) + } else { + Image( + modifier = modifier + .clip(CircleShape) + .background(MaterialTheme.colorScheme.primary), + bitmap = bitmap.asImageBitmap(), + contentDescription = "Profile Image", + contentScale = ContentScale.Crop, + ) + } +} + +@DevicePreviews +@Composable +private fun MifosUserImagePreview( + modifier: Modifier = Modifier, +) { + MifosMobileTheme { + MifosUserImage( + bitmap = null, + modifier = modifier, + username = "John Doe", + ) + } +} diff --git a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MonitorListItemWithIcon.kt b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MonitorListItemWithIcon.kt new file mode 100644 index 000000000..91f378d88 --- /dev/null +++ b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MonitorListItemWithIcon.kt @@ -0,0 +1,90 @@ +/* + * Copyright 2024 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/mobile-mobile/blob/master/LICENSE.md + */ +package org.mifos.mobile.core.ui.component + + +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.alpha +import androidx.compose.ui.unit.dp +import mifos_mobile.core.ui.generated.resources.Res +import mifos_mobile.core.ui.generated.resources.something_went_wrong +import mifos_mobile.core.ui.generated.resources.core_common_working +import org.jetbrains.compose.resources.DrawableResource +import org.jetbrains.compose.resources.StringResource +import org.jetbrains.compose.resources.stringResource +import org.mifos.mobile.core.designsystem.theme.MifosMobileTheme +import org.mifos.mobile.core.ui.utils.DevicePreviews + + +@Composable +fun MonitorListItemWithIcon( + titleId: StringResource, + subTitleId: StringResource, + iconId: DrawableResource, + onClick: () -> Unit, + modifier: Modifier = Modifier, +) { + Row( + modifier = modifier + .clickable { onClick.invoke() } + .padding(8.dp), + verticalAlignment = Alignment.CenterVertically, + ) { + MifosRoundIcon( + iconId = iconId, + modifier = Modifier.size(39.dp), + ) + Spacer(modifier = Modifier.width(8.dp)) + Column { + Text( + text = stringResource(titleId), + style = MaterialTheme.typography.bodyLarge, + color = MaterialTheme.colorScheme.onSurface, + modifier = Modifier.fillMaxWidth(), + ) + Text( + text = stringResource(subTitleId), + style = MaterialTheme.typography.bodyMedium, + color = MaterialTheme.colorScheme.onSurface, + modifier = Modifier + .alpha(0.7f) + .fillMaxWidth(), + ) + } + } +} + +@DevicePreviews +@Composable +private fun MonitorListItemWithIconPreview( + modifier: Modifier = Modifier, +) { + MifosMobileTheme { + MonitorListItemWithIcon( + titleId = Res.string.core_common_working, + subTitleId = Res.string.something_went_wrong, + iconId = Res.drawable.core_common_circular_background, + onClick = {}, + modifier = modifier, + ) + } +} diff --git a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/NoInternet.kt b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/NoInternet.kt new file mode 100644 index 000000000..f68c0fd70 --- /dev/null +++ b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/NoInternet.kt @@ -0,0 +1,101 @@ +/* + * Copyright 2024 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/mobile-mobile/blob/master/LICENSE.md + */ +package org.mifos.mobile.core.ui.component + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.material3.FilledTonalButton +import androidx.compose.material3.Icon +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import mifos_mobile.core.ui.generated.resources.Res +import androidx.compose.ui.graphics.vector.ImageVector + + +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import mifos_mobile.core.ui.generated.resources.no_internet + +import org.jetbrains.compose.resources.DrawableResource +import org.jetbrains.compose.resources.StringResource +import org.jetbrains.compose.resources.painterResource +import org.jetbrains.compose.resources.stringResource +import org.mifos.mobile.core.designsystem.icons.MifosIcons +import org.mifos.mobile.core.designsystem.theme.MifosMobileTheme +import org.mifos.mobile.core.ui.utils.DevicePreviews + +@Composable +fun NoInternet( + error: StringResource, + modifier: Modifier = Modifier, + isRetryEnabled: Boolean = true, + icon: DrawableResource? = null, + retry: () -> Unit = {}, +) { + Column( + modifier = modifier + .fillMaxSize() + .background(MaterialTheme.colorScheme.background), + verticalArrangement = Arrangement.Center, + horizontalAlignment = Alignment.CenterHorizontally, + ) { + Icon( + modifier = Modifier + .size(100.dp) + .padding(bottom = 12.dp), + painter = if (icon != null) { + painterResource(icon) + } else { + MifosIcons.WifiOff + }, + contentDescription = null, + tint = MaterialTheme.colorScheme.onSecondary, + ) + + Text( + text = stringResource(error), + style = TextStyle(fontSize = 20.sp), + color = MaterialTheme.colorScheme.onSecondary, + ) + + Spacer(modifier = Modifier.height(12.dp)) + if (isRetryEnabled) { + FilledTonalButton(onClick = { retry.invoke() }) { + Text(text = "Retry") + } + } + } +} + +@DevicePreviews +@Composable +private fun NoInternetPreview( + modifier: Modifier = Modifier, +) { + MifosMobileTheme { + NoInternet( + error = Res.string.no_internet, + modifier = modifier, + isRetryEnabled = true, + icon = Res.drawable.core_common_circular_background, + retry = {}, + ) + } +} \ No newline at end of file diff --git a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/UserProfileField.kt b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/UserProfileField.kt new file mode 100644 index 000000000..e7fa651ad --- /dev/null +++ b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/UserProfileField.kt @@ -0,0 +1,118 @@ +/* + * Copyright 2024 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/mobile-mobile/blob/master/LICENSE.md + */ +package org.mifos.mobile.core.ui.component + + +import androidx.compose.foundation.clickable +import androidx.compose.foundation.isSystemInDarkTheme +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.material3.HorizontalDivider +import androidx.compose.material3.Icon +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import mifos_mobile.core.ui.generated.resources.Res +import org.jetbrains.compose.resources.DrawableResource +import org.jetbrains.compose.resources.StringResource +import org.jetbrains.compose.resources.painterResource +import org.jetbrains.compose.resources.stringResource +import org.mifos.mobile.core.designsystem.theme.MifosMobileTheme +import org.mifos.mobile.core.ui.utils.DevicePreviews + +@Composable +fun UserProfileField( + text: StringResource, + icon: DrawableResource, + onClick: (() -> Unit), + modifier: Modifier = Modifier, +) { + Row( + modifier = modifier + .fillMaxWidth() + .clickable(onClick = onClick) + .padding(top = 16.dp, bottom = 16.dp, start = 8.dp, end = 8.dp), + horizontalArrangement = Arrangement.SpaceBetween, + ) { + Text( + text = stringResource(text), + color = Color(0xFF8E9099), + style = TextStyle(fontSize = 12.sp, fontWeight = FontWeight.SemiBold), + ) + Icon( + painter = painterResource(icon), + contentDescription = null, + tint = if (isSystemInDarkTheme()) Color.White else Color.Black, + ) + } + HorizontalDivider(color = if (isSystemInDarkTheme()) Color(0xFF8E9099) else Color.Black) +} + +@Composable +fun UserProfileField( + label: StringResource, + value: String, + modifier: Modifier = Modifier, +) { + Row( + modifier = modifier + .fillMaxWidth() + .padding(top = 16.dp, bottom = 16.dp, start = 8.dp, end = 8.dp), + horizontalArrangement = Arrangement.SpaceBetween, + ) { + Text( + text = stringResource(label), + color = Color(0xFF8E9099), + style = TextStyle(fontSize = 12.sp, fontWeight = FontWeight.SemiBold), + ) + Text( + text = value, + color = if (isSystemInDarkTheme()) Color.White else Color.Black, + style = TextStyle(fontSize = 14.sp), + ) + } + HorizontalDivider(color = Color(0xFF8E9099)) +} + +@DevicePreviews +@Composable +private fun UserProfileFieldPreview( + modifier: Modifier = Modifier, +) { + MifosMobileTheme { + UserProfileField( + text = Res.string.core_common_working, + icon = R.drawable.core_common_circular_background, + onClick = {}, + modifier = modifier, + ) + } +} + +@DevicePreviews +@Composable +private fun UserProfileFieldValuePreview( + modifier: Modifier = Modifier, +) { + MifosMobileTheme { + UserProfileField( + label = Res.string.core_common_working, + value = "UserProfileFieldValue", + modifier = modifier, + ) + } +} diff --git a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/UserProfileTopBar.kt b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/UserProfileTopBar.kt new file mode 100644 index 000000000..a76c44155 --- /dev/null +++ b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/UserProfileTopBar.kt @@ -0,0 +1,94 @@ +/* + * Copyright 2024 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/mobile-mobile/blob/master/LICENSE.md + */ +package org.mifos.mobile.core.ui.component + +import androidx.compose.foundation.clickable +import androidx.compose.foundation.isSystemInDarkTheme +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.Icon +import androidx.compose.material3.Text +import androidx.compose.material3.TopAppBar +import androidx.compose.material3.TopAppBarDefaults +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import org.jetbrains.compose.resources.StringResource +import org.jetbrains.compose.resources.stringResource +import org.mifos.mobile.core.designsystem.icons.MifosIcons + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun UserProfileTopBar( + text: StringResource, + home: () -> Unit, + modifier: Modifier = Modifier, +) { + TopAppBar( + modifier = modifier.height(64.dp), + title = { + Row( + modifier = Modifier + .fillMaxSize() + .padding(start = 16.dp), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.SpaceBetween, + ) { + Text( + text = stringResource(text), + color = if (isSystemInDarkTheme()) Color.White else Color.Black, + style = TextStyle(fontSize = 24.sp), + ) + Icon( + imageVector = MifosIcons.Edit, + contentDescription = null, + tint = if (isSystemInDarkTheme()) Color.White else Color.Black, + ) + } + }, + navigationIcon = { + Column( + modifier = Modifier + .fillMaxHeight() + .padding(start = 8.dp), + verticalArrangement = Arrangement.Center, + horizontalAlignment = Alignment.CenterHorizontally, + ) { + Icon( + imageVector = MifosIcons.ArrowBack, + contentDescription = null, + modifier = Modifier.clickable(onClick = { + home.invoke() + }), + tint = if (isSystemInDarkTheme()) Color.White else Color.Black, + ) + } + }, + colors = TopAppBarDefaults.topAppBarColors( + containerColor = if (isSystemInDarkTheme()) { + Color( + 0xFF1B1B1F, + ) + } else { + Color(0xFFFEFBFF) + }, + ), + ) +} diff --git a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/utils/ColorUtils.kt b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/utils/ColorUtils.kt new file mode 100644 index 000000000..8a7822b14 --- /dev/null +++ b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/utils/ColorUtils.kt @@ -0,0 +1,47 @@ +/* + * Copyright 2024 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/mobile-mobile/blob/master/LICENSE.md + */ +package org.mifos.mobile.core.ui.utils + +//import android.app.Activity +//import android.content.Context +//import android.util.TypedValue +//import androidx.annotation.AttrRes +//import androidx.annotation.ColorInt +//import androidx.core.graphics.ColorUtils +//import androidx.core.view.WindowCompat +// +//fun Activity.setStatusBarColor(@ColorInt color: Int) { +// if (!window.decorView.isInEditMode) { +// window.statusBarColor = color +// WindowCompat.getInsetsController(window, window.decorView).isAppearanceLightStatusBars = +// ColorUtils.calculateLuminance(color) > 0.5 +// } +//} +// +//@ColorInt +//fun Context.getThemeAttributeColor(@AttrRes colorAttribute: Int): Int { +// val typedValue = TypedValue() +// theme.resolveAttribute(colorAttribute, typedValue, true) +// return typedValue.data +//} + +import androidx.compose.runtime.Composable +import com.google.accompanist.systemuicontroller.rememberSystemUiController +import androidx.compose.ui.graphics.Color + +@Composable +fun SetStatusBarColor(color: Color) { + val systemUiController = rememberSystemUiController() + val isLightColor = androidx.compose.ui.graphics.ColorUtils.calculateLuminance(color) > 0.5 + systemUiController.setStatusBarColor( + color = color, + darkIcons = isLightColor + ) +} \ No newline at end of file diff --git a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/utils/DevicePreviews.kt b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/utils/DevicePreviews.kt new file mode 100644 index 000000000..e2b6ce675 --- /dev/null +++ b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/utils/DevicePreviews.kt @@ -0,0 +1,19 @@ +/* + * Copyright 2024 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/mobile-mobile/blob/master/LICENSE.md + */ +package org.mifos.mobile.core.ui.utils + +import org.jetbrains.compose.ui.tooling.preview.Preview + +/** + * Multipreview annotation that represents various device sizes. Add this annotation to a composable + * to render various devices. + */ +@Preview +annotation class DevicePreviews diff --git a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.kt b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.kt new file mode 100644 index 000000000..9ba20c089 --- /dev/null +++ b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.kt @@ -0,0 +1,141 @@ +/* + * Copyright 2024 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/mobile-mobile/blob/master/LICENSE.md + */ +package org.mifos.mobile.core.ui.utils + +import android.graphics.Bitmap +import android.graphics.BitmapFactory +import android.graphics.Canvas +import android.graphics.Matrix +import android.graphics.Paint +import android.util.Log + +object ImageUtil { + private const val DEFAULT_MAX_WIDTH = 816f + private const val DEFAULT_MAX_HEIGHT = 612f + + fun compressImage( + decodedBytes: ByteArray, + maxWidth: Float = DEFAULT_MAX_WIDTH, + maxHeight: Float = DEFAULT_MAX_HEIGHT, + ): Bitmap { + val options = BitmapFactory.Options().apply { + inJustDecodeBounds = true + } + + BitmapFactory.decodeByteArray(decodedBytes, 0, decodedBytes.size, options) + + val (actualWidth, actualHeight) = calculateActualDimensions(options, maxWidth, maxHeight) + + options.apply { + inJustDecodeBounds = false + inSampleSize = calculateInSampleSize(this, actualWidth, actualHeight) + inTempStorage = ByteArray(16 * 1024) + } + + val bmp = try { + BitmapFactory.decodeByteArray(decodedBytes, 0, decodedBytes.size, options) + } catch (e: OutOfMemoryError) { + Log.e(this::class.java.simpleName, "OutOfMemoryError while decoding bitmap", e) + return Bitmap.createBitmap( + 1, + 1, + Bitmap.Config.ARGB_8888, + ) // Return a 1x1 bitmap as fallback + } + + return try { + createScaledBitmap(bmp, actualWidth, actualHeight, options) + } catch (e: OutOfMemoryError) { + Log.e(this::class.java.simpleName, "OutOfMemoryError while scaling bitmap", e) + bmp // Return the original bitmap if scaling fails + } + } +} + +private fun calculateActualDimensions( + options: BitmapFactory.Options, + maxWidth: Float, + maxHeight: Float, +): Pair { + var actualWidth = options.outWidth + var actualHeight = options.outHeight + val imgRatio = actualWidth.toFloat() / actualHeight + val maxRatio = maxWidth / maxHeight + + if (actualHeight > maxHeight || actualWidth > maxWidth) { + when { + imgRatio < maxRatio -> { + actualHeight = maxHeight.toInt() + actualWidth = (maxHeight * imgRatio).toInt() + } + + imgRatio > maxRatio -> { + actualWidth = maxWidth.toInt() + actualHeight = (maxWidth / imgRatio).toInt() + } + + else -> { + actualHeight = maxHeight.toInt() + actualWidth = maxWidth.toInt() + } + } + } + + return Pair(actualWidth, actualHeight) +} + +private fun calculateInSampleSize( + options: BitmapFactory.Options, + reqWidth: Int, + reqHeight: Int, +): Int { + val (height, width) = options.run { outHeight to outWidth } + var inSampleSize = 1 + + if (height > reqHeight || width > reqWidth) { + val halfHeight = height / 2 + val halfWidth = width / 2 + + while (halfHeight / inSampleSize >= reqHeight && halfWidth / inSampleSize >= reqWidth) { + inSampleSize *= 2 + } + } + + return inSampleSize +} + +private fun createScaledBitmap( + bmp: Bitmap, + actualWidth: Int, + actualHeight: Int, + options: BitmapFactory.Options, +): Bitmap { + val scaledBitmap = Bitmap.createBitmap(actualWidth, actualHeight, Bitmap.Config.ARGB_8888) + val ratioX = actualWidth / options.outWidth.toFloat() + val ratioY = actualHeight / options.outHeight.toFloat() + val middleX = actualWidth / 2f + val middleY = actualHeight / 2f + + val scaleMatrix = Matrix().apply { + setScale(ratioX, ratioY, middleX, middleY) + } + + Canvas(scaledBitmap).apply { + setMatrix(scaleMatrix) + drawBitmap( + bmp, + middleX - bmp.width / 2, + middleY - bmp.height / 2, + Paint(Paint.FILTER_BITMAP_FLAG), + ) + } + + return scaledBitmap +} diff --git a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/utils/PresentOrFutureSelectableDates.kt b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/utils/PresentOrFutureSelectableDates.kt new file mode 100644 index 000000000..458857a83 --- /dev/null +++ b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/utils/PresentOrFutureSelectableDates.kt @@ -0,0 +1,34 @@ +/* + * Copyright 2024 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/mobile-mobile/blob/master/LICENSE.md + */ +package org.mifos.mobile.core.ui.utils + +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.SelectableDates +import kotlinx.datetime.Clock +import kotlinx.datetime.TimeZone +import kotlinx.datetime.toLocalDateTime + +@OptIn(ExperimentalMaterial3Api::class) +object PresentOrFutureSelectableDates : SelectableDates { + + @ExperimentalMaterial3Api + override fun isSelectableDate(utcTimeMillis: Long): Boolean { + val currentTimeMillis = Clock.System.now().toEpochMilliseconds() + return utcTimeMillis >= currentTimeMillis + } + + override fun isSelectableYear(year: Int): Boolean { + val currentYear = Clock.System.now() + .toLocalDateTime(TimeZone.currentSystemDefault()) + .year + return year >= currentYear + } +} + From 3e056656f81511c8f53a928edd659e5d02f473cf Mon Sep 17 00:00:00 2001 From: revanthkumarJ Date: Thu, 16 Jan 2025 20:27:38 +0530 Subject: [PATCH 02/11] updated --- .../demoDebugRuntimeClasspath.txt | 15 ++ .../demoReleaseRuntimeClasspath.txt | 15 ++ .../prodDebugRuntimeClasspath.txt | 15 ++ .../prodReleaseRuntimeClasspath.txt | 15 ++ core/ui/build.gradle.kts | 42 +++- .../mobile/core/ui/component/EmptyDataView.kt | 7 +- .../mobile/core/ui/component/FaqItemHolder.kt | 5 - .../core/ui/component/MifosErrorComponent.kt | 4 +- .../core/ui/component/MifosMobileIcon.kt | 1 - .../core/ui/component/MifosRoundIcon.kt | 1 - .../MifosTextButtonWithTopDrawable.kt | 1 - .../core/ui/component/MifosTitleSearchCard.kt | 1 - .../ui/component/MonitorListItemWithIcon.kt | 4 +- .../mobile/core/ui/component/NoInternet.kt | 8 +- .../core/ui/component/UserProfileField.kt | 1 - .../mifos/mobile/core/ui/utils/ColorUtils.kt | 30 +-- .../utils/PresentOrFutureSelectableDates.kt | 1 - core/ui/src/main/AndroidManifest.xml | 13 -- .../core/ui/component/AboutUsItemCard.kt | 75 ------ .../mobile/core/ui/component/EmptyDataView.kt | 85 ------- .../mobile/core/ui/component/FaqItemHolder.kt | 114 --------- .../mobile/core/ui/component/MFStepProcess.kt | 127 ---------- .../core/ui/component/MifosAlertDialog.kt | 74 ------ .../mobile/core/ui/component/MifosCheckBox.kt | 54 ----- .../ui/component/MifosDropDownTextField.kt | 220 ------------------ .../core/ui/component/MifosErrorComponent.kt | 202 ---------------- .../core/ui/component/MifosHiddenTextRow.kt | 105 --------- .../mobile/core/ui/component/MifosItemCard.kt | 60 ----- .../mobile/core/ui/component/MifosLinkText.kt | 56 ----- .../core/ui/component/MifosMobileIcon.kt | 55 ----- .../ui/component/MifosProgressIndicator.kt | 50 ---- .../component/MifosRadioButtonAlertDialog.kt | 99 -------- .../core/ui/component/MifosRoundIcon.kt | 58 ----- .../MifosTextButtonWithTopDrawable.kt | 82 ------- .../core/ui/component/MifosTextUserImage.kt | 71 ------ .../mobile/core/ui/component/MifosTexts.kt | 212 ----------------- .../core/ui/component/MifosTitleSearchCard.kt | 110 --------- .../core/ui/component/MifosUserImage.kt | 60 ----- .../ui/component/MonitorListItemWithIcon.kt | 86 ------- .../mobile/core/ui/component/NoInternet.kt | 97 -------- .../core/ui/component/UserProfileField.kt | 117 ---------- .../core/ui/component/UserProfileTopBar.kt | 93 -------- .../mifos/mobile/core/ui/utils/ColorUtils.kt | 33 --- .../mobile/core/ui/utils/DevicePreviews.kt | 22 -- .../mifos/mobile/core/ui/utils/ImageUtil.kt | 141 ----------- .../utils/PresentOrFutureSelectableDates.kt | 26 --- core/ui/src/main/res/values/colors.xml | 13 -- core/ui/src/main/res/values/strings.xml | 16 -- gradle.properties | 3 +- gradle/libs.versions.toml | 4 + 50 files changed, 120 insertions(+), 2679 deletions(-) delete mode 100644 core/ui/src/main/AndroidManifest.xml delete mode 100644 core/ui/src/main/java/org/mifos/mobile/core/ui/component/AboutUsItemCard.kt delete mode 100644 core/ui/src/main/java/org/mifos/mobile/core/ui/component/EmptyDataView.kt delete mode 100644 core/ui/src/main/java/org/mifos/mobile/core/ui/component/FaqItemHolder.kt delete mode 100644 core/ui/src/main/java/org/mifos/mobile/core/ui/component/MFStepProcess.kt delete mode 100644 core/ui/src/main/java/org/mifos/mobile/core/ui/component/MifosAlertDialog.kt delete mode 100644 core/ui/src/main/java/org/mifos/mobile/core/ui/component/MifosCheckBox.kt delete mode 100644 core/ui/src/main/java/org/mifos/mobile/core/ui/component/MifosDropDownTextField.kt delete mode 100644 core/ui/src/main/java/org/mifos/mobile/core/ui/component/MifosErrorComponent.kt delete mode 100644 core/ui/src/main/java/org/mifos/mobile/core/ui/component/MifosHiddenTextRow.kt delete mode 100644 core/ui/src/main/java/org/mifos/mobile/core/ui/component/MifosItemCard.kt delete mode 100644 core/ui/src/main/java/org/mifos/mobile/core/ui/component/MifosLinkText.kt delete mode 100644 core/ui/src/main/java/org/mifos/mobile/core/ui/component/MifosMobileIcon.kt delete mode 100644 core/ui/src/main/java/org/mifos/mobile/core/ui/component/MifosProgressIndicator.kt delete mode 100644 core/ui/src/main/java/org/mifos/mobile/core/ui/component/MifosRadioButtonAlertDialog.kt delete mode 100644 core/ui/src/main/java/org/mifos/mobile/core/ui/component/MifosRoundIcon.kt delete mode 100644 core/ui/src/main/java/org/mifos/mobile/core/ui/component/MifosTextButtonWithTopDrawable.kt delete mode 100644 core/ui/src/main/java/org/mifos/mobile/core/ui/component/MifosTextUserImage.kt delete mode 100644 core/ui/src/main/java/org/mifos/mobile/core/ui/component/MifosTexts.kt delete mode 100644 core/ui/src/main/java/org/mifos/mobile/core/ui/component/MifosTitleSearchCard.kt delete mode 100644 core/ui/src/main/java/org/mifos/mobile/core/ui/component/MifosUserImage.kt delete mode 100644 core/ui/src/main/java/org/mifos/mobile/core/ui/component/MonitorListItemWithIcon.kt delete mode 100644 core/ui/src/main/java/org/mifos/mobile/core/ui/component/NoInternet.kt delete mode 100644 core/ui/src/main/java/org/mifos/mobile/core/ui/component/UserProfileField.kt delete mode 100644 core/ui/src/main/java/org/mifos/mobile/core/ui/component/UserProfileTopBar.kt delete mode 100644 core/ui/src/main/java/org/mifos/mobile/core/ui/utils/ColorUtils.kt delete mode 100644 core/ui/src/main/java/org/mifos/mobile/core/ui/utils/DevicePreviews.kt delete mode 100644 core/ui/src/main/java/org/mifos/mobile/core/ui/utils/ImageUtil.kt delete mode 100644 core/ui/src/main/java/org/mifos/mobile/core/ui/utils/PresentOrFutureSelectableDates.kt delete mode 100644 core/ui/src/main/res/values/colors.xml delete mode 100644 core/ui/src/main/res/values/strings.xml diff --git a/androidApp/dependencies/demoDebugRuntimeClasspath.txt b/androidApp/dependencies/demoDebugRuntimeClasspath.txt index be9a20c67..94b4cc92d 100644 --- a/androidApp/dependencies/demoDebugRuntimeClasspath.txt +++ b/androidApp/dependencies/demoDebugRuntimeClasspath.txt @@ -140,8 +140,10 @@ co.touchlab:stately-concurrent-collections:2.1.0 co.touchlab:stately-strict-jvm:2.1.0 co.touchlab:stately-strict:2.1.0 com.caverock:androidsvg-aar:1.4 +com.google.accompanist:accompanist-drawablepainter:0.36.0 com.google.accompanist:accompanist-pager:0.34.0 com.google.accompanist:accompanist-permissions:0.34.0 +com.google.accompanist:accompanist-systemuicontroller:0.30.1 com.google.android.gms:play-services-ads-identifier:18.0.0 com.google.android.gms:play-services-base:18.5.0 com.google.android.gms:play-services-basement:18.4.0 @@ -195,6 +197,8 @@ com.squareup.retrofit2:converter-gson:2.11.0 com.squareup.retrofit2:retrofit:2.11.0 dev.chrisbanes.snapper:snapper:0.2.2 io.coil-kt.coil3:coil-android:3.0.4 +io.coil-kt.coil3:coil-compose-core-android:3.0.4 +io.coil-kt.coil3:coil-compose-core:3.0.4 io.coil-kt.coil3:coil-core-android:3.0.4 io.coil-kt.coil3:coil-core:3.0.4 io.coil-kt.coil3:coil-network-core-android:3.0.4 @@ -205,6 +209,10 @@ io.coil-kt.coil3:coil-svg-android:3.0.4 io.coil-kt.coil3:coil-svg:3.0.4 io.coil-kt.coil3:coil:3.0.4 io.github.mr0xf00:easycrop:0.1.1 +io.github.vinceglb:filekit-compose-android:0.8.7 +io.github.vinceglb:filekit-compose:0.8.7 +io.github.vinceglb:filekit-core-android:0.8.7 +io.github.vinceglb:filekit-core:0.8.7 io.insert-koin:koin-android:4.0.1-RC1 io.insert-koin:koin-androidx-compose:4.0.1-RC1 io.insert-koin:koin-annotations-jvm:1.4.0-RC4 @@ -250,11 +258,18 @@ org.jetbrains.androidx.lifecycle:lifecycle-runtime:2.8.3-rc01 org.jetbrains.androidx.lifecycle:lifecycle-viewmodel-compose:2.8.3 org.jetbrains.androidx.lifecycle:lifecycle-viewmodel-savedstate:2.8.3 org.jetbrains.androidx.lifecycle:lifecycle-viewmodel:2.8.3 +org.jetbrains.androidx.navigation:navigation-common:2.8.0-alpha10 +org.jetbrains.androidx.navigation:navigation-compose:2.8.0-alpha10 +org.jetbrains.androidx.navigation:navigation-runtime:2.8.0-alpha10 org.jetbrains.androidx.savedstate:savedstate:1.2.2 org.jetbrains.compose.animation:animation-core:1.7.0-rc01 org.jetbrains.compose.animation:animation:1.7.0-rc01 org.jetbrains.compose.annotation-internal:annotation:1.7.3 org.jetbrains.compose.collection-internal:collection:1.7.3 +org.jetbrains.compose.components:components-resources-android:1.7.0-rc01 +org.jetbrains.compose.components:components-resources:1.7.0-rc01 +org.jetbrains.compose.components:components-ui-tooling-preview-android:1.7.0-rc01 +org.jetbrains.compose.components:components-ui-tooling-preview:1.7.0-rc01 org.jetbrains.compose.foundation:foundation-layout:1.7.0-rc01 org.jetbrains.compose.foundation:foundation:1.7.0-rc01 org.jetbrains.compose.material3:material3:1.7.0-rc01 diff --git a/androidApp/dependencies/demoReleaseRuntimeClasspath.txt b/androidApp/dependencies/demoReleaseRuntimeClasspath.txt index 8f6afb06d..5c7dc8b63 100644 --- a/androidApp/dependencies/demoReleaseRuntimeClasspath.txt +++ b/androidApp/dependencies/demoReleaseRuntimeClasspath.txt @@ -135,8 +135,10 @@ co.touchlab:stately-concurrent-collections:2.1.0 co.touchlab:stately-strict-jvm:2.1.0 co.touchlab:stately-strict:2.1.0 com.caverock:androidsvg-aar:1.4 +com.google.accompanist:accompanist-drawablepainter:0.36.0 com.google.accompanist:accompanist-pager:0.34.0 com.google.accompanist:accompanist-permissions:0.34.0 +com.google.accompanist:accompanist-systemuicontroller:0.30.1 com.google.android.gms:play-services-ads-identifier:18.0.0 com.google.android.gms:play-services-base:18.5.0 com.google.android.gms:play-services-basement:18.4.0 @@ -190,6 +192,8 @@ com.squareup.retrofit2:converter-gson:2.11.0 com.squareup.retrofit2:retrofit:2.11.0 dev.chrisbanes.snapper:snapper:0.2.2 io.coil-kt.coil3:coil-android:3.0.4 +io.coil-kt.coil3:coil-compose-core-android:3.0.4 +io.coil-kt.coil3:coil-compose-core:3.0.4 io.coil-kt.coil3:coil-core-android:3.0.4 io.coil-kt.coil3:coil-core:3.0.4 io.coil-kt.coil3:coil-network-core-android:3.0.4 @@ -200,6 +204,10 @@ io.coil-kt.coil3:coil-svg-android:3.0.4 io.coil-kt.coil3:coil-svg:3.0.4 io.coil-kt.coil3:coil:3.0.4 io.github.mr0xf00:easycrop:0.1.1 +io.github.vinceglb:filekit-compose-android:0.8.7 +io.github.vinceglb:filekit-compose:0.8.7 +io.github.vinceglb:filekit-core-android:0.8.7 +io.github.vinceglb:filekit-core:0.8.7 io.insert-koin:koin-android:4.0.1-RC1 io.insert-koin:koin-androidx-compose:4.0.1-RC1 io.insert-koin:koin-annotations-jvm:1.4.0-RC4 @@ -245,11 +253,18 @@ org.jetbrains.androidx.lifecycle:lifecycle-runtime:2.8.3-rc01 org.jetbrains.androidx.lifecycle:lifecycle-viewmodel-compose:2.8.3 org.jetbrains.androidx.lifecycle:lifecycle-viewmodel-savedstate:2.8.3 org.jetbrains.androidx.lifecycle:lifecycle-viewmodel:2.8.3 +org.jetbrains.androidx.navigation:navigation-common:2.8.0-alpha10 +org.jetbrains.androidx.navigation:navigation-compose:2.8.0-alpha10 +org.jetbrains.androidx.navigation:navigation-runtime:2.8.0-alpha10 org.jetbrains.androidx.savedstate:savedstate:1.2.2 org.jetbrains.compose.animation:animation-core:1.7.0-rc01 org.jetbrains.compose.animation:animation:1.7.0-rc01 org.jetbrains.compose.annotation-internal:annotation:1.7.3 org.jetbrains.compose.collection-internal:collection:1.7.3 +org.jetbrains.compose.components:components-resources-android:1.7.0-rc01 +org.jetbrains.compose.components:components-resources:1.7.0-rc01 +org.jetbrains.compose.components:components-ui-tooling-preview-android:1.7.0-rc01 +org.jetbrains.compose.components:components-ui-tooling-preview:1.7.0-rc01 org.jetbrains.compose.foundation:foundation-layout:1.7.0-rc01 org.jetbrains.compose.foundation:foundation:1.7.0-rc01 org.jetbrains.compose.material3:material3:1.7.0-rc01 diff --git a/androidApp/dependencies/prodDebugRuntimeClasspath.txt b/androidApp/dependencies/prodDebugRuntimeClasspath.txt index be9a20c67..94b4cc92d 100644 --- a/androidApp/dependencies/prodDebugRuntimeClasspath.txt +++ b/androidApp/dependencies/prodDebugRuntimeClasspath.txt @@ -140,8 +140,10 @@ co.touchlab:stately-concurrent-collections:2.1.0 co.touchlab:stately-strict-jvm:2.1.0 co.touchlab:stately-strict:2.1.0 com.caverock:androidsvg-aar:1.4 +com.google.accompanist:accompanist-drawablepainter:0.36.0 com.google.accompanist:accompanist-pager:0.34.0 com.google.accompanist:accompanist-permissions:0.34.0 +com.google.accompanist:accompanist-systemuicontroller:0.30.1 com.google.android.gms:play-services-ads-identifier:18.0.0 com.google.android.gms:play-services-base:18.5.0 com.google.android.gms:play-services-basement:18.4.0 @@ -195,6 +197,8 @@ com.squareup.retrofit2:converter-gson:2.11.0 com.squareup.retrofit2:retrofit:2.11.0 dev.chrisbanes.snapper:snapper:0.2.2 io.coil-kt.coil3:coil-android:3.0.4 +io.coil-kt.coil3:coil-compose-core-android:3.0.4 +io.coil-kt.coil3:coil-compose-core:3.0.4 io.coil-kt.coil3:coil-core-android:3.0.4 io.coil-kt.coil3:coil-core:3.0.4 io.coil-kt.coil3:coil-network-core-android:3.0.4 @@ -205,6 +209,10 @@ io.coil-kt.coil3:coil-svg-android:3.0.4 io.coil-kt.coil3:coil-svg:3.0.4 io.coil-kt.coil3:coil:3.0.4 io.github.mr0xf00:easycrop:0.1.1 +io.github.vinceglb:filekit-compose-android:0.8.7 +io.github.vinceglb:filekit-compose:0.8.7 +io.github.vinceglb:filekit-core-android:0.8.7 +io.github.vinceglb:filekit-core:0.8.7 io.insert-koin:koin-android:4.0.1-RC1 io.insert-koin:koin-androidx-compose:4.0.1-RC1 io.insert-koin:koin-annotations-jvm:1.4.0-RC4 @@ -250,11 +258,18 @@ org.jetbrains.androidx.lifecycle:lifecycle-runtime:2.8.3-rc01 org.jetbrains.androidx.lifecycle:lifecycle-viewmodel-compose:2.8.3 org.jetbrains.androidx.lifecycle:lifecycle-viewmodel-savedstate:2.8.3 org.jetbrains.androidx.lifecycle:lifecycle-viewmodel:2.8.3 +org.jetbrains.androidx.navigation:navigation-common:2.8.0-alpha10 +org.jetbrains.androidx.navigation:navigation-compose:2.8.0-alpha10 +org.jetbrains.androidx.navigation:navigation-runtime:2.8.0-alpha10 org.jetbrains.androidx.savedstate:savedstate:1.2.2 org.jetbrains.compose.animation:animation-core:1.7.0-rc01 org.jetbrains.compose.animation:animation:1.7.0-rc01 org.jetbrains.compose.annotation-internal:annotation:1.7.3 org.jetbrains.compose.collection-internal:collection:1.7.3 +org.jetbrains.compose.components:components-resources-android:1.7.0-rc01 +org.jetbrains.compose.components:components-resources:1.7.0-rc01 +org.jetbrains.compose.components:components-ui-tooling-preview-android:1.7.0-rc01 +org.jetbrains.compose.components:components-ui-tooling-preview:1.7.0-rc01 org.jetbrains.compose.foundation:foundation-layout:1.7.0-rc01 org.jetbrains.compose.foundation:foundation:1.7.0-rc01 org.jetbrains.compose.material3:material3:1.7.0-rc01 diff --git a/androidApp/dependencies/prodReleaseRuntimeClasspath.txt b/androidApp/dependencies/prodReleaseRuntimeClasspath.txt index 8f6afb06d..5c7dc8b63 100644 --- a/androidApp/dependencies/prodReleaseRuntimeClasspath.txt +++ b/androidApp/dependencies/prodReleaseRuntimeClasspath.txt @@ -135,8 +135,10 @@ co.touchlab:stately-concurrent-collections:2.1.0 co.touchlab:stately-strict-jvm:2.1.0 co.touchlab:stately-strict:2.1.0 com.caverock:androidsvg-aar:1.4 +com.google.accompanist:accompanist-drawablepainter:0.36.0 com.google.accompanist:accompanist-pager:0.34.0 com.google.accompanist:accompanist-permissions:0.34.0 +com.google.accompanist:accompanist-systemuicontroller:0.30.1 com.google.android.gms:play-services-ads-identifier:18.0.0 com.google.android.gms:play-services-base:18.5.0 com.google.android.gms:play-services-basement:18.4.0 @@ -190,6 +192,8 @@ com.squareup.retrofit2:converter-gson:2.11.0 com.squareup.retrofit2:retrofit:2.11.0 dev.chrisbanes.snapper:snapper:0.2.2 io.coil-kt.coil3:coil-android:3.0.4 +io.coil-kt.coil3:coil-compose-core-android:3.0.4 +io.coil-kt.coil3:coil-compose-core:3.0.4 io.coil-kt.coil3:coil-core-android:3.0.4 io.coil-kt.coil3:coil-core:3.0.4 io.coil-kt.coil3:coil-network-core-android:3.0.4 @@ -200,6 +204,10 @@ io.coil-kt.coil3:coil-svg-android:3.0.4 io.coil-kt.coil3:coil-svg:3.0.4 io.coil-kt.coil3:coil:3.0.4 io.github.mr0xf00:easycrop:0.1.1 +io.github.vinceglb:filekit-compose-android:0.8.7 +io.github.vinceglb:filekit-compose:0.8.7 +io.github.vinceglb:filekit-core-android:0.8.7 +io.github.vinceglb:filekit-core:0.8.7 io.insert-koin:koin-android:4.0.1-RC1 io.insert-koin:koin-androidx-compose:4.0.1-RC1 io.insert-koin:koin-annotations-jvm:1.4.0-RC4 @@ -245,11 +253,18 @@ org.jetbrains.androidx.lifecycle:lifecycle-runtime:2.8.3-rc01 org.jetbrains.androidx.lifecycle:lifecycle-viewmodel-compose:2.8.3 org.jetbrains.androidx.lifecycle:lifecycle-viewmodel-savedstate:2.8.3 org.jetbrains.androidx.lifecycle:lifecycle-viewmodel:2.8.3 +org.jetbrains.androidx.navigation:navigation-common:2.8.0-alpha10 +org.jetbrains.androidx.navigation:navigation-compose:2.8.0-alpha10 +org.jetbrains.androidx.navigation:navigation-runtime:2.8.0-alpha10 org.jetbrains.androidx.savedstate:savedstate:1.2.2 org.jetbrains.compose.animation:animation-core:1.7.0-rc01 org.jetbrains.compose.animation:animation:1.7.0-rc01 org.jetbrains.compose.annotation-internal:annotation:1.7.3 org.jetbrains.compose.collection-internal:collection:1.7.3 +org.jetbrains.compose.components:components-resources-android:1.7.0-rc01 +org.jetbrains.compose.components:components-resources:1.7.0-rc01 +org.jetbrains.compose.components:components-ui-tooling-preview-android:1.7.0-rc01 +org.jetbrains.compose.components:components-ui-tooling-preview:1.7.0-rc01 org.jetbrains.compose.foundation:foundation-layout:1.7.0-rc01 org.jetbrains.compose.foundation:foundation:1.7.0-rc01 org.jetbrains.compose.material3:material3:1.7.0-rc01 diff --git a/core/ui/build.gradle.kts b/core/ui/build.gradle.kts index 3b2ac907b..993c3e970 100644 --- a/core/ui/build.gradle.kts +++ b/core/ui/build.gradle.kts @@ -8,23 +8,43 @@ * See https://github.com/openMF/mobile-mobile/blob/master/LICENSE.md */ plugins { - alias(libs.plugins.mifos.android.library) - alias(libs.plugins.mifos.android.library.compose) + alias(libs.plugins.mifos.kmp.library) +// alias(libs.plugins.mifos.android.library.compose) + alias(libs.plugins.jetbrainsCompose) + alias(libs.plugins.compose.compiler) } android { defaultConfig { testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" } - namespace = "org.mifos.mobile.core" + namespace = "org.mifos.mobile.core.ui" } -dependencies { - api(projects.core.designsystem) -// api(projects.core.model) - api(projects.core.common) - api(libs.androidx.metrics) - - testImplementation(libs.androidx.compose.ui.test) - androidTestImplementation(libs.bundles.androidx.compose.ui.test) +kotlin{ + sourceSets{ + androidMain.dependencies { + api(libs.androidx.metrics) + implementation(libs.androidx.compose.runtime) + implementation(libs.accompanist.pager) + } + commonMain.dependencies { +// api(projects.core.designsystem) + api(projects.core.model) + api(projects.core.common) + implementation(libs.jb.composeViewmodel) + implementation(libs.jb.lifecycleViewmodel) + implementation(libs.jb.lifecycleViewmodelSavedState) + implementation(libs.coil.kt) + implementation(libs.coil.kt.compose) + implementation(compose.material3) + implementation(compose.components.resources) + implementation(compose.components.uiToolingPreview) + implementation(libs.jb.composeNavigation) + implementation(libs.filekit.compose) + implementation(libs.filekit.core) + implementation(libs.accompanist.systemuicontroller) + } + } } + diff --git a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/EmptyDataView.kt b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/EmptyDataView.kt index 9af62a8c1..d6c4d5006 100644 --- a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/EmptyDataView.kt +++ b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/EmptyDataView.kt @@ -9,7 +9,6 @@ */ package org.mifos.mobile.core.ui.component - import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize @@ -25,6 +24,8 @@ import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp +import mifos_mobile.core.ui.generated.resources.Res +import mifos_mobile.core.ui.generated.resources.no_internet import org.jetbrains.compose.resources.DrawableResource import org.jetbrains.compose.resources.StringResource import org.jetbrains.compose.resources.painterResource @@ -32,14 +33,12 @@ import org.jetbrains.compose.resources.stringResource import org.mifos.mobile.core.designsystem.icons.MifosIcons import org.mifos.mobile.core.designsystem.theme.MifosMobileTheme import org.mifos.mobile.core.ui.utils.DevicePreviews -import mifos_mobile.core.ui.generated.resources.Res -import mifos_mobile.core.ui.generated.resources.no_internet @Composable fun EmptyDataView( error: StringResource, modifier: Modifier = Modifier.fillMaxSize(), - icon: DrawableResource?=null, + icon: DrawableResource? = null, errorString: String? = null, ) { Column( diff --git a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/FaqItemHolder.kt b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/FaqItemHolder.kt index 849ee2143..8ed4911b4 100644 --- a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/FaqItemHolder.kt +++ b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/FaqItemHolder.kt @@ -15,7 +15,6 @@ import androidx.compose.animation.core.spring import androidx.compose.animation.expandVertically import androidx.compose.animation.fadeIn import androidx.compose.foundation.clickable -import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxWidth @@ -28,7 +27,6 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.scale -import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.dp import org.mifos.mobile.core.designsystem.icons.MifosIcons import org.mifos.mobile.core.designsystem.theme.MifosMobileTheme @@ -59,7 +57,6 @@ fun FaqItemHolder( Text( text = question.orEmpty(), style = MaterialTheme.typography.bodyMedium, - color = if (isSystemInDarkTheme()) Color.White else Color.Black, modifier = Modifier .fillMaxWidth() .weight(1f), @@ -68,7 +65,6 @@ fun FaqItemHolder( Icon( imageVector = MifosIcons.ArrowDropDown, contentDescription = "drop down", - tint = if (isSystemInDarkTheme()) Color.White else Color.Gray, modifier = Modifier .scale(1f, if (isSelected) -1f else 1f), ) @@ -85,7 +81,6 @@ fun FaqItemHolder( Text( text = answer.orEmpty(), style = MaterialTheme.typography.bodyMedium, - color = if (isSystemInDarkTheme()) Color.White else Color.Black, modifier = Modifier .fillMaxWidth() .padding(bottom = 8.dp), diff --git a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosErrorComponent.kt b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosErrorComponent.kt index 896fadbea..79a27dae0 100644 --- a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosErrorComponent.kt +++ b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosErrorComponent.kt @@ -29,12 +29,12 @@ import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp -import org.jetbrains.compose.resources.stringResource -import mifos_mobile.core.ui.generated.resources.no_internet import mifos_mobile.core.ui.generated.resources.Res import mifos_mobile.core.ui.generated.resources.no_data +import mifos_mobile.core.ui.generated.resources.no_internet import mifos_mobile.core.ui.generated.resources.retry import mifos_mobile.core.ui.generated.resources.something_went_wrong +import org.jetbrains.compose.resources.stringResource import org.mifos.mobile.core.designsystem.icons.MifosIcons import org.mifos.mobile.core.designsystem.theme.MifosMobileTheme import org.mifos.mobile.core.ui.utils.DevicePreviews diff --git a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosMobileIcon.kt b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosMobileIcon.kt index 6686fb984..189273af5 100644 --- a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosMobileIcon.kt +++ b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosMobileIcon.kt @@ -9,7 +9,6 @@ */ package org.mifos.mobile.core.ui.component - import androidx.compose.foundation.Image import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxWidth diff --git a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosRoundIcon.kt b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosRoundIcon.kt index 6f63164bc..87ec1f16b 100644 --- a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosRoundIcon.kt +++ b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosRoundIcon.kt @@ -9,7 +9,6 @@ */ package org.mifos.mobile.core.ui.component - import androidx.compose.foundation.Image import androidx.compose.foundation.layout.padding import androidx.compose.foundation.shape.CircleShape diff --git a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosTextButtonWithTopDrawable.kt b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosTextButtonWithTopDrawable.kt index 83a8d3c89..c852cf3ae 100644 --- a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosTextButtonWithTopDrawable.kt +++ b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosTextButtonWithTopDrawable.kt @@ -9,7 +9,6 @@ */ package org.mifos.mobile.core.ui.component - import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer diff --git a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosTitleSearchCard.kt b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosTitleSearchCard.kt index 5b323f993..7c9520fcd 100644 --- a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosTitleSearchCard.kt +++ b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosTitleSearchCard.kt @@ -9,7 +9,6 @@ */ package org.mifos.mobile.core.ui.component - import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding diff --git a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MonitorListItemWithIcon.kt b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MonitorListItemWithIcon.kt index 91f378d88..8d05ff113 100644 --- a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MonitorListItemWithIcon.kt +++ b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MonitorListItemWithIcon.kt @@ -9,7 +9,6 @@ */ package org.mifos.mobile.core.ui.component - import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row @@ -26,15 +25,14 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.draw.alpha import androidx.compose.ui.unit.dp import mifos_mobile.core.ui.generated.resources.Res -import mifos_mobile.core.ui.generated.resources.something_went_wrong import mifos_mobile.core.ui.generated.resources.core_common_working +import mifos_mobile.core.ui.generated.resources.something_went_wrong import org.jetbrains.compose.resources.DrawableResource import org.jetbrains.compose.resources.StringResource import org.jetbrains.compose.resources.stringResource import org.mifos.mobile.core.designsystem.theme.MifosMobileTheme import org.mifos.mobile.core.ui.utils.DevicePreviews - @Composable fun MonitorListItemWithIcon( titleId: StringResource, diff --git a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/NoInternet.kt b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/NoInternet.kt index f68c0fd70..836ec644c 100644 --- a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/NoInternet.kt +++ b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/NoInternet.kt @@ -24,15 +24,11 @@ import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import mifos_mobile.core.ui.generated.resources.Res -import androidx.compose.ui.graphics.vector.ImageVector - - import androidx.compose.ui.text.TextStyle import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp +import mifos_mobile.core.ui.generated.resources.Res import mifos_mobile.core.ui.generated.resources.no_internet - import org.jetbrains.compose.resources.DrawableResource import org.jetbrains.compose.resources.StringResource import org.jetbrains.compose.resources.painterResource @@ -98,4 +94,4 @@ private fun NoInternetPreview( retry = {}, ) } -} \ No newline at end of file +} diff --git a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/UserProfileField.kt b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/UserProfileField.kt index e7fa651ad..998555173 100644 --- a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/UserProfileField.kt +++ b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/UserProfileField.kt @@ -9,7 +9,6 @@ */ package org.mifos.mobile.core.ui.component - import androidx.compose.foundation.clickable import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.foundation.layout.Arrangement diff --git a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/utils/ColorUtils.kt b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/utils/ColorUtils.kt index 8a7822b14..21ff8af11 100644 --- a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/utils/ColorUtils.kt +++ b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/utils/ColorUtils.kt @@ -9,32 +9,32 @@ */ package org.mifos.mobile.core.ui.utils -//import android.app.Activity -//import android.content.Context -//import android.util.TypedValue -//import androidx.annotation.AttrRes -//import androidx.annotation.ColorInt -//import androidx.core.graphics.ColorUtils -//import androidx.core.view.WindowCompat +// import android.app.Activity +// import android.content.Context +// import android.util.TypedValue +// import androidx.annotation.AttrRes +// import androidx.annotation.ColorInt +// import androidx.core.graphics.ColorUtils +// import androidx.core.view.WindowCompat // -//fun Activity.setStatusBarColor(@ColorInt color: Int) { +// fun Activity.setStatusBarColor(@ColorInt color: Int) { // if (!window.decorView.isInEditMode) { // window.statusBarColor = color // WindowCompat.getInsetsController(window, window.decorView).isAppearanceLightStatusBars = // ColorUtils.calculateLuminance(color) > 0.5 // } -//} +// } // -//@ColorInt -//fun Context.getThemeAttributeColor(@AttrRes colorAttribute: Int): Int { +// @ColorInt +// fun Context.getThemeAttributeColor(@AttrRes colorAttribute: Int): Int { // val typedValue = TypedValue() // theme.resolveAttribute(colorAttribute, typedValue, true) // return typedValue.data -//} +// } import androidx.compose.runtime.Composable -import com.google.accompanist.systemuicontroller.rememberSystemUiController import androidx.compose.ui.graphics.Color +import com.google.accompanist.systemuicontroller.rememberSystemUiController @Composable fun SetStatusBarColor(color: Color) { @@ -42,6 +42,6 @@ fun SetStatusBarColor(color: Color) { val isLightColor = androidx.compose.ui.graphics.ColorUtils.calculateLuminance(color) > 0.5 systemUiController.setStatusBarColor( color = color, - darkIcons = isLightColor + darkIcons = isLightColor, ) -} \ No newline at end of file +} diff --git a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/utils/PresentOrFutureSelectableDates.kt b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/utils/PresentOrFutureSelectableDates.kt index 458857a83..5489dcaf9 100644 --- a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/utils/PresentOrFutureSelectableDates.kt +++ b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/utils/PresentOrFutureSelectableDates.kt @@ -31,4 +31,3 @@ object PresentOrFutureSelectableDates : SelectableDates { return year >= currentYear } } - diff --git a/core/ui/src/main/AndroidManifest.xml b/core/ui/src/main/AndroidManifest.xml deleted file mode 100644 index 4ee22a4fb..000000000 --- a/core/ui/src/main/AndroidManifest.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - \ No newline at end of file diff --git a/core/ui/src/main/java/org/mifos/mobile/core/ui/component/AboutUsItemCard.kt b/core/ui/src/main/java/org/mifos/mobile/core/ui/component/AboutUsItemCard.kt deleted file mode 100644 index 1ffca5488..000000000 --- a/core/ui/src/main/java/org/mifos/mobile/core/ui/component/AboutUsItemCard.kt +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright 2024 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/mobile-mobile/blob/master/LICENSE.md - */ -package org.mifos.mobile.core.ui.component - -import androidx.annotation.DrawableRes -import androidx.annotation.StringRes -import androidx.compose.foundation.Image -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.padding -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.res.painterResource -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.unit.dp -import org.mifos.mobile.core.designsystem.theme.MifosMobileTheme -import org.mifos.mobile.core.ui.utils.DevicePreviews - -@Composable -fun AboutUsItemCard( - title: String, - @StringRes subtitle: Int?, - @DrawableRes iconUrl: Int?, - modifier: Modifier = Modifier, -) { - Row( - modifier = modifier.padding(16.dp), - ) { - iconUrl?.let { painterResource(id = it) }?.let { - Image( - painter = it, - contentDescription = null, - modifier = Modifier.padding(end = 8.dp), - ) - } - Column { - Text( - text = title, - style = MaterialTheme.typography.bodyLarge, - modifier = Modifier.padding(end = 8.dp), - ) - if (subtitle != null) { - Text( - text = stringResource(id = subtitle), - style = MaterialTheme.typography.bodyLarge, - modifier = Modifier.padding(end = 8.dp), - ) - } - } - } -} - -@DevicePreviews -@Composable -private fun AboutUsItemCardPreview( - modifier: Modifier = Modifier, -) { - MifosMobileTheme { - AboutUsItemCard( - title = "About Us", - modifier = modifier, - subtitle = null, - iconUrl = null, - ) - } -} diff --git a/core/ui/src/main/java/org/mifos/mobile/core/ui/component/EmptyDataView.kt b/core/ui/src/main/java/org/mifos/mobile/core/ui/component/EmptyDataView.kt deleted file mode 100644 index 3b94a30a4..000000000 --- a/core/ui/src/main/java/org/mifos/mobile/core/ui/component/EmptyDataView.kt +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright 2024 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/mobile-mobile/blob/master/LICENSE.md - */ -package org.mifos.mobile.core.ui.component - -import androidx.annotation.DrawableRes -import androidx.annotation.StringRes -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.material3.Icon -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.vector.ImageVector -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.res.vectorResource -import androidx.compose.ui.text.TextStyle -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import org.mifos.mobile.core.R -import org.mifos.mobile.core.designsystem.icons.MifosIcons -import org.mifos.mobile.core.designsystem.theme.MifosMobileTheme -import org.mifos.mobile.core.ui.utils.DevicePreviews - -@Composable -fun EmptyDataView( - @StringRes - error: Int, - modifier: Modifier = Modifier.fillMaxSize(), - @DrawableRes - icon: Int? = null, - errorString: String? = null, -) { - Column( - modifier = modifier, - verticalArrangement = Arrangement.Center, - horizontalAlignment = Alignment.CenterHorizontally, - ) { - Icon( - modifier = Modifier - .size(100.dp) - .padding(bottom = 12.dp), - imageVector = if (icon != null) { - ImageVector.vectorResource(id = icon) - } else { - MifosIcons.Error - }, - contentDescription = null, - tint = MaterialTheme.colorScheme.onSecondary, - ) - - Text( - modifier = Modifier.padding(horizontal = 20.dp), - text = errorString ?: stringResource(id = error), - style = TextStyle(fontSize = 20.sp), - color = MaterialTheme.colorScheme.onSecondary, - textAlign = TextAlign.Center, - ) - } -} - -@DevicePreviews -@Composable -private fun EmptyDataViewPreview( - modifier: Modifier = Modifier, -) { - MifosMobileTheme { - EmptyDataView( - error = R.string.no_internet, - modifier = modifier, - ) - } -} diff --git a/core/ui/src/main/java/org/mifos/mobile/core/ui/component/FaqItemHolder.kt b/core/ui/src/main/java/org/mifos/mobile/core/ui/component/FaqItemHolder.kt deleted file mode 100644 index 849ee2143..000000000 --- a/core/ui/src/main/java/org/mifos/mobile/core/ui/component/FaqItemHolder.kt +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright 2024 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/mobile-mobile/blob/master/LICENSE.md - */ -package org.mifos.mobile.core.ui.component - -import androidx.compose.animation.AnimatedVisibility -import androidx.compose.animation.core.Spring -import androidx.compose.animation.core.spring -import androidx.compose.animation.expandVertically -import androidx.compose.animation.fadeIn -import androidx.compose.foundation.clickable -import androidx.compose.foundation.isSystemInDarkTheme -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.padding -import androidx.compose.material3.HorizontalDivider -import androidx.compose.material3.Icon -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.scale -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.unit.dp -import org.mifos.mobile.core.designsystem.icons.MifosIcons -import org.mifos.mobile.core.designsystem.theme.MifosMobileTheme -import org.mifos.mobile.core.ui.utils.DevicePreviews - -@Composable -fun FaqItemHolder( - index: Int, - isSelected: Boolean, - onItemSelected: (Int) -> Unit, - question: String?, - answer: String?, - modifier: Modifier = Modifier, -) { - Column( - modifier = modifier - .fillMaxWidth() - .padding(horizontal = 16.dp), - ) { - Row( - modifier = Modifier - .clickable { - onItemSelected.invoke(index) - } - .padding(vertical = 8.dp), - verticalAlignment = Alignment.CenterVertically, - ) { - Text( - text = question.orEmpty(), - style = MaterialTheme.typography.bodyMedium, - color = if (isSystemInDarkTheme()) Color.White else Color.Black, - modifier = Modifier - .fillMaxWidth() - .weight(1f), - ) - - Icon( - imageVector = MifosIcons.ArrowDropDown, - contentDescription = "drop down", - tint = if (isSystemInDarkTheme()) Color.White else Color.Gray, - modifier = Modifier - .scale(1f, if (isSelected) -1f else 1f), - ) - } - - AnimatedVisibility( - visible = isSelected, - enter = fadeIn() + expandVertically( - animationSpec = spring( - stiffness = Spring.StiffnessMedium, - ), - ), - ) { - Text( - text = answer.orEmpty(), - style = MaterialTheme.typography.bodyMedium, - color = if (isSystemInDarkTheme()) Color.White else Color.Black, - modifier = Modifier - .fillMaxWidth() - .padding(bottom = 8.dp), - ) - } - - HorizontalDivider() - } -} - -@DevicePreviews -@Composable -private fun FaqItemHolderPreview( - modifier: Modifier = Modifier, -) { - MifosMobileTheme { - FaqItemHolder( - index = 0, - isSelected = false, - onItemSelected = {}, - question = "What is Mifos?", - answer = "Mifos is a platform for financial inclusion.", - modifier = modifier, - ) - } -} diff --git a/core/ui/src/main/java/org/mifos/mobile/core/ui/component/MFStepProcess.kt b/core/ui/src/main/java/org/mifos/mobile/core/ui/component/MFStepProcess.kt deleted file mode 100644 index 8295af7ef..000000000 --- a/core/ui/src/main/java/org/mifos/mobile/core/ui/component/MFStepProcess.kt +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright 2024 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/mobile-mobile/blob/master/LICENSE.md - */ -package org.mifos.mobile.core.ui.component - -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size -import androidx.compose.foundation.layout.width -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -import androidx.compose.runtime.setValue -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.layout.onGloballyPositioned -import androidx.compose.ui.platform.LocalDensity -import androidx.compose.ui.unit.dp -import org.mifos.mobile.core.designsystem.theme.MifosMobileTheme -import org.mifos.mobile.core.ui.utils.DevicePreviews - -@Composable -fun MFStepProcess( - stepNumber: String, - activateColor: Color, - deactivateColor: Color, - modifier: Modifier = Modifier, - isLastStep: Boolean = false, - processState: StepProcessState = StepProcessState.INACTIVE, - content: @Composable (Modifier) -> Unit, -) { - var barHeight by remember { mutableStateOf(0.dp) } - val localDensity = LocalDensity.current - - Row(modifier) { - Column(horizontalAlignment = Alignment.CenterHorizontally) { - Column( - modifier = Modifier - .size(40.dp) - .clip(CircleShape) - .background( - color = if (processState == StepProcessState.INACTIVE) { - deactivateColor - } else { - activateColor - }, - ), - verticalArrangement = Arrangement.Center, - horizontalAlignment = Alignment.CenterHorizontally, - ) { - Text( - text = if (processState == StepProcessState.COMPLETED) "✔" else stepNumber, - color = MaterialTheme.colorScheme.onPrimary, - ) - } - if (!isLastStep) { - Box( - modifier = Modifier - .height(barHeight) - .width(4.dp) - .background( - color = if (processState == StepProcessState.INACTIVE) { - deactivateColor - } else { - activateColor - }, - ), - ) - } - } - content( - Modifier - .padding(start = 10.dp, end = 6.dp) - .onGloballyPositioned { barHeight = with(localDensity) { it.size.height.toDp() } }, - ) - } -} - -enum class StepProcessState { - COMPLETED, - ACTIVE, - INACTIVE, -} - -fun getStepState(targetStep: Int, currentStep: Int): StepProcessState { - return when { - currentStep == targetStep -> StepProcessState.ACTIVE - currentStep > targetStep -> StepProcessState.COMPLETED - else -> StepProcessState.INACTIVE - } -} - -@DevicePreviews -@Composable -private fun Preview( - modifier: Modifier = Modifier, -) { - MifosMobileTheme { - MFStepProcess( - stepNumber = "1", - activateColor = Color.Red, - deactivateColor = Color.Gray, - modifier = modifier, - isLastStep = false, - processState = StepProcessState.ACTIVE, - ) { - Text(text = "Step 1") - } - } -} diff --git a/core/ui/src/main/java/org/mifos/mobile/core/ui/component/MifosAlertDialog.kt b/core/ui/src/main/java/org/mifos/mobile/core/ui/component/MifosAlertDialog.kt deleted file mode 100644 index c87a49027..000000000 --- a/core/ui/src/main/java/org/mifos/mobile/core/ui/component/MifosAlertDialog.kt +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2024 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/mobile-mobile/blob/master/LICENSE.md - */ -package org.mifos.mobile.core.ui.component - -import androidx.compose.material3.AlertDialog -import androidx.compose.material3.Icon -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.vector.ImageVector -import org.mifos.mobile.core.designsystem.components.MifosTextButton -import org.mifos.mobile.core.designsystem.theme.MifosMobileTheme -import org.mifos.mobile.core.ui.utils.DevicePreviews - -@Composable -fun MifosAlertDialog( - dialogTitle: String, - dialogText: String, - dismissText: String, - confirmationText: String, - onDismissRequest: () -> Unit, - onConfirmation: () -> Unit, - modifier: Modifier = Modifier, - icon: ImageVector? = null, -) { - AlertDialog( - icon = { - if (icon != null) { - Icon(imageVector = icon, contentDescription = null) - } - }, - title = { Text(text = dialogTitle) }, - text = { Text(text = dialogText) }, - modifier = modifier, - onDismissRequest = onDismissRequest, - confirmButton = { - MifosTextButton( - text = confirmationText, - onClick = onConfirmation, - ) - }, - dismissButton = { - MifosTextButton( - text = dismissText, - onClick = onDismissRequest, - ) - }, - ) -} - -@DevicePreviews -@Composable -private fun MifosAlertDialogPreview( - modifier: Modifier = Modifier, -) { - MifosMobileTheme { - MifosAlertDialog( - dialogTitle = "Dialog Title", - dialogText = "Dialog Text", - dismissText = "Dismiss", - confirmationText = "Confirm", - onDismissRequest = {}, - onConfirmation = {}, - modifier = modifier, - ) - } -} diff --git a/core/ui/src/main/java/org/mifos/mobile/core/ui/component/MifosCheckBox.kt b/core/ui/src/main/java/org/mifos/mobile/core/ui/component/MifosCheckBox.kt deleted file mode 100644 index 85724dbe9..000000000 --- a/core/ui/src/main/java/org/mifos/mobile/core/ui/component/MifosCheckBox.kt +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2024 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/mobile-mobile/blob/master/LICENSE.md - */ -package org.mifos.mobile.core.ui.component - -import androidx.compose.foundation.layout.Row -import androidx.compose.material3.Checkbox -import androidx.compose.material3.CheckboxColors -import androidx.compose.material3.CheckboxDefaults -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import org.mifos.mobile.core.designsystem.theme.MifosMobileTheme -import org.mifos.mobile.core.ui.utils.DevicePreviews - -@Composable -fun MifosCheckBox( - text: String, - checked: Boolean, - onCheckChanged: (Boolean) -> Unit, - modifier: Modifier = Modifier, - checkboxColors: CheckboxColors = CheckboxDefaults.colors(), -) { - Row( - modifier = modifier, - verticalAlignment = Alignment.CenterVertically, - ) { - Checkbox( - checked = checked, - onCheckedChange = { onCheckChanged.invoke(it) }, - colors = checkboxColors, - ) - Text(text = text) - } -} - -@DevicePreviews -@Composable -fun MifosCheckBoxPreview() { - MifosMobileTheme { - MifosCheckBox( - checked = false, - onCheckChanged = {}, - text = "", - ) - } -} diff --git a/core/ui/src/main/java/org/mifos/mobile/core/ui/component/MifosDropDownTextField.kt b/core/ui/src/main/java/org/mifos/mobile/core/ui/component/MifosDropDownTextField.kt deleted file mode 100644 index 4c03cffd6..000000000 --- a/core/ui/src/main/java/org/mifos/mobile/core/ui/component/MifosDropDownTextField.kt +++ /dev/null @@ -1,220 +0,0 @@ -/* - * Copyright 2024 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/mobile-mobile/blob/master/LICENSE.md - */ -package org.mifos.mobile.core.ui.component - -import androidx.annotation.StringRes -import androidx.compose.foundation.interaction.MutableInteractionSource -import androidx.compose.foundation.interaction.collectIsPressedAsState -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.heightIn -import androidx.compose.material3.DropdownMenu -import androidx.compose.material3.DropdownMenuItem -import androidx.compose.material3.Icon -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.OutlinedTextField -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -import androidx.compose.runtime.saveable.rememberSaveable -import androidx.compose.runtime.setValue -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.alpha -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.unit.dp -import org.mifos.mobile.core.designsystem.icons.MifosIcons -import org.mifos.mobile.core.designsystem.theme.MifosMobileTheme -import org.mifos.mobile.core.ui.utils.DevicePreviews - -@Composable -fun MifosDropDownTextField( - onClick: (Int, String) -> Unit, - modifier: Modifier = Modifier, - @StringRes - labelResId: Int = 0, - isEnabled: Boolean = true, - supportingText: String? = null, - error: Boolean = false, - optionsList: List = listOf(), - selectedOption: String? = null, -) { - var expanded by rememberSaveable { mutableStateOf(false) } - val interactionSource = remember { MutableInteractionSource() } - val isPressed by interactionSource.collectIsPressedAsState() - - LaunchedEffect(key1 = isPressed) { - if (isPressed) expanded = true && isEnabled - } - - Box( - modifier = modifier.alpha(if (!isEnabled) 0.4f else 1f), - ) { - OutlinedTextField( - value = selectedOption ?: "", - onValueChange = { }, - label = { Text(stringResource(id = labelResId)) }, - interactionSource = interactionSource, - modifier = Modifier - .fillMaxWidth(), - readOnly = true, - enabled = isEnabled, - textStyle = MaterialTheme.typography.labelSmall, - supportingText = { if (error) Text(text = supportingText ?: "") }, - isError = error, - trailingIcon = { - Icon( - imageVector = if (expanded) { - MifosIcons.ArrowDropUp - } else { - MifosIcons.ArrowDropDown - }, - contentDescription = null, - ) - }, - ) - - DropdownMenu( - expanded = expanded && isEnabled, - modifier = Modifier - .fillMaxWidth(0.92f) - .heightIn(max = 200.dp), - onDismissRequest = { expanded = false }, - ) { - optionsList.forEachIndexed { index, item -> - DropdownMenuItem( - onClick = { - expanded = false - onClick(index, item) - }, - text = { Text(text = item) }, - ) - } - } - } -} - -@Composable -fun MifosDropDownDoubleTextField( - onClick: (Int, Pair) -> Unit, - modifier: Modifier = Modifier, - @StringRes - labelResId: Int = 0, - isEnabled: Boolean = true, - supportingText: String? = null, - error: Boolean = false, - optionsList: List> = listOf(), - selectedOption: String? = null, -) { - var expanded by rememberSaveable { mutableStateOf(false) } - val interactionSource = remember { MutableInteractionSource() } - val isPressed by interactionSource.collectIsPressedAsState() - - LaunchedEffect(key1 = isPressed) { - if (isPressed) expanded = true && isEnabled - } - - Box( - modifier = modifier.alpha(if (!isEnabled) 0.4f else 1f), - ) { - OutlinedTextField( - value = selectedOption ?: "", - onValueChange = { }, - label = { Text(stringResource(id = labelResId)) }, - interactionSource = interactionSource, - modifier = Modifier - .fillMaxWidth(), - readOnly = true, - enabled = isEnabled, - textStyle = MaterialTheme.typography.labelSmall, - supportingText = { if (error) Text(text = supportingText ?: "") }, - isError = error, - trailingIcon = { - Icon( - imageVector = if (expanded) { - MifosIcons.ArrowDropUp - } else { - MifosIcons.ArrowDropDown - }, - contentDescription = null, - ) - }, - ) - - DropdownMenu( - expanded = expanded && isEnabled, - modifier = Modifier - .fillMaxWidth(0.92f) - .heightIn(max = 200.dp), - onDismissRequest = { expanded = false }, - ) { - optionsList.forEachIndexed { index, item -> - DropdownMenuItem( - onClick = { - expanded = false - onClick(index, item) - }, - text = { - Column { - Text(text = item.first) - Text(text = item.second) - } - }, - - ) - } - } - } -} - -@DevicePreviews -@Composable -private fun MifosDropDownTextFieldPreview( - modifier: Modifier = Modifier, -) { - MifosMobileTheme { - MifosDropDownTextField( - onClick = { _, _ -> }, - modifier = modifier, - labelResId = 0, - isEnabled = true, - supportingText = null, - error = false, - optionsList = listOf("Option 1", "Option 2", "Option 3"), - selectedOption = null, - ) - } -} - -@DevicePreviews -@Composable -private fun MifosDropDownDoubleTextFieldPreview( - modifier: Modifier = Modifier, -) { - MifosMobileTheme { - MifosDropDownDoubleTextField( - onClick = { _, _ -> }, - modifier = modifier, - labelResId = 0, - isEnabled = true, - supportingText = null, - error = false, - optionsList = listOf( - Pair("Option 1", "Option 1 Description"), - Pair("Option 2", "Option 2 Description"), - Pair("Option 3", "Option 3 Description"), - ), - selectedOption = null, - ) - } -} diff --git a/core/ui/src/main/java/org/mifos/mobile/core/ui/component/MifosErrorComponent.kt b/core/ui/src/main/java/org/mifos/mobile/core/ui/component/MifosErrorComponent.kt deleted file mode 100644 index ce3555a40..000000000 --- a/core/ui/src/main/java/org/mifos/mobile/core/ui/component/MifosErrorComponent.kt +++ /dev/null @@ -1,202 +0,0 @@ -/* - * Copyright 2024 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/mobile-mobile/blob/master/LICENSE.md - */ -package org.mifos.mobile.core.ui.component - -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size -import androidx.compose.material3.FilledTonalButton -import androidx.compose.material3.Icon -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.vector.ImageVector -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.TextStyle -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import org.mifos.mobile.core.R -import org.mifos.mobile.core.designsystem.icons.MifosIcons -import org.mifos.mobile.core.designsystem.theme.MifosMobileTheme -import org.mifos.mobile.core.ui.utils.DevicePreviews - -@Composable -fun MifosErrorComponent( - modifier: Modifier = Modifier, - isNetworkConnected: Boolean = true, - message: String? = null, - isEmptyData: Boolean = false, - isRetryEnabled: Boolean = false, - onRetry: () -> Unit = {}, -) { - when { - !isNetworkConnected -> NoInternetComponent(isRetryEnabled = isRetryEnabled) { onRetry() } - else -> EmptyDataComponent( - modifier = modifier, - isEmptyData = isEmptyData, - message = message, - isRetryEnabled = isRetryEnabled, - onRetry = onRetry, - ) - } -} - -@Composable -fun NoInternetComponent( - modifier: Modifier = Modifier, - isRetryEnabled: Boolean = false, - onRetry: () -> Unit = {}, -) { - Column( - modifier = modifier - .fillMaxSize() - .background(MaterialTheme.colorScheme.background), - verticalArrangement = Arrangement.Center, - horizontalAlignment = Alignment.CenterHorizontally, - ) { - Icon( - modifier = Modifier - .size(100.dp) - .padding(bottom = 12.dp), - imageVector = MifosIcons.WifiOff, - contentDescription = null, - tint = MaterialTheme.colorScheme.onSecondary, - ) - - Text( - text = stringResource(id = R.string.no_internet), - style = TextStyle(fontSize = 20.sp), - color = MaterialTheme.colorScheme.onSecondary, - ) - - Spacer(modifier = Modifier.height(12.dp)) - - if (isRetryEnabled) { - FilledTonalButton(onClick = { onRetry.invoke() }) { - Text(text = stringResource(id = R.string.retry)) - } - } - } -} - -@Composable -fun EmptyDataComponent( - modifier: Modifier = Modifier, - isEmptyData: Boolean = false, - message: String? = null, - isRetryEnabled: Boolean = false, - onRetry: () -> Unit = {}, -) { - Column( - modifier = modifier.fillMaxSize(), - verticalArrangement = Arrangement.Center, - horizontalAlignment = Alignment.CenterHorizontally, - ) { - Icon( - modifier = Modifier - .size(100.dp) - .padding(bottom = 12.dp), - imageVector = MifosIcons.Info, - contentDescription = null, - tint = MaterialTheme.colorScheme.onSecondary, - ) - - Text( - modifier = Modifier.padding(horizontal = 20.dp), - text = message ?: if (isEmptyData) { - stringResource(id = R.string.no_data) - } else { - stringResource(id = R.string.something_went_wrong) - }, - style = TextStyle(fontSize = 20.sp), - color = MaterialTheme.colorScheme.onSecondary, - textAlign = TextAlign.Center, - ) - - if (isRetryEnabled) { - FilledTonalButton( - modifier = Modifier.padding(top = 8.dp), - onClick = { onRetry.invoke() }, - ) { - Text(text = stringResource(id = R.string.retry)) - } - } - } -} - -@Composable -fun EmptyDataComponentWithModifiedMessageAndIcon( - message: String, - icon: ImageVector, - modifier: Modifier = Modifier, - isEmptyData: Boolean = false, -) { - Column( - modifier = modifier.fillMaxSize(), - verticalArrangement = Arrangement.Center, - horizontalAlignment = Alignment.CenterHorizontally, - ) { - Icon( - modifier = Modifier - .size(100.dp) - .padding(bottom = 12.dp), - imageVector = if (isEmptyData) icon else MifosIcons.Info, - contentDescription = null, - tint = MaterialTheme.colorScheme.onSecondary, - ) - - Text( - modifier = Modifier.padding(horizontal = 20.dp), - text = if (isEmptyData) message else stringResource(id = R.string.something_went_wrong), - style = TextStyle(fontSize = 20.sp), - color = MaterialTheme.colorScheme.onSecondary, - textAlign = TextAlign.Center, - ) - } -} - -@DevicePreviews -@Composable -fun NoInternetPreview() { - MifosMobileTheme { - NoInternetComponent() - } -} - -@DevicePreviews -@Composable -fun EmptyDataPreview() { - MifosMobileTheme { - EmptyDataComponent() - } -} - -@DevicePreviews -@Composable -private fun EmptyDataComponentWithModifiedMessageAndIconPreview( - modifier: Modifier = Modifier, -) { - MifosMobileTheme { - EmptyDataComponentWithModifiedMessageAndIcon( - message = "No data found", - icon = MifosIcons.Error, - modifier = modifier, - isEmptyData = true, - ) - } -} diff --git a/core/ui/src/main/java/org/mifos/mobile/core/ui/component/MifosHiddenTextRow.kt b/core/ui/src/main/java/org/mifos/mobile/core/ui/component/MifosHiddenTextRow.kt deleted file mode 100644 index 657802e15..000000000 --- a/core/ui/src/main/java/org/mifos/mobile/core/ui/component/MifosHiddenTextRow.kt +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright 2024 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/mobile-mobile/blob/master/LICENSE.md - */ -package org.mifos.mobile.core.ui.component - -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size -import androidx.compose.material3.Icon -import androidx.compose.material3.IconButton -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -import androidx.compose.runtime.setValue -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.alpha -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.res.painterResource -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.unit.dp -import org.mifos.mobile.core.designsystem.theme.MifosMobileTheme -import org.mifos.mobile.core.ui.utils.DevicePreviews - -@Composable -fun MifosHiddenTextRow( - title: String, - hiddenText: String, - hiddenColor: Color, - hidingText: String, - visibilityIconId: Int, - visibilityOffIconId: Int, - onClick: () -> Unit, - modifier: Modifier = Modifier, -) { - var isHidden by remember { mutableStateOf(true) } - - Row( - modifier.clickable { onClick.invoke() }, - verticalAlignment = Alignment.CenterVertically, - ) { - Text( - text = title, - style = MaterialTheme.typography.labelMedium, - modifier = Modifier - .alpha(0.7f) - .weight(1f), - ) - Text( - text = if (isHidden) { - hidingText - } else { - hiddenText - }, - style = MaterialTheme.typography.bodyLarge, - fontWeight = FontWeight.Bold, - color = hiddenColor, - ) - IconButton( - onClick = { isHidden = !isHidden }, - modifier = Modifier - .padding(start = 6.dp) - .size(24.dp), - ) { - Icon( - painter = if (isHidden) { - painterResource(id = visibilityIconId) - } else { - painterResource(id = visibilityOffIconId) - }, - contentDescription = "Show or hide total amount", - tint = MaterialTheme.colorScheme.primary, - ) - } - } -} - -@DevicePreviews -@Composable -private fun MifosHiddenTextRowPreview( - modifier: Modifier = Modifier, -) { - MifosMobileTheme { - MifosHiddenTextRow( - title = "Title", - hiddenText = "Hidden Text", - hiddenColor = MaterialTheme.colorScheme.primary, - hidingText = "Hiding Text", - visibilityIconId = 0, - visibilityOffIconId = 0, - onClick = {}, - modifier = modifier, - ) - } -} diff --git a/core/ui/src/main/java/org/mifos/mobile/core/ui/component/MifosItemCard.kt b/core/ui/src/main/java/org/mifos/mobile/core/ui/component/MifosItemCard.kt deleted file mode 100644 index 72dea308b..000000000 --- a/core/ui/src/main/java/org/mifos/mobile/core/ui/component/MifosItemCard.kt +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2024 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/mobile-mobile/blob/master/LICENSE.md - */ -package org.mifos.mobile.core.ui.component - -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.ColumnScope -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.Card -import androidx.compose.material3.CardDefaults -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Shape -import androidx.compose.ui.unit.Dp -import androidx.compose.ui.unit.dp -import org.mifos.mobile.core.designsystem.theme.MifosMobileTheme -import org.mifos.mobile.core.ui.utils.DevicePreviews - -@Composable -fun MifosItemCard( - onClick: () -> Unit, - modifier: Modifier = Modifier, - elevation: Dp = 1.dp, - shape: Shape = RoundedCornerShape(8.dp), - content: @Composable ColumnScope.() -> Unit, -) { - Card( - shape = shape, - modifier = modifier - .fillMaxWidth() - .clickable(onClick = onClick), - elevation = CardDefaults.cardElevation( - defaultElevation = elevation, - ), - content = content, - ) -} - -@DevicePreviews -@Composable -private fun MifosItemCardPreview( - modifier: Modifier = Modifier, -) { - MifosMobileTheme { - MifosItemCard( - onClick = {}, - modifier = modifier, - ) { - Text(text = "Card Content") - } - } -} diff --git a/core/ui/src/main/java/org/mifos/mobile/core/ui/component/MifosLinkText.kt b/core/ui/src/main/java/org/mifos/mobile/core/ui/component/MifosLinkText.kt deleted file mode 100644 index e09e38741..000000000 --- a/core/ui/src/main/java/org/mifos/mobile/core/ui/component/MifosLinkText.kt +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2024 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/mobile-mobile/blob/master/LICENSE.md - */ -package org.mifos.mobile.core.ui.component - -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.padding -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.text.style.TextDecoration -import androidx.compose.ui.unit.dp -import org.mifos.mobile.core.designsystem.theme.MifosMobileTheme -import org.mifos.mobile.core.ui.utils.DevicePreviews - -@Composable -fun MifosLinkText( - text: String, - onClick: () -> Unit, - modifier: Modifier = Modifier, - isUnderlined: Boolean = true, -) { - Text( - text = text, - style = MaterialTheme.typography.bodyMedium.copy( - color = MaterialTheme.colorScheme.primary, - textDecoration = if (isUnderlined) TextDecoration.Underline else null, - ), - modifier = modifier - .padding(vertical = 2.dp) - .clickable { - onClick() - }, - ) -} - -@DevicePreviews -@Composable -private fun MifosLinkTextPreview( - modifier: Modifier = Modifier, -) { - MifosMobileTheme { - MifosLinkText( - text = "Link Text", - onClick = {}, - modifier = modifier, - ) - } -} diff --git a/core/ui/src/main/java/org/mifos/mobile/core/ui/component/MifosMobileIcon.kt b/core/ui/src/main/java/org/mifos/mobile/core/ui/component/MifosMobileIcon.kt deleted file mode 100644 index 7b6439a54..000000000 --- a/core/ui/src/main/java/org/mifos/mobile/core/ui/component/MifosMobileIcon.kt +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2024 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/mobile-mobile/blob/master/LICENSE.md - */ -package org.mifos.mobile.core.ui.component - -import androidx.annotation.DrawableRes -import androidx.compose.foundation.Image -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.padding -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.res.painterResource -import androidx.compose.ui.unit.dp -import org.mifos.mobile.core.R -import org.mifos.mobile.core.designsystem.theme.MifosMobileTheme -import org.mifos.mobile.core.ui.utils.DevicePreviews - -@Composable -fun MifosMobileIcon( - @DrawableRes - id: Int, - modifier: Modifier = Modifier, -) { - Column(modifier) { - Image( - painter = painterResource(id = id), - contentDescription = null, - modifier = Modifier - .fillMaxWidth() - .align(Alignment.CenterHorizontally) - .padding(0.dp, 56.dp), - ) - } -} - -@DevicePreviews -@Composable -private fun MifosMobileIconPreview( - modifier: Modifier = Modifier, -) { - MifosMobileTheme { - MifosMobileIcon( - id = R.drawable.core_common_circular_background, - modifier = modifier, - ) - } -} diff --git a/core/ui/src/main/java/org/mifos/mobile/core/ui/component/MifosProgressIndicator.kt b/core/ui/src/main/java/org/mifos/mobile/core/ui/component/MifosProgressIndicator.kt deleted file mode 100644 index 88041d598..000000000 --- a/core/ui/src/main/java/org/mifos/mobile/core/ui/component/MifosProgressIndicator.kt +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2024 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/mobile-mobile/blob/master/LICENSE.md - */ -package org.mifos.mobile.core.ui.component - -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.material3.CircularProgressIndicator -import androidx.compose.material3.MaterialTheme -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.tooling.preview.Preview - -@Preview(showSystemUi = true) -@Composable -fun MifosProgressIndicator( - modifier: Modifier = Modifier.fillMaxSize(), -) { - Column( - modifier = modifier, - verticalArrangement = Arrangement.Center, - horizontalAlignment = Alignment.CenterHorizontally, - ) { - CircularProgressIndicator() - } -} - -@Preview(showSystemUi = true) -@Composable -fun MifosProgressIndicatorOverlay( - modifier: Modifier = Modifier.fillMaxSize(), -) { - Column( - modifier = modifier - .background(MaterialTheme.colorScheme.background.copy(alpha = 0.7f)), - verticalArrangement = Arrangement.Center, - horizontalAlignment = Alignment.CenterHorizontally, - ) { - CircularProgressIndicator() - } -} diff --git a/core/ui/src/main/java/org/mifos/mobile/core/ui/component/MifosRadioButtonAlertDialog.kt b/core/ui/src/main/java/org/mifos/mobile/core/ui/component/MifosRadioButtonAlertDialog.kt deleted file mode 100644 index bd161c328..000000000 --- a/core/ui/src/main/java/org/mifos/mobile/core/ui/component/MifosRadioButtonAlertDialog.kt +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright 2024 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/mobile-mobile/blob/master/LICENSE.md - */ -package org.mifos.mobile.core.ui.component - -import androidx.annotation.StringRes -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.heightIn -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.lazy.itemsIndexed -import androidx.compose.material3.BasicAlertDialog -import androidx.compose.material3.Card -import androidx.compose.material3.ExperimentalMaterial3Api -import androidx.compose.material3.RadioButton -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.unit.dp -import org.mifos.mobile.core.R -import org.mifos.mobile.core.designsystem.theme.MifosMobileTheme - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun MifosRadioButtonDialog( - @StringRes - titleResId: Int, - selectedItem: String, - items: Array, - selectItem: (item: String, index: Int) -> Unit, - onDismissRequest: () -> Unit, - modifier: Modifier = Modifier, -) { - BasicAlertDialog( - onDismissRequest = onDismissRequest, - modifier = modifier, - ) { - Card { - Column(modifier = Modifier.padding(20.dp)) { - Text(text = stringResource(id = titleResId)) - LazyColumn( - modifier = Modifier - .fillMaxWidth() - .heightIn(max = 500.dp), - ) { - itemsIndexed(items = items) { index, item -> - Row( - verticalAlignment = Alignment.CenterVertically, - modifier = Modifier - .clickable { - onDismissRequest.invoke() - selectItem.invoke(item, index) - } - .fillMaxWidth(), - ) { - RadioButton( - selected = (item == selectedItem), - onClick = { - onDismissRequest.invoke() - selectItem.invoke(item, index) - }, - ) - Text( - text = item, - modifier = Modifier.padding(start = 4.dp), - ) - } - } - } - } - } - } -} - -@Preview -@Composable -fun PreviewRadioButtonDialog() { - MifosMobileTheme { - MifosRadioButtonDialog( - titleResId = R.string.core_common_working, - items = arrayOf("1", "2", "3"), - selectedItem = "1", - onDismissRequest = { }, - selectItem = { _, _ -> }, - ) - } -} diff --git a/core/ui/src/main/java/org/mifos/mobile/core/ui/component/MifosRoundIcon.kt b/core/ui/src/main/java/org/mifos/mobile/core/ui/component/MifosRoundIcon.kt deleted file mode 100644 index 2dd12fb2a..000000000 --- a/core/ui/src/main/java/org/mifos/mobile/core/ui/component/MifosRoundIcon.kt +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2024 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/mobile-mobile/blob/master/LICENSE.md - */ -package org.mifos.mobile.core.ui.component - -import androidx.annotation.DrawableRes -import androidx.compose.foundation.Image -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Surface -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.res.painterResource -import androidx.compose.ui.unit.dp -import org.mifos.mobile.core.R -import org.mifos.mobile.core.designsystem.theme.MifosMobileTheme -import org.mifos.mobile.core.ui.utils.DevicePreviews - -@Composable -fun MifosRoundIcon( - @DrawableRes - iconId: Int, - modifier: Modifier = Modifier, - contentDescription: String? = null, -) { - Surface( - color = MaterialTheme.colorScheme.surfaceVariant, - modifier = modifier - .clip(CircleShape), - ) { - Image( - modifier = Modifier.padding(all = 6.dp), - painter = painterResource(id = iconId), - contentDescription = contentDescription, - ) - } -} - -@DevicePreviews -@Composable -private fun MifosRoundIconPreview( - modifier: Modifier = Modifier, -) { - MifosMobileTheme { - MifosRoundIcon( - iconId = R.drawable.core_common_circular_background, - modifier = modifier, - ) - } -} diff --git a/core/ui/src/main/java/org/mifos/mobile/core/ui/component/MifosTextButtonWithTopDrawable.kt b/core/ui/src/main/java/org/mifos/mobile/core/ui/component/MifosTextButtonWithTopDrawable.kt deleted file mode 100644 index 510162bdf..000000000 --- a/core/ui/src/main/java/org/mifos/mobile/core/ui/component/MifosTextButtonWithTopDrawable.kt +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright 2024 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/mobile-mobile/blob/master/LICENSE.md - */ -package org.mifos.mobile.core.ui.component - -import androidx.annotation.StringRes -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.height -import androidx.compose.material3.ButtonDefaults -import androidx.compose.material3.Icon -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.vector.ImageVector -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.unit.dp -import org.mifos.mobile.core.R -import org.mifos.mobile.core.designsystem.components.MifosTextButton -import org.mifos.mobile.core.designsystem.icons.MifosIcons -import org.mifos.mobile.core.designsystem.theme.MifosMobileTheme -import org.mifos.mobile.core.ui.utils.DevicePreviews - -@Composable -fun MifosTextButtonWithTopDrawable( - @StringRes - textResourceId: Int, - icon: ImageVector, - onClick: () -> Unit, - contentDescription: String?, - modifier: Modifier = Modifier, -) { - MifosTextButton( - onClick = onClick, - modifier = modifier, - colors = ButtonDefaults.textButtonColors( - contentColor = MaterialTheme.colorScheme.primary, - ), - content = { - Column( - horizontalAlignment = Alignment.CenterHorizontally, - verticalArrangement = Arrangement.Center, - ) { - Icon( - imageVector = icon, - contentDescription = contentDescription, - ) - Spacer(modifier = Modifier.height(4.dp)) - Text( - text = stringResource(id = textResourceId), - textAlign = TextAlign.Center, - ) - } - }, - ) -} - -@DevicePreviews -@Composable -private fun MifosTextButtonWithTopDrawablePreview( - modifier: Modifier = Modifier, -) { - MifosMobileTheme { - MifosTextButtonWithTopDrawable( - textResourceId = R.string.core_common_working, - icon = MifosIcons.Add, - onClick = {}, - contentDescription = null, - modifier = modifier, - ) - } -} diff --git a/core/ui/src/main/java/org/mifos/mobile/core/ui/component/MifosTextUserImage.kt b/core/ui/src/main/java/org/mifos/mobile/core/ui/component/MifosTextUserImage.kt deleted file mode 100644 index 1a2de0af7..000000000 --- a/core/ui/src/main/java/org/mifos/mobile/core/ui/component/MifosTextUserImage.kt +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright 2024 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/mobile-mobile/blob/master/LICENSE.md - */ -package org.mifos.mobile.core.ui.component - -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -import androidx.compose.runtime.setValue -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.geometry.Size -import androidx.compose.ui.layout.onGloballyPositioned -import androidx.compose.ui.platform.LocalDensity -import org.mifos.mobile.core.designsystem.theme.MifosMobileTheme -import org.mifos.mobile.core.ui.utils.DevicePreviews -import kotlin.math.min - -@Composable -fun MifosTextUserImage( - text: String, - modifier: Modifier = Modifier, -) { - var boxSize by remember { mutableStateOf(Size.Zero) } - Box( - modifier = modifier - .clip(CircleShape) - .background(color = MaterialTheme.colorScheme.primary) - .onGloballyPositioned { coordinates -> - boxSize = Size( - coordinates.size.width.toFloat(), - coordinates.size.height.toFloat(), - ) - }, - contentAlignment = Alignment.Center, - ) { - Text( - text = text, - color = MaterialTheme.colorScheme.onPrimary, - fontSize = with(LocalDensity.current) { - (min(boxSize.width, boxSize.height) / 2).toSp() - }, - ) - } -} - -@DevicePreviews -@Composable -private fun MifosTextUserImagePreview( - modifier: Modifier = Modifier, -) { - MifosMobileTheme { - MifosTextUserImage( - text = "A", - modifier = modifier, - ) - } -} diff --git a/core/ui/src/main/java/org/mifos/mobile/core/ui/component/MifosTexts.kt b/core/ui/src/main/java/org/mifos/mobile/core/ui/component/MifosTexts.kt deleted file mode 100644 index 1bd0e0f92..000000000 --- a/core/ui/src/main/java/org/mifos/mobile/core/ui/component/MifosTexts.kt +++ /dev/null @@ -1,212 +0,0 @@ -/* - * Copyright 2024 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/mobile-mobile/blob/master/LICENSE.md - */ -package org.mifos.mobile.core.ui.component - -import androidx.annotation.DrawableRes -import androidx.compose.foundation.Image -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.size -import androidx.compose.foundation.layout.width -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.alpha -import androidx.compose.ui.res.painterResource -import androidx.compose.ui.text.TextStyle -import androidx.compose.ui.unit.Dp -import androidx.compose.ui.unit.dp -import org.mifos.mobile.core.R -import org.mifos.mobile.core.designsystem.theme.MifosMobileTheme -import org.mifos.mobile.core.ui.utils.DevicePreviews - -@Composable -fun MifosTextTitleDescSingleLine( - title: String, - description: String, - modifier: Modifier = Modifier, -) { - Row( - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.SpaceBetween, - modifier = modifier.fillMaxWidth(), - ) { - Text( - style = MaterialTheme.typography.labelMedium, - color = MaterialTheme.colorScheme.onSurface, - text = title, - modifier = Modifier - .alpha(0.7f), - ) - - Text( - style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.onSurface, - text = description, - ) - } -} - -@Composable -fun MifosTextTitleDescDoubleLine( - title: String, - description: String, - descriptionStyle: TextStyle, - modifier: Modifier = Modifier, -) { - Column(modifier = modifier.fillMaxWidth()) { - Text( - text = title, - style = MaterialTheme.typography.labelMedium, - color = MaterialTheme.colorScheme.onSurface, - modifier = Modifier - .alpha(0.7f) - .fillMaxWidth(), - ) - Text( - text = description, - style = descriptionStyle, - color = MaterialTheme.colorScheme.onSurface, - modifier = Modifier.fillMaxWidth(), - ) - } -} - -@Composable -fun MifosTextTitleDescDrawableSingleLine( - title: String, - description: String, - @DrawableRes - imageResId: Int, - modifier: Modifier = Modifier, - imageSize: Dp = 14.dp, - onDrawableClick: () -> Unit = {}, -) { - Row( - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.SpaceBetween, - modifier = modifier.fillMaxWidth(), - ) { - Text( - style = MaterialTheme.typography.labelMedium, - color = MaterialTheme.colorScheme.onSurface, - text = title, - modifier = Modifier - .weight(1f) - .alpha(0.7f), - ) - Text( - style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.onSurface, - text = description, - ) - Spacer(modifier = Modifier.width(5.dp)) - Image( - painter = painterResource(id = imageResId), - contentDescription = null, - modifier = Modifier - .size(imageSize) - .clickable { onDrawableClick() }, - ) - } -} - -@Composable -fun MifosTitleDescSingleLineEqual( - title: String, - description: String, - modifier: Modifier = Modifier, -) { - Row( - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.SpaceBetween, - modifier = modifier.fillMaxWidth(), - ) { - Text( - style = MaterialTheme.typography.labelMedium, - color = MaterialTheme.colorScheme.onSurface, - text = title, - modifier = Modifier - .alpha(0.7f) - .weight(1f), - ) - - Text( - style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.onSurface, - text = description, - modifier = Modifier.weight(1f), - ) - } -} - -@DevicePreviews -@Composable -private fun MifosTextTitleDescSingleLinePreview( - modifier: Modifier = Modifier, -) { - MifosMobileTheme { - MifosTextTitleDescSingleLine( - title = "MifosTextTitleDescSingleLine Title", - description = "MifosTextTitleDescSingleLine Description", - modifier = modifier, - ) - } -} - -@DevicePreviews -@Composable -private fun MifosTextTitleDescDoubleLinePreview( - modifier: Modifier = Modifier, -) { - MifosMobileTheme { - MifosTextTitleDescDoubleLine( - title = "MifosTextTitleDescDoubleLine Title", - description = "MifosTextTitleDescDoubleLine Description", - descriptionStyle = MaterialTheme.typography.bodyMedium, - modifier = modifier, - ) - } -} - -@DevicePreviews -@Composable -private fun MifosTextTitleDescDrawableSingleLinePreview( - modifier: Modifier = Modifier, -) { - MifosMobileTheme { - MifosTextTitleDescDrawableSingleLine( - title = "MifosTextTitleDescDrawableSingleLine Title", - description = "MifosTextTitleDescDrawableSingleLine Description", - imageResId = R.drawable.core_common_circular_background, - modifier = modifier, - ) - } -} - -@DevicePreviews -@Composable -private fun MifosTitleDescSingleLineEqualPreview( - modifier: Modifier = Modifier, -) { - MifosMobileTheme { - MifosTitleDescSingleLineEqual( - title = "MifosTitleDescSingleLineEqual Title", - description = "MifosTitleDescSingleLineEqual Description", - modifier = modifier, - ) - } -} diff --git a/core/ui/src/main/java/org/mifos/mobile/core/ui/component/MifosTitleSearchCard.kt b/core/ui/src/main/java/org/mifos/mobile/core/ui/component/MifosTitleSearchCard.kt deleted file mode 100644 index b390b7fd6..000000000 --- a/core/ui/src/main/java/org/mifos/mobile/core/ui/component/MifosTitleSearchCard.kt +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright 2024 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/mobile-mobile/blob/master/LICENSE.md - */ -package org.mifos.mobile.core.ui.component - -import androidx.annotation.StringRes -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.padding -import androidx.compose.material3.Icon -import androidx.compose.material3.IconButton -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -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.Modifier -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.TextStyle -import androidx.compose.ui.text.input.TextFieldValue -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import org.mifos.mobile.core.R -import org.mifos.mobile.core.designsystem.components.MifosSearchTextField -import org.mifos.mobile.core.designsystem.icons.MifosIcons -import org.mifos.mobile.core.designsystem.theme.MifosMobileTheme -import org.mifos.mobile.core.ui.utils.DevicePreviews - -@Composable -fun MifosTitleSearchCard( - @StringRes - titleResourceId: Int, - searchQuery: (String) -> Unit, - onSearchDismiss: () -> Unit, - modifier: Modifier = Modifier, -) { - var isSearching by rememberSaveable { mutableStateOf(false) } - var searchedQuery by rememberSaveable(stateSaver = TextFieldValue.Saver) { - mutableStateOf( - TextFieldValue(""), - ) - } - - if (!isSearching) { - Row( - modifier = modifier, - verticalAlignment = Alignment.CenterVertically, - ) { - Text( - text = stringResource(id = titleResourceId), - color = MaterialTheme.colorScheme.onSurface, - style = TextStyle(fontSize = 24.sp), - modifier = Modifier.weight(1f), - maxLines = 1, - ) - - IconButton(onClick = { isSearching = true }) { - Icon( - imageVector = MifosIcons.Search, - contentDescription = "Search Icon", - tint = MaterialTheme.colorScheme.onSurface, - ) - } - } - } else { - Row( - modifier = Modifier - .padding(horizontal = 4.dp), - verticalAlignment = Alignment.CenterVertically, - ) { - MifosSearchTextField( - modifier = Modifier.fillMaxWidth(), - value = searchedQuery, - onValueChange = { - searchedQuery = it - searchQuery(it.text) - }, - onSearchDismiss = { - searchedQuery = TextFieldValue("") - isSearching = false - onSearchDismiss.invoke() - }, - ) - } - } -} - -@DevicePreviews -@Composable -private fun MifosTitleSearchCardPreview( - modifier: Modifier = Modifier, -) { - MifosMobileTheme { - MifosTitleSearchCard( - titleResourceId = R.string.core_common_working, - searchQuery = {}, - onSearchDismiss = {}, - modifier = modifier, - ) - } -} diff --git a/core/ui/src/main/java/org/mifos/mobile/core/ui/component/MifosUserImage.kt b/core/ui/src/main/java/org/mifos/mobile/core/ui/component/MifosUserImage.kt deleted file mode 100644 index f1b6b9c5f..000000000 --- a/core/ui/src/main/java/org/mifos/mobile/core/ui/component/MifosUserImage.kt +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2024 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/mobile-mobile/blob/master/LICENSE.md - */ -package org.mifos.mobile.core.ui.component - -import android.graphics.Bitmap -import androidx.compose.foundation.Image -import androidx.compose.foundation.background -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.material3.MaterialTheme -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.asImageBitmap -import androidx.compose.ui.layout.ContentScale -import org.mifos.mobile.core.designsystem.theme.MifosMobileTheme -import org.mifos.mobile.core.ui.utils.DevicePreviews - -@Composable -fun MifosUserImage( - bitmap: Bitmap?, - modifier: Modifier = Modifier, - username: String? = null, -) { - if (bitmap == null) { - MifosTextUserImage( - text = username?.firstOrNull()?.toString() ?: "M", - modifier = modifier, - ) - } else { - Image( - modifier = modifier - .clip(CircleShape) - .background(MaterialTheme.colorScheme.primary), - bitmap = bitmap.asImageBitmap(), - contentDescription = "Profile Image", - contentScale = ContentScale.Crop, - ) - } -} - -@DevicePreviews -@Composable -private fun MifosUserImagePreview( - modifier: Modifier = Modifier, -) { - MifosMobileTheme { - MifosUserImage( - bitmap = null, - modifier = modifier, - username = "John Doe", - ) - } -} diff --git a/core/ui/src/main/java/org/mifos/mobile/core/ui/component/MonitorListItemWithIcon.kt b/core/ui/src/main/java/org/mifos/mobile/core/ui/component/MonitorListItemWithIcon.kt deleted file mode 100644 index faddb190d..000000000 --- a/core/ui/src/main/java/org/mifos/mobile/core/ui/component/MonitorListItemWithIcon.kt +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright 2024 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/mobile-mobile/blob/master/LICENSE.md - */ -package org.mifos.mobile.core.ui.component - -import androidx.annotation.DrawableRes -import androidx.annotation.StringRes -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size -import androidx.compose.foundation.layout.width -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.alpha -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.unit.dp -import org.mifos.mobile.core.R -import org.mifos.mobile.core.designsystem.theme.MifosMobileTheme -import org.mifos.mobile.core.ui.utils.DevicePreviews - -@Composable -fun MonitorListItemWithIcon( - @StringRes titleId: Int, - @StringRes subTitleId: Int, - @DrawableRes iconId: Int, - onClick: () -> Unit, - modifier: Modifier = Modifier, -) { - Row( - modifier = modifier - .clickable { onClick.invoke() } - .padding(8.dp), - verticalAlignment = Alignment.CenterVertically, - ) { - MifosRoundIcon( - iconId = iconId, - modifier = Modifier.size(39.dp), - ) - Spacer(modifier = Modifier.width(8.dp)) - Column { - Text( - text = stringResource(id = titleId), - style = MaterialTheme.typography.bodyLarge, - color = MaterialTheme.colorScheme.onSurface, - modifier = Modifier.fillMaxWidth(), - ) - Text( - text = stringResource(id = subTitleId), - style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.onSurface, - modifier = Modifier - .alpha(0.7f) - .fillMaxWidth(), - ) - } - } -} - -@DevicePreviews -@Composable -private fun MonitorListItemWithIconPreview( - modifier: Modifier = Modifier, -) { - MifosMobileTheme { - MonitorListItemWithIcon( - titleId = R.string.core_common_working, - subTitleId = R.string.something_went_wrong, - iconId = R.drawable.core_common_circular_background, - onClick = {}, - modifier = modifier, - ) - } -} diff --git a/core/ui/src/main/java/org/mifos/mobile/core/ui/component/NoInternet.kt b/core/ui/src/main/java/org/mifos/mobile/core/ui/component/NoInternet.kt deleted file mode 100644 index 29bedc79d..000000000 --- a/core/ui/src/main/java/org/mifos/mobile/core/ui/component/NoInternet.kt +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright 2024 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/mobile-mobile/blob/master/LICENSE.md - */ -package org.mifos.mobile.core.ui.component - -import androidx.annotation.DrawableRes -import androidx.annotation.StringRes -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size -import androidx.compose.material3.FilledTonalButton -import androidx.compose.material3.Icon -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.vector.ImageVector -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.res.vectorResource -import androidx.compose.ui.text.TextStyle -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import org.mifos.mobile.core.R -import org.mifos.mobile.core.designsystem.icons.MifosIcons -import org.mifos.mobile.core.designsystem.theme.MifosMobileTheme -import org.mifos.mobile.core.ui.utils.DevicePreviews - -@Composable -fun NoInternet( - @StringRes error: Int, - modifier: Modifier = Modifier, - isRetryEnabled: Boolean = true, - @DrawableRes icon: Int? = null, - retry: () -> Unit = {}, -) { - Column( - modifier = modifier - .fillMaxSize() - .background(MaterialTheme.colorScheme.background), - verticalArrangement = Arrangement.Center, - horizontalAlignment = Alignment.CenterHorizontally, - ) { - Icon( - modifier = Modifier - .size(100.dp) - .padding(bottom = 12.dp), - imageVector = if (icon != null) { - ImageVector.vectorResource(id = icon) - } else { - MifosIcons.WifiOff - }, - contentDescription = null, - tint = MaterialTheme.colorScheme.onSecondary, - ) - - Text( - text = stringResource(id = error), - style = TextStyle(fontSize = 20.sp), - color = MaterialTheme.colorScheme.onSecondary, - ) - - Spacer(modifier = Modifier.height(12.dp)) - if (isRetryEnabled) { - FilledTonalButton(onClick = { retry.invoke() }) { - Text(text = "Retry") - } - } - } -} - -@DevicePreviews -@Composable -private fun NoInternetPreview( - modifier: Modifier = Modifier, -) { - MifosMobileTheme { - NoInternet( - error = R.string.no_internet, - modifier = modifier, - isRetryEnabled = true, - icon = R.drawable.core_common_circular_background, - retry = {}, - ) - } -} diff --git a/core/ui/src/main/java/org/mifos/mobile/core/ui/component/UserProfileField.kt b/core/ui/src/main/java/org/mifos/mobile/core/ui/component/UserProfileField.kt deleted file mode 100644 index 20b41deec..000000000 --- a/core/ui/src/main/java/org/mifos/mobile/core/ui/component/UserProfileField.kt +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright 2024 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/mobile-mobile/blob/master/LICENSE.md - */ -package org.mifos.mobile.core.ui.component - -import androidx.annotation.DrawableRes -import androidx.annotation.StringRes -import androidx.compose.foundation.clickable -import androidx.compose.foundation.isSystemInDarkTheme -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.material3.HorizontalDivider -import androidx.compose.material3.Icon -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.res.painterResource -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.TextStyle -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import org.mifos.mobile.core.R -import org.mifos.mobile.core.designsystem.theme.MifosMobileTheme -import org.mifos.mobile.core.ui.utils.DevicePreviews - -@Composable -fun UserProfileField( - @StringRes text: Int, - @DrawableRes icon: Int, - onClick: (() -> Unit), - modifier: Modifier = Modifier, -) { - Row( - modifier = modifier - .fillMaxWidth() - .clickable(onClick = onClick) - .padding(top = 16.dp, bottom = 16.dp, start = 8.dp, end = 8.dp), - horizontalArrangement = Arrangement.SpaceBetween, - ) { - Text( - text = stringResource(id = text), - color = Color(0xFF8E9099), - style = TextStyle(fontSize = 12.sp, fontWeight = FontWeight.SemiBold), - ) - Icon( - painter = painterResource(id = icon), - contentDescription = null, - tint = if (isSystemInDarkTheme()) Color.White else Color.Black, - ) - } - HorizontalDivider(color = if (isSystemInDarkTheme()) Color(0xFF8E9099) else Color.Black) -} - -@Composable -fun UserProfileField( - @StringRes label: Int, - value: String, - modifier: Modifier = Modifier, -) { - Row( - modifier = modifier - .fillMaxWidth() - .padding(top = 16.dp, bottom = 16.dp, start = 8.dp, end = 8.dp), - horizontalArrangement = Arrangement.SpaceBetween, - ) { - Text( - text = stringResource(id = label), - color = Color(0xFF8E9099), - style = TextStyle(fontSize = 12.sp, fontWeight = FontWeight.SemiBold), - ) - Text( - text = value, - color = if (isSystemInDarkTheme()) Color.White else Color.Black, - style = TextStyle(fontSize = 14.sp), - ) - } - HorizontalDivider(color = Color(0xFF8E9099)) -} - -@DevicePreviews -@Composable -private fun UserProfileFieldPreview( - modifier: Modifier = Modifier, -) { - MifosMobileTheme { - UserProfileField( - text = R.string.core_common_working, - icon = R.drawable.core_common_circular_background, - onClick = {}, - modifier = modifier, - ) - } -} - -@DevicePreviews -@Composable -private fun UserProfileFieldValuePreview( - modifier: Modifier = Modifier, -) { - MifosMobileTheme { - UserProfileField( - label = R.string.core_common_working, - value = "UserProfileFieldValue", - modifier = modifier, - ) - } -} diff --git a/core/ui/src/main/java/org/mifos/mobile/core/ui/component/UserProfileTopBar.kt b/core/ui/src/main/java/org/mifos/mobile/core/ui/component/UserProfileTopBar.kt deleted file mode 100644 index 1f9346992..000000000 --- a/core/ui/src/main/java/org/mifos/mobile/core/ui/component/UserProfileTopBar.kt +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright 2024 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/mobile-mobile/blob/master/LICENSE.md - */ -package org.mifos.mobile.core.ui.component - -import androidx.compose.foundation.clickable -import androidx.compose.foundation.isSystemInDarkTheme -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.fillMaxHeight -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.padding -import androidx.compose.material3.ExperimentalMaterial3Api -import androidx.compose.material3.Icon -import androidx.compose.material3.Text -import androidx.compose.material3.TopAppBar -import androidx.compose.material3.TopAppBarDefaults -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.TextStyle -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import org.mifos.mobile.core.designsystem.icons.MifosIcons - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun UserProfileTopBar( - text: Int, - home: () -> Unit, - modifier: Modifier = Modifier, -) { - TopAppBar( - modifier = modifier.height(64.dp), - title = { - Row( - modifier = Modifier - .fillMaxSize() - .padding(start = 16.dp), - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.SpaceBetween, - ) { - Text( - text = stringResource(id = text), - color = if (isSystemInDarkTheme()) Color.White else Color.Black, - style = TextStyle(fontSize = 24.sp), - ) - Icon( - imageVector = MifosIcons.Edit, - contentDescription = null, - tint = if (isSystemInDarkTheme()) Color.White else Color.Black, - ) - } - }, - navigationIcon = { - Column( - modifier = Modifier - .fillMaxHeight() - .padding(start = 8.dp), - verticalArrangement = Arrangement.Center, - horizontalAlignment = Alignment.CenterHorizontally, - ) { - Icon( - imageVector = MifosIcons.ArrowBack, - contentDescription = null, - modifier = Modifier.clickable(onClick = { - home.invoke() - }), - tint = if (isSystemInDarkTheme()) Color.White else Color.Black, - ) - } - }, - colors = TopAppBarDefaults.topAppBarColors( - containerColor = if (isSystemInDarkTheme()) { - Color( - 0xFF1B1B1F, - ) - } else { - Color(0xFFFEFBFF) - }, - ), - ) -} diff --git a/core/ui/src/main/java/org/mifos/mobile/core/ui/utils/ColorUtils.kt b/core/ui/src/main/java/org/mifos/mobile/core/ui/utils/ColorUtils.kt deleted file mode 100644 index b7d9e9b99..000000000 --- a/core/ui/src/main/java/org/mifos/mobile/core/ui/utils/ColorUtils.kt +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2024 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/mobile-mobile/blob/master/LICENSE.md - */ -package org.mifos.mobile.core.ui.utils - -import android.app.Activity -import android.content.Context -import android.util.TypedValue -import androidx.annotation.AttrRes -import androidx.annotation.ColorInt -import androidx.core.graphics.ColorUtils -import androidx.core.view.WindowCompat - -fun Activity.setStatusBarColor(@ColorInt color: Int) { - if (!window.decorView.isInEditMode) { - window.statusBarColor = color - WindowCompat.getInsetsController(window, window.decorView).isAppearanceLightStatusBars = - ColorUtils.calculateLuminance(color) > 0.5 - } -} - -@ColorInt -fun Context.getThemeAttributeColor(@AttrRes colorAttribute: Int): Int { - val typedValue = TypedValue() - theme.resolveAttribute(colorAttribute, typedValue, true) - return typedValue.data -} diff --git a/core/ui/src/main/java/org/mifos/mobile/core/ui/utils/DevicePreviews.kt b/core/ui/src/main/java/org/mifos/mobile/core/ui/utils/DevicePreviews.kt deleted file mode 100644 index d5f9461ca..000000000 --- a/core/ui/src/main/java/org/mifos/mobile/core/ui/utils/DevicePreviews.kt +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright 2024 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/mobile-mobile/blob/master/LICENSE.md - */ -package org.mifos.mobile.core.ui.utils - -import androidx.compose.ui.tooling.preview.Preview - -/** - * Multipreview annotation that represents various device sizes. Add this annotation to a composable - * to render various devices. - */ -@Preview(name = "phone", device = "spec:width=360dp,height=640dp,dpi=480") -@Preview(name = "landscape", device = "spec:width=640dp,height=360dp,dpi=480") -@Preview(name = "foldable", device = "spec:width=673dp,height=841dp,dpi=480") -@Preview(name = "tablet", device = "spec:width=1280dp,height=800dp,dpi=480") -annotation class DevicePreviews diff --git a/core/ui/src/main/java/org/mifos/mobile/core/ui/utils/ImageUtil.kt b/core/ui/src/main/java/org/mifos/mobile/core/ui/utils/ImageUtil.kt deleted file mode 100644 index 9ba20c089..000000000 --- a/core/ui/src/main/java/org/mifos/mobile/core/ui/utils/ImageUtil.kt +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright 2024 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/mobile-mobile/blob/master/LICENSE.md - */ -package org.mifos.mobile.core.ui.utils - -import android.graphics.Bitmap -import android.graphics.BitmapFactory -import android.graphics.Canvas -import android.graphics.Matrix -import android.graphics.Paint -import android.util.Log - -object ImageUtil { - private const val DEFAULT_MAX_WIDTH = 816f - private const val DEFAULT_MAX_HEIGHT = 612f - - fun compressImage( - decodedBytes: ByteArray, - maxWidth: Float = DEFAULT_MAX_WIDTH, - maxHeight: Float = DEFAULT_MAX_HEIGHT, - ): Bitmap { - val options = BitmapFactory.Options().apply { - inJustDecodeBounds = true - } - - BitmapFactory.decodeByteArray(decodedBytes, 0, decodedBytes.size, options) - - val (actualWidth, actualHeight) = calculateActualDimensions(options, maxWidth, maxHeight) - - options.apply { - inJustDecodeBounds = false - inSampleSize = calculateInSampleSize(this, actualWidth, actualHeight) - inTempStorage = ByteArray(16 * 1024) - } - - val bmp = try { - BitmapFactory.decodeByteArray(decodedBytes, 0, decodedBytes.size, options) - } catch (e: OutOfMemoryError) { - Log.e(this::class.java.simpleName, "OutOfMemoryError while decoding bitmap", e) - return Bitmap.createBitmap( - 1, - 1, - Bitmap.Config.ARGB_8888, - ) // Return a 1x1 bitmap as fallback - } - - return try { - createScaledBitmap(bmp, actualWidth, actualHeight, options) - } catch (e: OutOfMemoryError) { - Log.e(this::class.java.simpleName, "OutOfMemoryError while scaling bitmap", e) - bmp // Return the original bitmap if scaling fails - } - } -} - -private fun calculateActualDimensions( - options: BitmapFactory.Options, - maxWidth: Float, - maxHeight: Float, -): Pair { - var actualWidth = options.outWidth - var actualHeight = options.outHeight - val imgRatio = actualWidth.toFloat() / actualHeight - val maxRatio = maxWidth / maxHeight - - if (actualHeight > maxHeight || actualWidth > maxWidth) { - when { - imgRatio < maxRatio -> { - actualHeight = maxHeight.toInt() - actualWidth = (maxHeight * imgRatio).toInt() - } - - imgRatio > maxRatio -> { - actualWidth = maxWidth.toInt() - actualHeight = (maxWidth / imgRatio).toInt() - } - - else -> { - actualHeight = maxHeight.toInt() - actualWidth = maxWidth.toInt() - } - } - } - - return Pair(actualWidth, actualHeight) -} - -private fun calculateInSampleSize( - options: BitmapFactory.Options, - reqWidth: Int, - reqHeight: Int, -): Int { - val (height, width) = options.run { outHeight to outWidth } - var inSampleSize = 1 - - if (height > reqHeight || width > reqWidth) { - val halfHeight = height / 2 - val halfWidth = width / 2 - - while (halfHeight / inSampleSize >= reqHeight && halfWidth / inSampleSize >= reqWidth) { - inSampleSize *= 2 - } - } - - return inSampleSize -} - -private fun createScaledBitmap( - bmp: Bitmap, - actualWidth: Int, - actualHeight: Int, - options: BitmapFactory.Options, -): Bitmap { - val scaledBitmap = Bitmap.createBitmap(actualWidth, actualHeight, Bitmap.Config.ARGB_8888) - val ratioX = actualWidth / options.outWidth.toFloat() - val ratioY = actualHeight / options.outHeight.toFloat() - val middleX = actualWidth / 2f - val middleY = actualHeight / 2f - - val scaleMatrix = Matrix().apply { - setScale(ratioX, ratioY, middleX, middleY) - } - - Canvas(scaledBitmap).apply { - setMatrix(scaleMatrix) - drawBitmap( - bmp, - middleX - bmp.width / 2, - middleY - bmp.height / 2, - Paint(Paint.FILTER_BITMAP_FLAG), - ) - } - - return scaledBitmap -} diff --git a/core/ui/src/main/java/org/mifos/mobile/core/ui/utils/PresentOrFutureSelectableDates.kt b/core/ui/src/main/java/org/mifos/mobile/core/ui/utils/PresentOrFutureSelectableDates.kt deleted file mode 100644 index 9526fa3e9..000000000 --- a/core/ui/src/main/java/org/mifos/mobile/core/ui/utils/PresentOrFutureSelectableDates.kt +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright 2024 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/mobile-mobile/blob/master/LICENSE.md - */ -package org.mifos.mobile.core.ui.utils - -import androidx.compose.material3.ExperimentalMaterial3Api -import androidx.compose.material3.SelectableDates -import java.time.LocalDate - -@OptIn(ExperimentalMaterial3Api::class) -object PresentOrFutureSelectableDates : SelectableDates { - @ExperimentalMaterial3Api - override fun isSelectableDate(utcTimeMillis: Long): Boolean { - return utcTimeMillis >= System.currentTimeMillis() - } - - override fun isSelectableYear(year: Int): Boolean { - return year >= LocalDate.now().year - } -} diff --git a/core/ui/src/main/res/values/colors.xml b/core/ui/src/main/res/values/colors.xml deleted file mode 100644 index d7ccaf034..000000000 --- a/core/ui/src/main/res/values/colors.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - #FF325ca8 - \ No newline at end of file diff --git a/core/ui/src/main/res/values/strings.xml b/core/ui/src/main/res/values/strings.xml deleted file mode 100644 index 2f7ca73f0..000000000 --- a/core/ui/src/main/res/values/strings.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - No Internet - Retry - No Data - Something went wrong - \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index f95c904a9..c5553b7cd 100644 --- a/gradle.properties +++ b/gradle.properties @@ -45,4 +45,5 @@ 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 \ No newline at end of file +android.defaults.buildfeatures.shaders=false +org.jetbrains.compose.experimental.jscanvas.enabled=true \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 51ad70317..e14b60eea 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,4 +1,5 @@ [versions] +accompanistSystemuicontrollerVersion = "0.30.1" accompanistVersion = "0.34.0" activityVersion = "1.9.3" androidDesugarJdkLibs = "2.1.4" @@ -42,6 +43,7 @@ hilt = "2.54" hiltExt = "1.2.0" jacoco = "0.8.7" junitVersion = "4.13.2" +kotlinxDatetimeVersion = "0.4.0" ktlint = "12.1.1" libphonenumberAndroidVersion = "8.13.35" lifecycleExtensionsVersion = "2.2.0" @@ -119,6 +121,7 @@ packageVersion = "1.0.0" [libraries] accompanist-pager = { group = "com.google.accompanist", name = "accompanist-pager", version.ref = "accompanistVersion" } accompanist-permissions = { group = "com.google.accompanist", name = "accompanist-permissions", version.ref = "accompanistVersion" } +accompanist-systemuicontroller = { module = "com.google.accompanist:accompanist-systemuicontroller", version.ref = "accompanistSystemuicontrollerVersion" } android-desugarJdkLibs = { group = "com.android.tools", name = "desugar_jdk_libs", version.ref = "androidDesugarJdkLibs" } android-gradlePlugin = { group = "com.android.tools.build", name = "gradle", version.ref = "androidGradlePlugin" } android-tools-common = { group = "com.android.tools", name = "common", version.ref = "androidTools" } @@ -194,6 +197,7 @@ hilt-ext-compiler = { group = "androidx.hilt", name = "hilt-compiler", version.r hilt-ext-work = { group = "androidx.hilt", name = "hilt-work", version.ref = "hiltExt" } jetbrains-kotlin-jdk7 = { group = "org.jetbrains.kotlin", name = "kotlin-stdlib-jdk7", version.ref = "kotlin" } junit = { group = "junit", name = "junit", version.ref = "junitVersion" } +kotlinx-datetime-v040 = { module = "org.jetbrains.kotlinx:kotlinx-datetime", version.ref = "kotlinxDatetimeVersion" } ktlint-gradlePlugin = { group = "org.jlleitschuh.gradle", name = "ktlint-gradle", version.ref = "ktlint" } libphonenumber-android = { group = "io.michaelrocks", name = "libphonenumber-android", version.ref = "libphonenumberAndroidVersion" } lint-api = { group = "com.android.tools.lint", name = "lint-api", version.ref = "androidTools" } From c4dc6b802914300c2a9927dc0d8240d9762f0f53 Mon Sep 17 00:00:00 2001 From: revanthkumarJ Date: Sun, 19 Jan 2025 16:15:37 +0530 Subject: [PATCH 03/11] updated --- core/ui/build.gradle.kts | 2 +- .../mobile/core/ui/utils/ImageUtil.android.kt | 142 +++++++++- .../mobile/core/ui/component/EmptyDataView.kt | 13 +- .../mobile/core/ui/component/FaqItemHolder.kt | 2 +- .../core/ui/component/MifosAlertDialog.kt | 6 +- .../ui/component/MifosDropDownTextField.kt | 8 +- .../core/ui/component/MifosErrorComponent.kt | 2 +- .../core/ui/component/MifosHiddenTextRow.kt | 6 +- .../core/ui/component/MifosMobileIcon.kt | 3 +- .../core/ui/component/MifosRoundIcon.kt | 3 +- .../MifosTextButtonWithTopDrawable.kt | 9 +- .../mobile/core/ui/component/MifosTexts.kt | 3 +- .../core/ui/component/MifosTitleSearchCard.kt | 5 +- .../ui/component/MonitorListItemWithIcon.kt | 3 +- .../mobile/core/ui/component/NoInternet.kt | 14 +- .../core/ui/component/UserProfileField.kt | 4 +- .../core/ui/component/UserProfileTopBar.kt | 2 +- .../mifos/mobile/core/ui/utils/ImageUtil.kt | 251 +++++++++--------- .../mobile/core/ui/utils/ImageUtil.native.kt | 25 +- 19 files changed, 333 insertions(+), 170 deletions(-) diff --git a/core/ui/build.gradle.kts b/core/ui/build.gradle.kts index 993c3e970..8a1c0fd0b 100644 --- a/core/ui/build.gradle.kts +++ b/core/ui/build.gradle.kts @@ -29,7 +29,7 @@ kotlin{ implementation(libs.accompanist.pager) } commonMain.dependencies { -// api(projects.core.designsystem) + api(projects.core.designsystem) api(projects.core.model) api(projects.core.common) implementation(libs.jb.composeViewmodel) diff --git a/core/ui/src/androidMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.android.kt b/core/ui/src/androidMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.android.kt index 7bf3065f0..7122f00d9 100644 --- a/core/ui/src/androidMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.android.kt +++ b/core/ui/src/androidMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.android.kt @@ -1,2 +1,142 @@ -package org.mifos.mobile.core.ui.utils +/* + * 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/mobile-mobile/blob/master/LICENSE.md + */ +package org.mifos.mobile.core.ui.utils +import android.graphics.Bitmap +import android.graphics.BitmapFactory +import android.graphics.Canvas +import android.graphics.Matrix +import android.graphics.Paint +import android.util.Log +import java.io.ByteArrayOutputStream + +actual object ImageUtil { + actual val DEFAULT_MAX_WIDTH: Float = 816f + actual val DEFAULT_MAX_HEIGHT: Float = 612f + + actual fun compressImage( + decodedBytes: ByteArray, + maxWidth: Float, + maxHeight: Float, + ): ByteArray { + val options = BitmapFactory.Options().apply { + inJustDecodeBounds = true + } + + BitmapFactory.decodeByteArray(decodedBytes, 0, decodedBytes.size, options) + + val (actualWidth, actualHeight) = calculateActualDimensions(options, maxWidth, maxHeight) + + options.apply { + inJustDecodeBounds = false + inSampleSize = calculateInSampleSize(this, actualWidth, actualHeight) + inTempStorage = ByteArray(16 * 1024) + } + + val bmp = try { + BitmapFactory.decodeByteArray(decodedBytes, 0, decodedBytes.size, options) + } catch (e: OutOfMemoryError) { + Log.e(this::class.java.simpleName, "OutOfMemoryError while decoding bitmap", e) + return ByteArray(0) + } + + val scaledBitmap = try { + createScaledBitmap(bmp, actualWidth, actualHeight, options) + } catch (e: OutOfMemoryError) { + Log.e(this::class.java.simpleName, "OutOfMemoryError while scaling bitmap", e) + bmp + } + + val byteArrayOutputStream = ByteArrayOutputStream() + scaledBitmap.compress(Bitmap.CompressFormat.JPEG, 85, byteArrayOutputStream) + return byteArrayOutputStream.toByteArray() + } + + private fun calculateActualDimensions( + options: BitmapFactory.Options, + maxWidth: Float, + maxHeight: Float, + ): Pair { + var actualWidth = options.outWidth + var actualHeight = options.outHeight + val imgRatio = actualWidth.toFloat() / actualHeight + val maxRatio = maxWidth / maxHeight + + if (actualHeight > maxHeight || actualWidth > maxWidth) { + when { + imgRatio < maxRatio -> { + actualHeight = maxHeight.toInt() + actualWidth = (maxHeight * imgRatio).toInt() + } + + imgRatio > maxRatio -> { + actualWidth = maxWidth.toInt() + actualHeight = (maxWidth / imgRatio).toInt() + } + + else -> { + actualHeight = maxHeight.toInt() + actualWidth = maxWidth.toInt() + } + } + } + + return Pair(actualWidth, actualHeight) + } + + private fun calculateInSampleSize( + options: BitmapFactory.Options, + reqWidth: Int, + reqHeight: Int, + ): Int { + val (height, width) = options.run { outHeight to outWidth } + var inSampleSize = 1 + + if (height > reqHeight || width > reqWidth) { + val halfHeight = height / 2 + val halfWidth = width / 2 + + while (halfHeight / inSampleSize >= reqHeight && halfWidth / inSampleSize >= reqWidth) { + inSampleSize *= 2 + } + } + + return inSampleSize + } + + private fun createScaledBitmap( + bmp: Bitmap, + actualWidth: Int, + actualHeight: Int, + options: BitmapFactory.Options, + ): Bitmap { + val scaledBitmap = Bitmap.createBitmap(actualWidth, actualHeight, Bitmap.Config.ARGB_8888) + val ratioX = actualWidth / options.outWidth.toFloat() + val ratioY = actualHeight / options.outHeight.toFloat() + val middleX = actualWidth / 2f + val middleY = actualHeight / 2f + + val scaleMatrix = Matrix().apply { + setScale(ratioX, ratioY, middleX, middleY) + } + + Canvas(scaledBitmap).apply { + setMatrix(scaleMatrix) + drawBitmap( + bmp, + middleX - bmp.width / 2, + middleY - bmp.height / 2, + Paint(Paint.FILTER_BITMAP_FLAG), + ) + } + + return scaledBitmap + } +} diff --git a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/EmptyDataView.kt b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/EmptyDataView.kt index d6c4d5006..8a88f6bad 100644 --- a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/EmptyDataView.kt +++ b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/EmptyDataView.kt @@ -20,17 +20,16 @@ import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import mifos_mobile.core.ui.generated.resources.Res import mifos_mobile.core.ui.generated.resources.no_internet -import org.jetbrains.compose.resources.DrawableResource import org.jetbrains.compose.resources.StringResource -import org.jetbrains.compose.resources.painterResource import org.jetbrains.compose.resources.stringResource -import org.mifos.mobile.core.designsystem.icons.MifosIcons +import org.mifos.mobile.core.designsystem.icon.MifosIcons import org.mifos.mobile.core.designsystem.theme.MifosMobileTheme import org.mifos.mobile.core.ui.utils.DevicePreviews @@ -38,7 +37,7 @@ import org.mifos.mobile.core.ui.utils.DevicePreviews fun EmptyDataView( error: StringResource, modifier: Modifier = Modifier.fillMaxSize(), - icon: DrawableResource? = null, + icon: ImageVector = MifosIcons.Error, errorString: String? = null, ) { Column( @@ -50,11 +49,7 @@ fun EmptyDataView( modifier = Modifier .size(100.dp) .padding(bottom = 12.dp), - painter = if (icon != null) { - painterResource(icon) - } else { - MifosIcons.Error - }, + imageVector = icon, contentDescription = null, tint = MaterialTheme.colorScheme.onSecondary, ) diff --git a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/FaqItemHolder.kt b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/FaqItemHolder.kt index 8ed4911b4..4f967cf67 100644 --- a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/FaqItemHolder.kt +++ b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/FaqItemHolder.kt @@ -28,7 +28,7 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.scale import androidx.compose.ui.unit.dp -import org.mifos.mobile.core.designsystem.icons.MifosIcons +import org.mifos.mobile.core.designsystem.icon.MifosIcons import org.mifos.mobile.core.designsystem.theme.MifosMobileTheme import org.mifos.mobile.core.ui.utils.DevicePreviews diff --git a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosAlertDialog.kt b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosAlertDialog.kt index c87a49027..8b5115e94 100644 --- a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosAlertDialog.kt +++ b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosAlertDialog.kt @@ -15,7 +15,7 @@ import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.vector.ImageVector -import org.mifos.mobile.core.designsystem.components.MifosTextButton +import org.mifos.mobile.core.designsystem.component.MifosTextButton import org.mifos.mobile.core.designsystem.theme.MifosMobileTheme import org.mifos.mobile.core.ui.utils.DevicePreviews @@ -42,13 +42,13 @@ fun MifosAlertDialog( onDismissRequest = onDismissRequest, confirmButton = { MifosTextButton( - text = confirmationText, + text = { Text(text = confirmationText) }, onClick = onConfirmation, ) }, dismissButton = { MifosTextButton( - text = dismissText, + text = { Text(text = dismissText) }, onClick = onDismissRequest, ) }, diff --git a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosDropDownTextField.kt b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosDropDownTextField.kt index 582459f56..d14f0afe3 100644 --- a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosDropDownTextField.kt +++ b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosDropDownTextField.kt @@ -31,9 +31,11 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.draw.alpha import androidx.compose.ui.unit.dp +import mifos_mobile.core.ui.generated.resources.Res +import mifos_mobile.core.ui.generated.resources.retry import org.jetbrains.compose.resources.StringResource import org.jetbrains.compose.resources.stringResource -import org.mifos.mobile.core.designsystem.icons.MifosIcons +import org.mifos.mobile.core.designsystem.icon.MifosIcons import org.mifos.mobile.core.designsystem.theme.MifosMobileTheme import org.mifos.mobile.core.ui.utils.DevicePreviews @@ -184,7 +186,7 @@ private fun MifosDropDownTextFieldPreview( MifosDropDownTextField( onClick = { _, _ -> }, modifier = modifier, - labelResId = 0, + labelResId = Res.string.retry, isEnabled = true, supportingText = null, error = false, @@ -203,7 +205,7 @@ private fun MifosDropDownDoubleTextFieldPreview( MifosDropDownDoubleTextField( onClick = { _, _ -> }, modifier = modifier, - labelResId = 0, + labelResId = Res.string.retry, isEnabled = true, supportingText = null, error = false, diff --git a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosErrorComponent.kt b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosErrorComponent.kt index 79a27dae0..af647fef5 100644 --- a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosErrorComponent.kt +++ b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosErrorComponent.kt @@ -35,7 +35,7 @@ import mifos_mobile.core.ui.generated.resources.no_internet import mifos_mobile.core.ui.generated.resources.retry import mifos_mobile.core.ui.generated.resources.something_went_wrong import org.jetbrains.compose.resources.stringResource -import org.mifos.mobile.core.designsystem.icons.MifosIcons +import org.mifos.mobile.core.designsystem.icon.MifosIcons import org.mifos.mobile.core.designsystem.theme.MifosMobileTheme import org.mifos.mobile.core.ui.utils.DevicePreviews diff --git a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosHiddenTextRow.kt b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosHiddenTextRow.kt index c124c30d6..983413c0a 100644 --- a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosHiddenTextRow.kt +++ b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosHiddenTextRow.kt @@ -28,6 +28,8 @@ import androidx.compose.ui.draw.alpha import androidx.compose.ui.graphics.Color import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp +import mifos_mobile.core.ui.generated.resources.Res +import mifos_mobile.core.ui.generated.resources.core_ui_money_in import org.jetbrains.compose.resources.DrawableResource import org.jetbrains.compose.resources.painterResource import org.mifos.mobile.core.designsystem.theme.MifosMobileTheme @@ -97,8 +99,8 @@ private fun MifosHiddenTextRowPreview( hiddenText = "Hidden Text", hiddenColor = MaterialTheme.colorScheme.primary, hidingText = "Hiding Text", - visibilityIconId = 0, - visibilityOffIconId = 0, + visibilityIconId = Res.drawable.core_ui_money_in, + visibilityOffIconId = Res.drawable.core_ui_money_in, onClick = {}, modifier = modifier, ) diff --git a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosMobileIcon.kt b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosMobileIcon.kt index 189273af5..3c75609bf 100644 --- a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosMobileIcon.kt +++ b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosMobileIcon.kt @@ -18,6 +18,7 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import mifos_mobile.core.ui.generated.resources.Res +import mifos_mobile.core.ui.generated.resources.core_ui_money_in import org.jetbrains.compose.resources.DrawableResource import org.jetbrains.compose.resources.painterResource import org.mifos.mobile.core.designsystem.theme.MifosMobileTheme @@ -47,7 +48,7 @@ private fun MifosMobileIconPreview( ) { MifosMobileTheme { MifosMobileIcon( - id = Res.drawable.core_common_circular_background, + id = Res.drawable.core_ui_money_in, modifier = modifier, ) } diff --git a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosRoundIcon.kt b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosRoundIcon.kt index 87ec1f16b..5eb3aba0d 100644 --- a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosRoundIcon.kt +++ b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosRoundIcon.kt @@ -19,6 +19,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.unit.dp import mifos_mobile.core.ui.generated.resources.Res +import mifos_mobile.core.ui.generated.resources.core_ui_money_in import org.jetbrains.compose.resources.DrawableResource import org.jetbrains.compose.resources.painterResource import org.mifos.mobile.core.designsystem.theme.MifosMobileTheme @@ -50,7 +51,7 @@ private fun MifosRoundIconPreview( ) { MifosMobileTheme { MifosRoundIcon( - iconId = Res.drawable.core_common_circular_background, + iconId = Res.drawable.core_ui_money_in, modifier = modifier, ) } diff --git a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosTextButtonWithTopDrawable.kt b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosTextButtonWithTopDrawable.kt index c852cf3ae..62c421d38 100644 --- a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosTextButtonWithTopDrawable.kt +++ b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosTextButtonWithTopDrawable.kt @@ -13,9 +13,7 @@ import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.height -import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.Icon -import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment @@ -27,8 +25,8 @@ import mifos_mobile.core.ui.generated.resources.Res import mifos_mobile.core.ui.generated.resources.core_common_working import org.jetbrains.compose.resources.StringResource import org.jetbrains.compose.resources.stringResource -import org.mifos.mobile.core.designsystem.components.MifosTextButton -import org.mifos.mobile.core.designsystem.icons.MifosIcons +import org.mifos.mobile.core.designsystem.component.MifosTextButton +import org.mifos.mobile.core.designsystem.icon.MifosIcons import org.mifos.mobile.core.designsystem.theme.MifosMobileTheme import org.mifos.mobile.core.ui.utils.DevicePreviews @@ -43,9 +41,6 @@ fun MifosTextButtonWithTopDrawable( MifosTextButton( onClick = onClick, modifier = modifier, - colors = ButtonDefaults.textButtonColors( - contentColor = MaterialTheme.colorScheme.primary, - ), content = { Column( horizontalAlignment = Alignment.CenterHorizontally, diff --git a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosTexts.kt b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosTexts.kt index 8c0d6881b..a234acb5b 100644 --- a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosTexts.kt +++ b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosTexts.kt @@ -28,6 +28,7 @@ import androidx.compose.ui.text.TextStyle import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import mifos_mobile.core.ui.generated.resources.Res +import mifos_mobile.core.ui.generated.resources.core_ui_money_in import org.jetbrains.compose.resources.DrawableResource import org.jetbrains.compose.resources.painterResource import org.mifos.mobile.core.designsystem.theme.MifosMobileTheme @@ -190,7 +191,7 @@ private fun MifosTextTitleDescDrawableSingleLinePreview( MifosTextTitleDescDrawableSingleLine( title = "MifosTextTitleDescDrawableSingleLine Title", description = "MifosTextTitleDescDrawableSingleLine Description", - imageResId = Res.drawable.core_common_circular_background, + imageResId = Res.drawable.core_ui_money_in, modifier = modifier, ) } diff --git a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosTitleSearchCard.kt b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosTitleSearchCard.kt index 7c9520fcd..59f84ab13 100644 --- a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosTitleSearchCard.kt +++ b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosTitleSearchCard.kt @@ -28,10 +28,11 @@ import androidx.compose.ui.text.input.TextFieldValue import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import mifos_mobile.core.ui.generated.resources.Res +import mifos_mobile.core.ui.generated.resources.core_common_working import org.jetbrains.compose.resources.StringResource import org.jetbrains.compose.resources.stringResource -import org.mifos.mobile.core.designsystem.components.MifosSearchTextField -import org.mifos.mobile.core.designsystem.icons.MifosIcons +import org.mifos.mobile.core.designsystem.component.MifosSearchTextField +import org.mifos.mobile.core.designsystem.icon.MifosIcons import org.mifos.mobile.core.designsystem.theme.MifosMobileTheme import org.mifos.mobile.core.ui.utils.DevicePreviews diff --git a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MonitorListItemWithIcon.kt b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MonitorListItemWithIcon.kt index 8d05ff113..cde46abf0 100644 --- a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MonitorListItemWithIcon.kt +++ b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MonitorListItemWithIcon.kt @@ -26,6 +26,7 @@ import androidx.compose.ui.draw.alpha import androidx.compose.ui.unit.dp import mifos_mobile.core.ui.generated.resources.Res import mifos_mobile.core.ui.generated.resources.core_common_working +import mifos_mobile.core.ui.generated.resources.core_ui_money_in import mifos_mobile.core.ui.generated.resources.something_went_wrong import org.jetbrains.compose.resources.DrawableResource import org.jetbrains.compose.resources.StringResource @@ -80,7 +81,7 @@ private fun MonitorListItemWithIconPreview( MonitorListItemWithIcon( titleId = Res.string.core_common_working, subTitleId = Res.string.something_went_wrong, - iconId = Res.drawable.core_common_circular_background, + iconId = Res.drawable.core_ui_money_in, onClick = {}, modifier = modifier, ) diff --git a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/NoInternet.kt b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/NoInternet.kt index 836ec644c..d412b9bc0 100644 --- a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/NoInternet.kt +++ b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/NoInternet.kt @@ -24,16 +24,15 @@ import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.text.TextStyle import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import mifos_mobile.core.ui.generated.resources.Res import mifos_mobile.core.ui.generated.resources.no_internet -import org.jetbrains.compose.resources.DrawableResource import org.jetbrains.compose.resources.StringResource -import org.jetbrains.compose.resources.painterResource import org.jetbrains.compose.resources.stringResource -import org.mifos.mobile.core.designsystem.icons.MifosIcons +import org.mifos.mobile.core.designsystem.icon.MifosIcons import org.mifos.mobile.core.designsystem.theme.MifosMobileTheme import org.mifos.mobile.core.ui.utils.DevicePreviews @@ -42,7 +41,7 @@ fun NoInternet( error: StringResource, modifier: Modifier = Modifier, isRetryEnabled: Boolean = true, - icon: DrawableResource? = null, + icon: ImageVector = MifosIcons.WifiOff, retry: () -> Unit = {}, ) { Column( @@ -56,11 +55,7 @@ fun NoInternet( modifier = Modifier .size(100.dp) .padding(bottom = 12.dp), - painter = if (icon != null) { - painterResource(icon) - } else { - MifosIcons.WifiOff - }, + imageVector = icon, contentDescription = null, tint = MaterialTheme.colorScheme.onSecondary, ) @@ -90,7 +85,6 @@ private fun NoInternetPreview( error = Res.string.no_internet, modifier = modifier, isRetryEnabled = true, - icon = Res.drawable.core_common_circular_background, retry = {}, ) } diff --git a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/UserProfileField.kt b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/UserProfileField.kt index 998555173..76e52f5a5 100644 --- a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/UserProfileField.kt +++ b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/UserProfileField.kt @@ -26,6 +26,8 @@ import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import mifos_mobile.core.ui.generated.resources.Res +import mifos_mobile.core.ui.generated.resources.core_common_working +import mifos_mobile.core.ui.generated.resources.core_ui_money_in import org.jetbrains.compose.resources.DrawableResource import org.jetbrains.compose.resources.StringResource import org.jetbrains.compose.resources.painterResource @@ -95,7 +97,7 @@ private fun UserProfileFieldPreview( MifosMobileTheme { UserProfileField( text = Res.string.core_common_working, - icon = R.drawable.core_common_circular_background, + icon = Res.drawable.core_ui_money_in, onClick = {}, modifier = modifier, ) diff --git a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/UserProfileTopBar.kt b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/UserProfileTopBar.kt index a76c44155..dfb344da6 100644 --- a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/UserProfileTopBar.kt +++ b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/UserProfileTopBar.kt @@ -32,7 +32,7 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import org.jetbrains.compose.resources.StringResource import org.jetbrains.compose.resources.stringResource -import org.mifos.mobile.core.designsystem.icons.MifosIcons +import org.mifos.mobile.core.designsystem.icon.MifosIcons @OptIn(ExperimentalMaterial3Api::class) @Composable diff --git a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.kt b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.kt index 9ba20c089..4fb8472c0 100644 --- a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.kt +++ b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.kt @@ -9,133 +9,138 @@ */ package org.mifos.mobile.core.ui.utils -import android.graphics.Bitmap -import android.graphics.BitmapFactory -import android.graphics.Canvas -import android.graphics.Matrix -import android.graphics.Paint -import android.util.Log - -object ImageUtil { - private const val DEFAULT_MAX_WIDTH = 816f - private const val DEFAULT_MAX_HEIGHT = 612f +expect object ImageUtil { + val DEFAULT_MAX_WIDTH: Float + val DEFAULT_MAX_HEIGHT: Float fun compressImage( decodedBytes: ByteArray, maxWidth: Float = DEFAULT_MAX_WIDTH, maxHeight: Float = DEFAULT_MAX_HEIGHT, - ): Bitmap { - val options = BitmapFactory.Options().apply { - inJustDecodeBounds = true - } - - BitmapFactory.decodeByteArray(decodedBytes, 0, decodedBytes.size, options) - - val (actualWidth, actualHeight) = calculateActualDimensions(options, maxWidth, maxHeight) - - options.apply { - inJustDecodeBounds = false - inSampleSize = calculateInSampleSize(this, actualWidth, actualHeight) - inTempStorage = ByteArray(16 * 1024) - } - - val bmp = try { - BitmapFactory.decodeByteArray(decodedBytes, 0, decodedBytes.size, options) - } catch (e: OutOfMemoryError) { - Log.e(this::class.java.simpleName, "OutOfMemoryError while decoding bitmap", e) - return Bitmap.createBitmap( - 1, - 1, - Bitmap.Config.ARGB_8888, - ) // Return a 1x1 bitmap as fallback - } - - return try { - createScaledBitmap(bmp, actualWidth, actualHeight, options) - } catch (e: OutOfMemoryError) { - Log.e(this::class.java.simpleName, "OutOfMemoryError while scaling bitmap", e) - bmp // Return the original bitmap if scaling fails - } - } + ): ByteArray } -private fun calculateActualDimensions( - options: BitmapFactory.Options, - maxWidth: Float, - maxHeight: Float, -): Pair { - var actualWidth = options.outWidth - var actualHeight = options.outHeight - val imgRatio = actualWidth.toFloat() / actualHeight - val maxRatio = maxWidth / maxHeight - - if (actualHeight > maxHeight || actualWidth > maxWidth) { - when { - imgRatio < maxRatio -> { - actualHeight = maxHeight.toInt() - actualWidth = (maxHeight * imgRatio).toInt() - } - - imgRatio > maxRatio -> { - actualWidth = maxWidth.toInt() - actualHeight = (maxWidth / imgRatio).toInt() - } - - else -> { - actualHeight = maxHeight.toInt() - actualWidth = maxWidth.toInt() - } - } - } - - return Pair(actualWidth, actualHeight) -} - -private fun calculateInSampleSize( - options: BitmapFactory.Options, - reqWidth: Int, - reqHeight: Int, -): Int { - val (height, width) = options.run { outHeight to outWidth } - var inSampleSize = 1 - - if (height > reqHeight || width > reqWidth) { - val halfHeight = height / 2 - val halfWidth = width / 2 - - while (halfHeight / inSampleSize >= reqHeight && halfWidth / inSampleSize >= reqWidth) { - inSampleSize *= 2 - } - } - - return inSampleSize -} - -private fun createScaledBitmap( - bmp: Bitmap, - actualWidth: Int, - actualHeight: Int, - options: BitmapFactory.Options, -): Bitmap { - val scaledBitmap = Bitmap.createBitmap(actualWidth, actualHeight, Bitmap.Config.ARGB_8888) - val ratioX = actualWidth / options.outWidth.toFloat() - val ratioY = actualHeight / options.outHeight.toFloat() - val middleX = actualWidth / 2f - val middleY = actualHeight / 2f - - val scaleMatrix = Matrix().apply { - setScale(ratioX, ratioY, middleX, middleY) - } - - Canvas(scaledBitmap).apply { - setMatrix(scaleMatrix) - drawBitmap( - bmp, - middleX - bmp.width / 2, - middleY - bmp.height / 2, - Paint(Paint.FILTER_BITMAP_FLAG), - ) - } - - return scaledBitmap -} +// +// object ImageUtil { +// private const val DEFAULT_MAX_WIDTH = 816f +// private const val DEFAULT_MAX_HEIGHT = 612f +// +// fun compressImage( +// decodedBytes: ByteArray, +// maxWidth: Float = DEFAULT_MAX_WIDTH, +// maxHeight: Float = DEFAULT_MAX_HEIGHT, +// ): Bitmap { +// val options = BitmapFactory.Options().apply { +// inJustDecodeBounds = true +// } +// +// BitmapFactory.decodeByteArray(decodedBytes, 0, decodedBytes.size, options) +// +// val (actualWidth, actualHeight) = calculateActualDimensions(options, maxWidth, maxHeight) +// +// options.apply { +// inJustDecodeBounds = false +// inSampleSize = calculateInSampleSize(this, actualWidth, actualHeight) +// inTempStorage = ByteArray(16 * 1024) +// } +// +// val bmp = try { +// BitmapFactory.decodeByteArray(decodedBytes, 0, decodedBytes.size, options) +// } catch (e: OutOfMemoryError) { +// Log.e(this::class.java.simpleName, "OutOfMemoryError while decoding bitmap", e) +// return Bitmap.createBitmap( +// 1, +// 1, +// Bitmap.Config.ARGB_8888, +// ) // Return a 1x1 bitmap as fallback +// } +// +// return try { +// createScaledBitmap(bmp, actualWidth, actualHeight, options) +// } catch (e: OutOfMemoryError) { +// Log.e(this::class.java.simpleName, "OutOfMemoryError while scaling bitmap", e) +// bmp // Return the original bitmap if scaling fails +// } +// } +// } +// +// private fun calculateActualDimensions( +// options: BitmapFactory.Options, +// maxWidth: Float, +// maxHeight: Float, +// ): Pair { +// var actualWidth = options.outWidth +// var actualHeight = options.outHeight +// val imgRatio = actualWidth.toFloat() / actualHeight +// val maxRatio = maxWidth / maxHeight +// +// if (actualHeight > maxHeight || actualWidth > maxWidth) { +// when { +// imgRatio < maxRatio -> { +// actualHeight = maxHeight.toInt() +// actualWidth = (maxHeight * imgRatio).toInt() +// } +// +// imgRatio > maxRatio -> { +// actualWidth = maxWidth.toInt() +// actualHeight = (maxWidth / imgRatio).toInt() +// } +// +// else -> { +// actualHeight = maxHeight.toInt() +// actualWidth = maxWidth.toInt() +// } +// } +// } +// +// return Pair(actualWidth, actualHeight) +// } +// +// private fun calculateInSampleSize( +// options: BitmapFactory.Options, +// reqWidth: Int, +// reqHeight: Int, +// ): Int { +// val (height, width) = options.run { outHeight to outWidth } +// var inSampleSize = 1 +// +// if (height > reqHeight || width > reqWidth) { +// val halfHeight = height / 2 +// val halfWidth = width / 2 +// +// while (halfHeight / inSampleSize >= reqHeight && halfWidth / inSampleSize >= reqWidth) { +// inSampleSize *= 2 +// } +// } +// +// return inSampleSize +// } +// +// private fun createScaledBitmap( +// bmp: Bitmap, +// actualWidth: Int, +// actualHeight: Int, +// options: BitmapFactory.Options, +// ): Bitmap { +// val scaledBitmap = Bitmap.createBitmap(actualWidth, actualHeight, Bitmap.Config.ARGB_8888) +// val ratioX = actualWidth / options.outWidth.toFloat() +// val ratioY = actualHeight / options.outHeight.toFloat() +// val middleX = actualWidth / 2f +// val middleY = actualHeight / 2f +// +// val scaleMatrix = Matrix().apply { +// setScale(ratioX, ratioY, middleX, middleY) +// } +// +// Canvas(scaledBitmap).apply { +// setMatrix(scaleMatrix) +// drawBitmap( +// bmp, +// middleX - bmp.width / 2, +// middleY - bmp.height / 2, +// Paint(Paint.FILTER_BITMAP_FLAG), +// ) +// } +// +// return scaledBitmap +// } diff --git a/core/ui/src/nativeMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.native.kt b/core/ui/src/nativeMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.native.kt index 7bf3065f0..700e9cd5d 100644 --- a/core/ui/src/nativeMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.native.kt +++ b/core/ui/src/nativeMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.native.kt @@ -1,2 +1,25 @@ -package org.mifos.mobile.core.ui.utils +/* + * 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/mobile-mobile/blob/master/LICENSE.md + */ +package org.mifos.mobile.core.ui.utils +actual object ImageUtil { + actual val DEFAULT_MAX_WIDTH: Float + get() = TODO("Not yet implemented") + actual val DEFAULT_MAX_HEIGHT: Float + get() = TODO("Not yet implemented") + + actual fun compressImage( + decodedBytes: ByteArray, + maxWidth: Float, + maxHeight: Float, + ): ByteArray { + TODO("Not yet implemented") + } +} From 75fab65b4a5d04b535d18962f1471febef282d0a Mon Sep 17 00:00:00 2001 From: revanthkumarJ Date: Wed, 22 Jan 2025 20:19:01 +0530 Subject: [PATCH 04/11] updated --- .../core/ui/component/MifosErrorComponent.kt | 4 +- .../core/ui/component/MifosMobileIcon.kt | 8 +- .../core/ui/component/MifosRoundIcon.kt | 5 +- .../MifosTextButtonWithTopDrawable.kt | 2 +- .../mobile/core/ui/component/MifosTexts.kt | 2 +- .../mobile/core/ui/component/NoInternet.kt | 2 +- .../core/ui/component/UserProfileField.kt | 10 +- .../core/ui/component/UserProfileTopBar.kt | 18 +-- .../mifos/mobile/core/ui/utils/ImageUtil.kt | 127 +----------------- .../mobile/core/ui/utils/ImageUtil.desktop.kt | 17 +++ .../mobile/core/ui/utils/ImageUtil.js.kt | 17 +++ .../mobile/core/ui/utils/ImageUtil.wasmJs.kt | 17 +++ 12 files changed, 71 insertions(+), 158 deletions(-) create mode 100644 core/ui/src/desktopMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.desktop.kt create mode 100644 core/ui/src/jsMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.js.kt create mode 100644 core/ui/src/wasmJsMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.wasmJs.kt diff --git a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosErrorComponent.kt b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosErrorComponent.kt index af647fef5..d7977abc9 100644 --- a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosErrorComponent.kt +++ b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosErrorComponent.kt @@ -116,7 +116,7 @@ fun EmptyDataComponent( .size(100.dp) .padding(bottom = 12.dp), imageVector = MifosIcons.Info, - contentDescription = null, + contentDescription = "Info Icon", tint = MaterialTheme.colorScheme.onSecondary, ) @@ -160,7 +160,7 @@ fun EmptyDataComponentWithModifiedMessageAndIcon( .size(100.dp) .padding(bottom = 12.dp), imageVector = if (isEmptyData) icon else MifosIcons.Info, - contentDescription = null, + contentDescription = "Info Icon", tint = MaterialTheme.colorScheme.onSecondary, ) diff --git a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosMobileIcon.kt b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosMobileIcon.kt index 3c75609bf..d06afa431 100644 --- a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosMobileIcon.kt +++ b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosMobileIcon.kt @@ -26,13 +26,13 @@ import org.mifos.mobile.core.ui.utils.DevicePreviews @Composable fun MifosMobileIcon( - id: DrawableResource, + mobileIcon: DrawableResource, modifier: Modifier = Modifier, ) { Column(modifier) { Image( - painter = painterResource(id), - contentDescription = null, + painter = painterResource(mobileIcon), + contentDescription = "Mobile Icon", modifier = Modifier .fillMaxWidth() .align(Alignment.CenterHorizontally) @@ -48,7 +48,7 @@ private fun MifosMobileIconPreview( ) { MifosMobileTheme { MifosMobileIcon( - id = Res.drawable.core_ui_money_in, + mobileIcon = Res.drawable.core_ui_money_in, modifier = modifier, ) } diff --git a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosRoundIcon.kt b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosRoundIcon.kt index 5eb3aba0d..22b907f09 100644 --- a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosRoundIcon.kt +++ b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosRoundIcon.kt @@ -28,8 +28,7 @@ import org.mifos.mobile.core.ui.utils.DevicePreviews @Composable fun MifosRoundIcon( iconId: DrawableResource, - modifier: Modifier = Modifier, - contentDescription: String? = null, + modifier: Modifier = Modifier ) { Surface( color = MaterialTheme.colorScheme.surfaceVariant, @@ -39,7 +38,7 @@ fun MifosRoundIcon( Image( modifier = Modifier.padding(all = 6.dp), painter = painterResource(iconId), - contentDescription = contentDescription, + contentDescription = "Icon", ) } } diff --git a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosTextButtonWithTopDrawable.kt b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosTextButtonWithTopDrawable.kt index 62c421d38..30b442dc9 100644 --- a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosTextButtonWithTopDrawable.kt +++ b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosTextButtonWithTopDrawable.kt @@ -70,7 +70,7 @@ private fun MifosTextButtonWithTopDrawablePreview( textResourceId = Res.string.core_common_working, icon = MifosIcons.Add, onClick = {}, - contentDescription = null, + contentDescription = "Add Icon", modifier = modifier, ) } diff --git a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosTexts.kt b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosTexts.kt index a234acb5b..c3aead792 100644 --- a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosTexts.kt +++ b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosTexts.kt @@ -116,7 +116,7 @@ fun MifosTextTitleDescDrawableSingleLine( Spacer(modifier = Modifier.width(5.dp)) Image( painter = painterResource(imageResId), - contentDescription = null, + contentDescription = "Image", modifier = Modifier .size(imageSize) .clickable { onDrawableClick() }, diff --git a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/NoInternet.kt b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/NoInternet.kt index d412b9bc0..eba231e29 100644 --- a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/NoInternet.kt +++ b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/NoInternet.kt @@ -56,7 +56,7 @@ fun NoInternet( .size(100.dp) .padding(bottom = 12.dp), imageVector = icon, - contentDescription = null, + contentDescription = "No Internet Icon", tint = MaterialTheme.colorScheme.onSecondary, ) diff --git a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/UserProfileField.kt b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/UserProfileField.kt index 76e52f5a5..6c828cc7d 100644 --- a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/UserProfileField.kt +++ b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/UserProfileField.kt @@ -51,16 +51,14 @@ fun UserProfileField( ) { Text( text = stringResource(text), - color = Color(0xFF8E9099), style = TextStyle(fontSize = 12.sp, fontWeight = FontWeight.SemiBold), ) Icon( painter = painterResource(icon), - contentDescription = null, - tint = if (isSystemInDarkTheme()) Color.White else Color.Black, + contentDescription = "User Profile Icon", ) } - HorizontalDivider(color = if (isSystemInDarkTheme()) Color(0xFF8E9099) else Color.Black) + HorizontalDivider() } @Composable @@ -77,16 +75,14 @@ fun UserProfileField( ) { Text( text = stringResource(label), - color = Color(0xFF8E9099), style = TextStyle(fontSize = 12.sp, fontWeight = FontWeight.SemiBold), ) Text( text = value, - color = if (isSystemInDarkTheme()) Color.White else Color.Black, style = TextStyle(fontSize = 14.sp), ) } - HorizontalDivider(color = Color(0xFF8E9099)) + HorizontalDivider() } @DevicePreviews diff --git a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/UserProfileTopBar.kt b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/UserProfileTopBar.kt index dfb344da6..2fd91c1e5 100644 --- a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/UserProfileTopBar.kt +++ b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/UserProfileTopBar.kt @@ -20,6 +20,7 @@ import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon +import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.material3.TopAppBar import androidx.compose.material3.TopAppBarDefaults @@ -53,13 +54,11 @@ fun UserProfileTopBar( ) { Text( text = stringResource(text), - color = if (isSystemInDarkTheme()) Color.White else Color.Black, style = TextStyle(fontSize = 24.sp), ) Icon( imageVector = MifosIcons.Edit, - contentDescription = null, - tint = if (isSystemInDarkTheme()) Color.White else Color.Black, + contentDescription = "User Profile Icon", ) } }, @@ -73,22 +72,15 @@ fun UserProfileTopBar( ) { Icon( imageVector = MifosIcons.ArrowBack, - contentDescription = null, + contentDescription = "Arrow Back Icon", modifier = Modifier.clickable(onClick = { home.invoke() - }), - tint = if (isSystemInDarkTheme()) Color.White else Color.Black, + }) ) } }, colors = TopAppBarDefaults.topAppBarColors( - containerColor = if (isSystemInDarkTheme()) { - Color( - 0xFF1B1B1F, - ) - } else { - Color(0xFFFEFBFF) - }, + containerColor = MaterialTheme.colorScheme.primary ), ) } diff --git a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.kt b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.kt index 4fb8472c0..4ce5d8869 100644 --- a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.kt +++ b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.kt @@ -18,129 +18,4 @@ expect object ImageUtil { maxWidth: Float = DEFAULT_MAX_WIDTH, maxHeight: Float = DEFAULT_MAX_HEIGHT, ): ByteArray -} - -// -// object ImageUtil { -// private const val DEFAULT_MAX_WIDTH = 816f -// private const val DEFAULT_MAX_HEIGHT = 612f -// -// fun compressImage( -// decodedBytes: ByteArray, -// maxWidth: Float = DEFAULT_MAX_WIDTH, -// maxHeight: Float = DEFAULT_MAX_HEIGHT, -// ): Bitmap { -// val options = BitmapFactory.Options().apply { -// inJustDecodeBounds = true -// } -// -// BitmapFactory.decodeByteArray(decodedBytes, 0, decodedBytes.size, options) -// -// val (actualWidth, actualHeight) = calculateActualDimensions(options, maxWidth, maxHeight) -// -// options.apply { -// inJustDecodeBounds = false -// inSampleSize = calculateInSampleSize(this, actualWidth, actualHeight) -// inTempStorage = ByteArray(16 * 1024) -// } -// -// val bmp = try { -// BitmapFactory.decodeByteArray(decodedBytes, 0, decodedBytes.size, options) -// } catch (e: OutOfMemoryError) { -// Log.e(this::class.java.simpleName, "OutOfMemoryError while decoding bitmap", e) -// return Bitmap.createBitmap( -// 1, -// 1, -// Bitmap.Config.ARGB_8888, -// ) // Return a 1x1 bitmap as fallback -// } -// -// return try { -// createScaledBitmap(bmp, actualWidth, actualHeight, options) -// } catch (e: OutOfMemoryError) { -// Log.e(this::class.java.simpleName, "OutOfMemoryError while scaling bitmap", e) -// bmp // Return the original bitmap if scaling fails -// } -// } -// } -// -// private fun calculateActualDimensions( -// options: BitmapFactory.Options, -// maxWidth: Float, -// maxHeight: Float, -// ): Pair { -// var actualWidth = options.outWidth -// var actualHeight = options.outHeight -// val imgRatio = actualWidth.toFloat() / actualHeight -// val maxRatio = maxWidth / maxHeight -// -// if (actualHeight > maxHeight || actualWidth > maxWidth) { -// when { -// imgRatio < maxRatio -> { -// actualHeight = maxHeight.toInt() -// actualWidth = (maxHeight * imgRatio).toInt() -// } -// -// imgRatio > maxRatio -> { -// actualWidth = maxWidth.toInt() -// actualHeight = (maxWidth / imgRatio).toInt() -// } -// -// else -> { -// actualHeight = maxHeight.toInt() -// actualWidth = maxWidth.toInt() -// } -// } -// } -// -// return Pair(actualWidth, actualHeight) -// } -// -// private fun calculateInSampleSize( -// options: BitmapFactory.Options, -// reqWidth: Int, -// reqHeight: Int, -// ): Int { -// val (height, width) = options.run { outHeight to outWidth } -// var inSampleSize = 1 -// -// if (height > reqHeight || width > reqWidth) { -// val halfHeight = height / 2 -// val halfWidth = width / 2 -// -// while (halfHeight / inSampleSize >= reqHeight && halfWidth / inSampleSize >= reqWidth) { -// inSampleSize *= 2 -// } -// } -// -// return inSampleSize -// } -// -// private fun createScaledBitmap( -// bmp: Bitmap, -// actualWidth: Int, -// actualHeight: Int, -// options: BitmapFactory.Options, -// ): Bitmap { -// val scaledBitmap = Bitmap.createBitmap(actualWidth, actualHeight, Bitmap.Config.ARGB_8888) -// val ratioX = actualWidth / options.outWidth.toFloat() -// val ratioY = actualHeight / options.outHeight.toFloat() -// val middleX = actualWidth / 2f -// val middleY = actualHeight / 2f -// -// val scaleMatrix = Matrix().apply { -// setScale(ratioX, ratioY, middleX, middleY) -// } -// -// Canvas(scaledBitmap).apply { -// setMatrix(scaleMatrix) -// drawBitmap( -// bmp, -// middleX - bmp.width / 2, -// middleY - bmp.height / 2, -// Paint(Paint.FILTER_BITMAP_FLAG), -// ) -// } -// -// return scaledBitmap -// } +} \ No newline at end of file diff --git a/core/ui/src/desktopMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.desktop.kt b/core/ui/src/desktopMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.desktop.kt new file mode 100644 index 000000000..96c84898b --- /dev/null +++ b/core/ui/src/desktopMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.desktop.kt @@ -0,0 +1,17 @@ +package org.mifos.mobile.core.ui.utils + +actual object ImageUtil { + actual val DEFAULT_MAX_WIDTH: Float + get() = TODO("Not yet implemented") + actual val DEFAULT_MAX_HEIGHT: Float + get() = TODO("Not yet implemented") + + actual fun compressImage( + decodedBytes: ByteArray, + maxWidth: Float, + maxHeight: Float + ): ByteArray { + TODO("Not yet implemented") + } + +} \ No newline at end of file diff --git a/core/ui/src/jsMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.js.kt b/core/ui/src/jsMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.js.kt new file mode 100644 index 000000000..96c84898b --- /dev/null +++ b/core/ui/src/jsMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.js.kt @@ -0,0 +1,17 @@ +package org.mifos.mobile.core.ui.utils + +actual object ImageUtil { + actual val DEFAULT_MAX_WIDTH: Float + get() = TODO("Not yet implemented") + actual val DEFAULT_MAX_HEIGHT: Float + get() = TODO("Not yet implemented") + + actual fun compressImage( + decodedBytes: ByteArray, + maxWidth: Float, + maxHeight: Float + ): ByteArray { + TODO("Not yet implemented") + } + +} \ No newline at end of file diff --git a/core/ui/src/wasmJsMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.wasmJs.kt b/core/ui/src/wasmJsMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.wasmJs.kt new file mode 100644 index 000000000..96c84898b --- /dev/null +++ b/core/ui/src/wasmJsMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.wasmJs.kt @@ -0,0 +1,17 @@ +package org.mifos.mobile.core.ui.utils + +actual object ImageUtil { + actual val DEFAULT_MAX_WIDTH: Float + get() = TODO("Not yet implemented") + actual val DEFAULT_MAX_HEIGHT: Float + get() = TODO("Not yet implemented") + + actual fun compressImage( + decodedBytes: ByteArray, + maxWidth: Float, + maxHeight: Float + ): ByteArray { + TODO("Not yet implemented") + } + +} \ No newline at end of file From 278786f399dcd4d364ff77cd36f3584710b5e820 Mon Sep 17 00:00:00 2001 From: revanthkumarJ Date: Wed, 22 Jan 2025 23:34:38 +0530 Subject: [PATCH 05/11] updated --- core/ui/build.gradle.kts | 3 +++ .../mobile/core/ui/component/AboutUsItemCard.kt | 2 +- .../mobile/core/ui/component/EmptyDataView.kt | 4 +--- .../core/ui/component/MifosDropDownTextField.kt | 12 ++++++++++-- .../core/ui/component/MifosErrorComponent.kt | 2 +- .../mobile/core/ui/component/MifosRoundIcon.kt | 2 +- .../mobile/core/ui/component/MifosUserImage.kt | 6 +++--- .../mobile/core/ui/component/UserProfileField.kt | 2 -- .../mobile/core/ui/component/UserProfileTopBar.kt | 6 ++---- .../org/mifos/mobile/core/ui/utils/ImageUtil.kt | 2 +- .../mobile/core/ui/utils/ImageUtil.desktop.kt | 14 +++++++++++--- .../org/mifos/mobile/core/ui/utils/ImageUtil.js.kt | 14 +++++++++++--- .../mifos/mobile/core/ui/utils/ImageUtil.wasmJs.kt | 14 +++++++++++--- gradle/libs.versions.toml | 2 ++ 14 files changed, 58 insertions(+), 27 deletions(-) diff --git a/core/ui/build.gradle.kts b/core/ui/build.gradle.kts index 8a1c0fd0b..a40784080 100644 --- a/core/ui/build.gradle.kts +++ b/core/ui/build.gradle.kts @@ -47,4 +47,7 @@ kotlin{ } } } +dependencies { + implementation(libs.androidx.ui.graphics.android) +} diff --git a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/AboutUsItemCard.kt b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/AboutUsItemCard.kt index 262f42aef..da0914d66 100644 --- a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/AboutUsItemCard.kt +++ b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/AboutUsItemCard.kt @@ -38,7 +38,7 @@ fun AboutUsItemCard( iconUrl?.let { painterResource(it) }?.let { Image( painter = it, - contentDescription = null, + contentDescription = "About Us Icon URL", modifier = Modifier.padding(end = 8.dp), ) } diff --git a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/EmptyDataView.kt b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/EmptyDataView.kt index 8a88f6bad..afb2192bc 100644 --- a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/EmptyDataView.kt +++ b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/EmptyDataView.kt @@ -21,10 +21,8 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.vector.ImageVector -import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp import mifos_mobile.core.ui.generated.resources.Res import mifos_mobile.core.ui.generated.resources.no_internet import org.jetbrains.compose.resources.StringResource @@ -57,7 +55,7 @@ fun EmptyDataView( Text( modifier = Modifier.padding(horizontal = 20.dp), text = errorString ?: stringResource(error), - style = TextStyle(fontSize = 20.sp), + style = MaterialTheme.typography.labelSmall, color = MaterialTheme.colorScheme.onSecondary, textAlign = TextAlign.Center, ) diff --git a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosDropDownTextField.kt b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosDropDownTextField.kt index d14f0afe3..095d62c0c 100644 --- a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosDropDownTextField.kt +++ b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosDropDownTextField.kt @@ -80,7 +80,11 @@ fun MifosDropDownTextField( } else { MifosIcons.ArrowDropDown }, - contentDescription = null, + contentDescription = if (expanded) { + "Arrow Up Icon" + } else { + "Arrow Down Icon" + }, ) }, ) @@ -146,7 +150,11 @@ fun MifosDropDownDoubleTextField( } else { MifosIcons.ArrowDropDown }, - contentDescription = null, + contentDescription = if (expanded) { + "Arrow Up Icon" + } else { + "Arrow Down Icon" + }, ) }, ) diff --git a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosErrorComponent.kt b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosErrorComponent.kt index d7977abc9..4975c0f2d 100644 --- a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosErrorComponent.kt +++ b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosErrorComponent.kt @@ -78,7 +78,7 @@ fun NoInternetComponent( .size(100.dp) .padding(bottom = 12.dp), imageVector = MifosIcons.WifiOff, - contentDescription = null, + contentDescription = "Wifi Icon", tint = MaterialTheme.colorScheme.onSecondary, ) diff --git a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosRoundIcon.kt b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosRoundIcon.kt index 22b907f09..e2f722f18 100644 --- a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosRoundIcon.kt +++ b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosRoundIcon.kt @@ -28,7 +28,7 @@ import org.mifos.mobile.core.ui.utils.DevicePreviews @Composable fun MifosRoundIcon( iconId: DrawableResource, - modifier: Modifier = Modifier + modifier: Modifier = Modifier, ) { Surface( color = MaterialTheme.colorScheme.surfaceVariant, diff --git a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosUserImage.kt b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosUserImage.kt index e0b4b2a4d..3e1812756 100644 --- a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosUserImage.kt +++ b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/MifosUserImage.kt @@ -16,14 +16,14 @@ import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.ImageBitmap import androidx.compose.ui.layout.ContentScale -import coil3.Bitmap import org.mifos.mobile.core.designsystem.theme.MifosMobileTheme import org.mifos.mobile.core.ui.utils.DevicePreviews @Composable fun MifosUserImage( - bitmap: Bitmap?, + bitmap: ImageBitmap?, modifier: Modifier = Modifier, username: String? = null, ) { @@ -37,7 +37,7 @@ fun MifosUserImage( modifier = modifier .clip(CircleShape) .background(MaterialTheme.colorScheme.primary), - bitmap = bitmap.asImageBitmap(), + bitmap = bitmap, contentDescription = "Profile Image", contentScale = ContentScale.Crop, ) diff --git a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/UserProfileField.kt b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/UserProfileField.kt index 6c828cc7d..0894237e7 100644 --- a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/UserProfileField.kt +++ b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/UserProfileField.kt @@ -10,7 +10,6 @@ package org.mifos.mobile.core.ui.component import androidx.compose.foundation.clickable -import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxWidth @@ -20,7 +19,6 @@ import androidx.compose.material3.Icon import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp diff --git a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/UserProfileTopBar.kt b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/UserProfileTopBar.kt index 2fd91c1e5..c54cbb21f 100644 --- a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/UserProfileTopBar.kt +++ b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/UserProfileTopBar.kt @@ -10,7 +10,6 @@ package org.mifos.mobile.core.ui.component import androidx.compose.foundation.clickable -import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row @@ -27,7 +26,6 @@ import androidx.compose.material3.TopAppBarDefaults import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color import androidx.compose.ui.text.TextStyle import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp @@ -75,12 +73,12 @@ fun UserProfileTopBar( contentDescription = "Arrow Back Icon", modifier = Modifier.clickable(onClick = { home.invoke() - }) + }), ) } }, colors = TopAppBarDefaults.topAppBarColors( - containerColor = MaterialTheme.colorScheme.primary + containerColor = MaterialTheme.colorScheme.primary, ), ) } diff --git a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.kt b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.kt index 4ce5d8869..0761b0d39 100644 --- a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.kt +++ b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.kt @@ -18,4 +18,4 @@ expect object ImageUtil { maxWidth: Float = DEFAULT_MAX_WIDTH, maxHeight: Float = DEFAULT_MAX_HEIGHT, ): ByteArray -} \ No newline at end of file +} diff --git a/core/ui/src/desktopMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.desktop.kt b/core/ui/src/desktopMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.desktop.kt index 96c84898b..700e9cd5d 100644 --- a/core/ui/src/desktopMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.desktop.kt +++ b/core/ui/src/desktopMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.desktop.kt @@ -1,3 +1,12 @@ +/* + * 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/mobile-mobile/blob/master/LICENSE.md + */ package org.mifos.mobile.core.ui.utils actual object ImageUtil { @@ -9,9 +18,8 @@ actual object ImageUtil { actual fun compressImage( decodedBytes: ByteArray, maxWidth: Float, - maxHeight: Float + maxHeight: Float, ): ByteArray { TODO("Not yet implemented") } - -} \ No newline at end of file +} diff --git a/core/ui/src/jsMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.js.kt b/core/ui/src/jsMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.js.kt index 96c84898b..700e9cd5d 100644 --- a/core/ui/src/jsMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.js.kt +++ b/core/ui/src/jsMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.js.kt @@ -1,3 +1,12 @@ +/* + * 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/mobile-mobile/blob/master/LICENSE.md + */ package org.mifos.mobile.core.ui.utils actual object ImageUtil { @@ -9,9 +18,8 @@ actual object ImageUtil { actual fun compressImage( decodedBytes: ByteArray, maxWidth: Float, - maxHeight: Float + maxHeight: Float, ): ByteArray { TODO("Not yet implemented") } - -} \ No newline at end of file +} diff --git a/core/ui/src/wasmJsMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.wasmJs.kt b/core/ui/src/wasmJsMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.wasmJs.kt index 96c84898b..700e9cd5d 100644 --- a/core/ui/src/wasmJsMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.wasmJs.kt +++ b/core/ui/src/wasmJsMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.wasmJs.kt @@ -1,3 +1,12 @@ +/* + * 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/mobile-mobile/blob/master/LICENSE.md + */ package org.mifos.mobile.core.ui.utils actual object ImageUtil { @@ -9,9 +18,8 @@ actual object ImageUtil { actual fun compressImage( decodedBytes: ByteArray, maxWidth: Float, - maxHeight: Float + maxHeight: Float, ): ByteArray { TODO("Not yet implemented") } - -} \ No newline at end of file +} diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 44a9c0905..cacb77940 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -119,6 +119,7 @@ jbSavedState = "1.2.2" packageName = "MifosWallet" packageNamespace = "org.mifos.desktop" packageVersion = "1.0.0" +uiGraphicsAndroidVersion = "1.7.6" [libraries] accompanist-pager = { group = "com.google.accompanist", name = "accompanist-pager", version.ref = "accompanistVersion" } @@ -321,6 +322,7 @@ moko-permission = { group = "dev.icerock.moko", name = "permissions", version.re moko-permission-compose = { group = "dev.icerock.moko", name = "permissions-compose", version.ref = "mokoPermission" } window-size = { group = "dev.chrisbanes.material3", name = "material3-window-size-class-multiplatform", version.ref = "windowsSizeClass" } +androidx-ui-graphics-android = { group = "androidx.compose.ui", name = "ui-graphics-android", version.ref = "uiGraphicsAndroidVersion" } [bundles] androidx-compose-ui-test = [ From bd4359c7ee68f1377f5552979da38fb68635f6f7 Mon Sep 17 00:00:00 2001 From: revanthkumarJ Date: Wed, 22 Jan 2025 23:58:51 +0530 Subject: [PATCH 06/11] updated --- .../org/mifos/mobile/core/ui/component/UserProfileTopBar.kt | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/UserProfileTopBar.kt b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/UserProfileTopBar.kt index c54cbb21f..fa9edc3e6 100644 --- a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/UserProfileTopBar.kt +++ b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/component/UserProfileTopBar.kt @@ -26,9 +26,7 @@ import androidx.compose.material3.TopAppBarDefaults import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.text.TextStyle import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp import org.jetbrains.compose.resources.StringResource import org.jetbrains.compose.resources.stringResource import org.mifos.mobile.core.designsystem.icon.MifosIcons @@ -52,7 +50,7 @@ fun UserProfileTopBar( ) { Text( text = stringResource(text), - style = TextStyle(fontSize = 24.sp), + style = MaterialTheme.typography.bodySmall, ) Icon( imageVector = MifosIcons.Edit, From 2d9d3fbe2b5b358a7711833739d2c470cf5201cd Mon Sep 17 00:00:00 2001 From: revanthkumarJ Date: Fri, 24 Jan 2025 15:28:51 +0530 Subject: [PATCH 07/11] updated --- core/ui/build.gradle.kts | 10 ++- .../mifos/mobile/core/ui/utils/ImageUtil.kt | 2 +- .../mobile/core/ui/utils/ImageUtil.desktop.kt | 81 ++++++++++++++++-- .../mobile/core/ui/utils/ImageUtil.js.kt | 3 +- .../mobile/core/ui/utils/ImageUtil.native.kt | 83 +++++++++++++++++-- .../mobile/core/ui/utils/ImageUtil.wasmJs.kt | 1 + gradle/libs.versions.toml | 8 +- 7 files changed, 166 insertions(+), 22 deletions(-) diff --git a/core/ui/build.gradle.kts b/core/ui/build.gradle.kts index a40784080..bc6a65e13 100644 --- a/core/ui/build.gradle.kts +++ b/core/ui/build.gradle.kts @@ -9,7 +9,6 @@ */ plugins { alias(libs.plugins.mifos.kmp.library) -// alias(libs.plugins.mifos.android.library.compose) alias(libs.plugins.jetbrainsCompose) alias(libs.plugins.compose.compiler) } @@ -30,8 +29,7 @@ kotlin{ } commonMain.dependencies { api(projects.core.designsystem) - api(projects.core.model) - api(projects.core.common) + api(libs.kotlinx.datetime) implementation(libs.jb.composeViewmodel) implementation(libs.jb.lifecycleViewmodel) implementation(libs.jb.lifecycleViewmodelSavedState) @@ -43,7 +41,11 @@ kotlin{ implementation(libs.jb.composeNavigation) implementation(libs.filekit.compose) implementation(libs.filekit.core) - implementation(libs.accompanist.systemuicontroller) + } + desktopMain.dependencies { + implementation(libs.kotlin.stdlib.jdk8) + implementation(libs.imageio.core) + } } } diff --git a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.kt b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.kt index 0761b0d39..4ce5d8869 100644 --- a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.kt +++ b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.kt @@ -18,4 +18,4 @@ expect object ImageUtil { maxWidth: Float = DEFAULT_MAX_WIDTH, maxHeight: Float = DEFAULT_MAX_HEIGHT, ): ByteArray -} +} \ No newline at end of file diff --git a/core/ui/src/desktopMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.desktop.kt b/core/ui/src/desktopMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.desktop.kt index 700e9cd5d..10a67deac 100644 --- a/core/ui/src/desktopMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.desktop.kt +++ b/core/ui/src/desktopMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.desktop.kt @@ -9,17 +9,88 @@ */ package org.mifos.mobile.core.ui.utils +import java.awt.Graphics2D +import java.awt.image.BufferedImage +import java.io.ByteArrayInputStream +import java.io.ByteArrayOutputStream +import javax.imageio.ImageIO + actual object ImageUtil { - actual val DEFAULT_MAX_WIDTH: Float - get() = TODO("Not yet implemented") - actual val DEFAULT_MAX_HEIGHT: Float - get() = TODO("Not yet implemented") + actual val DEFAULT_MAX_WIDTH: Float = 816f + actual val DEFAULT_MAX_HEIGHT: Float = 612f actual fun compressImage( decodedBytes: ByteArray, maxWidth: Float, maxHeight: Float, ): ByteArray { - TODO("Not yet implemented") + + val inputStream = ByteArrayInputStream(decodedBytes) + val originalImage: BufferedImage = try { + ImageIO.read(inputStream) + } catch (e: Exception) { + e.printStackTrace() + return ByteArray(0) + } + + val (actualWidth, actualHeight) = calculateActualDimensions( + originalImage.width.toFloat(), + originalImage.height.toFloat(), + maxWidth, + maxHeight + ) + + val scaledImage = createScaledImage(originalImage, actualWidth, actualHeight) + + val byteArrayOutputStream = ByteArrayOutputStream() + try { + ImageIO.write(scaledImage, "JPEG", byteArrayOutputStream) + } catch (e: Exception) { + e.printStackTrace() + } + + return byteArrayOutputStream.toByteArray() + } + + private fun calculateActualDimensions( + actualWidth: Float, + actualHeight: Float, + maxWidth: Float, + maxHeight: Float + ): Pair { + val imgRatio = actualWidth / actualHeight + val maxRatio = maxWidth / maxHeight + + var finalWidth = actualWidth + var finalHeight = actualHeight + + if (actualHeight > maxHeight || actualWidth > maxWidth) { + when { + imgRatio < maxRatio -> { + finalHeight = maxHeight + finalWidth = maxHeight * imgRatio + } + imgRatio > maxRatio -> { + finalWidth = maxWidth + finalHeight = maxWidth / imgRatio + } + else -> { + finalWidth = maxWidth + finalHeight = maxHeight + } + } + } + + return Pair(finalWidth.toInt(), finalHeight.toInt()) + } + + private fun createScaledImage(image: BufferedImage, targetWidth: Int, targetHeight: Int): BufferedImage { + val scaledImage = BufferedImage(targetWidth, targetHeight, BufferedImage.TYPE_INT_RGB) + val g2d: Graphics2D = scaledImage.createGraphics() + g2d.drawImage(image, 0, 0, targetWidth, targetHeight, null) + g2d.dispose() + + return scaledImage } } + diff --git a/core/ui/src/jsMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.js.kt b/core/ui/src/jsMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.js.kt index 700e9cd5d..18e7a0933 100644 --- a/core/ui/src/jsMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.js.kt +++ b/core/ui/src/jsMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.js.kt @@ -22,4 +22,5 @@ actual object ImageUtil { ): ByteArray { TODO("Not yet implemented") } -} + +} \ No newline at end of file diff --git a/core/ui/src/nativeMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.native.kt b/core/ui/src/nativeMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.native.kt index 700e9cd5d..5685eeab7 100644 --- a/core/ui/src/nativeMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.native.kt +++ b/core/ui/src/nativeMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.native.kt @@ -9,17 +9,86 @@ */ package org.mifos.mobile.core.ui.utils +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext +import org.jetbrains.skia.Bitmap +import org.jetbrains.skia.Canvas +import org.jetbrains.skia.Image +import org.jetbrains.skia.Matrix33 +import org.jetbrains.skia.Paint +import org.jetbrains.skia.Rect +import java.io.ByteArrayOutputStream + actual object ImageUtil { - actual val DEFAULT_MAX_WIDTH: Float - get() = TODO("Not yet implemented") - actual val DEFAULT_MAX_HEIGHT: Float - get() = TODO("Not yet implemented") + actual val DEFAULT_MAX_WIDTH: Float = 816f + actual val DEFAULT_MAX_HEIGHT: Float = 612f - actual fun compressImage( + actual suspend fun compressImage( decodedBytes: ByteArray, maxWidth: Float, maxHeight: Float, - ): ByteArray { - TODO("Not yet implemented") + ): ByteArray = withContext(Dispatchers.Default) { + val bitmap = Bitmap.makeFromImage(Image.makeFromEncoded(decodedBytes)) + + val (actualWidth, actualHeight) = calculateActualDimensions(bitmap.width, bitmap.height, maxWidth, maxHeight) + val scaledBitmap = createScaledBitmap(bitmap, actualWidth, actualHeight) + + val byteArrayOutputStream = ByteArrayOutputStream() + scaledBitmap.encodeToData()?.bytes?.let { byteArrayOutputStream.write(it) } + byteArrayOutputStream.toByteArray() + } + + private fun calculateActualDimensions( + width: Int, + height: Int, + maxWidth: Float, + maxHeight: Float, + ): Pair { + val imgRatio = width.toFloat() / height + val maxRatio = maxWidth / maxHeight + + return if (height > maxHeight || width > maxWidth) { + when { + imgRatio < maxRatio -> { + val newHeight = maxHeight.toInt() + val newWidth = (maxHeight * imgRatio).toInt() + Pair(newWidth, newHeight) + } + + imgRatio > maxRatio -> { + val newWidth = maxWidth.toInt() + val newHeight = (maxWidth / imgRatio).toInt() + Pair(newWidth, newHeight) + } + + else -> { + Pair(maxWidth.toInt(), maxHeight.toInt()) + } + } + } else { + Pair(width, height) + } + } + + private fun createScaledBitmap( + bitmap: Bitmap, + targetWidth: Int, + targetHeight: Int, + ): Bitmap { + val scaledBitmap = Bitmap().apply { + allocPixels(targetWidth, targetHeight) + } + + val canvas = Canvas(scaledBitmap) + val scaleX = targetWidth.toFloat() / bitmap.width + val scaleY = targetHeight.toFloat() / bitmap.height + val scaleMatrix = Matrix33.makeScale(scaleX, scaleY) + + canvas.save() + canvas.concat(scaleMatrix) + canvas.drawBitmapRect(bitmap, Rect.makeWH(bitmap.width.toFloat(), bitmap.height.toFloat()), Paint()) + canvas.restore() + + return scaledBitmap } } diff --git a/core/ui/src/wasmJsMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.wasmJs.kt b/core/ui/src/wasmJsMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.wasmJs.kt index 700e9cd5d..1cf818e01 100644 --- a/core/ui/src/wasmJsMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.wasmJs.kt +++ b/core/ui/src/wasmJsMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.wasmJs.kt @@ -9,6 +9,7 @@ */ package org.mifos.mobile.core.ui.utils +// TODO: Not Implemented actual object ImageUtil { actual val DEFAULT_MAX_WIDTH: Float get() = TODO("Not yet implemented") diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index cacb77940..7e6b4e7cf 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -24,6 +24,7 @@ androidxUiAutomator = "2.3.0" annotation = "1.9.1" appcompatVersion = "1.7.0" cameraCoreVersion = "1.3.4" +imageioCoreVersion = "1.1" mlkit="17.3.0" guavaVersion = "33.3.1-android" cameraxVersion = "1.4.1" @@ -124,7 +125,6 @@ uiGraphicsAndroidVersion = "1.7.6" [libraries] accompanist-pager = { group = "com.google.accompanist", name = "accompanist-pager", version.ref = "accompanistVersion" } accompanist-permissions = { group = "com.google.accompanist", name = "accompanist-permissions", version.ref = "accompanistVersion" } -accompanist-systemuicontroller = { module = "com.google.accompanist:accompanist-systemuicontroller", version.ref = "accompanistSystemuicontrollerVersion" } android-desugarJdkLibs = { group = "com.android.tools", name = "desugar_jdk_libs", version.ref = "androidDesugarJdkLibs" } android-gradlePlugin = { group = "com.android.tools.build", name = "gradle", version.ref = "androidGradlePlugin" } android-tools-common = { group = "com.android.tools", name = "common", version.ref = "androidTools" } @@ -136,6 +136,9 @@ androidx-camera-camera2 = { group = "androidx.camera", name = "camera-camera2", androidx-camera-core = { group = "androidx.camera", name = "camera-core", version.ref = "cameraxVersion" } androidx-camera-lifecycle = { group = "androidx.camera", name = "camera-lifecycle", version.ref = "cameraxVersion" } androidx-camera-view = { group = "androidx.camera", name = "camera-view", version.ref = "cameraxVersion" } +imageio-core = { module = "javax.imageio:imageio-core", version.ref = "imageioCoreVersion" } +jetbrains-kotlin-stdlib-jdk8 = { module = "org.jetbrains.kotlin:kotlin-stdlib-jdk8" } +kotlin-stdlib-jdk8 = { module = "org.jetbrains.kotlin:kotlin-stdlib-jdk8" } mlkit-barcode-scanning = { module = "com.google.mlkit:barcode-scanning", version.ref = "mlkit" } guava = { module = "com.google.guava:guava", version.ref = "guavaVersion" } androidx-compose-animation = { group = "androidx.compose.animation", name = "animation" } @@ -202,7 +205,6 @@ hilt-ext-compiler = { group = "androidx.hilt", name = "hilt-compiler", version.r hilt-ext-work = { group = "androidx.hilt", name = "hilt-work", version.ref = "hiltExt" } jetbrains-kotlin-jdk7 = { group = "org.jetbrains.kotlin", name = "kotlin-stdlib-jdk7", version.ref = "kotlin" } junit = { group = "junit", name = "junit", version.ref = "junitVersion" } -kotlinx-datetime-v040 = { module = "org.jetbrains.kotlinx:kotlinx-datetime", version.ref = "kotlinxDatetimeVersion" } ktlint-gradlePlugin = { group = "org.jlleitschuh.gradle", name = "ktlint-gradle", version.ref = "ktlint" } libphonenumber-android = { group = "io.michaelrocks", name = "libphonenumber-android", version.ref = "libphonenumberAndroidVersion" } lint-api = { group = "com.android.tools.lint", name = "lint-api", version.ref = "androidTools" } @@ -272,9 +274,7 @@ kotlinx-coroutines-test = { group = "org.jetbrains.kotlinx", name = "kotlinx-cor kotlinx-datetime = { group = "org.jetbrains.kotlinx", name = "kotlinx-datetime", version.ref = "kotlinxDatetime" } kotlinx-serialization-core = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-core", version.ref = "kotlinxSerializationJson" } kotlinx-serialization-json = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-json", version.ref = "kotlinxSerializationJson" } - ksp-gradlePlugin = { group = "com.google.devtools.ksp", name = "com.google.devtools.ksp.gradle.plugin", version.ref = "ksp" } - ktor-client-android = { group = "io.ktor", name = "ktor-client-android", version.ref = "ktorVersion" } ktor-client-auth = { group = "io.ktor", name = "ktor-client-auth", version.ref = "ktorVersion" } ktor-client-cio = { group = "io.ktor", name = "ktor-client-cio", version.ref = "ktorVersion" } From 56500cb5880bfc244bbcbf0cc3012e1bc11a1acf Mon Sep 17 00:00:00 2001 From: revanthkumarJ Date: Fri, 24 Jan 2025 16:40:38 +0530 Subject: [PATCH 08/11] updated --- androidApp/dependencies/demoDebugRuntimeClasspath.txt | 1 - androidApp/dependencies/demoReleaseRuntimeClasspath.txt | 1 - androidApp/dependencies/prodDebugRuntimeClasspath.txt | 1 - androidApp/dependencies/prodReleaseRuntimeClasspath.txt | 1 - core/ui/build.gradle.kts | 6 +++--- .../kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.kt | 2 +- .../org/mifos/mobile/core/ui/utils/ImageUtil.desktop.kt | 6 ++---- .../kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.js.kt | 3 +-- 8 files changed, 7 insertions(+), 14 deletions(-) diff --git a/androidApp/dependencies/demoDebugRuntimeClasspath.txt b/androidApp/dependencies/demoDebugRuntimeClasspath.txt index aac30d42d..186c7cb05 100644 --- a/androidApp/dependencies/demoDebugRuntimeClasspath.txt +++ b/androidApp/dependencies/demoDebugRuntimeClasspath.txt @@ -147,7 +147,6 @@ com.caverock:androidsvg-aar:1.4 com.google.accompanist:accompanist-drawablepainter:0.36.0 com.google.accompanist:accompanist-pager:0.34.0 com.google.accompanist:accompanist-permissions:0.34.0 -com.google.accompanist:accompanist-systemuicontroller:0.30.1 com.google.android.datatransport:transport-api:2.2.1 com.google.android.datatransport:transport-backend-cct:2.3.3 com.google.android.datatransport:transport-runtime:2.2.6 diff --git a/androidApp/dependencies/demoReleaseRuntimeClasspath.txt b/androidApp/dependencies/demoReleaseRuntimeClasspath.txt index acc01178e..ede622e16 100644 --- a/androidApp/dependencies/demoReleaseRuntimeClasspath.txt +++ b/androidApp/dependencies/demoReleaseRuntimeClasspath.txt @@ -142,7 +142,6 @@ com.caverock:androidsvg-aar:1.4 com.google.accompanist:accompanist-drawablepainter:0.36.0 com.google.accompanist:accompanist-pager:0.34.0 com.google.accompanist:accompanist-permissions:0.34.0 -com.google.accompanist:accompanist-systemuicontroller:0.30.1 com.google.android.datatransport:transport-api:2.2.1 com.google.android.datatransport:transport-backend-cct:2.3.3 com.google.android.datatransport:transport-runtime:2.2.6 diff --git a/androidApp/dependencies/prodDebugRuntimeClasspath.txt b/androidApp/dependencies/prodDebugRuntimeClasspath.txt index aac30d42d..186c7cb05 100644 --- a/androidApp/dependencies/prodDebugRuntimeClasspath.txt +++ b/androidApp/dependencies/prodDebugRuntimeClasspath.txt @@ -147,7 +147,6 @@ com.caverock:androidsvg-aar:1.4 com.google.accompanist:accompanist-drawablepainter:0.36.0 com.google.accompanist:accompanist-pager:0.34.0 com.google.accompanist:accompanist-permissions:0.34.0 -com.google.accompanist:accompanist-systemuicontroller:0.30.1 com.google.android.datatransport:transport-api:2.2.1 com.google.android.datatransport:transport-backend-cct:2.3.3 com.google.android.datatransport:transport-runtime:2.2.6 diff --git a/androidApp/dependencies/prodReleaseRuntimeClasspath.txt b/androidApp/dependencies/prodReleaseRuntimeClasspath.txt index acc01178e..ede622e16 100644 --- a/androidApp/dependencies/prodReleaseRuntimeClasspath.txt +++ b/androidApp/dependencies/prodReleaseRuntimeClasspath.txt @@ -142,7 +142,6 @@ com.caverock:androidsvg-aar:1.4 com.google.accompanist:accompanist-drawablepainter:0.36.0 com.google.accompanist:accompanist-pager:0.34.0 com.google.accompanist:accompanist-permissions:0.34.0 -com.google.accompanist:accompanist-systemuicontroller:0.30.1 com.google.android.datatransport:transport-api:2.2.1 com.google.android.datatransport:transport-backend-cct:2.3.3 com.google.android.datatransport:transport-runtime:2.2.6 diff --git a/core/ui/build.gradle.kts b/core/ui/build.gradle.kts index bc6a65e13..0cb7282a8 100644 --- a/core/ui/build.gradle.kts +++ b/core/ui/build.gradle.kts @@ -49,7 +49,7 @@ kotlin{ } } } -dependencies { - implementation(libs.androidx.ui.graphics.android) -} +//dependencies { +// implementation(libs.androidx.ui.graphics.android) +//} diff --git a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.kt b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.kt index 4ce5d8869..0761b0d39 100644 --- a/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.kt +++ b/core/ui/src/commonMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.kt @@ -18,4 +18,4 @@ expect object ImageUtil { maxWidth: Float = DEFAULT_MAX_WIDTH, maxHeight: Float = DEFAULT_MAX_HEIGHT, ): ByteArray -} \ No newline at end of file +} diff --git a/core/ui/src/desktopMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.desktop.kt b/core/ui/src/desktopMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.desktop.kt index 10a67deac..a4209982e 100644 --- a/core/ui/src/desktopMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.desktop.kt +++ b/core/ui/src/desktopMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.desktop.kt @@ -24,7 +24,6 @@ actual object ImageUtil { maxWidth: Float, maxHeight: Float, ): ByteArray { - val inputStream = ByteArrayInputStream(decodedBytes) val originalImage: BufferedImage = try { ImageIO.read(inputStream) @@ -37,7 +36,7 @@ actual object ImageUtil { originalImage.width.toFloat(), originalImage.height.toFloat(), maxWidth, - maxHeight + maxHeight, ) val scaledImage = createScaledImage(originalImage, actualWidth, actualHeight) @@ -56,7 +55,7 @@ actual object ImageUtil { actualWidth: Float, actualHeight: Float, maxWidth: Float, - maxHeight: Float + maxHeight: Float, ): Pair { val imgRatio = actualWidth / actualHeight val maxRatio = maxWidth / maxHeight @@ -93,4 +92,3 @@ actual object ImageUtil { return scaledImage } } - diff --git a/core/ui/src/jsMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.js.kt b/core/ui/src/jsMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.js.kt index 18e7a0933..700e9cd5d 100644 --- a/core/ui/src/jsMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.js.kt +++ b/core/ui/src/jsMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.js.kt @@ -22,5 +22,4 @@ actual object ImageUtil { ): ByteArray { TODO("Not yet implemented") } - -} \ No newline at end of file +} From d70406ff988257c53a8e14e0c9646a1d41a40fa6 Mon Sep 17 00:00:00 2001 From: revanthkumarJ Date: Fri, 24 Jan 2025 21:59:16 +0530 Subject: [PATCH 09/11] updated --- core/ui/build.gradle.kts | 3 --- gradle/libs.versions.toml | 2 -- 2 files changed, 5 deletions(-) diff --git a/core/ui/build.gradle.kts b/core/ui/build.gradle.kts index 0cb7282a8..586e4bda6 100644 --- a/core/ui/build.gradle.kts +++ b/core/ui/build.gradle.kts @@ -49,7 +49,4 @@ kotlin{ } } } -//dependencies { -// implementation(libs.androidx.ui.graphics.android) -//} diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 7e6b4e7cf..be87b1ab7 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,5 +1,4 @@ [versions] -accompanistSystemuicontrollerVersion = "0.30.1" accompanistVersion = "0.34.0" activityVersion = "1.9.3" androidDesugarJdkLibs = "2.1.4" @@ -46,7 +45,6 @@ hilt = "2.54" hiltExt = "1.2.0" jacoco = "0.8.7" junitVersion = "4.13.2" -kotlinxDatetimeVersion = "0.4.0" ktlint = "12.1.1" libphonenumberAndroidVersion = "8.13.35" lifecycleExtensionsVersion = "2.2.0" From 1b5c00eddf797bc51315b522cabe19d29ae88d55 Mon Sep 17 00:00:00 2001 From: revanthkumarJ Date: Sun, 26 Jan 2025 16:36:17 +0530 Subject: [PATCH 10/11] removed unintentinal ones from libs.versions --- core/ui/build.gradle.kts | 5 -- .../mobile/core/ui/utils/ImageUtil.js.kt | 9 ++-- .../mobile/core/ui/utils/ImageUtil.native.kt | 47 +++++++++---------- .../mobile/core/ui/utils/ImageUtil.wasmJs.kt | 8 ++-- gradle/libs.versions.toml | 6 --- 5 files changed, 29 insertions(+), 46 deletions(-) diff --git a/core/ui/build.gradle.kts b/core/ui/build.gradle.kts index 586e4bda6..8e9e84b75 100644 --- a/core/ui/build.gradle.kts +++ b/core/ui/build.gradle.kts @@ -42,11 +42,6 @@ kotlin{ implementation(libs.filekit.compose) implementation(libs.filekit.core) } - desktopMain.dependencies { - implementation(libs.kotlin.stdlib.jdk8) - implementation(libs.imageio.core) - - } } } diff --git a/core/ui/src/jsMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.js.kt b/core/ui/src/jsMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.js.kt index 700e9cd5d..17732cc71 100644 --- a/core/ui/src/jsMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.js.kt +++ b/core/ui/src/jsMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.js.kt @@ -9,17 +9,16 @@ */ package org.mifos.mobile.core.ui.utils +// TODO: Not Implemented actual object ImageUtil { - actual val DEFAULT_MAX_WIDTH: Float - get() = TODO("Not yet implemented") - actual val DEFAULT_MAX_HEIGHT: Float - get() = TODO("Not yet implemented") + actual val DEFAULT_MAX_WIDTH: Float = 816f + actual val DEFAULT_MAX_HEIGHT: Float = 612f actual fun compressImage( decodedBytes: ByteArray, maxWidth: Float, maxHeight: Float, ): ByteArray { - TODO("Not yet implemented") + return decodedBytes } } diff --git a/core/ui/src/nativeMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.native.kt b/core/ui/src/nativeMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.native.kt index 5685eeab7..3716babf7 100644 --- a/core/ui/src/nativeMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.native.kt +++ b/core/ui/src/nativeMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.native.kt @@ -9,33 +9,33 @@ */ package org.mifos.mobile.core.ui.utils -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.withContext import org.jetbrains.skia.Bitmap import org.jetbrains.skia.Canvas import org.jetbrains.skia.Image -import org.jetbrains.skia.Matrix33 +import org.jetbrains.skia.ImageInfo import org.jetbrains.skia.Paint import org.jetbrains.skia.Rect -import java.io.ByteArrayOutputStream + actual object ImageUtil { actual val DEFAULT_MAX_WIDTH: Float = 816f actual val DEFAULT_MAX_HEIGHT: Float = 612f - actual suspend fun compressImage( + actual fun compressImage( decodedBytes: ByteArray, maxWidth: Float, maxHeight: Float, - ): ByteArray = withContext(Dispatchers.Default) { - val bitmap = Bitmap.makeFromImage(Image.makeFromEncoded(decodedBytes)) + ): ByteArray { + val image = Image.makeFromEncoded(decodedBytes) + val bitmap = Bitmap.makeFromImage(image) val (actualWidth, actualHeight) = calculateActualDimensions(bitmap.width, bitmap.height, maxWidth, maxHeight) val scaledBitmap = createScaledBitmap(bitmap, actualWidth, actualHeight) - val byteArrayOutputStream = ByteArrayOutputStream() - scaledBitmap.encodeToData()?.bytes?.let { byteArrayOutputStream.write(it) } - byteArrayOutputStream.toByteArray() + val scaledImage = Image.makeFromBitmap(scaledBitmap) + + return scaledImage.encodeToData()?.bytes + ?: throw IllegalStateException("Failed to encode bitmap") } private fun calculateActualDimensions( @@ -54,16 +54,12 @@ actual object ImageUtil { val newWidth = (maxHeight * imgRatio).toInt() Pair(newWidth, newHeight) } - imgRatio > maxRatio -> { val newWidth = maxWidth.toInt() val newHeight = (maxWidth / imgRatio).toInt() Pair(newWidth, newHeight) } - - else -> { - Pair(maxWidth.toInt(), maxHeight.toInt()) - } + else -> Pair(maxWidth.toInt(), maxHeight.toInt()) } } else { Pair(width, height) @@ -75,19 +71,20 @@ actual object ImageUtil { targetWidth: Int, targetHeight: Int, ): Bitmap { - val scaledBitmap = Bitmap().apply { - allocPixels(targetWidth, targetHeight) - } + val imageInfo = ImageInfo.makeN32Premul(targetWidth, targetHeight) + val scaledBitmap = Bitmap() + scaledBitmap.allocPixels(imageInfo) val canvas = Canvas(scaledBitmap) - val scaleX = targetWidth.toFloat() / bitmap.width - val scaleY = targetHeight.toFloat() / bitmap.height - val scaleMatrix = Matrix33.makeScale(scaleX, scaleY) + val sourceRect = Rect.makeWH(bitmap.width.toFloat(), bitmap.height.toFloat()) + val targetRect = Rect.makeWH(targetWidth.toFloat(), targetHeight.toFloat()) - canvas.save() - canvas.concat(scaleMatrix) - canvas.drawBitmapRect(bitmap, Rect.makeWH(bitmap.width.toFloat(), bitmap.height.toFloat()), Paint()) - canvas.restore() + canvas.drawImageRect( + Image.makeFromBitmap(bitmap), + sourceRect, + targetRect, + Paint() + ) return scaledBitmap } diff --git a/core/ui/src/wasmJsMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.wasmJs.kt b/core/ui/src/wasmJsMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.wasmJs.kt index 1cf818e01..17732cc71 100644 --- a/core/ui/src/wasmJsMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.wasmJs.kt +++ b/core/ui/src/wasmJsMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.wasmJs.kt @@ -11,16 +11,14 @@ package org.mifos.mobile.core.ui.utils // TODO: Not Implemented actual object ImageUtil { - actual val DEFAULT_MAX_WIDTH: Float - get() = TODO("Not yet implemented") - actual val DEFAULT_MAX_HEIGHT: Float - get() = TODO("Not yet implemented") + actual val DEFAULT_MAX_WIDTH: Float = 816f + actual val DEFAULT_MAX_HEIGHT: Float = 612f actual fun compressImage( decodedBytes: ByteArray, maxWidth: Float, maxHeight: Float, ): ByteArray { - TODO("Not yet implemented") + return decodedBytes } } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index be87b1ab7..dd504ad87 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -23,7 +23,6 @@ androidxUiAutomator = "2.3.0" annotation = "1.9.1" appcompatVersion = "1.7.0" cameraCoreVersion = "1.3.4" -imageioCoreVersion = "1.1" mlkit="17.3.0" guavaVersion = "33.3.1-android" cameraxVersion = "1.4.1" @@ -118,7 +117,6 @@ jbSavedState = "1.2.2" packageName = "MifosWallet" packageNamespace = "org.mifos.desktop" packageVersion = "1.0.0" -uiGraphicsAndroidVersion = "1.7.6" [libraries] accompanist-pager = { group = "com.google.accompanist", name = "accompanist-pager", version.ref = "accompanistVersion" } @@ -134,9 +132,6 @@ androidx-camera-camera2 = { group = "androidx.camera", name = "camera-camera2", androidx-camera-core = { group = "androidx.camera", name = "camera-core", version.ref = "cameraxVersion" } androidx-camera-lifecycle = { group = "androidx.camera", name = "camera-lifecycle", version.ref = "cameraxVersion" } androidx-camera-view = { group = "androidx.camera", name = "camera-view", version.ref = "cameraxVersion" } -imageio-core = { module = "javax.imageio:imageio-core", version.ref = "imageioCoreVersion" } -jetbrains-kotlin-stdlib-jdk8 = { module = "org.jetbrains.kotlin:kotlin-stdlib-jdk8" } -kotlin-stdlib-jdk8 = { module = "org.jetbrains.kotlin:kotlin-stdlib-jdk8" } mlkit-barcode-scanning = { module = "com.google.mlkit:barcode-scanning", version.ref = "mlkit" } guava = { module = "com.google.guava:guava", version.ref = "guavaVersion" } androidx-compose-animation = { group = "androidx.compose.animation", name = "animation" } @@ -320,7 +315,6 @@ moko-permission = { group = "dev.icerock.moko", name = "permissions", version.re moko-permission-compose = { group = "dev.icerock.moko", name = "permissions-compose", version.ref = "mokoPermission" } window-size = { group = "dev.chrisbanes.material3", name = "material3-window-size-class-multiplatform", version.ref = "windowsSizeClass" } -androidx-ui-graphics-android = { group = "androidx.compose.ui", name = "ui-graphics-android", version.ref = "uiGraphicsAndroidVersion" } [bundles] androidx-compose-ui-test = [ From e0e0e477c158fd9b4b07eee023eb85525398f5b7 Mon Sep 17 00:00:00 2001 From: revanthkumarJ Date: Sun, 26 Jan 2025 16:45:56 +0530 Subject: [PATCH 11/11] updated --- .../kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.native.kt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/core/ui/src/nativeMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.native.kt b/core/ui/src/nativeMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.native.kt index 3716babf7..164de6957 100644 --- a/core/ui/src/nativeMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.native.kt +++ b/core/ui/src/nativeMain/kotlin/org/mifos/mobile/core/ui/utils/ImageUtil.native.kt @@ -16,7 +16,6 @@ import org.jetbrains.skia.ImageInfo import org.jetbrains.skia.Paint import org.jetbrains.skia.Rect - actual object ImageUtil { actual val DEFAULT_MAX_WIDTH: Float = 816f actual val DEFAULT_MAX_HEIGHT: Float = 612f @@ -83,7 +82,7 @@ actual object ImageUtil { Image.makeFromBitmap(bitmap), sourceRect, targetRect, - Paint() + Paint(), ) return scaledBitmap