diff --git a/app/src/main/java/com/bitchat/android/ui/GeohashViewModel.kt b/app/src/main/java/com/bitchat/android/ui/GeohashViewModel.kt index 0db0a580..9aafe488 100644 --- a/app/src/main/java/com/bitchat/android/ui/GeohashViewModel.kt +++ b/app/src/main/java/com/bitchat/android/ui/GeohashViewModel.kt @@ -3,6 +3,10 @@ package com.bitchat.android.ui import android.app.Application import android.util.Log import androidx.lifecycle.AndroidViewModel +import androidx.lifecycle.DefaultLifecycleObserver +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.LifecycleOwner +import androidx.lifecycle.ProcessLifecycleOwner import androidx.lifecycle.viewModelScope import com.bitchat.android.nostr.GeohashMessageHandler import com.bitchat.android.nostr.GeohashRepository @@ -31,7 +35,7 @@ class GeohashViewModel( private val meshDelegateHandler: MeshDelegateHandler, private val dataManager: DataManager, private val notificationManager: NotificationManager -) : AndroidViewModel(application) { +) : AndroidViewModel(application), DefaultLifecycleObserver { companion object { private const val TAG = "GeohashViewModel" } @@ -68,6 +72,10 @@ class GeohashViewModel( fun initialize() { subscriptionManager.connect() + // Observe process lifecycle to manage background sampling + kotlin.runCatching { + ProcessLifecycleOwner.get().lifecycle.addObserver(this) + } val identity = NostrIdentityBridge.getCurrentNostrIdentity(getApplication()) if (identity != null) { // Use global chat-messages only for full account DMs (mesh context). For geohash DMs, subscribe per-geohash below. @@ -235,15 +243,11 @@ class GeohashViewModel( } // Add new subscriptions - toAdd.forEach { geohash -> - subscriptionManager.subscribeGeohash( - geohash = geohash, - sinceMs = System.currentTimeMillis() - 86400000L, - limit = 200, - id = "sampling-$geohash", - handler = { event -> geohashMessageHandler.onEvent(event, geohash) } - ) - activeSamplingGeohashes.add(geohash) + activeSamplingGeohashes.addAll(toAdd) + if (isAppInForeground()) { + toAdd.forEach { geohash -> + performSubscribeSampling(geohash) + } } } @@ -379,4 +383,35 @@ class GeohashViewModel( } } } + + override fun onCleared() { + super.onCleared() + kotlin.runCatching { + ProcessLifecycleOwner.get().lifecycle.removeObserver(this) + } + } + + override fun onStart(owner: LifecycleOwner) { + Log.d(TAG, "🌍 App foregrounded: Resuming sampling for ${activeSamplingGeohashes.size} geohashes") + activeSamplingGeohashes.forEach { performSubscribeSampling(it) } + } + + override fun onStop(owner: LifecycleOwner) { + Log.d(TAG, "🌍 App backgrounded: Pausing sampling for ${activeSamplingGeohashes.size} geohashes") + activeSamplingGeohashes.forEach { subscriptionManager.unsubscribe("sampling-$it") } + } + + private fun performSubscribeSampling(geohash: String) { + subscriptionManager.subscribeGeohash( + geohash = geohash, + sinceMs = System.currentTimeMillis() - 86400000L, + limit = 200, + id = "sampling-$geohash", + handler = { event -> geohashMessageHandler.onEvent(event, geohash) } + ) + } + + private fun isAppInForeground(): Boolean { + return ProcessLifecycleOwner.get().lifecycle.currentState.isAtLeast(Lifecycle.State.STARTED) + } }