From b30ab84722e1e2358f0214abe357502d865cd46b Mon Sep 17 00:00:00 2001 From: a1denvalu3 <> Date: Sun, 18 Jan 2026 23:21:25 +0100 Subject: [PATCH 1/2] Fix #646: Display shortened pubkey instead of 'anon' for unnamed users --- .../android/nostr/GeohashRepository.kt | 29 +++++++++++-------- 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/com/bitchat/android/nostr/GeohashRepository.kt b/app/src/main/java/com/bitchat/android/nostr/GeohashRepository.kt index 822606c2..303ff22c 100644 --- a/app/src/main/java/com/bitchat/android/nostr/GeohashRepository.kt +++ b/app/src/main/java/com/bitchat/android/nostr/GeohashRepository.kt @@ -107,6 +107,10 @@ class GeohashRepository( return participants.keys.count { !dataManager.isGeohashUserBlocked(it) } } + private fun formatAnonName(pubkeyHex: String): String { + return "${pubkeyHex.take(8)}..." + } + fun refreshGeohashPeople() { val geohash = currentGeohash if (geohash == null) { @@ -130,11 +134,11 @@ class GeohashRepository( val base = try { val myHex = currentGeohash?.let { NostrIdentityBridge.deriveIdentity(it, application).publicKeyHex } if (myHex != null && myHex.equals(pubkeyHex, true)) { - state.getNicknameValue() ?: "anon" + state.getNicknameValue().ifEmpty { formatAnonName(pubkeyHex) } } else { - getCachedNickname(pubkeyHex) ?: "anon" + getCachedNickname(pubkeyHex) ?: formatAnonName(pubkeyHex) } - } catch (_: Exception) { getCachedNickname(pubkeyHex) ?: "anon" } + } catch (_: Exception) { getCachedNickname(pubkeyHex) ?: formatAnonName(pubkeyHex) } GeoPerson( id = pubkeyHex.lowercase(), displayName = base, // UI can add #hash if necessary @@ -172,11 +176,12 @@ class GeohashRepository( try { val my = NostrIdentityBridge.deriveIdentity(current, application) if (my.publicKeyHex.equals(lower, true)) { - return "${state.getNicknameValue()}#$suffix" + val selfNick = state.getNicknameValue() + return if (selfNick.isNotEmpty()) "$selfNick#$suffix" else "${formatAnonName(lower)}#$suffix" } } catch (_: Exception) {} } - val nick = geoNicknames[lower] ?: "anon" + val nick = geoNicknames[lower] ?: formatAnonName(lower) return "$nick#$suffix" } @@ -188,10 +193,10 @@ class GeohashRepository( if (current != null) { val my = NostrIdentityBridge.deriveIdentity(current, application) if (my.publicKeyHex.equals(lower, true)) { - state.getNicknameValue() ?: "anon" - } else geoNicknames[lower] ?: "anon" - } else geoNicknames[lower] ?: "anon" - } catch (_: Exception) { geoNicknames[lower] ?: "anon" } + state.getNicknameValue().ifEmpty { formatAnonName(lower) } + } else geoNicknames[lower] ?: formatAnonName(lower) + } else geoNicknames[lower] ?: formatAnonName(lower) + } catch (_: Exception) { geoNicknames[lower] ?: formatAnonName(lower) } if (current == null) return base return try { val cutoff = Date(System.currentTimeMillis() - 5 * 60 * 1000) @@ -200,7 +205,7 @@ class GeohashRepository( for ((k, t) in participants) { if (dataManager.isGeohashUserBlocked(k)) continue if (t.before(cutoff)) continue - val name = if (k.equals(lower, true)) base else (geoNicknames[k.lowercase()] ?: "anon") + val name = if (k.equals(lower, true)) base else (geoNicknames[k.lowercase()] ?: formatAnonName(k)) if (name.equals(base, true)) { count++; if (count > 1) break } } if (!participants.containsKey(lower)) count += 1 @@ -214,7 +219,7 @@ class GeohashRepository( fun displayNameForGeohashConversation(pubkeyHex: String, sourceGeohash: String): String { val lower = pubkeyHex.lowercase() val suffix = pubkeyHex.takeLast(4) - val base = geoNicknames[lower] ?: "anon" + val base = geoNicknames[lower] ?: formatAnonName(lower) return try { val cutoff = Date(System.currentTimeMillis() - 5 * 60 * 1000) val participants = geohashParticipants[sourceGeohash] ?: emptyMap() @@ -222,7 +227,7 @@ class GeohashRepository( for ((k, t) in participants) { if (dataManager.isGeohashUserBlocked(k)) continue if (t.before(cutoff)) continue - val name = if (k.equals(lower, true)) base else (geoNicknames[k.lowercase()] ?: "anon") + val name = if (k.equals(lower, true)) base else (geoNicknames[k.lowercase()] ?: formatAnonName(k)) if (name.equals(base, true)) { count++; if (count > 1) break } } if (!participants.containsKey(lower)) count += 1 From c1752844ee123871db61ecefff4a417befe22c24 Mon Sep 17 00:00:00 2001 From: a1denvalu3 <> Date: Sun, 18 Jan 2026 23:25:29 +0100 Subject: [PATCH 2/2] Prioritize named users in geohash peer list sorting --- .../com/bitchat/android/ui/GeohashPeopleList.kt | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) 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 0bdc85ee..2de0bd62 100644 --- a/app/src/main/java/com/bitchat/android/ui/GeohashPeopleList.kt +++ b/app/src/main/java/com/bitchat/android/ui/GeohashPeopleList.kt @@ -108,13 +108,24 @@ fun GeohashPeopleList( } } - // Sort people: me first, then by lastSeen (matches iOS exactly) + // Sort people: me first, then named users, then anons (by lastSeen within groups) val orderedPeople = remember(geohashPeople, myHex) { geohashPeople.sortedWith { a, b -> + // Check if display name indicates an "anon" (shortened hex) + val aIsAnon = a.displayName == "${a.id.take(8)}..." + val bIsAnon = b.displayName == "${b.id.take(8)}..." + when { + // 1. Me always first myHex != null && a.id == myHex && b.id != myHex -> -1 myHex != null && b.id == myHex && a.id != myHex -> 1 - else -> b.lastSeen.compareTo(a.lastSeen) // Most recent first + + // 2. Named users before anon users + !aIsAnon && bIsAnon -> -1 + aIsAnon && !bIsAnon -> 1 + + // 3. Otherwise sort by recency + else -> b.lastSeen.compareTo(a.lastSeen) } } }