From 33579c0f2a91593b64b912b53395b229de1cc00d Mon Sep 17 00:00:00 2001 From: Piyush Date: Tue, 27 Jan 2026 03:33:50 +0530 Subject: [PATCH 1/4] chore: implement TODO for file size formatting and unique file name generation --- .../uploadDocs/UploadDocsViewmodel.kt | 69 ++++++++++--------- .../component/BottomSheetContent.kt | 2 +- 2 files changed, 38 insertions(+), 33 deletions(-) diff --git a/feature/loan-application/src/commonMain/kotlin/org/mifos/mobile/feature/loan/application/uploadDocs/UploadDocsViewmodel.kt b/feature/loan-application/src/commonMain/kotlin/org/mifos/mobile/feature/loan/application/uploadDocs/UploadDocsViewmodel.kt index a145d1fa5..76d862127 100644 --- a/feature/loan-application/src/commonMain/kotlin/org/mifos/mobile/feature/loan/application/uploadDocs/UploadDocsViewmodel.kt +++ b/feature/loan-application/src/commonMain/kotlin/org/mifos/mobile/feature/loan/application/uploadDocs/UploadDocsViewmodel.kt @@ -29,6 +29,8 @@ import org.mifos.mobile.core.ui.utils.BaseViewModel import org.mifos.mobile.feature.loan.application.component.DocumentType import org.mifos.mobile.feature.loan.application.component.SignatureUploadType import kotlin.io.encoding.ExperimentalEncodingApi +import kotlin.time.Clock +import kotlin.time.ExperimentalTime /** * `ViewModel` for the Upload Documents screen. @@ -88,10 +90,9 @@ internal class UploadDocsViewModel : mutableStateFlow.update { it.copy( dialogState = null, - signatureDocumentFile = action.image, - // TODO:: Generate Unique Name & Calculate Size - signatureFileName = "signature.png", - signatureSize = "100 KB", + signatureDocumentFile = action.imageArray.toBase64DataUri(), + signatureFileName = generateUniqueFileName("signature", "png"), + signatureSize = formatFileSize(action.imageArray.size.toLong()), ) } } @@ -172,19 +173,11 @@ internal class UploadDocsViewModel : try { val image = FileKit.openFilePicker(type = FileKitType.Image) image?.let { file -> - val sizeInKB = file.size() / 1024 - val sizeInMb = sizeInKB / 1024 - val showFileSize = if (sizeInMb >= 1) { - "$sizeInMb MB" - } else { - "$sizeInKB KB" - } - mutableStateFlow.update { it.copy( propertyDocumentsFile = file.readBytes().toBase64DataUri(), propertyDocumentFileName = file.name, - propertyDocumentsSize = showFileSize, + propertyDocumentsSize = formatFileSize(file.size()), ) } } @@ -204,19 +197,11 @@ internal class UploadDocsViewModel : try { val image = FileKit.openFilePicker(type = FileKitType.Image) image?.let { file -> - val sizeInKB = file.size() / 1024 - val sizeInMb = sizeInKB / 1024 - val showFileSize = if (sizeInMb >= 1) { - "$sizeInMb MB" - } else { - "$sizeInKB KB" - } - mutableStateFlow.update { it.copy( bankStatementFile = file.readBytes().toBase64DataUri(), bankStatementFileName = file.name, - bankStatementSize = showFileSize, + bankStatementSize = formatFileSize(file.size()), ) } } @@ -252,20 +237,12 @@ internal class UploadDocsViewModel : val image = FileKit.openFilePicker(type = FileKitType.Image) image?.let { file -> - val sizeInKB = file.size() / 1024 - val sizeInMb = sizeInKB / 1024 - val showFileSize = if (sizeInMb >= 1) { - "$sizeInMb MB" - } else { - "$sizeInKB KB" - } - mutableStateFlow.update { it.copy( dialogState = null, signatureDocumentFile = file.readBytes().toBase64DataUri(), signatureFileName = file.name, - signatureSize = showFileSize, + signatureSize = formatFileSize(file.size()), ) } } @@ -342,6 +319,34 @@ internal class UploadDocsViewModel : private fun handleUploadDocumentResult(action: UploadDocsAction.Internal.UploadDocumentResultReceived) { // TODO: Implement logic to handle the upload result, e.g., show a toast or update state. } + + /** + * Calculates and formats the file size from bytes to a human-readable string. + * + * @param bytes The size in bytes. + * @return A formatted string showing size in MB or KB. + */ + private fun formatFileSize(bytes: Long): String { + val sizeInKB = bytes / 1024 + val sizeInMb = sizeInKB / 1024 + return if (sizeInMb >= 1) { + "$sizeInMb MB" + } else { + "$sizeInKB KB" + } + } + + /** + * Generates a unique filename with a timestamp. + * + * @param prefix The prefix for the filename . + * @param extension The file extension without the dot. + * @return A unique filename in the format "prefix_timestamp.extension". + */ + @OptIn(ExperimentalTime::class) + private fun generateUniqueFileName(prefix: String, extension: String): String { + return "${prefix}_${Clock.System.now().toEpochMilliseconds()}.$extension" + } } /** @@ -443,7 +448,7 @@ internal sealed interface UploadDocsAction { * User action to upload a signed image. * @property image The base64-encoded string of the signature image. */ - data class UploadSign(val image: String) : UploadDocsAction + data class UploadSign(val imageArray: ByteArray) : UploadDocsAction /** * User action to initiate the upload of a document. diff --git a/feature/loan-application/src/commonMain/kotlin/org/mifos/mobile/feature/loan/application/uploadDocs/component/BottomSheetContent.kt b/feature/loan-application/src/commonMain/kotlin/org/mifos/mobile/feature/loan/application/uploadDocs/component/BottomSheetContent.kt index b7873c965..0ac01796d 100644 --- a/feature/loan-application/src/commonMain/kotlin/org/mifos/mobile/feature/loan/application/uploadDocs/component/BottomSheetContent.kt +++ b/feature/loan-application/src/commonMain/kotlin/org/mifos/mobile/feature/loan/application/uploadDocs/component/BottomSheetContent.kt @@ -291,7 +291,7 @@ private fun SignatureContent( backgroundColor = Color.White, ) if (data != null) { - val data = data.encodeToByteArray().toBase64DataUri() + val data = data.encodeToByteArray() onAction(UploadDocsAction.UploadSign(data)) } } From 04f8667b62ad8f387d0a857652cdb772e9193ed2 Mon Sep 17 00:00:00 2001 From: Piyush Date: Tue, 27 Jan 2026 04:08:04 +0530 Subject: [PATCH 2/4] Update UploadDocsViewmodel.kt --- .../feature/loan/application/uploadDocs/UploadDocsViewmodel.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/feature/loan-application/src/commonMain/kotlin/org/mifos/mobile/feature/loan/application/uploadDocs/UploadDocsViewmodel.kt b/feature/loan-application/src/commonMain/kotlin/org/mifos/mobile/feature/loan/application/uploadDocs/UploadDocsViewmodel.kt index 76d862127..249481e66 100644 --- a/feature/loan-application/src/commonMain/kotlin/org/mifos/mobile/feature/loan/application/uploadDocs/UploadDocsViewmodel.kt +++ b/feature/loan-application/src/commonMain/kotlin/org/mifos/mobile/feature/loan/application/uploadDocs/UploadDocsViewmodel.kt @@ -446,7 +446,7 @@ internal sealed interface UploadDocsAction { /** * User action to upload a signed image. - * @property image The base64-encoded string of the signature image. + * @property imageArray The base64-encoded string of the signature image. */ data class UploadSign(val imageArray: ByteArray) : UploadDocsAction From 92ec4c8121dd7168596090b92691bbc90454772d Mon Sep 17 00:00:00 2001 From: Piyush Date: Tue, 27 Jan 2026 04:33:09 +0530 Subject: [PATCH 3/4] Clarify imageArray property in UploadSign action Updated documentation for UploadSign action to clarify imageArray property. --- .../feature/loan/application/uploadDocs/UploadDocsViewmodel.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/feature/loan-application/src/commonMain/kotlin/org/mifos/mobile/feature/loan/application/uploadDocs/UploadDocsViewmodel.kt b/feature/loan-application/src/commonMain/kotlin/org/mifos/mobile/feature/loan/application/uploadDocs/UploadDocsViewmodel.kt index 249481e66..15a15e99c 100644 --- a/feature/loan-application/src/commonMain/kotlin/org/mifos/mobile/feature/loan/application/uploadDocs/UploadDocsViewmodel.kt +++ b/feature/loan-application/src/commonMain/kotlin/org/mifos/mobile/feature/loan/application/uploadDocs/UploadDocsViewmodel.kt @@ -446,7 +446,7 @@ internal sealed interface UploadDocsAction { /** * User action to upload a signed image. - * @property imageArray The base64-encoded string of the signature image. + * `@property` imageArray Raw bytes of the signature image. */ data class UploadSign(val imageArray: ByteArray) : UploadDocsAction From 53153c26157e80644981dfc5ad40fbb8c7145122 Mon Sep 17 00:00:00 2001 From: Piyush Date: Thu, 29 Jan 2026 02:02:04 +0530 Subject: [PATCH 4/4] Remove unused import in BottomSheetContent.kt Removed unused import for toBase64DataUri. --- .../loan/application/uploadDocs/component/BottomSheetContent.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/feature/loan-application/src/commonMain/kotlin/org/mifos/mobile/feature/loan/application/uploadDocs/component/BottomSheetContent.kt b/feature/loan-application/src/commonMain/kotlin/org/mifos/mobile/feature/loan/application/uploadDocs/component/BottomSheetContent.kt index 0ac01796d..9e5f4c1ca 100644 --- a/feature/loan-application/src/commonMain/kotlin/org/mifos/mobile/feature/loan/application/uploadDocs/component/BottomSheetContent.kt +++ b/feature/loan-application/src/commonMain/kotlin/org/mifos/mobile/feature/loan/application/uploadDocs/component/BottomSheetContent.kt @@ -59,7 +59,6 @@ import mifos_mobile.feature.loan_application.generated.resources.sign import mifos_mobile.feature.loan_application.generated.resources.sign_here import org.jetbrains.compose.resources.StringResource import org.jetbrains.compose.resources.stringResource -import org.mifos.mobile.core.common.toBase64DataUri import org.mifos.mobile.core.designsystem.component.CardVariant import org.mifos.mobile.core.designsystem.component.MifosButton import org.mifos.mobile.core.designsystem.component.MifosCustomCard