Browse Source

Increment version to 1.3.1, updating versionCode to 6 in build.gradle.kts. Introduce AppLifecycleState for managing app background state, and integrate it into MainActivity, DashboardScreenModel, WalletScreenModel, and WorkersScreenModel to trigger data refresh on app resume. Refactor DashboardContent for improved readability.

codeskraps 1 day ago
parent
commit
b7fcd4fe82

+ 3 - 2
app/build.gradle.kts

@@ -15,8 +15,9 @@ android {
         applicationId = "com.codeskraps.publicpool"
         minSdk = 26
         targetSdk = 35
-        versionCode = 5
-        versionName = "1.3.0"
+        versionCode = 6
+        versionName = "1.3.1"
+        setProperty("archivesBaseName", "publicpool-v$versionName.$versionCode")
 
         testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
         vectorDrawables {

+ 12 - 0
app/src/main/java/com/codeskraps/publicpool/MainActivity.kt

@@ -28,6 +28,7 @@ import cafe.adriel.voyager.navigator.Navigator
 import cafe.adriel.voyager.navigator.tab.LocalTabNavigator
 import cafe.adriel.voyager.navigator.tab.Tab
 import cafe.adriel.voyager.navigator.tab.TabNavigator
+import com.codeskraps.publicpool.di.AppLifecycleState
 import com.codeskraps.publicpool.di.AppReadinessState
 import com.codeskraps.publicpool.presentation.navigation.DashboardTab
 import com.codeskraps.publicpool.presentation.navigation.WalletTab
@@ -37,6 +38,7 @@ import org.koin.android.ext.android.inject
 
 class MainActivity : ComponentActivity() {
     val appReadinessState: AppReadinessState by inject()
+    val appLifecycleState: AppLifecycleState by inject()
 
     override fun onCreate(savedInstanceState: Bundle?) {
         installSplashScreen()
@@ -56,6 +58,16 @@ class MainActivity : ComponentActivity() {
         }
     }
 
+    override fun onPause() {
+        super.onPause()
+        appLifecycleState.setAppInBackground(true)
+    }
+
+    override fun onResume() {
+        super.onResume()
+        appLifecycleState.setAppInBackground(false)
+    }
+
     private fun setupSplashScreenKeepCondition() {
         val content: View = findViewById(android.R.id.content)
         content.viewTreeObserver.addOnPreDrawListener(

+ 14 - 0
app/src/main/java/com/codeskraps/publicpool/di/AppLifecycleState.kt

@@ -0,0 +1,14 @@
+package com.codeskraps.publicpool.di
+
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.asStateFlow
+
+class AppLifecycleState {
+    private val _isAppInBackground = MutableStateFlow(false)
+    val isAppInBackground: StateFlow<Boolean> = _isAppInBackground.asStateFlow()
+
+    fun setAppInBackground(value: Boolean) {
+        _isAppInBackground.value = value
+    }
+} 

+ 3 - 0
app/src/main/java/com/codeskraps/publicpool/di/AppModule.kt

@@ -18,4 +18,7 @@ val appModule = module {
     
     // Provide AppReadinessState as a singleton
     singleOf(::AppReadinessState)
+    
+    // Provide AppLifecycleState as a singleton
+    singleOf(::AppLifecycleState)
 } 

+ 3 - 1
app/src/main/java/com/codeskraps/publicpool/presentation/dashboard/DashboardContent.kt

@@ -125,7 +125,9 @@ fun DashboardContent(screenModel: DashboardScreenModel) {
     ) { paddingValues ->
         PullToRefreshBox(
             isRefreshing = state.isLoading,
-            onRefresh = { screenModel.handleEvent(DashboardEvent.RefreshData) },
+            onRefresh = { 
+                screenModel.handleEvent(DashboardEvent.RefreshData)
+            },
             modifier = Modifier
                 .fillMaxSize()
                 .padding(

+ 13 - 1
app/src/main/java/com/codeskraps/publicpool/presentation/dashboard/DashboardScreenModel.kt

@@ -10,6 +10,7 @@ import com.codeskraps.publicpool.domain.usecase.GetNetworkInfoUseCase
 import com.codeskraps.publicpool.domain.usecase.GetWalletAddressUseCase
 import com.codeskraps.publicpool.domain.usecase.TrackPageViewUseCase
 import com.codeskraps.publicpool.domain.usecase.TrackEventUseCase
+import com.codeskraps.publicpool.di.AppLifecycleState
 import com.codeskraps.publicpool.di.AppReadinessState
 import kotlinx.coroutines.Job
 import kotlinx.coroutines.channels.Channel
@@ -24,7 +25,8 @@ class DashboardScreenModel(
     private val calculateTwoHourAverageUseCase: CalculateTwoHourAverageUseCase,
     private val trackPageViewUseCase: TrackPageViewUseCase,
     private val trackEventUseCase: TrackEventUseCase,
-    private val appReadinessState: AppReadinessState
+    private val appReadinessState: AppReadinessState,
+    private val appLifecycleState: AppLifecycleState
 ) : StateScreenModel<DashboardState>(DashboardState()) {
 
     private val _effect = Channel<DashboardEffect>()
@@ -35,6 +37,16 @@ class DashboardScreenModel(
     init {
         // Start loading data immediately
         handleEvent(DashboardEvent.LoadData)
+
+        // Observe app lifecycle state
+        screenModelScope.launch {
+            appLifecycleState.isAppInBackground.collect { isInBackground ->
+                if (!isInBackground) {
+                    // App came back to foreground, trigger refresh
+                    handleEvent(DashboardEvent.RefreshData)
+                }
+            }
+        }
     }
 
     fun handleEvent(event: DashboardEvent) {

+ 13 - 1
app/src/main/java/com/codeskraps/publicpool/presentation/wallet/WalletScreenModel.kt

@@ -7,6 +7,7 @@ import com.codeskraps.publicpool.domain.usecase.GetWalletAddressUseCase
 import com.codeskraps.publicpool.domain.usecase.GetBtcPriceUseCase
 import com.codeskraps.publicpool.domain.usecase.TrackPageViewUseCase
 import com.codeskraps.publicpool.domain.usecase.TrackEventUseCase
+import com.codeskraps.publicpool.di.AppLifecycleState
 import kotlinx.coroutines.channels.Channel
 import kotlinx.coroutines.flow.*
 import kotlinx.coroutines.launch
@@ -17,7 +18,8 @@ class WalletScreenModel(
     private val getBlockchainWalletInfoUseCase: GetBlockchainWalletInfoUseCase,
     private val getBtcPriceUseCase: GetBtcPriceUseCase,
     private val trackPageViewUseCase: TrackPageViewUseCase,
-    private val trackEventUseCase: TrackEventUseCase
+    private val trackEventUseCase: TrackEventUseCase,
+    private val appLifecycleState: AppLifecycleState
 ) : StateScreenModel<WalletState>(WalletState()) {
 
     private val _effect = Channel<WalletEffect>()
@@ -26,6 +28,16 @@ class WalletScreenModel(
     init {
         // Start loading wallet address immediately
         handleEvent(WalletEvent.LoadWalletDetails)
+
+        // Observe app lifecycle state
+        screenModelScope.launch {
+            appLifecycleState.isAppInBackground.collect { isInBackground ->
+                if (!isInBackground) {
+                    // App came back to foreground, trigger refresh
+                    handleEvent(WalletEvent.LoadWalletDetails)
+                }
+            }
+        }
     }
 
     fun handleEvent(event: WalletEvent) {

+ 13 - 1
app/src/main/java/com/codeskraps/publicpool/presentation/workers/WorkersScreenModel.kt

@@ -6,6 +6,7 @@ import com.codeskraps.publicpool.domain.usecase.GetClientInfoUseCase
 import com.codeskraps.publicpool.domain.usecase.GetWalletAddressUseCase
 import com.codeskraps.publicpool.domain.usecase.TrackEventUseCase
 import com.codeskraps.publicpool.domain.usecase.TrackPageViewUseCase
+import com.codeskraps.publicpool.di.AppLifecycleState
 import kotlinx.coroutines.channels.Channel
 import kotlinx.coroutines.flow.catch
 import kotlinx.coroutines.flow.onStart
@@ -17,7 +18,8 @@ class WorkersScreenModel(
     private val getWalletAddressUseCase: GetWalletAddressUseCase,
     private val getClientInfoUseCase: GetClientInfoUseCase,
     private val trackPageViewUseCase: TrackPageViewUseCase,
-    private val trackEventUseCase: TrackEventUseCase
+    private val trackEventUseCase: TrackEventUseCase,
+    private val appLifecycleState: AppLifecycleState
 ) : StateScreenModel<WorkersState>(WorkersState()) {
 
     private val _effect = Channel<WorkersEffect>()
@@ -26,6 +28,16 @@ class WorkersScreenModel(
     init {
         // Start loading wallet address immediately
         handleEvent(WorkersEvent.LoadWorkers)
+
+        // Observe app lifecycle state
+        screenModelScope.launch {
+            appLifecycleState.isAppInBackground.collect { isInBackground ->
+                if (!isInBackground) {
+                    // App came back to foreground, trigger refresh
+                    handleEvent(WorkersEvent.LoadWorkers)
+                }
+            }
+        }
     }
 
     fun handleEvent(event: WorkersEvent) {