From 00975aa7cce9b17ff69662eba226edde340bdd45 Mon Sep 17 00:00:00 2001 From: ngenohkevin Date: Sat, 21 Mar 2026 22:35:00 +0300 Subject: [PATCH] Fix update notification: add banner UI + reset rate limit on version change --- .../java/com/ledga/app/ui/home/HomeScreen.kt | 40 ++++++++++++++++++- .../com/ledga/app/ui/home/HomeViewModel.kt | 2 + .../com/ledga/app/worker/UpdateCheckWorker.kt | 15 ++++++- 3 files changed, 54 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/ledga/app/ui/home/HomeScreen.kt b/app/src/main/java/com/ledga/app/ui/home/HomeScreen.kt index 529a6cf..a1bbb5d 100644 --- a/app/src/main/java/com/ledga/app/ui/home/HomeScreen.kt +++ b/app/src/main/java/com/ledga/app/ui/home/HomeScreen.kt @@ -38,6 +38,7 @@ import com.ledga.app.ui.components.TransactionCard import com.ledga.app.ui.components.categoryIcon import com.ledga.app.ui.components.parseColor import com.ledga.app.ui.theme.MpesaGreen +import com.ledga.app.ui.theme.MpesaGreenDark import com.ledga.app.util.CurrencyFormatter @Composable @@ -52,9 +53,46 @@ fun HomeScreen( .padding(horizontal = 16.dp), verticalArrangement = Arrangement.spacedBy(16.dp) ) { + // Update banner + if (state.updateAvailable != null) { + item { + Spacer(modifier = Modifier.height(12.dp)) + Card( + modifier = Modifier.fillMaxWidth(), + shape = RoundedCornerShape(16.dp), + colors = CardDefaults.cardColors( + containerColor = MpesaGreenDark + ) + ) { + Row( + modifier = Modifier + .fillMaxWidth() + .padding(16.dp), + verticalAlignment = Alignment.CenterVertically + ) { + Column(modifier = Modifier.weight(1f)) { + Text( + text = "Update Available", + style = MaterialTheme.typography.titleSmall, + fontWeight = FontWeight.Bold, + color = androidx.compose.ui.graphics.Color.White + ) + Text( + text = "Version ${state.updateAvailable!!.tag_name}", + style = MaterialTheme.typography.bodySmall, + color = androidx.compose.ui.graphics.Color.White.copy(alpha = 0.8f) + ) + } + } + } + } + } + // Greeting item { - Spacer(modifier = Modifier.height(12.dp)) + if (state.updateAvailable == null) { + Spacer(modifier = Modifier.height(12.dp)) + } Text( text = state.greeting, style = MaterialTheme.typography.headlineMedium, 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 4e2ca57..e6d1210 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 @@ -128,6 +128,8 @@ class HomeViewModel @Inject constructor( donutSegments = segments, categoryBreakdown = breakdown ) + }.combine(_updateAvailable) { state, update -> + state.copy(updateAvailable = update) }.stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), HomeUiState()) fun selectPeriod(period: Period) { diff --git a/app/src/main/java/com/ledga/app/worker/UpdateCheckWorker.kt b/app/src/main/java/com/ledga/app/worker/UpdateCheckWorker.kt index 7806d36..f8581af 100644 --- a/app/src/main/java/com/ledga/app/worker/UpdateCheckWorker.kt +++ b/app/src/main/java/com/ledga/app/worker/UpdateCheckWorker.kt @@ -47,6 +47,7 @@ object UpdateChecker { private val json = Json { ignoreUnknownKeys = true } private const val PREFS_NAME = "update_prefs" private const val LAST_CHECK_KEY = "last_check" + private const val LAST_VERSION_KEY = "last_version" suspend fun checkForUpdate( context: Context, @@ -54,11 +55,21 @@ object UpdateChecker { repo: String, currentVersion: String ): GitHubRelease? = withContext(Dispatchers.IO) { - // Rate limit: max once per day val prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE) val lastCheck = prefs.getLong(LAST_CHECK_KEY, 0) + val lastVersion = prefs.getString(LAST_VERSION_KEY, "") ?: "" val oneDayMs = 24 * 60 * 60 * 1000L - if (System.currentTimeMillis() - lastCheck < oneDayMs) return@withContext null + + // Reset rate limit if app version changed (just updated) + val versionChanged = lastVersion != currentVersion + if (versionChanged) { + prefs.edit().putString(LAST_VERSION_KEY, currentVersion).apply() + } + + // Rate limit: max once per day (skip if version just changed) + if (!versionChanged && System.currentTimeMillis() - lastCheck < oneDayMs) { + return@withContext null + } prefs.edit().putLong(LAST_CHECK_KEY, System.currentTimeMillis()).apply()