diff --git a/app/src/main/java/com/bitchat/android/geohash/LocationChannelManager.kt b/app/src/main/java/com/bitchat/android/geohash/LocationChannelManager.kt index 53bb381a..3ca45a73 100644 --- a/app/src/main/java/com/bitchat/android/geohash/LocationChannelManager.kt +++ b/app/src/main/java/com/bitchat/android/geohash/LocationChannelManager.kt @@ -149,8 +149,28 @@ class LocationChannelManager private constructor(private val context: Context) { */ fun select(channel: ChannelID) { Log.d(TAG, "Selected channel: ${channel.displayName}") - _selectedChannel.postValue(channel) + // Use synchronous set to avoid race with background recomputation + _selectedChannel.value = channel saveChannelSelection(channel) + + // Immediately recompute teleported status against the latest known location + lastLocation?.let { location -> + when (channel) { + is ChannelID.Mesh -> { + _teleported.postValue(false) + } + is ChannelID.Location -> { + val currentGeohash = Geohash.encode( + latitude = location.latitude, + longitude = location.longitude, + precision = channel.channel.level.precision + ) + val isTeleportedNow = currentGeohash != channel.channel.geohash + _teleported.postValue(isTeleportedNow) + Log.d(TAG, "Teleported (immediate recompute): $isTeleportedNow (current: $currentGeohash, selected: ${channel.channel.geohash})") + } + } + } } /** diff --git a/app/src/main/java/com/bitchat/android/nostr/NostrGeohashService.kt b/app/src/main/java/com/bitchat/android/nostr/NostrGeohashService.kt index fd6cc101..7777a554 100644 --- a/app/src/main/java/com/bitchat/android/nostr/NostrGeohashService.kt +++ b/app/src/main/java/com/bitchat/android/nostr/NostrGeohashService.kt @@ -181,7 +181,8 @@ class NostrGeohashService( content = content, geohash = channel.geohash, senderIdentity = identity, - nickname = nickname + nickname = nickname, + teleported = teleported ) val nostrRelayManager = NostrRelayManager.getInstance(application) diff --git a/app/src/main/java/com/bitchat/android/nostr/NostrProtocol.kt b/app/src/main/java/com/bitchat/android/nostr/NostrProtocol.kt index 3c3657f1..744a5edb 100644 --- a/app/src/main/java/com/bitchat/android/nostr/NostrProtocol.kt +++ b/app/src/main/java/com/bitchat/android/nostr/NostrProtocol.kt @@ -99,7 +99,8 @@ object NostrProtocol { content: String, geohash: String, senderIdentity: NostrIdentity, - nickname: String? = null + nickname: String? = null, + teleported: Boolean = false ): NostrEvent { val tags = mutableListOf>() tags.add(listOf("g", geohash)) @@ -108,6 +109,11 @@ object NostrProtocol { tags.add(listOf("n", nickname)) } + if (teleported) { + // Use tag consistent with event handlers ("t","teleport") + tags.add(listOf("t", "teleport")) + } + val event = NostrEvent( pubkey = senderIdentity.publicKeyHex, createdAt = (System.currentTimeMillis() / 1000).toInt(), diff --git a/app/src/main/java/com/bitchat/android/ui/GeohashPeopleList.kt b/app/src/main/java/com/bitchat/android/ui/GeohashPeopleList.kt index 70e159f8..382874c8 100644 --- a/app/src/main/java/com/bitchat/android/ui/GeohashPeopleList.kt +++ b/app/src/main/java/com/bitchat/android/ui/GeohashPeopleList.kt @@ -5,6 +5,8 @@ import androidx.compose.foundation.* import androidx.compose.foundation.layout.* import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.* +import androidx.compose.material.icons.outlined.Explore +import androidx.compose.material.icons.outlined.LocationOn import androidx.compose.material3.* import androidx.compose.runtime.* import androidx.compose.runtime.livedata.observeAsState @@ -182,8 +184,8 @@ private fun GeohashPersonItem( // Use appropriate Material icon (closest match to iOS SF Symbols) val icon = when (iconName) { - "face.dashed" -> Icons.Default.Face // Use regular face icon (no dashed variant in Material) - else -> Icons.Default.Face + "face.dashed" -> Icons.Outlined.Explore + else -> Icons.Outlined.LocationOn } Icon(