Skip to content
Merged
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
14 changes: 14 additions & 0 deletions app/src/main/java/com/bitchat/android/nostr/GeohashRepository.kt
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,20 @@ class GeohashRepository(
}?.key
}

fun findPubkeyByShortId(shortId: String): String? {
// First check cached nicknames (fastest)
var found = geoNicknames.keys.firstOrNull { it.startsWith(shortId, ignoreCase = true) }
if (found != null) return found

// If not found in nicknames (e.g. anon user), check all known participants across all geohashes
for (participants in geohashParticipants.values) {
found = participants.keys.firstOrNull { it.startsWith(shortId, ignoreCase = true) }
if (found != null) return found
}

return null
}

// peerID alias -> nostr pubkey mapping for geohash DMs and temp aliases
private val nostrKeyMapping: MutableMap<String, String> = mutableMapOf()

Expand Down
28 changes: 28 additions & 0 deletions app/src/main/java/com/bitchat/android/ui/ChatUserSheet.kt
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ fun ChatUserSheet(
val isDark = colorScheme.background.red + colorScheme.background.green + colorScheme.background.blue < 1.5f
val standardGreen = if (isDark) Color(0xFF32D74B) else Color(0xFF248A3D) // iOS green
val standardBlue = Color(0xFF007AFF) // iOS blue
val standardPurple = if (isDark) Color(0xFFBF5AF2) else Color(0xFFAF52DE) // iOS purple
val standardRed = Color(0xFFFF3B30) // iOS red
val standardGrey = if (isDark) Color(0xFF8E8E93) else Color(0xFF6D6D70) // iOS grey

Expand Down Expand Up @@ -92,6 +93,33 @@ fun ChatUserSheet(

// Only show user actions for other users' messages or when no message is selected
if (selectedMessage?.sender != viewModel.nickname.value) {
// Send private message action
item {
UserActionRow(
title = stringResource(R.string.action_private_message_title, targetNickname),
subtitle = stringResource(R.string.action_private_message_subtitle),
titleColor = standardPurple,
onClick = {
val selectedLocationChannel = viewModel.selectedLocationChannel.value
if (selectedLocationChannel is com.bitchat.android.geohash.ChannelID.Location) {
if (selectedMessage?.senderPeerID?.startsWith("nostr:") == true) {
val shortId = selectedMessage.senderPeerID!!.substring(6)
viewModel.startGeohashDMByShortId(shortId)
} else {
viewModel.startGeohashDMByNickname(targetNickname)
}
} else {
// Mesh chat
val peerID = selectedMessage?.senderPeerID ?: viewModel.getPeerIDForNickname(targetNickname)
if (peerID != null) {
viewModel.showPrivateChatSheet(peerID)
}
}
onDismiss()
}
)
}

// Slap action
item {
UserActionRow(
Expand Down
12 changes: 12 additions & 0 deletions app/src/main/java/com/bitchat/android/ui/ChatViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -1065,6 +1065,18 @@ class ChatViewModel(
}
}

fun startGeohashDMByNickname(nickname: String) {
geohashViewModel.startGeohashDMByNickname(nickname) { convKey ->
showPrivateChatSheet(convKey)
}
}

fun startGeohashDMByShortId(shortId: String) {
geohashViewModel.startGeohashDMByShortId(shortId) { convKey ->
showPrivateChatSheet(convKey)
}
}

fun selectLocationChannel(channel: com.bitchat.android.geohash.ChannelID) {
geohashViewModel.selectLocationChannel(channel)
}
Expand Down
19 changes: 19 additions & 0 deletions app/src/main/java/com/bitchat/android/ui/GeohashViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,25 @@ class GeohashViewModel(
Log.d(TAG, "🗨️ Started geohash DM with ${pubkeyHex} -> ${convKey} (geohash=${gh})")
}

fun startGeohashDMByNickname(nickname: String, onStartPrivateChat: (String) -> Unit) {
val pubkey = repo.findPubkeyByNickname(nickname)
if (pubkey != null) {
startGeohashDM(pubkey, onStartPrivateChat)
} else {
Log.w(TAG, "Cannot start geohash DM: nickname '$nickname' not found in repo")
// Optionally notify user
}
}

fun startGeohashDMByShortId(shortId: String, onStartPrivateChat: (String) -> Unit) {
val pubkey = repo.findPubkeyByShortId(shortId)
if (pubkey != null) {
startGeohashDM(pubkey, onStartPrivateChat)
} else {
Log.w(TAG, "Cannot start geohash DM: shortId '$shortId' not found in repo")
}
}

fun getNostrKeyMapping(): Map<String, String> = repo.getNostrKeyMapping()

fun blockUserInGeohash(targetNickname: String) {
Expand Down
5 changes: 4 additions & 1 deletion app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,10 @@
<string name="action_hug_title">hug %1$s</string>
<string name="action_hug_subtitle">send a friendly hug message</string>
<string name="action_block_title">block %1$s</string>
<string name="action_block_subtitle">block all messages from this user</string>
<string name="action_block_subtitle">block all messages from this user</string>
<string name="action_private_message_title">message %1$s</string>
<string name="action_private_message_subtitle">send a private message</string>


<!-- Location channels sheet -->
<string name="location_channels_title">#location channels</string>
Expand Down
Loading