mirror of
https://github.com/permissionlesstech/bitchat-android.git
synced 2026-08-08 06:46:11 +00:00
Fix Cashu payment review issues
This commit is contained in:
parent
6f4f6b988b
commit
199f95fdbd
@ -47,7 +47,7 @@ object CashuTokenDecoder {
|
||||
}
|
||||
if (token.length !in 12..MAX_TOKEN_LENGTH) return null
|
||||
if (!token.startsWith("cashuA") && !token.startsWith("cashuB")) return null
|
||||
if (token.any { !it.isLetterOrDigit() && it !in "-_+/=." }) return null
|
||||
if (token.any { !it.isLetterOrDigit() && it !in "-_+/=" }) return null
|
||||
return token
|
||||
}
|
||||
|
||||
@ -198,7 +198,7 @@ object CashuTokenDecoder {
|
||||
}.getOrNull()?.takeIf { it >= 0 }
|
||||
}
|
||||
|
||||
private val TOKEN_REGEX = Regex("""(?i:cashu:(?://)?)?cashu[AB][A-Za-z0-9_+/.=%-]{6,}""")
|
||||
private val TOKEN_REGEX = Regex("""(?i:cashu:(?://)?)?cashu[AB][A-Za-z0-9_+/%=-]{6,}""")
|
||||
}
|
||||
|
||||
private sealed interface CborValue {
|
||||
|
||||
@ -920,6 +920,20 @@ class ChatViewModel(
|
||||
mesh.myPeerID,
|
||||
state.getNicknameValue()
|
||||
)
|
||||
} else if (channel != null && channelManager.hasChannelKey(channel)) {
|
||||
channelManager.sendEncryptedChannelMessage(
|
||||
messageContent,
|
||||
mentions,
|
||||
channel,
|
||||
state.getNicknameValue(),
|
||||
mesh.myPeerID,
|
||||
onEncryptedPayload = {
|
||||
mesh.sendMessage(messageContent, mentions, channel)
|
||||
},
|
||||
onFallback = {
|
||||
mesh.sendMessage(messageContent, mentions, channel)
|
||||
}
|
||||
)
|
||||
} else {
|
||||
mesh.sendMessage(messageContent, mentions, channel)
|
||||
}
|
||||
|
||||
@ -438,11 +438,18 @@ class CommandProcessor(
|
||||
isRelay = false
|
||||
)
|
||||
val selectedPeer = state.getSelectedPrivateChatPeerValue()
|
||||
val selectedLocationChannel = state.selectedLocationChannel.value
|
||||
val channel = state.getCurrentChannelValue()
|
||||
when {
|
||||
selectedPeer != null -> {
|
||||
messageManager.addPrivateMessageNoUnread(selectedPeer, message.copy(isPrivate = true))
|
||||
}
|
||||
selectedLocationChannel is com.bitchat.android.geohash.ChannelID.Location -> {
|
||||
messageManager.addChannelMessage(
|
||||
"geo:${selectedLocationChannel.channel.geohash}",
|
||||
message
|
||||
)
|
||||
}
|
||||
channel != null -> channelManager.addChannelMessage(channel, message, null)
|
||||
else -> messageManager.addMessage(message)
|
||||
}
|
||||
|
||||
@ -1,5 +1,11 @@
|
||||
package com.bitchat.android.ui
|
||||
|
||||
import android.content.ActivityNotFoundException
|
||||
import android.content.ClipData
|
||||
import android.content.ClipboardManager
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Close
|
||||
import androidx.compose.animation.AnimatedContent
|
||||
@ -15,7 +21,9 @@ import androidx.compose.animation.fadeOut
|
||||
import androidx.compose.animation.togetherWith
|
||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.border
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.combinedClickable
|
||||
import androidx.compose.foundation.gestures.detectTapGestures
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
@ -25,13 +33,17 @@ import androidx.compose.foundation.layout.calculateEndPadding
|
||||
import androidx.compose.foundation.layout.calculateStartPadding
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.heightIn
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.LazyListState
|
||||
import androidx.compose.foundation.lazy.itemsIndexed
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.ColorScheme
|
||||
import androidx.compose.material3.DropdownMenu
|
||||
import androidx.compose.material3.DropdownMenuItem
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
@ -53,6 +65,8 @@ import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.platform.LocalHapticFeedback
|
||||
import androidx.compose.ui.platform.LocalLayoutDirection
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.semantics.contentDescription
|
||||
import androidx.compose.ui.semantics.semantics
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.Dp
|
||||
|
||||
@ -94,6 +94,14 @@ class CashuTokenDecoderTest {
|
||||
assertEquals(first, CashuTokenDecoder.bareToken("cashu%3A$first"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `sentence punctuation is not included in extracted token`() {
|
||||
val token = v3Token("""{"token":[{"proofs":[{"amount":1}]}]}""")
|
||||
|
||||
assertEquals(listOf(token), CashuTokenDecoder.extractTokens("Redeem $token."))
|
||||
assertNull(CashuTokenDecoder.bareToken("$token."))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `oversized and deeply nested input fails closed`() {
|
||||
assertNull(CashuTokenDecoder.decode("cashuA" + "A".repeat(CashuTokenDecoder.MAX_TOKEN_LENGTH)))
|
||||
|
||||
@ -2,6 +2,9 @@ package com.bitchat.android.ui
|
||||
|
||||
import android.content.Context
|
||||
import androidx.test.core.app.ApplicationProvider
|
||||
import com.bitchat.android.geohash.ChannelID
|
||||
import com.bitchat.android.geohash.GeohashChannel
|
||||
import com.bitchat.android.geohash.GeohashChannelLevel
|
||||
import com.bitchat.android.mesh.MeshService
|
||||
import com.bitchat.android.model.BitchatMessage
|
||||
import junit.framework.TestCase.assertEquals
|
||||
@ -136,4 +139,26 @@ class CommandProcessorTest() {
|
||||
|
||||
assertTrue(locallyRead.contains(message.id))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `pay feedback is added to active geohash channel`() {
|
||||
val geohash = "u0nd"
|
||||
chatState.setSelectedLocationChannel(
|
||||
ChannelID.Location(GeohashChannel(GeohashChannelLevel.PROVINCE, geohash))
|
||||
)
|
||||
|
||||
commandProcessor.processCommand(
|
||||
command = "/pay invalid",
|
||||
meshService = meshService,
|
||||
myPeerID = "peer-id",
|
||||
onSendMessage = { _, _, _ -> },
|
||||
viewModel = null
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
"invalid cashu token — not sending it",
|
||||
chatState.getChannelMessagesValue()["geo:$geohash"]?.single()?.content
|
||||
)
|
||||
assertEquals(0, chatState.getMessagesValue().size)
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user