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 c845ac0e..40f9274e 100644 --- a/app/src/main/java/com/bitchat/android/nostr/NostrGeohashService.kt +++ b/app/src/main/java/com/bitchat/android/nostr/NostrGeohashService.kt @@ -1231,12 +1231,14 @@ class NostrGeohashService( Log.d(TAG, "🔔 Triggering geohash notification - geohash: $geohash, mention: $isMention, first: $isFirstMessage") withContext(Dispatchers.Main) { + val locationName = getLocationNameForGeohash(geohash) notificationManager.showGeohashNotification( geohash = geohash, senderNickname = senderName, messageContent = content, isMention = isMention, - isFirstMessage = isFirstMessage + isFirstMessage = isFirstMessage, + locationName = locationName ) } } @@ -1605,5 +1607,30 @@ class NostrGeohashService( private fun isGeohashUserBlocked(pubkeyHex: String): Boolean { return dataManager.isGeohashUserBlocked(pubkeyHex) } + + /** + * Get location name for a geohash if available + */ + private fun getLocationNameForGeohash(geohash: String): String? { + return try { + val locationManager = com.bitchat.android.geohash.LocationChannelManager.getInstance(application) + val locationNames = locationManager.locationNames.value ?: return null + + // Determine the level from geohash length + val level = when (geohash.length) { + in 0..2 -> com.bitchat.android.geohash.GeohashChannelLevel.REGION + in 3..4 -> com.bitchat.android.geohash.GeohashChannelLevel.PROVINCE + 5 -> com.bitchat.android.geohash.GeohashChannelLevel.CITY + 6 -> com.bitchat.android.geohash.GeohashChannelLevel.NEIGHBORHOOD + 7 -> com.bitchat.android.geohash.GeohashChannelLevel.BLOCK + else -> com.bitchat.android.geohash.GeohashChannelLevel.BLOCK + } + + locationNames[level] + } catch (e: Exception) { + Log.w(TAG, "Failed to get location name for geohash $geohash: ${e.message}") + null + } + } } diff --git a/app/src/main/java/com/bitchat/android/onboarding/LocationCheckScreen.kt b/app/src/main/java/com/bitchat/android/onboarding/LocationCheckScreen.kt index 0995940b..5a8f06fd 100644 --- a/app/src/main/java/com/bitchat/android/onboarding/LocationCheckScreen.kt +++ b/app/src/main/java/com/bitchat/android/onboarding/LocationCheckScreen.kt @@ -139,7 +139,7 @@ private fun LocationDisabledContent( ) Text( - text = "• Bluetooth device scanning (Android requirement)\n" + + text = "• Bluetooth device scanning\n" + "• Discovering nearby users on mesh network\n" + "• Geohash chat feature\n" + "• No tracking or location collection", diff --git a/app/src/main/java/com/bitchat/android/ui/NotificationManager.kt b/app/src/main/java/com/bitchat/android/ui/NotificationManager.kt index 857160ec..e1043d86 100644 --- a/app/src/main/java/com/bitchat/android/ui/NotificationManager.kt +++ b/app/src/main/java/com/bitchat/android/ui/NotificationManager.kt @@ -82,7 +82,8 @@ class NotificationManager( val messageContent: String, val timestamp: Long, val isMention: Boolean, - val isFirstMessage: Boolean + val isFirstMessage: Boolean, + val locationName: String? = null ) init { @@ -397,7 +398,8 @@ class NotificationManager( senderNickname: String, messageContent: String, isMention: Boolean = false, - isFirstMessage: Boolean = false + isFirstMessage: Boolean = false, + locationName: String? = null ) { // Only show notifications if app is in background OR user is not viewing this specific geohash val shouldNotify = isAppInBackground || (!isAppInBackground && currentGeohash != geohash) @@ -415,7 +417,8 @@ class NotificationManager( messageContent = messageContent, timestamp = System.currentTimeMillis(), isMention = isMention, - isFirstMessage = isFirstMessage + isFirstMessage = isFirstMessage, + locationName = locationName ) // Add to pending notifications for this geohash @@ -453,12 +456,13 @@ class NotificationManager( PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT ) - // Build notification content + // Build notification content with location name if available + val geohashDisplay = latestNotification.locationName?.let { "$it (#$geohash)" } ?: "#$geohash" val contentTitle = when { - mentionCount > 0 && firstMessageCount > 0 -> "Mentioned in #$geohash (+${messageCount - 1} more)" - mentionCount > 0 -> if (mentionCount == 1) "Mentioned in #$geohash" else "$mentionCount mentions in #$geohash" - firstMessageCount > 0 -> "New activity in #$geohash" - else -> "Messages in #$geohash" + mentionCount > 0 && firstMessageCount > 0 -> "Mentioned in $geohashDisplay (+${messageCount - 1} more)" + mentionCount > 0 -> if (mentionCount == 1) "Mentioned in $geohashDisplay" else "$mentionCount mentions in $geohashDisplay" + firstMessageCount > 0 -> "New activity in $geohashDisplay" + else -> "Messages in $geohashDisplay" } val contentText = when { @@ -564,10 +568,12 @@ class NotificationManager( pendingGeohashNotifications.entries.take(5).forEach { (geohash, notifications) -> val mentionCount = notifications.count { it.isMention } val messageCount = notifications.size + val latestNotification = notifications.last() + val geohashDisplay = latestNotification.locationName?.let { "$it (#$geohash)" } ?: "#$geohash" val line = when { - mentionCount > 0 -> "#$geohash: $mentionCount mentions (+${messageCount - mentionCount} more)" - messageCount == 1 -> "#$geohash: 1 message" - else -> "#$geohash: $messageCount messages" + mentionCount > 0 -> "$geohashDisplay: $mentionCount mentions (+${messageCount - mentionCount} more)" + messageCount == 1 -> "$geohashDisplay: 1 message" + else -> "$geohashDisplay: $messageCount messages" } style.addLine(line) } diff --git a/app/src/test/kotlin/com/bitchat/NotificationManagerTest.kt b/app/src/test/kotlin/com/bitchat/NotificationManagerTest.kt index 9f821fcb..23e20912 100644 --- a/app/src/test/kotlin/com/bitchat/NotificationManagerTest.kt +++ b/app/src/test/kotlin/com/bitchat/NotificationManagerTest.kt @@ -107,4 +107,38 @@ class NotificationManagerTest { notificationManager.showActiveUserNotification(listOf("peer-3")) verify(notificationManagerCompat, times(1)).notify(any(), any()) } + + @Test + fun `geohash notification includes location name when available`() { + notificationManager.setAppBackgroundState(true) + notificationManager.setCurrentGeohash("abc123") + + notificationManager.showGeohashNotification( + geohash = "abc123", + senderNickname = "testuser", + messageContent = "Hello world", + isMention = false, + isFirstMessage = false, + locationName = "San Francisco" + ) + + verify(notificationManagerCompat, times(1)).notify(any(), any()) + } + + @Test + fun `geohash notification works without location name`() { + notificationManager.setAppBackgroundState(true) + notificationManager.setCurrentGeohash("abc123") + + notificationManager.showGeohashNotification( + geohash = "abc123", + senderNickname = "testuser", + messageContent = "Hello world", + isMention = false, + isFirstMessage = false, + locationName = null + ) + + verify(notificationManagerCompat, times(1)).notify(any(), any()) + } }