feat: add lottie animation progress indicators (#1924)

This commit is contained in:
Biplab Dutta 2025-09-10 09:49:04 +05:30 committed by GitHub
parent df7be3d35c
commit 9b4ee9de23
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
37 changed files with 280 additions and 220 deletions

View File

@ -1404,9 +1404,9 @@
| | | | \--- org.jetbrains.kotlin:kotlin-stdlib:2.0.21 -> 2.1.21 (*)
| | | +--- com.squareup.okio:okio:3.15.0 (*)
| | | +--- org.jetbrains.kotlin:kotlin-stdlib:2.1.20 -> 2.1.21 (*)
| | | +--- org.jetbrains.kotlinx:kotlinx-datetime:0.6.2
| | | | \--- org.jetbrains.kotlinx:kotlinx-datetime-jvm:0.6.2
| | | | \--- org.jetbrains.kotlin:kotlin-stdlib:1.9.21 -> 2.1.21 (*)
| | | +--- org.jetbrains.kotlinx:kotlinx-datetime:0.7.1
| | | | \--- org.jetbrains.kotlinx:kotlinx-datetime-jvm:0.7.1
| | | | \--- org.jetbrains.kotlin:kotlin-stdlib:2.1.20 -> 2.1.21 (*)
| | | +--- io.insert-koin:koin-bom:4.1.0 (*)
| | | +--- io.insert-koin:koin-core:4.1.0 (*)
| | | +--- io.insert-koin:koin-annotations:2.1.0
@ -1990,21 +1990,46 @@
| | | +--- org.jetbrains.kotlin:kotlin-stdlib:2.1.21-RC2 -> 2.1.21 (*)
| | | +--- androidx.annotation:annotation:1.9.1 (*)
| | | \--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.2 (*)
| | \--- io.github.vinceglb:filekit-dialogs-compose:0.10.0-beta04
| | \--- io.github.vinceglb:filekit-dialogs-compose-android:0.10.0-beta04
| | +--- androidx.activity:activity-compose:1.10.1 (*)
| | +--- androidx.exifinterface:exifinterface:1.4.1 (*)
| | +--- io.github.vinceglb:filekit-dialogs:0.10.0-beta04
| | | \--- io.github.vinceglb:filekit-dialogs-android:0.10.0-beta04
| | | +--- androidx.activity:activity-ktx:1.10.1 (*)
| | | +--- io.github.vinceglb:filekit-core:0.10.0-beta04 (*)
| | | +--- org.jetbrains.kotlin:kotlin-stdlib:2.1.21-RC2 -> 2.1.21 (*)
| | | \--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.2 (*)
| | +--- org.jetbrains.kotlin:kotlin-stdlib:2.1.21-RC2 -> 2.1.21 (*)
| | +--- org.jetbrains.compose.runtime:runtime:1.8.0 -> 1.8.2 (*)
| | +--- org.jetbrains.compose.ui:ui:1.8.0 -> 1.8.2 (*)
| | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.2 (*)
| | \--- androidx.annotation:annotation:1.9.1 (*)
| | +--- io.github.vinceglb:filekit-dialogs-compose:0.10.0-beta04
| | | \--- io.github.vinceglb:filekit-dialogs-compose-android:0.10.0-beta04
| | | +--- androidx.activity:activity-compose:1.10.1 (*)
| | | +--- androidx.exifinterface:exifinterface:1.4.1 (*)
| | | +--- io.github.vinceglb:filekit-dialogs:0.10.0-beta04
| | | | \--- io.github.vinceglb:filekit-dialogs-android:0.10.0-beta04
| | | | +--- androidx.activity:activity-ktx:1.10.1 (*)
| | | | +--- io.github.vinceglb:filekit-core:0.10.0-beta04 (*)
| | | | +--- org.jetbrains.kotlin:kotlin-stdlib:2.1.21-RC2 -> 2.1.21 (*)
| | | | \--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.2 (*)
| | | +--- org.jetbrains.kotlin:kotlin-stdlib:2.1.21-RC2 -> 2.1.21 (*)
| | | +--- org.jetbrains.compose.runtime:runtime:1.8.0 -> 1.8.2 (*)
| | | +--- org.jetbrains.compose.ui:ui:1.8.0 -> 1.8.2 (*)
| | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.2 (*)
| | | \--- androidx.annotation:annotation:1.9.1 (*)
| | +--- io.github.alexzhirkevich:compottie-resources:2.0.0-rc05
| | | \--- io.github.alexzhirkevich:compottie-resources-android:2.0.0-rc05
| | | +--- io.github.alexzhirkevich:compottie-core:2.0.0-rc05
| | | | \--- io.github.alexzhirkevich:compottie-core-android:2.0.0-rc05
| | | | +--- io.github.alexzhirkevich:keight-core:0.0.02
| | | | | \--- io.github.alexzhirkevich:keight-core-android:0.0.02
| | | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.9.0 -> 1.10.2 (*)
| | | | | +--- org.jetbrains.kotlinx:kotlinx-datetime:0.7.1 (*)
| | | | | \--- org.jetbrains.kotlin:kotlin-stdlib:2.1.20 -> 2.1.21 (*)
| | | | +--- org.jetbrains.kotlin:kotlin-stdlib:2.1.20 -> 2.1.21 (*)
| | | | +--- org.jetbrains.compose.foundation:foundation:1.8.2 (*)
| | | | +--- org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.3 -> 1.8.1 (*)
| | | | +--- com.squareup.okio:okio:3.15.0 (*)
| | | | \--- org.jetbrains.kotlinx:atomicfu:0.23.2
| | | | \--- org.jetbrains.kotlinx:atomicfu-jvm:0.23.2
| | | | \--- org.jetbrains.kotlin:kotlin-stdlib:{prefer 1.9.21} -> 2.1.21 (*)
| | | +--- org.jetbrains.kotlin:kotlin-stdlib:2.1.20 -> 2.1.21 (*)
| | | +--- org.jetbrains.compose.ui:ui:1.8.2 (*)
| | | +--- org.jetbrains.compose.components:components-resources:1.8.2 (*)
| | | \--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.2 (*)
| | \--- io.github.alexzhirkevich:compottie-lite:2.0.0-rc05
| | \--- io.github.alexzhirkevich:compottie-lite-android:2.0.0-rc05
| | +--- io.github.alexzhirkevich:compottie-core:2.0.0-rc05 (*)
| | +--- org.jetbrains.kotlin:kotlin-stdlib:2.1.20 -> 2.1.21 (*)
| | \--- org.jetbrains.compose.foundation:foundation:1.8.2 (*)
| +--- project :core:designsystem (*)
| +--- io.insert-koin:koin-compose:4.1.0 (*)
| +--- io.insert-koin:koin-compose-viewmodel:4.1.0 (*)

View File

@ -307,6 +307,14 @@ io.coil-kt.coil3:coil-network-ktor3:3.2.0
io.coil-kt.coil3:coil-svg-android:3.2.0
io.coil-kt.coil3:coil-svg:3.2.0
io.coil-kt.coil3:coil:3.2.0
io.github.alexzhirkevich:compottie-core-android:2.0.0-rc05
io.github.alexzhirkevich:compottie-core:2.0.0-rc05
io.github.alexzhirkevich:compottie-lite-android:2.0.0-rc05
io.github.alexzhirkevich:compottie-lite:2.0.0-rc05
io.github.alexzhirkevich:compottie-resources-android:2.0.0-rc05
io.github.alexzhirkevich:compottie-resources:2.0.0-rc05
io.github.alexzhirkevich:keight-core-android:0.0.02
io.github.alexzhirkevich:keight-core:0.0.02
io.github.alexzhirkevich:qrose-android:1.0.1
io.github.alexzhirkevich:qrose-core-android:1.0.1
io.github.alexzhirkevich:qrose-core:1.0.1
@ -420,6 +428,8 @@ org.jetbrains.kotlin:kotlin-reflect:2.1.21
org.jetbrains.kotlin:kotlin-stdlib-jdk7:2.1.0
org.jetbrains.kotlin:kotlin-stdlib-jdk8:2.1.0
org.jetbrains.kotlin:kotlin-stdlib:2.1.21
org.jetbrains.kotlinx:atomicfu-jvm:0.23.2
org.jetbrains.kotlinx:atomicfu:0.23.2
org.jetbrains.kotlinx:kotlinx-collections-immutable-jvm:0.3.8
org.jetbrains.kotlinx:kotlinx-collections-immutable:0.3.8
org.jetbrains.kotlinx:kotlinx-coroutines-android:1.10.2
@ -428,8 +438,8 @@ org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.10.2
org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.2
org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.10.2
org.jetbrains.kotlinx:kotlinx-coroutines-slf4j:1.10.2
org.jetbrains.kotlinx:kotlinx-datetime-jvm:0.6.2
org.jetbrains.kotlinx:kotlinx-datetime:0.6.2
org.jetbrains.kotlinx:kotlinx-datetime-jvm:0.7.1
org.jetbrains.kotlinx:kotlinx-datetime:0.7.1
org.jetbrains.kotlinx:kotlinx-io-bytestring-jvm:0.7.0
org.jetbrains.kotlinx:kotlinx-io-bytestring:0.7.0
org.jetbrains.kotlinx:kotlinx-io-core-jvm:0.7.0

View File

@ -9,7 +9,6 @@
*/
package org.mifospay.core.common
import kotlinx.datetime.Clock
import kotlinx.datetime.Instant
import kotlinx.datetime.LocalDate
import kotlinx.datetime.LocalDateTime
@ -17,9 +16,13 @@ import kotlinx.datetime.Month
import kotlinx.datetime.TimeZone
import kotlinx.datetime.atStartOfDayIn
import kotlinx.datetime.format
import kotlinx.datetime.format.FormatStringsInDatetimeFormats
import kotlinx.datetime.format.byUnicodePattern
import kotlinx.datetime.toLocalDateTime
import kotlin.time.Clock
import kotlin.time.ExperimentalTime
@OptIn(ExperimentalTime::class)
object DateHelper {
/*
* This is the full month format for the date picker.
@ -35,10 +38,12 @@ object DateHelper {
const val MONTH_FORMAT = "dd MMMM"
@OptIn(FormatStringsInDatetimeFormats::class)
private val fullMonthFormat = LocalDateTime.Format {
byUnicodePattern(FULL_MONTH)
}
@OptIn(FormatStringsInDatetimeFormats::class)
private val shortMonthFormat = LocalDateTime.Format {
byUnicodePattern(SHORT_MONTH)
}
@ -94,6 +99,7 @@ object DateHelper {
* @param dateString date string
* @return dd MMMM yyyy format date string.
*/
@OptIn(FormatStringsInDatetimeFormats::class)
fun getSpecificFormat(format: String, dateString: String): String {
val pickerFormat = shortMonthFormat
val finalFormat = LocalDateTime.Format { byUnicodePattern(format) }
@ -101,6 +107,7 @@ object DateHelper {
return finalFormat.format(pickerFormat.parse(dateString))
}
@OptIn(FormatStringsInDatetimeFormats::class)
private fun getFormatConverter(
currentFormat: String,
requiredFormat: String,
@ -239,7 +246,7 @@ object DateHelper {
val timeZone = TimeZone.currentSystemDefault()
val now = Clock.System.now()
val nowDateTime = now.toLocalDateTime(timeZone)
val nowDateTime = Instant.fromEpochMilliseconds(now.toEpochMilliseconds()).toLocalDateTime(timeZone)
return when {
// Same year
@ -296,7 +303,7 @@ object DateHelper {
val timestamp = this.toLong()
val instant = Instant.fromEpochMilliseconds(timestamp)
val timeZone = TimeZone.currentSystemDefault()
val nowDateTime = Clock.System.now().toLocalDateTime(timeZone)
val nowDateTime = Instant.fromEpochMilliseconds(Clock.System.now().toEpochMilliseconds()).toLocalDateTime(timeZone)
val neededDateTime = instant.toLocalDateTime(timeZone)
return when {
@ -356,19 +363,25 @@ object DateHelper {
if (it.isLowerCase()) it.titlecase() else it.toString()
}
val currentDate = Clock.System.now().toLocalDateTime(TimeZone.currentSystemDefault())
val currentDate: LocalDateTime by lazy {
Instant.fromEpochMilliseconds(Clock.System.now().toEpochMilliseconds()).toLocalDateTime(TimeZone.currentSystemDefault())
}
/**
* This is the full date format for the date picker.
* "dd MM yyyy" is the format of the date picker.
*/
val formattedFullDate = currentDate.format(fullMonthFormat)
val formattedFullDate: String by lazy {
currentDate.format(fullMonthFormat)
}
/**
* This is the short date format for the date picker.
* "dd-MM-yyyy" is the format of the date picker.
*/
val formattedShortDate = currentDate.format(shortMonthFormat)
val formattedShortDate: String by lazy {
currentDate.format(shortMonthFormat)
}
/**
* Parses a date string in "dd MMM yyyy" format and converts it to milliseconds.

View File

@ -43,6 +43,8 @@ kotlin {
implementation(libs.jb.composeNavigation)
implementation(libs.filekit.core)
implementation(libs.filekit.dialogs.compose)
implementation(libs.compottie.resources)
implementation(libs.compottie.lite)
}
androidInstrumentedTest.dependencies {
implementation(libs.bundles.androidx.compose.ui.test)

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,103 @@
/*
* 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-wallet/blob/master/LICENSE.md
*/
package org.mifospay.core.ui
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import io.github.alexzhirkevich.compottie.LottieCompositionSpec
import io.github.alexzhirkevich.compottie.animateLottieCompositionAsState
import io.github.alexzhirkevich.compottie.rememberLottieComposition
import io.github.alexzhirkevich.compottie.rememberLottiePainter
import mobile_wallet.core.ui.generated.resources.Res
import org.jetbrains.compose.ui.tooling.preview.Preview
import org.mifospay.core.designsystem.theme.MifosTheme
import org.mifospay.core.ui.utils.LottieConstants
@Composable
fun MifosProgressIndicator(
modifier: Modifier = Modifier.fillMaxSize(),
) {
val composition by rememberLottieComposition {
LottieCompositionSpec.JsonString(
Res.readBytes(LottieConstants.LOADING_ANIMATION).decodeToString(),
)
}
val progress by animateLottieCompositionAsState(composition)
Box(
modifier = modifier,
contentAlignment = Alignment.Center,
) {
Image(
painter = rememberLottiePainter(
composition = composition,
progress = { progress },
),
contentDescription = "Lottie animation",
)
}
}
@Composable
fun MifosProgressIndicatorOverlay(
modifier: Modifier = Modifier.fillMaxSize(),
) {
val composition by rememberLottieComposition {
LottieCompositionSpec.JsonString(
Res.readBytes(LottieConstants.LOADING_ANIMATION).decodeToString(),
)
}
val progress by animateLottieCompositionAsState(composition)
Box(
modifier = modifier
.background(MaterialTheme.colorScheme.background.copy(alpha = 0.7f))
.clickable(
enabled = false,
indication = null,
interactionSource = remember { MutableInteractionSource() },
) { },
contentAlignment = Alignment.Center,
) {
Image(
painter = rememberLottiePainter(
composition = composition,
progress = { progress },
),
contentDescription = "Loading animation",
)
}
}
@Preview
@Composable
private fun Loading_Preview() {
MifosTheme {
MifosProgressIndicator()
}
}
@Preview
@Composable
private fun Overlay_Loading_Preview() {
MifosTheme {
MifosProgressIndicatorOverlay()
}
}

View File

@ -0,0 +1,14 @@
/*
* 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-wallet/blob/master/LICENSE.md
*/
package org.mifospay.core.ui.utils
object LottieConstants {
const val LOADING_ANIMATION = "files/loading_animation.json"
}

View File

@ -62,7 +62,6 @@ import mobile_wallet.feature.accounts.generated.resources.feature_accounts_edit
import mobile_wallet.feature.accounts.generated.resources.feature_accounts_edit_beneficiary
import mobile_wallet.feature.accounts.generated.resources.feature_accounts_error_oops
import mobile_wallet.feature.accounts.generated.resources.feature_accounts_info
import mobile_wallet.feature.accounts.generated.resources.feature_accounts_loading
import mobile_wallet.feature.accounts.generated.resources.feature_accounts_savings_account
import mobile_wallet.feature.accounts.generated.resources.feature_accounts_status_active
import mobile_wallet.feature.accounts.generated.resources.feature_accounts_status_approved
@ -82,7 +81,6 @@ import org.jetbrains.compose.resources.vectorResource
import org.koin.compose.viewmodel.koinViewModel
import org.mifospay.core.designsystem.component.BasicDialogState
import org.mifospay.core.designsystem.component.LoadingDialogState
import org.mifospay.core.designsystem.component.MfLoadingWheel
import org.mifospay.core.designsystem.component.MifosBasicDialog
import org.mifospay.core.designsystem.component.MifosButton
import org.mifospay.core.designsystem.component.MifosLoadingDialog
@ -93,6 +91,7 @@ import org.mifospay.core.model.beneficiary.Beneficiary
import org.mifospay.core.model.savingsaccount.Status
import org.mifospay.core.ui.AvatarBox
import org.mifospay.core.ui.EmptyContentScreen
import org.mifospay.core.ui.MifosProgressIndicator
import org.mifospay.core.ui.MifosSmallChip
import org.mifospay.core.ui.RevealDirection
import org.mifospay.core.ui.RevealSwipe
@ -192,11 +191,7 @@ internal fun AccountsScreenContent(
contentAlignment = Alignment.Center,
) {
when (state) {
is AccountState.ViewState.Loading -> {
MfLoadingWheel(
contentDesc = stringResource(Res.string.feature_accounts_loading),
)
}
is AccountState.ViewState.Loading -> MifosProgressIndicator()
is AccountState.ViewState.Error -> {
EmptyContentScreen(

View File

@ -70,12 +70,10 @@ import mobile_wallet.feature.accounts.generated.resources.feature_accounts_add_s
import mobile_wallet.feature.accounts.generated.resources.feature_accounts_add_with_hold_tax
import mobile_wallet.feature.accounts.generated.resources.feature_accounts_add_withdrawal_fee
import mobile_wallet.feature.accounts.generated.resources.feature_accounts_error_oops
import mobile_wallet.feature.accounts.generated.resources.feature_accounts_loading
import org.jetbrains.compose.resources.stringResource
import org.koin.compose.viewmodel.koinViewModel
import org.mifospay.core.designsystem.component.BasicDialogState
import org.mifospay.core.designsystem.component.LoadingDialogState
import org.mifospay.core.designsystem.component.MfLoadingWheel
import org.mifospay.core.designsystem.component.MifosBasicDialog
import org.mifospay.core.designsystem.component.MifosButton
import org.mifospay.core.designsystem.component.MifosLoadingDialog
@ -85,6 +83,7 @@ import org.mifospay.core.model.utils.Locale
import org.mifospay.core.model.utils.filterLocales
import org.mifospay.core.ui.EmptyContentScreen
import org.mifospay.core.ui.MifosDivider
import org.mifospay.core.ui.MifosProgressIndicator
import org.mifospay.core.ui.utils.EventsEffect
import template.core.base.designsystem.theme.KptTheme
@ -176,11 +175,7 @@ internal fun AddEditSavingAccountScreenContent(
contentAlignment = Alignment.Center,
) {
when (state.viewState) {
is AESState.ViewState.Loading -> {
MfLoadingWheel(
contentDesc = stringResource(Res.string.feature_accounts_loading),
)
}
is AESState.ViewState.Loading -> MifosProgressIndicator()
is AESState.ViewState.Error -> {
EmptyContentScreen(

View File

@ -64,11 +64,9 @@ import mobile_wallet.feature.accounts.generated.resources.feature_accounts_detai
import mobile_wallet.feature.accounts.generated.resources.feature_accounts_detail_total_withdrawals
import mobile_wallet.feature.accounts.generated.resources.feature_accounts_detail_wallet_balance
import mobile_wallet.feature.accounts.generated.resources.feature_accounts_error_oops
import mobile_wallet.feature.accounts.generated.resources.feature_accounts_loading
import org.jetbrains.compose.resources.stringResource
import org.koin.compose.viewmodel.koinViewModel
import org.mifospay.core.common.CurrencyFormatter
import org.mifospay.core.designsystem.component.MfLoadingWheel
import org.mifospay.core.designsystem.component.MifosScaffold
import org.mifospay.core.model.account.Account
import org.mifospay.core.model.savingsaccount.SavingAccountDetail
@ -78,6 +76,7 @@ import org.mifospay.core.model.savingsaccount.formatAmount
import org.mifospay.core.model.savingsaccount.toAccount
import org.mifospay.core.ui.EmptyContentScreen
import org.mifospay.core.ui.MifosDivider
import org.mifospay.core.ui.MifosProgressIndicator
import org.mifospay.core.ui.TransactionHistoryCard
import org.mifospay.core.ui.utils.EventsEffect
import org.mifospay.feature.accounts.SavingAccountStatus
@ -145,12 +144,7 @@ internal fun SavingAccountDetailScreen(
contentAlignment = Alignment.Center,
) {
when (state) {
is SADState.ViewState.Loading -> {
MfLoadingWheel(
contentDesc = stringResource(Res.string.feature_accounts_loading),
backgroundColor = KptTheme.colorScheme.surface,
)
}
is SADState.ViewState.Loading -> MifosProgressIndicator()
is SADState.ViewState.Error -> {
EmptyContentScreen(

View File

@ -43,15 +43,14 @@ import org.jetbrains.compose.resources.stringResource
import org.jetbrains.compose.ui.tooling.preview.Preview
import org.koin.compose.viewmodel.koinViewModel
import org.mifospay.core.designsystem.component.BasicDialogState
import org.mifospay.core.designsystem.component.LoadingDialogState
import org.mifospay.core.designsystem.component.MifosBasicDialog
import org.mifospay.core.designsystem.component.MifosButton
import org.mifospay.core.designsystem.component.MifosLoadingDialog
import org.mifospay.core.designsystem.component.MifosOutlinedTextField
import org.mifospay.core.designsystem.component.MifosScaffold
import org.mifospay.core.designsystem.theme.MifosTheme
import org.mifospay.core.designsystem.theme.styleNormal18sp
import org.mifospay.core.ui.MifosPasswordField
import org.mifospay.core.ui.MifosProgressIndicatorOverlay
import org.mifospay.core.ui.utils.EventsEffect
import template.core.base.designsystem.theme.KptTheme
@ -96,6 +95,10 @@ internal fun LoginScreen(
{ viewModel.trySendAction(it) }
},
)
if (state.dialogState is LoginState.DialogState.Loading) {
MifosProgressIndicatorOverlay()
}
}
@Composable
@ -133,9 +136,7 @@ private fun LoginDialogs(
onDismissRequest = onDismissRequest,
)
is LoginState.DialogState.Loading -> MifosLoadingDialog(
visibilityState = LoadingDialogState.Shown,
)
is LoginState.DialogState.Loading -> Unit
null -> Unit
}

View File

@ -10,7 +10,6 @@
package org.mifospay.feature.history
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
@ -18,22 +17,20 @@ import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import mobile_wallet.feature.history.generated.resources.Res
import mobile_wallet.feature.history.generated.resources.feature_history_empty
import mobile_wallet.feature.history.generated.resources.feature_history_error
import mobile_wallet.feature.history.generated.resources.feature_history_error_oops
import mobile_wallet.feature.history.generated.resources.feature_history_loading
import mobile_wallet.feature.history.generated.resources.feature_history_title
import org.jetbrains.compose.resources.stringResource
import org.koin.compose.viewmodel.koinViewModel
import org.mifospay.core.designsystem.component.MifosLoadingWheel
import org.mifospay.core.designsystem.component.MifosScaffold
import org.mifospay.core.designsystem.component.MifosTopBar
import org.mifospay.core.model.savingsaccount.TransactionType
import org.mifospay.core.ui.EmptyContentScreen
import org.mifospay.core.ui.MifosProgressIndicator
import org.mifospay.core.ui.utils.EventsEffect
import org.mifospay.feature.history.components.HistoryScreenFilter
import org.mifospay.feature.history.components.TransactionList
@ -88,18 +85,7 @@ internal fun HistoryScreenContent(
},
) { paddingValues ->
when (state.viewState) {
is HistoryState.ViewState.Loading -> {
Box(
modifier = Modifier
.fillMaxSize()
.padding(paddingValues),
contentAlignment = Alignment.Center,
) {
MifosLoadingWheel(
contentDesc = stringResource(Res.string.feature_history_loading),
)
}
}
is HistoryState.ViewState.Loading -> MifosProgressIndicator()
is HistoryState.ViewState.Error -> {
EmptyContentScreen(

View File

@ -23,15 +23,14 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
import mobile_wallet.feature.history.generated.resources.Res
import mobile_wallet.feature.history.generated.resources.feature_history_error
import mobile_wallet.feature.history.generated.resources.feature_history_error_oops
import mobile_wallet.feature.history.generated.resources.feature_history_loading
import mobile_wallet.feature.history.generated.resources.feature_history_share
import mobile_wallet.feature.history.generated.resources.feature_history_transaction_details
import org.jetbrains.compose.resources.stringResource
import org.koin.compose.viewmodel.koinViewModel
import org.mifospay.core.designsystem.component.MifosLoadingWheel
import org.mifospay.core.designsystem.component.MifosScaffold
import org.mifospay.core.designsystem.icon.MifosIcons
import org.mifospay.core.ui.EmptyContentScreen
import org.mifospay.core.ui.MifosProgressIndicator
import org.mifospay.core.ui.utils.EventsEffect
import org.mifospay.feature.history.components.TransactionDetail
import template.core.base.designsystem.theme.KptTheme
@ -91,12 +90,7 @@ internal fun TransactionDetailScreenContent(
contentAlignment = Alignment.Center,
) {
when (state) {
is TransactionDetailState.ViewState.Loading -> {
MifosLoadingWheel(
modifier = Modifier.align(Alignment.Center),
contentDesc = stringResource(Res.string.feature_history_loading),
)
}
is TransactionDetailState.ViewState.Loading -> MifosProgressIndicator()
is TransactionDetailState.ViewState.Error -> {
EmptyContentScreen(

View File

@ -80,7 +80,6 @@ import mobile_wallet.feature.home.generated.resources.feature_home_account_type
import mobile_wallet.feature.home.generated.resources.feature_home_arrow_up
import mobile_wallet.feature.home.generated.resources.feature_home_coin_image
import mobile_wallet.feature.home.generated.resources.feature_home_desc
import mobile_wallet.feature.home.generated.resources.feature_home_loading
import mobile_wallet.feature.home.generated.resources.feature_home_mark_default
import mobile_wallet.feature.home.generated.resources.feature_home_request
import mobile_wallet.feature.home.generated.resources.feature_home_request_money
@ -98,7 +97,6 @@ import org.koin.compose.viewmodel.koinViewModel
import org.mifospay.core.common.CurrencyFormatter
import org.mifospay.core.designsystem.component.BasicDialogState
import org.mifospay.core.designsystem.component.LoadingDialogState
import org.mifospay.core.designsystem.component.MfLoadingWheel
import org.mifospay.core.designsystem.component.MifosBasicDialog
import org.mifospay.core.designsystem.component.MifosLoadingDialog
import org.mifospay.core.designsystem.component.MifosScaffold
@ -108,6 +106,7 @@ import org.mifospay.core.designsystem.component.scrollbar.scrollbarState
import org.mifospay.core.designsystem.icon.MifosIcons
import org.mifospay.core.model.account.Account
import org.mifospay.core.ui.ErrorScreenContent
import org.mifospay.core.ui.MifosProgressIndicator
import org.mifospay.core.ui.MifosSmallChip
import org.mifospay.core.ui.TransactionHistoryCard
import org.mifospay.core.ui.utils.EventsEffect
@ -206,11 +205,7 @@ fun HomeScreenContent(
contentAlignment = Alignment.Center,
) {
when (viewState) {
is ViewState.Loading -> {
MfLoadingWheel(
contentDesc = stringResource(Res.string.feature_home_loading),
)
}
is ViewState.Loading -> MifosProgressIndicator()
is ViewState.Content -> {
HomeScreenContent(

View File

@ -80,7 +80,9 @@ class HomeViewModel(
ViewState.Error(Res.string.feature_home_no_account)
}
is DataState.Loading -> ViewState.Loading
is DataState.Loading -> {
ViewState.Loading
}
is DataState.Success -> {
mutableStateFlow.update {
@ -88,8 +90,9 @@ class HomeViewModel(
}
if (state.defaultAccountId == null && result.data.accounts.isNotEmpty()) {
val accountId = result.data.accounts.first().id
val accountNo = result.data.accounts.first().number
val account = result.data.accounts.first()
val accountId = account.id
val accountNo = account.number
sendAction(HomeAction.MarkAsDefault(accountId, accountNo))
}
@ -173,12 +176,16 @@ class HomeViewModel(
}
}
is HomeAction.OnRetryClicked -> mutableStateFlow.update {
it.copy(reloadTrigger = !it.reloadTrigger)
is HomeAction.OnRetryClicked -> {
mutableStateFlow.update {
it.copy(reloadTrigger = !it.reloadTrigger)
}
}
is HomeAction.OnPullToRefresh -> mutableStateFlow.update {
it.copy(isRefreshing = true, reloadTrigger = !it.reloadTrigger)
is HomeAction.OnPullToRefresh -> {
mutableStateFlow.update {
it.copy(isRefreshing = true, reloadTrigger = !it.reloadTrigger)
}
}
}
}

View File

@ -13,7 +13,6 @@ import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyListState
@ -28,14 +27,13 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
import mobile_wallet.feature.invoices.generated.resources.Res
import mobile_wallet.feature.invoices.generated.resources.feature_invoices_error_no_invoices_found
import mobile_wallet.feature.invoices.generated.resources.feature_invoices_error_oops
import mobile_wallet.feature.invoices.generated.resources.feature_invoices_loading
import mobile_wallet.feature.invoices.generated.resources.feature_invoices_unexpected_error_subtitle
import org.jetbrains.compose.resources.stringResource
import org.koin.compose.viewmodel.koinViewModel
import org.mifospay.core.designsystem.component.MifosLoadingWheel
import org.mifospay.core.designsystem.component.MifosScaffold
import org.mifospay.core.model.datatables.invoice.Invoice
import org.mifospay.core.ui.EmptyContentScreen
import org.mifospay.core.ui.MifosProgressIndicator
import org.mifospay.core.ui.utils.EventsEffect
import template.core.base.designsystem.theme.KptTheme
@ -81,12 +79,7 @@ private fun InvoiceScreen(
contentAlignment = Alignment.Center,
) {
when (invoiceUiState) {
is InvoicesUiState.Loading -> {
MifosLoadingWheel(
modifier = Modifier.fillMaxWidth(),
contentDesc = stringResource(Res.string.feature_invoices_loading),
)
}
is InvoicesUiState.Loading -> MifosProgressIndicator()
is InvoicesUiState.Empty -> {
EmptyContentScreen(

View File

@ -35,18 +35,17 @@ import mobile_wallet.feature.invoices.generated.resources.feature_invoices_consu
import mobile_wallet.feature.invoices.generated.resources.feature_invoices_date
import mobile_wallet.feature.invoices.generated.resources.feature_invoices_invoice_details
import mobile_wallet.feature.invoices.generated.resources.feature_invoices_items_bought
import mobile_wallet.feature.invoices.generated.resources.feature_invoices_loading
import mobile_wallet.feature.invoices.generated.resources.feature_invoices_merchant_id
import mobile_wallet.feature.invoices.generated.resources.feature_invoices_status
import mobile_wallet.feature.invoices.generated.resources.feature_invoices_transaction_id
import org.jetbrains.compose.resources.stringResource
import org.koin.compose.viewmodel.koinViewModel
import org.mifospay.core.common.Constants
import org.mifospay.core.designsystem.component.MifosLoadingWheel
import org.mifospay.core.designsystem.component.MifosScaffold
import org.mifospay.core.model.datatables.invoice.Invoice
import org.mifospay.core.ui.ErrorScreenContent
import org.mifospay.core.ui.MifosDivider
import org.mifospay.core.ui.MifosProgressIndicator
import org.mifospay.core.ui.utils.EventsEffect
import org.mifospay.feature.invoices.details.InvoiceDetailState.ViewState.Content
import org.mifospay.feature.invoices.details.InvoiceDetailState.ViewState.Error
@ -94,12 +93,7 @@ internal fun InvoiceDetailScreen(
contentAlignment = Alignment.Center,
) {
when (state) {
is Loading -> {
MifosLoadingWheel(
modifier = Modifier.align(Alignment.Center),
contentDesc = stringResource(Res.string.feature_invoices_loading),
)
}
is Loading -> MifosProgressIndicator()
is Error -> {
ErrorScreenContent(

View File

@ -37,14 +37,13 @@ import mobile_wallet.feature.kyc.generated.resources.Res
import mobile_wallet.feature.kyc.generated.resources.feature_kyc_check
import mobile_wallet.feature.kyc.generated.resources.feature_kyc_complete_kyc
import mobile_wallet.feature.kyc.generated.resources.feature_kyc_error_oops
import mobile_wallet.feature.kyc.generated.resources.feature_kyc_loading
import mobile_wallet.feature.kyc.generated.resources.feature_kyc_unexpected_error_subtitle
import org.jetbrains.compose.resources.stringResource
import org.koin.compose.viewmodel.koinViewModel
import org.mifospay.core.designsystem.component.MifosOverlayLoadingWheel
import org.mifospay.core.designsystem.icon.MifosIcons
import org.mifospay.core.ui.AvatarBox
import org.mifospay.core.ui.EmptyContentScreen
import org.mifospay.core.ui.MifosProgressIndicatorOverlay
import org.mifospay.core.ui.utils.EventsEffect
import template.core.base.designsystem.theme.KptTheme
@ -86,9 +85,7 @@ private fun KYCDescriptionScreen(
contentAlignment = Alignment.Center,
) {
when (kUiState) {
KYCDescriptionUiState.Loading -> {
MifosOverlayLoadingWheel(contentDesc = stringResource(Res.string.feature_kyc_loading))
}
KYCDescriptionUiState.Loading -> MifosProgressIndicatorOverlay()
is KYCDescriptionUiState.Error -> {
EmptyContentScreen(

View File

@ -15,7 +15,6 @@ import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import kotlinx.datetime.Clock
import kotlinx.serialization.Serializable
import kotlinx.serialization.Transient
import org.mifospay.core.common.DataState
@ -30,6 +29,8 @@ import org.mifospay.core.ui.utils.BaseViewModel
import org.mifospay.feature.kyc.KycLevel1Action.Internal.HandleLevel1Result
import org.mifospay.feature.kyc.KycLevel1Action.Internal.KycLevel1DetailsResult
import org.mifospay.feature.kyc.KycLevel1State.DialogState.Error
import kotlin.time.Clock
import kotlin.time.ExperimentalTime
internal class KYCLevel1ViewModel(
private val kycLevelRepository: KycLevelRepository,
@ -266,6 +267,7 @@ internal data class KycLevel1State(
val submitButtonText: String
get() = if (doesExist) "Update" else "Submit"
@OptIn(ExperimentalTime::class)
val initialDate = Clock.System.now().toEpochMilliseconds()
@Transient

View File

@ -50,11 +50,11 @@ import org.mifospay.core.designsystem.component.LoadingDialogState
import org.mifospay.core.designsystem.component.MifosBasicDialog
import org.mifospay.core.designsystem.component.MifosButton
import org.mifospay.core.designsystem.component.MifosLoadingDialog
import org.mifospay.core.designsystem.component.MifosLoadingWheel
import org.mifospay.core.designsystem.component.MifosScaffold
import org.mifospay.core.designsystem.component.MifosTextField
import org.mifospay.core.designsystem.icon.MifosIcons
import org.mifospay.core.ui.AvatarBox
import org.mifospay.core.ui.MifosProgressIndicator
import org.mifospay.core.ui.utils.EventsEffect
import template.core.base.designsystem.theme.KptTheme
@ -240,12 +240,7 @@ private fun DocumentPicker(
)
}
is AsyncImagePainter.State.Loading -> {
MifosLoadingWheel(
contentDesc = "Loading Image",
modifier = Modifier.align(Alignment.Center),
)
}
is AsyncImagePainter.State.Loading -> MifosProgressIndicator()
is AsyncImagePainter.State.Success -> {
SubcomposeAsyncImageContent(

View File

@ -46,7 +46,6 @@ import mobile_wallet.feature.make_transfer.generated.resources.feature_make_tran
import mobile_wallet.feature.make_transfer.generated.resources.feature_make_transfer_continue_button
import mobile_wallet.feature.make_transfer.generated.resources.feature_make_transfer_description_label
import mobile_wallet.feature.make_transfer.generated.resources.feature_make_transfer_from_account
import mobile_wallet.feature.make_transfer.generated.resources.feature_make_transfer_loading
import mobile_wallet.feature.make_transfer.generated.resources.feature_make_transfer_no_accounts_found
import mobile_wallet.feature.make_transfer.generated.resources.feature_make_transfer_oops_title
import mobile_wallet.feature.make_transfer.generated.resources.feature_make_transfer_review_title
@ -60,7 +59,6 @@ import org.mifospay.core.designsystem.component.MifosBasicDialog
import org.mifospay.core.designsystem.component.MifosBottomSheetScaffold
import org.mifospay.core.designsystem.component.MifosButton
import org.mifospay.core.designsystem.component.MifosLoadingDialog
import org.mifospay.core.designsystem.component.MifosLoadingWheel
import org.mifospay.core.designsystem.component.MifosTextField
import org.mifospay.core.designsystem.component.MifosTopBar
import org.mifospay.core.designsystem.icon.MifosIcons
@ -68,6 +66,7 @@ import org.mifospay.core.model.account.Account
import org.mifospay.core.model.utils.PaymentQrData
import org.mifospay.core.ui.AvatarBox
import org.mifospay.core.ui.EmptyContentScreen
import org.mifospay.core.ui.MifosProgressIndicator
import org.mifospay.core.ui.utils.EventsEffect
import template.core.base.designsystem.theme.KptTheme
@ -198,16 +197,7 @@ private fun AccountListState(
contentAlignment = Alignment.Center,
) {
when (state) {
is ViewState.Loading -> {
Box(modifier = Modifier.fillMaxWidth()) {
MifosLoadingWheel(
contentDesc = stringResource(Res.string.feature_make_transfer_loading),
modifier = Modifier
.align(Alignment.Center)
.padding(KptTheme.spacing.md),
)
}
}
is ViewState.Loading -> MifosProgressIndicator()
is ViewState.Empty -> {
EmptyContentScreen(

View File

@ -37,13 +37,11 @@ import mobile_wallet.feature.merchants.generated.resources.feature_merchants_clo
import mobile_wallet.feature.merchants.generated.resources.feature_merchants_empty_no_merchants_subtitle
import mobile_wallet.feature.merchants.generated.resources.feature_merchants_empty_no_merchants_title
import mobile_wallet.feature.merchants.generated.resources.feature_merchants_error_oops
import mobile_wallet.feature.merchants.generated.resources.feature_merchants_loading
import mobile_wallet.feature.merchants.generated.resources.feature_merchants_search
import mobile_wallet.feature.merchants.generated.resources.feature_merchants_unexpected_error_subtitle
import org.jetbrains.compose.resources.stringResource
import org.jetbrains.compose.ui.tooling.preview.Preview
import org.koin.compose.viewmodel.koinViewModel
import org.mifospay.core.designsystem.component.MfLoadingWheel
import org.mifospay.core.designsystem.component.MifosScaffold
import org.mifospay.core.designsystem.component.rememberMifosPullToRefreshState
import org.mifospay.core.designsystem.icon.MifosIcons
@ -57,6 +55,7 @@ import org.mifospay.core.model.savingsaccount.SubStatus
import org.mifospay.core.model.savingsaccount.Summary
import org.mifospay.core.model.savingsaccount.Timeline
import org.mifospay.core.ui.EmptyContentScreen
import org.mifospay.core.ui.MifosProgressIndicator
import org.mifospay.feature.merchants.MerchantUiState
import org.mifospay.feature.merchants.MerchantViewModel
import org.mifospay.feature.merchants.navigation.navigateToMerchantTransferScreen
@ -124,12 +123,7 @@ internal fun MerchantScreen(
)
}
MerchantUiState.Loading -> {
MfLoadingWheel(
contentDesc = stringResource(Res.string.feature_merchants_loading),
backgroundColor = KptTheme.colorScheme.surface,
)
}
MerchantUiState.Loading -> MifosProgressIndicator()
is MerchantUiState.ShowMerchants -> {
MerchantScreenContent(

View File

@ -49,7 +49,6 @@ import mobile_wallet.feature.merchants.generated.resources.feature_merchants_amo
import mobile_wallet.feature.merchants.generated.resources.feature_merchants_credits
import mobile_wallet.feature.merchants.generated.resources.feature_merchants_debits
import mobile_wallet.feature.merchants.generated.resources.feature_merchants_error_oops
import mobile_wallet.feature.merchants.generated.resources.feature_merchants_loading
import mobile_wallet.feature.merchants.generated.resources.feature_merchants_merchant_transaction
import mobile_wallet.feature.merchants.generated.resources.feature_merchants_no_transactions_found
import mobile_wallet.feature.merchants.generated.resources.feature_merchants_other
@ -63,7 +62,6 @@ import org.jetbrains.compose.ui.tooling.preview.Preview
import org.jetbrains.compose.ui.tooling.preview.PreviewParameter
import org.jetbrains.compose.ui.tooling.preview.PreviewParameterProvider
import org.koin.compose.viewmodel.koinViewModel
import org.mifospay.core.designsystem.component.MfLoadingWheel
import org.mifospay.core.designsystem.component.MifosBottomSheet
import org.mifospay.core.designsystem.component.MifosButton
import org.mifospay.core.designsystem.component.MifosOutlinedTextField
@ -74,6 +72,7 @@ import org.mifospay.core.model.savingsaccount.Currency
import org.mifospay.core.model.savingsaccount.Transaction
import org.mifospay.core.model.savingsaccount.TransactionType
import org.mifospay.core.ui.EmptyContentScreen
import org.mifospay.core.ui.MifosProgressIndicator
import org.mifospay.feature.merchants.MerchantTransferUiState
import org.mifospay.feature.merchants.MerchantTransferViewModel
import template.core.base.designsystem.theme.KptTheme
@ -122,12 +121,7 @@ internal fun MerchantTransferScreen(
contentAlignment = Alignment.Center,
) {
when (uiState) {
is MerchantTransferUiState.Loading -> {
MfLoadingWheel(
contentDesc = stringResource(Res.string.feature_merchants_loading),
backgroundColor = KptTheme.colorScheme.surface,
)
}
is MerchantTransferUiState.Loading -> MifosProgressIndicator()
is MerchantTransferUiState.Error -> {
EmptyContentScreen(

View File

@ -31,7 +31,6 @@ import androidx.compose.ui.graphics.Color
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import mobile_wallet.feature.notification.generated.resources.Res
import mobile_wallet.feature.notification.generated.resources.feature_notification_error_oops
import mobile_wallet.feature.notification.generated.resources.feature_notification_loading
import mobile_wallet.feature.notification.generated.resources.feature_notification_nothing_to_notify
import mobile_wallet.feature.notification.generated.resources.feature_notification_notifications
import mobile_wallet.feature.notification.generated.resources.feature_notification_there_is_nothing_to_show
@ -41,11 +40,11 @@ import org.jetbrains.compose.ui.tooling.preview.Preview
import org.jetbrains.compose.ui.tooling.preview.PreviewParameter
import org.jetbrains.compose.ui.tooling.preview.PreviewParameterProvider
import org.koin.compose.viewmodel.koinViewModel
import org.mifospay.core.designsystem.component.MfLoadingWheel
import org.mifospay.core.designsystem.component.MifosScaffold
import org.mifospay.core.designsystem.theme.MifosTheme
import org.mifospay.core.model.notification.Notification
import org.mifospay.core.ui.EmptyContentScreen
import org.mifospay.core.ui.MifosProgressIndicator
import template.core.base.designsystem.theme.KptTheme
@Composable
@ -92,13 +91,7 @@ internal fun NotificationScreen(
)
}
is NotificationUiState.Loading -> {
MfLoadingWheel(
contentDesc = stringResource(Res.string.feature_notification_loading),
modifier = Modifier.align(Alignment.Center),
backgroundColor = Color.Transparent,
)
}
is NotificationUiState.Loading -> MifosProgressIndicator()
is NotificationUiState.Success -> {
if (uiState.notificationList.isEmpty()) {

View File

@ -29,7 +29,6 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import mobile_wallet.feature.profile.generated.resources.Res
import mobile_wallet.feature.profile.generated.resources.feature_profile_loading
import mobile_wallet.feature.profile.generated.resources.feature_profile_personal_qr_code
import org.jetbrains.compose.resources.stringResource
import org.koin.compose.viewmodel.koinViewModel
@ -38,10 +37,10 @@ import org.mifospay.core.designsystem.component.LoadingDialogState
import org.mifospay.core.designsystem.component.MifosBasicDialog
import org.mifospay.core.designsystem.component.MifosButton
import org.mifospay.core.designsystem.component.MifosLoadingDialog
import org.mifospay.core.designsystem.component.MifosOverlayLoadingWheel
import org.mifospay.core.designsystem.component.MifosScaffold
import org.mifospay.core.designsystem.icon.MifosIcons
import org.mifospay.core.ui.ErrorScreenContent
import org.mifospay.core.ui.MifosProgressIndicatorOverlay
import org.mifospay.core.ui.utils.EventsEffect
import org.mifospay.feature.profile.components.ProfileDetailsCard
import org.mifospay.feature.profile.components.ProfileImage
@ -98,12 +97,7 @@ internal fun ProfileScreenContent(
contentAlignment = Alignment.Center,
) {
when (clientState) {
is ProfileState.ViewState.Loading -> {
MifosOverlayLoadingWheel(
contentDesc = stringResource(Res.string.feature_profile_loading),
modifier = Modifier.align(Alignment.Center),
)
}
is ProfileState.ViewState.Loading -> MifosProgressIndicatorOverlay()
is ProfileState.ViewState.Error -> {
ErrorScreenContent(

View File

@ -106,6 +106,7 @@ private fun EditProfileScreenContent(
onAction(EditProfileAction.NavigateBack)
},
snackbarHost = { SnackbarHost(snackbarHostState) },
containerColor = KptTheme.colorScheme.background,
) { paddingValues ->
LazyColumn(
modifier = modifier

View File

@ -18,13 +18,12 @@ import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import mobile_wallet.feature.receipt.generated.resources.Res
import mobile_wallet.feature.receipt.generated.resources.feature_receipt_loading
import mobile_wallet.feature.receipt.generated.resources.feature_receipt_receipt
import org.jetbrains.compose.resources.stringResource
import org.koin.compose.viewmodel.koinViewModel
import org.mifospay.core.designsystem.component.MifosLoadingWheel
import org.mifospay.core.designsystem.component.MifosScaffold
import org.mifospay.core.ui.EmptyContentScreen
import org.mifospay.core.ui.MifosProgressIndicator
import template.core.base.designsystem.theme.KptTheme
@Composable
@ -59,11 +58,7 @@ internal fun ReceiptScreen(
.padding(it),
) {
when (uiState) {
is ReceiptUiState.Loading -> {
MifosLoadingWheel(
contentDesc = stringResource(Res.string.feature_receipt_loading),
)
}
is ReceiptUiState.Loading -> MifosProgressIndicator()
is ReceiptUiState.Error -> {
EmptyContentScreen(

View File

@ -39,9 +39,9 @@ import org.koin.compose.viewmodel.koinViewModel
import org.mifospay.core.designsystem.component.LoadingDialogState
import org.mifospay.core.designsystem.component.MifosButton
import org.mifospay.core.designsystem.component.MifosLoadingDialog
import org.mifospay.core.designsystem.component.MifosLoadingWheel
import org.mifospay.core.designsystem.component.MifosOutlinedButton
import org.mifospay.core.designsystem.component.MifosScaffold
import org.mifospay.core.ui.MifosProgressIndicator
import org.mifospay.core.ui.utils.EventsEffect
import template.core.base.designsystem.theme.KptTheme
@ -117,9 +117,7 @@ internal fun ShowQrScreen(
contentAlignment = Alignment.Center,
) {
when (state.viewState) {
is ShowQrState.ViewState.Loading -> {
MifosLoadingWheel(contentDesc = "Loading")
}
is ShowQrState.ViewState.Loading -> MifosProgressIndicator()
is ShowQrState.ViewState.Content -> {
ShowQrScreenContent(

View File

@ -47,20 +47,19 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
import kotlinx.coroutines.launch
import mobile_wallet.feature.savedcards.generated.resources.Res
import mobile_wallet.feature.savedcards.generated.resources.feature_savedcards_error_oops
import mobile_wallet.feature.savedcards.generated.resources.feature_savedcards_loading
import mobile_wallet.feature.savedcards.generated.resources.feature_savedcards_subtitle
import org.jetbrains.compose.resources.stringResource
import org.jetbrains.compose.resources.vectorResource
import org.koin.compose.viewmodel.koinViewModel
import org.mifospay.core.designsystem.component.BasicDialogState
import org.mifospay.core.designsystem.component.LoadingDialogState
import org.mifospay.core.designsystem.component.MfLoadingWheel
import org.mifospay.core.designsystem.component.MifosBasicDialog
import org.mifospay.core.designsystem.component.MifosLoadingDialog
import org.mifospay.core.designsystem.component.MifosScaffold
import org.mifospay.core.designsystem.icon.MifosIcons
import org.mifospay.core.model.savedcards.SavedCard
import org.mifospay.core.ui.EmptyContentScreen
import org.mifospay.core.ui.MifosProgressIndicator
import org.mifospay.core.ui.utils.EventsEffect
import org.mifospay.feature.savedcards.createOrUpdate.CardAddEditType
import org.mifospay.feature.savedcards.utils.CreditCardUtils.detectCardType
@ -180,11 +179,7 @@ internal fun CardsScreen(
contentAlignment = Alignment.Center,
) {
when (state) {
is ViewState.Loading -> {
MfLoadingWheel(
contentDesc = stringResource(Res.string.feature_savedcards_loading),
)
}
is ViewState.Loading -> MifosProgressIndicator()
is ViewState.Empty -> {
EmptyContentScreen(

View File

@ -40,15 +40,14 @@ import androidx.compose.ui.unit.sp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import mobile_wallet.feature.savedcards.generated.resources.Res
import mobile_wallet.feature.savedcards.generated.resources.feature_savedcards_error_oops
import mobile_wallet.feature.savedcards.generated.resources.feature_savedcards_loading
import mobile_wallet.feature.savedcards.generated.resources.feature_savedcards_subtitle
import org.jetbrains.compose.resources.stringResource
import org.koin.compose.viewmodel.koinViewModel
import org.mifospay.core.designsystem.component.MfLoadingWheel
import org.mifospay.core.designsystem.component.MifosScaffold
import org.mifospay.core.model.savedcards.SavedCard
import org.mifospay.core.ui.EmptyContentScreen
import org.mifospay.core.ui.MifosDivider
import org.mifospay.core.ui.MifosProgressIndicator
import org.mifospay.core.ui.utils.EventsEffect
import org.mifospay.feature.savedcards.components.CreditCard
import org.mifospay.feature.savedcards.utils.CardMaskStyle
@ -98,12 +97,7 @@ internal fun CardDetailScreen(
contentAlignment = Alignment.Center,
) {
when (state) {
is ViewState.Loading -> {
MfLoadingWheel(
contentDesc = stringResource(Res.string.feature_savedcards_loading),
backgroundColor = KptTheme.colorScheme.surface,
)
}
is ViewState.Loading -> MifosProgressIndicator()
is ViewState.Error -> {
EmptyContentScreen(

View File

@ -10,7 +10,6 @@
package org.mifospay.feature.savedcards.utils
import androidx.compose.ui.graphics.Color
import kotlinx.datetime.Clock
import kotlinx.datetime.LocalDate
import kotlinx.datetime.Month
import kotlinx.datetime.TimeZone
@ -24,6 +23,8 @@ import mobile_wallet.feature.savedcards.generated.resources.ic_visa
import mobile_wallet.feature.savedcards.generated.resources.maestro
import mobile_wallet.feature.savedcards.generated.resources.rupay_logo
import org.jetbrains.compose.resources.DrawableResource
import kotlin.time.Clock
import kotlin.time.ExperimentalTime
object CreditCardUtils {
// Extension function for card type detection
@ -109,12 +110,12 @@ object CreditCardUtils {
}
}
@OptIn(ExperimentalTime::class)
fun isValid(): Boolean {
if (month !in 1..12) return false
val now = Clock.System.now()
.toLocalDateTime(TimeZone.currentSystemDefault())
.date
val expiryDate = LocalDate(
year = year,
@ -124,7 +125,7 @@ object CreditCardUtils {
// Check if card is not expired
// Add 1 month because cards typically expire at the end of the month
return now.monthsUntil(expiryDate) >= -1
return now.date.monthsUntil(expiryDate) >= -1
}
}

View File

@ -61,12 +61,12 @@ import org.mifospay.core.designsystem.component.BasicDialogState
import org.mifospay.core.designsystem.component.LoadingDialogState
import org.mifospay.core.designsystem.component.MifosBasicDialog
import org.mifospay.core.designsystem.component.MifosLoadingDialog
import org.mifospay.core.designsystem.component.MifosLoadingWheel
import org.mifospay.core.designsystem.component.MifosScaffold
import org.mifospay.core.designsystem.icon.MifosIcons
import org.mifospay.core.designsystem.theme.toRoundedCornerShape
import org.mifospay.core.model.standinginstruction.StandingInstruction
import org.mifospay.core.ui.EmptyContentScreen
import org.mifospay.core.ui.MifosProgressIndicator
import org.mifospay.core.ui.RevealDirection
import org.mifospay.core.ui.RevealSwipe
import org.mifospay.core.ui.rememberRevealState
@ -179,9 +179,7 @@ internal fun StandingInstructionScreen(
contentAlignment = Alignment.Center,
) {
when (state) {
is SIViewState.Loading -> {
MifosLoadingWheel(contentDesc = "Loading")
}
is SIViewState.Loading -> MifosProgressIndicator()
is SIViewState.Error -> {
EmptyContentScreen(

View File

@ -61,7 +61,6 @@ import org.mifospay.core.designsystem.component.LoadingDialogState
import org.mifospay.core.designsystem.component.MifosBasicDialog
import org.mifospay.core.designsystem.component.MifosButton
import org.mifospay.core.designsystem.component.MifosLoadingDialog
import org.mifospay.core.designsystem.component.MifosLoadingWheel
import org.mifospay.core.designsystem.component.MifosScaffold
import org.mifospay.core.designsystem.component.MifosTextField
import org.mifospay.core.designsystem.icon.MifosIcons
@ -74,6 +73,7 @@ import org.mifospay.core.ui.DropdownBoxItem
import org.mifospay.core.ui.EmptyContentScreen
import org.mifospay.core.ui.ExposedDropdownBox
import org.mifospay.core.ui.MifosDivider
import org.mifospay.core.ui.MifosProgressIndicator
import org.mifospay.core.ui.utils.EventsEffect
import template.core.base.designsystem.theme.KptTheme
@ -168,9 +168,7 @@ internal fun AddEditSIScreen(
contentAlignment = Alignment.Center,
) {
when (state.viewState) {
is AddEditSIState.ViewState.Loading -> {
MifosLoadingWheel(contentDesc = "Loading")
}
is AddEditSIState.ViewState.Loading -> MifosProgressIndicator()
is AddEditSIState.ViewState.Error -> {
EmptyContentScreen(

View File

@ -20,7 +20,6 @@ import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import kotlinx.datetime.Clock
import kotlinx.serialization.Serializable
import kotlinx.serialization.Transient
import org.mifospay.core.common.DataState
@ -42,6 +41,8 @@ import org.mifospay.feature.standing.instruction.createOrUpdate.AddEditSIAction.
import org.mifospay.feature.standing.instruction.createOrUpdate.AddEditSIAction.Internal.HandleTemplateResult
import org.mifospay.feature.standing.instruction.createOrUpdate.AddEditSIAction.Internal.LoadClientAccount
import org.mifospay.feature.standing.instruction.createOrUpdate.AddEditSIState.DialogState.Error
import kotlin.time.Clock
import kotlin.time.ExperimentalTime
internal class AddEditSIViewModel(
private val repository: StandingInstructionRepository,
@ -580,6 +581,7 @@ internal data class AddEditSIState(
it.id == payload.recurrenceFrequency
}?.value ?: ""
@OptIn(ExperimentalTime::class)
@Transient
val initialDate = Clock.System.now().toEpochMilliseconds()

View File

@ -38,11 +38,11 @@ import org.jetbrains.compose.resources.stringResource
import org.koin.compose.viewmodel.koinViewModel
import org.mifospay.core.common.CurrencyFormatter
import org.mifospay.core.common.DateHelper
import org.mifospay.core.designsystem.component.MifosLoadingWheel
import org.mifospay.core.designsystem.component.MifosScaffold
import org.mifospay.core.model.standinginstruction.StandingInstruction
import org.mifospay.core.ui.EmptyContentScreen
import org.mifospay.core.ui.MifosDivider
import org.mifospay.core.ui.MifosProgressIndicator
import org.mifospay.core.ui.utils.EventsEffect
import org.mifospay.feature.standing.instruction.components.FrequencyChip
import org.mifospay.feature.standing.instruction.components.InstructionTypeChip
@ -92,9 +92,7 @@ internal fun SIDetailsScreen(
contentAlignment = Alignment.Center,
) {
when (state.viewState) {
is ViewState.Loading -> {
MifosLoadingWheel(contentDesc = "Loading")
}
is ViewState.Loading -> MifosProgressIndicator()
is ViewState.Error -> {
EmptyContentScreen(

View File

@ -14,18 +14,16 @@ import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import org.jetbrains.compose.ui.tooling.preview.Preview
import org.koin.compose.viewmodel.koinViewModel
import org.mifospay.core.designsystem.component.MifosLoadingWheel
import org.mifospay.core.designsystem.theme.MifosTheme
import org.mifospay.core.ui.MifosProgressIndicatorOverlay
import org.mifospay.core.ui.VerifyStepHeader
import org.mifospay.feature.upi.setup.viewmodel.DebitCardUiState
import org.mifospay.feature.upi.setup.viewmodel.DebitCardViewModel
@ -99,14 +97,7 @@ internal fun DebitCardScreenWithHeaderAndContent(
is DebitCardUiState.Initials -> {
}
is DebitCardUiState.Verifying -> {
MifosLoadingWheel(
modifier = Modifier
.wrapContentSize()
.align(Alignment.Center),
contentDesc = "Verifying Debit Card",
)
}
is DebitCardUiState.Verifying -> MifosProgressIndicatorOverlay()
is DebitCardUiState.Verified -> {
onDebitCardVerified((debitCardUiState).otp)

View File

@ -65,6 +65,8 @@ credentialsVersion = "1.5.0"
review = "2.0.2"
appUpdate = "2.1.0"
integrity = "1.4.0"
lottie = "6.6.7"
compottie = "2.0.0-rc05"
# Static Analysis & Code Formatting
ktlint = "12.1.1"
@ -85,7 +87,7 @@ firebasePerfPlugin = "1.4.2"
kotlin = "2.1.20"
kotlinInject = "0.7.2"
kotlinxCoroutines = "1.9.0"
kotlinxDatetime = "0.6.2"
kotlinxDatetime = "0.7.1"
kotlinxImmutable = "0.3.8"
kotlinxSerializationJson = "1.8.1"
ksp = "2.1.20-2.0.1"
@ -347,6 +349,12 @@ filekit-dialogs-compose = { module = "io.github.vinceglb:filekit-dialogs-compose
filekit-coil = { module = "io.github.vinceglb:filekit-coil", version.ref = "fileKit" }
filekit-compose = { group = "io.github.vinceglb", name = "filekit-compose", version.ref = "fileKitCompose" }
qrose = { group = "io.github.alexzhirkevich", name="qrose", version.ref = "qroseVersion" }
lottie-compose = { group = "com.airbnb.android", name = "lottie-compose", version.ref = "lottie" }
compottie = { module = "io.github.alexzhirkevich:compottie", version.ref = "compottie" }
compottie-lite = { module = "io.github.alexzhirkevich:compottie-lite", version.ref = "compottie" }
compottie-dot = { module = "io.github.alexzhirkevich:compottie-dot", version.ref = "compottie" }
compottie-network = { module = "io.github.alexzhirkevich:compottie-network", version.ref = "compottie" }
compottie-resources = { module = "io.github.alexzhirkevich:compottie-resources", version.ref = "compottie" }
kermit-logging = { group = "co.touchlab", name = "kermit", version.ref = "kermit" }
kermit-simple = { group = "co.touchlab", name = "kermit-simple", version.ref = "kermit" }