From 6879906b71cc1341ba4410d8944d5cc490088ad2 Mon Sep 17 00:00:00 2001 From: callebtc <93376500+callebtc@users.noreply.github.com> Date: Fri, 17 Oct 2025 22:25:13 +0200 Subject: [PATCH] works --- .../java/com/bitchat/android/MainActivity.kt | 40 +++++++++++-------- .../android/nostr/LocationNotesManager.kt | 39 +++++++++++++++--- .../com/bitchat/android/nostr/NostrFilter.kt | 8 ++++ 3 files changed, 65 insertions(+), 22 deletions(-) diff --git a/app/src/main/java/com/bitchat/android/MainActivity.kt b/app/src/main/java/com/bitchat/android/MainActivity.kt index 9da01527..b45023e1 100644 --- a/app/src/main/java/com/bitchat/android/MainActivity.kt +++ b/app/src/main/java/com/bitchat/android/MainActivity.kt @@ -602,16 +602,24 @@ class MainActivity : ComponentActivity() { com.bitchat.android.nostr.LocationNotesCounter.initialize( relayManager = { com.bitchat.android.nostr.NostrRelayManager.getInstance(this@MainActivity) }, subscribe = { filter, id, handler -> - // Use subscribeForGeohash for location notes (finds geo-local relays) - val geohashFromFilter = filter.getDebugDescription().substringAfter("#g=").substringBefore(")").substringBefore(",") - com.bitchat.android.nostr.NostrRelayManager.getInstance(this@MainActivity).subscribeForGeohash( - geohash = geohashFromFilter, - filter = filter, - id = id, - handler = handler, - includeDefaults = true, - nRelays = 5 - ) + // CRITICAL FIX: Extract geohash properly from filter (not from debug string!) + val geohashFromFilter = filter.getGeohash() ?: run { + Log.e("MainActivity", "Cannot extract geohash from filter for location notes counter") + "" + } + + if (geohashFromFilter.isNotEmpty()) { + com.bitchat.android.nostr.NostrRelayManager.getInstance(this@MainActivity).subscribeForGeohash( + geohash = geohashFromFilter, + filter = filter, + id = id, + handler = handler, + includeDefaults = true, + nRelays = 5 + ) + } else { + id + } }, unsubscribe = { id -> com.bitchat.android.nostr.NostrRelayManager.getInstance(this@MainActivity).unsubscribe(id) @@ -623,13 +631,13 @@ class MainActivity : ComponentActivity() { com.bitchat.android.nostr.LocationNotesManager.getInstance().initialize( relayManager = { com.bitchat.android.nostr.NostrRelayManager.getInstance(this@MainActivity) }, subscribe = { filter, id, handler -> - // Extract geohash from filter for geo-routing - val geohashFromFilter = filter.getDebugDescription() - .substringAfter("#g=") - .substringBefore(")") - .substringBefore(",") + // CRITICAL FIX: Extract geohash properly from filter using getGeohash() method + val geohashFromFilter = filter.getGeohash() ?: run { + Log.e("MainActivity", "❌ Cannot extract geohash from filter for location notes") + return@initialize id // Return subscription ID even on error + } - Log.d("MainActivity", "Location Notes subscribing to geohash: $geohashFromFilter") + Log.d("MainActivity", "📍 Location Notes subscribing to geohash: $geohashFromFilter") com.bitchat.android.nostr.NostrRelayManager.getInstance(this@MainActivity).subscribeForGeohash( geohash = geohashFromFilter, diff --git a/app/src/main/java/com/bitchat/android/nostr/LocationNotesManager.kt b/app/src/main/java/com/bitchat/android/nostr/LocationNotesManager.kt index b0076e5a..8743e142 100644 --- a/app/src/main/java/com/bitchat/android/nostr/LocationNotesManager.kt +++ b/app/src/main/java/com/bitchat/android/nostr/LocationNotesManager.kt @@ -157,6 +157,28 @@ class LocationNotesManager private constructor() { return } + val trimmed = content.trim() + if (trimmed.isEmpty()) { + return + } + + // CRITICAL FIX: Get geo-specific relays for sending (matching iOS pattern) + // iOS: let relays = dependencies.relayLookup(geohash, TransportConfig.nostrGeoRelayCount) + val relays = try { + com.bitchat.android.nostr.RelayDirectory.closestRelaysForGeohash(currentGeohash, 5) + } catch (e: Exception) { + Log.e(TAG, "Failed to lookup relays for geohash $currentGeohash: ${e.message}") + emptyList() + } + + // Check if we have relays (iOS pattern: guard !relays.isEmpty()) + if (relays.isEmpty()) { + Log.w(TAG, "Send blocked - no geo relays for geohash: $currentGeohash") + _state.value = State.NO_RELAYS + _errorMessage.value = "No relays available" + return + } + val deriveIdentity = deriveIdentityFunc if (deriveIdentity == null) { Log.e(TAG, "Cannot send note - deriveIdentity not initialized") @@ -164,7 +186,7 @@ class LocationNotesManager private constructor() { return } - Log.d(TAG, "Sending note to geohash: $currentGeohash") + Log.d(TAG, "Sending note to geohash: $currentGeohash via ${relays.size} geo relays") scope.launch { try { @@ -174,7 +196,7 @@ class LocationNotesManager private constructor() { val event = withContext(Dispatchers.IO) { NostrProtocol.createGeohashTextNote( - content = content, + content = trimmed, geohash = currentGeohash, senderIdentity = identity, nickname = nickname @@ -185,7 +207,7 @@ class LocationNotesManager private constructor() { val localNote = Note( id = event.id, pubkey = event.pubkey, - content = content, + content = trimmed, createdAt = event.createdAt, nickname = nickname ) @@ -201,12 +223,17 @@ class LocationNotesManager private constructor() { } } - // Send to relays + // CRITICAL FIX: Send to geo-specific relays (matching iOS pattern) + // iOS: dependencies.sendEvent(event, relays) withContext(Dispatchers.IO) { - sendEventFunc?.invoke(event, null) + sendEventFunc?.invoke(event, relays) } - Log.d(TAG, "✅ Note sent successfully: ${event.id.take(16)}...") + Log.d(TAG, "✅ Note sent successfully to ${relays.size} geo relays: ${event.id.take(16)}...") + + // Clear any error messages on successful send + _errorMessage.value = null + _state.value = State.READY } catch (e: Exception) { Log.e(TAG, "Failed to send note: ${e.message}") diff --git a/app/src/main/java/com/bitchat/android/nostr/NostrFilter.kt b/app/src/main/java/com/bitchat/android/nostr/NostrFilter.kt index f2cea4fb..b6313ea7 100644 --- a/app/src/main/java/com/bitchat/android/nostr/NostrFilter.kt +++ b/app/src/main/java/com/bitchat/android/nostr/NostrFilter.kt @@ -205,4 +205,12 @@ data class NostrFilter( return "NostrFilter(${parts.joinToString(", ")})" } + + /** + * Get geohash value from g tag filter (if present) + * Returns the first geohash in the filter or null if none + */ + fun getGeohash(): String? { + return tagFilters?.get("g")?.firstOrNull() + } }