diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 32e4bab..e13f759 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -27,8 +27,8 @@ android { applicationId = "com.ledga.app" minSdk = 26 targetSdk = 34 - versionCode = 7 - versionName = "1.3.4" + versionCode = 8 + versionName = "1.3.5" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" } diff --git a/app/src/main/java/com/ledga/app/ui/home/HomeViewModel.kt b/app/src/main/java/com/ledga/app/ui/home/HomeViewModel.kt index 75b07e9..3a64461 100644 --- a/app/src/main/java/com/ledga/app/ui/home/HomeViewModel.kt +++ b/app/src/main/java/com/ledga/app/ui/home/HomeViewModel.kt @@ -51,7 +51,7 @@ data class HomeUiState( val donutSegments: List = emptyList(), val categoryBreakdown: List = emptyList(), val recentTransactions: List = emptyList(), - val selectedPeriod: Period = Period.THIS_MONTH, + val selectedPeriod: Period = Period.TODAY, val monthLabel: String = "", val updateAvailable: GitHubRelease? = null, /** True when the background worker has already downloaded the APK. */ @@ -99,7 +99,7 @@ class HomeViewModel @Inject constructor( } } - private val _selectedPeriod = MutableStateFlow(Period.THIS_MONTH) + private val _selectedPeriod = MutableStateFlow(Period.TODAY) private val timeRange = _selectedPeriod.flatMapLatest { period -> val now = System.currentTimeMillis() diff --git a/app/src/main/java/com/ledga/app/ui/settings/SettingsViewModel.kt b/app/src/main/java/com/ledga/app/ui/settings/SettingsViewModel.kt index 057a2c0..0b31ee8 100644 --- a/app/src/main/java/com/ledga/app/ui/settings/SettingsViewModel.kt +++ b/app/src/main/java/com/ledga/app/ui/settings/SettingsViewModel.kt @@ -112,10 +112,20 @@ class SettingsViewModel @Inject constructor( private val _reparseAllResult = MutableStateFlow(null) val reparseAllResult: StateFlow = _reparseAllResult + private val _reparseAllRunning = MutableStateFlow(false) + val reparseAllRunning: StateFlow = _reparseAllRunning + /** Re-runs MpesaSmsParser over every stored row to pick up parser fixes. */ fun reparseAll() { + if (_reparseAllRunning.value) return + _reparseAllRunning.value = true + _reparseAllResult.value = null viewModelScope.launch { - _reparseAllResult.value = transactionRepository.reparseAllTransactions() + try { + _reparseAllResult.value = transactionRepository.reparseAllTransactions() + } finally { + _reparseAllRunning.value = false + } } } diff --git a/app/src/main/java/com/ledga/app/ui/you/YouScreen.kt b/app/src/main/java/com/ledga/app/ui/you/YouScreen.kt index 7a98e47..fb2c432 100644 --- a/app/src/main/java/com/ledga/app/ui/you/YouScreen.kt +++ b/app/src/main/java/com/ledga/app/ui/you/YouScreen.kt @@ -76,6 +76,7 @@ fun YouScreen( val importStatus by viewModel.importStatus.collectAsState() val reparseResult by viewModel.reparseResult.collectAsState() val reparseAllResult by viewModel.reparseAllResult.collectAsState() + val reparseAllRunning by viewModel.reparseAllRunning.collectAsState() val exportResult by viewModel.exportResult.collectAsState() val fileImportResult by viewModel.fileImportResult.collectAsState() val backupStatus by viewModel.backupStatus.collectAsState() @@ -216,11 +217,35 @@ fun YouScreen( } TextButtonRow("View unparsed messages", onNavigateToUnparsed) } - TextButtonRow("Re-parse ALL transactions") { - viewModel.reparseAll() + if (reparseAllRunning) { + Row( + modifier = Modifier + .fillMaxWidth() + .padding(vertical = 10.dp), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.spacedBy(10.dp), + ) { + androidx.compose.material3.CircularProgressIndicator( + modifier = Modifier.size(16.dp), + strokeWidth = 2.dp, + color = LedgaAccent, + ) + Text( + text = "Re-parsing all transactions…", + style = LedgaText.BodyL, + color = MaterialTheme.colorScheme.onSurface, + ) + } + } else { + TextButtonRow("Re-parse ALL transactions") { + viewModel.reparseAll() + } } reparseAllResult?.let { - StatusLine("Re-parsed ${it.fixed} of ${it.total} (${it.stillUnknown} skipped)") + StatusLine( + if (it.total == 0) "No transactions yet — try Import SMS history first." + else "Re-parsed ${it.fixed} of ${it.total} (${it.stillUnknown} skipped)" + ) } }