Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,7 @@ import com.bitchat.android.model.BitchatMessage
import com.bitchat.android.ui.ChatState
import com.bitchat.android.ui.MessageManager
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.util.Date

/**
Expand Down Expand Up @@ -44,7 +42,7 @@ class GeohashMessageHandler(
}

fun onEvent(event: NostrEvent, subscribedGeohash: String) {
scope.launch(Dispatchers.Default) {
scope.launch {
try {
if (event.kind != NostrKind.EPHEMERAL_EVENT && event.kind != NostrKind.GEOHASH_PRESENCE) return@launch
val tagGeo = event.tags.firstOrNull { it.size >= 2 && it[0] == "g" }?.getOrNull(1)
Expand All @@ -62,9 +60,6 @@ class GeohashMessageHandler(
// Blocked users check (use injected DataManager which has loaded state)
if (dataManager.isGeohashUserBlocked(event.pubkey)) return@launch

// Update repository (participants, nickname, teleport)
// Update repository on a background-safe path; repository will post updates to LiveData

// Update participant count (last seen) on BOTH Presence (20001) and Chat (20000) events
if (event.kind == NostrKind.GEOHASH_PRESENCE || event.kind == NostrKind.EPHEMERAL_EVENT) {
repo.updateParticipant(subscribedGeohash, event.pubkey, Date(event.createdAt * 1000L))
Expand Down Expand Up @@ -104,7 +99,7 @@ class GeohashMessageHandler(
if (hasNonce) NostrProofOfWork.calculateDifficulty(event.id).takeIf { it > 0 } else null
} catch (_: Exception) { null }
)
withContext(Dispatchers.Main) { messageManager.addChannelMessage("geo:$subscribedGeohash", msg) }
messageManager.addChannelMessage("geo:$subscribedGeohash", msg)
} catch (e: Exception) {
Log.e(TAG, "onEvent error: ${e.message}")
}
Expand Down
11 changes: 10 additions & 1 deletion app/src/main/java/com/bitchat/android/nostr/GeohashRepository.kt
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,16 @@ class GeohashRepository(

fun updateParticipant(geohash: String, participantId: String, lastSeen: Date) {
val participants = geohashParticipants.getOrPut(geohash) { mutableMapOf() }
participants[participantId] = lastSeen
// Cap to now: prevents future-timestamped events (clock skew / malicious created_at)
// from pinning lastSeen and blocking subsequent normal heartbeats.
// Also keeps max: relays send events newest-first, so subsequent older events for
// the same user must not overwrite a fresher lastSeen.
val now = Date()
val effective = if (lastSeen.after(now)) now else lastSeen
val existing = participants[participantId]
if (existing == null || effective.after(existing)) {
participants[participantId] = effective
}
if (currentGeohash == geohash) refreshGeohashPeople()
updateReactiveParticipantCounts()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,7 @@ class GeohashViewModel(
is com.bitchat.android.geohash.ChannelID.Location -> {
Log.d(TAG, "📍 Switching to geohash channel: ${channel.channel.geohash}")
repo.setCurrentGeohash(channel.channel.geohash)
repo.refreshGeohashPeople()
notificationManager.setCurrentGeohash(channel.channel.geohash)
notificationManager.clearNotificationsForGeohash(channel.channel.geohash)
try { messageManager.clearChannelUnreadCount("geo:${channel.channel.geohash}") } catch (_: Exception) { }
Expand Down
Loading