diff --git a/app/src/main/java/com/bitchat/android/ui/LocationNotesViewModelExtensions.kt b/app/src/main/java/com/bitchat/android/ui/LocationNotesViewModelExtensions.kt index c568e402..d8e638ce 100644 --- a/app/src/main/java/com/bitchat/android/ui/LocationNotesViewModelExtensions.kt +++ b/app/src/main/java/com/bitchat/android/ui/LocationNotesViewModelExtensions.kt @@ -1,81 +1,58 @@ package com.bitchat.android.ui import android.app.Application -import android.util.Log -import androidx.lifecycle.viewModelScope import com.bitchat.android.geohash.ChannelID import com.bitchat.android.geohash.GeohashChannelLevel import com.bitchat.android.geohash.LocationChannelManager import com.bitchat.android.nostr.LocationNotesManager -import kotlinx.coroutines.launch +import com.bitchat.android.geohash.LocationChannelManager.PermissionState + +private val BUILDING_LEVEL = GeohashChannelLevel.BUILDING /** - * Extension functions for ChatViewModel to manage LocationNotesManager subscription - * Extracts location notes subscription logic for better separation of concerns - */ - -private const val TAG = "LocationNotesVM" - -/** - * Initialize location notes manager subscription (no separate counter) - * Subscribes/unsubscribes based on channel selection and location permission + * Automatically keep LocationNotesManager in sync with mesh chat and location availability. + * Subscribes to building-level notes when the user is in mesh chat and location access is ready. */ fun ChatViewModel.initializeLocationNotesManagerSubscription() { - viewModelScope.launch { - // Observe channel changes - selectedLocationChannel.observeForever { channel -> - updateLocationNotesSubscription(channel) - } - } -} + val app = getApplication() + val locationManager = LocationChannelManager.getInstance(app) + val notesManager = LocationNotesManager.getInstance() -/** - * Update location notes subscription based on current channel and location permission - * iOS pattern: Subscribe when in mesh mode and location is authorized - */ -private fun ChatViewModel.updateLocationNotesSubscription(channel: ChannelID?) { - try { - val locationManager = LocationChannelManager.getInstance(getApplication()) - val permissionState = locationManager.permissionState.value - val locationPermissionGranted = permissionState == LocationChannelManager.PermissionState.AUTHORIZED - - when (channel) { - is ChannelID.Mesh -> { - // Mesh mode: subscribe to building-level geohash notes if location authorized - if (locationPermissionGranted) { - // Refresh location to get current building geohash - locationManager.refreshChannels() - - // Get building-level geohash (precision 8, same as iOS) - val buildingGeohash = locationManager.availableChannels.value - ?.firstOrNull { it.level == GeohashChannelLevel.BUILDING } - ?.geohash - - if (buildingGeohash != null) { - Log.d(TAG, "📍 Subscribing to location notes for building geohash: $buildingGeohash") - LocationNotesManager.getInstance().setGeohash(buildingGeohash) - } else { - // Cancel if no building geohash available - if (LocationNotesManager.getInstance().geohash.value == null) { - LocationNotesManager.getInstance().cancel() - } - } - } else { - LocationNotesManager.getInstance().cancel() - } - } - is ChannelID.Location -> { - // Location channel mode: cancel (only show in mesh mode) - LocationNotesManager.getInstance().cancel() - } - null -> { - // Default to mesh behavior - if (locationPermissionGranted) { - locationManager.refreshChannels() - } + fun refreshNotesSubscription() { + val permissionGranted = locationManager.permissionState.value == PermissionState.AUTHORIZED + val servicesEnabled = locationManager.isLocationServicesEnabled() + val viewingMesh = selectedLocationChannel.value is ChannelID.Mesh + + if (permissionGranted && servicesEnabled && viewingMesh) { + val buildingChannel = locationManager.availableChannels.value + ?.firstOrNull { it.level == BUILDING_LEVEL } + + if (buildingChannel != null) { + notesManager.setGeohash(buildingChannel.geohash) + } else { + // Trigger a refresh; when channels arrive we'll get called again + locationManager.refreshChannels() } + } else { + notesManager.cancel() } - } catch (e: Exception) { - Log.w(TAG, "updateLocationNotesSubscription failed: ${e.message}") } + + selectedLocationChannel.observeForever { refreshNotesSubscription() } + locationManager.permissionState.observeForever { + if (it == PermissionState.AUTHORIZED) { + locationManager.refreshChannels() + } + refreshNotesSubscription() + } + locationManager.availableChannels.observeForever { refreshNotesSubscription() } + locationManager.locationServicesEnabled.observeForever { enabled -> + if (enabled) { + locationManager.refreshChannels() + } + refreshNotesSubscription() + } + + // Evaluate immediately with current state + refreshNotesSubscription() }