fix zap splits and show message if user uninstall amber

This commit is contained in:
greenart7c3
2023-09-16 08:23:56 -03:00
parent 3a753f0d5d
commit 9f9f158709
5 changed files with 161 additions and 156 deletions

View File

@@ -450,7 +450,8 @@ class Account(
userProfile().latestContactList?.relays()?.keys?.ifEmpty { null } userProfile().latestContactList?.relays()?.keys?.ifEmpty { null }
?: localRelays.map { it.url }.toSet(), ?: localRelays.map { it.url }.toSet(),
pollOption, pollOption,
message message,
toUser?.pubkeyHex
) )
} }
LnZapEvent.ZapType.PUBLIC -> { LnZapEvent.ZapType.PUBLIC -> {
@@ -460,7 +461,8 @@ class Account(
?: localRelays.map { it.url }.toSet(), ?: localRelays.map { it.url }.toSet(),
keyPair.pubKey.toHexKey(), keyPair.pubKey.toHexKey(),
pollOption, pollOption,
message message,
toUser?.pubkeyHex
) )
AmberUtils.openAmber(unsignedEvent) AmberUtils.openAmber(unsignedEvent)
val content = AmberUtils.content[unsignedEvent.id] ?: "" val content = AmberUtils.content[unsignedEvent.id] ?: ""
@@ -479,7 +481,8 @@ class Account(
?: localRelays.map { it.url }.toSet(), ?: localRelays.map { it.url }.toSet(),
keyPair.pubKey.toHexKey(), keyPair.pubKey.toHexKey(),
pollOption, pollOption,
message message,
toUser?.pubkeyHex
) )
AmberUtils.openAmber(unsignedEvent, "event") AmberUtils.openAmber(unsignedEvent, "event")
val content = AmberUtils.content[unsignedEvent.id] ?: "" val content = AmberUtils.content[unsignedEvent.id] ?: ""

View File

@@ -3,11 +3,13 @@ package com.vitorpamplona.amethyst.service
import android.app.Activity import android.app.Activity
import android.content.Intent import android.content.Intent
import android.net.Uri import android.net.Uri
import android.util.Log
import android.util.LruCache import android.util.LruCache
import android.widget.Toast import android.widget.Toast
import androidx.activity.result.ActivityResultLauncher import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts
import com.vitorpamplona.amethyst.Amethyst import com.vitorpamplona.amethyst.Amethyst
import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.ServiceManager import com.vitorpamplona.amethyst.ServiceManager
import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.model.Account
import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.model.LocalCache
@@ -49,7 +51,7 @@ object AmberUtils {
GlobalScope.launch(Dispatchers.Main) { GlobalScope.launch(Dispatchers.Main) {
Toast.makeText( Toast.makeText(
Amethyst.instance, Amethyst.instance,
"Sign request rejected", Amethyst.instance.getString(R.string.sign_request_rejected),
Toast.LENGTH_SHORT Toast.LENGTH_SHORT
).show() ).show()
} }
@@ -133,6 +135,7 @@ object AmberUtils {
} }
} }
@OptIn(DelicateCoroutinesApi::class)
fun openAmber( fun openAmber(
data: String, data: String,
type: SignerType, type: SignerType,
@@ -140,25 +143,36 @@ object AmberUtils {
pubKey: HexKey, pubKey: HexKey,
id: String id: String
) { ) {
ServiceManager.shouldPauseService = false try {
val intent = Intent(Intent.ACTION_VIEW, Uri.parse("nostrsigner:$data")) ServiceManager.shouldPauseService = false
val signerType = when (type) { val intent = Intent(Intent.ACTION_VIEW, Uri.parse("nostrsigner:$data"))
SignerType.SIGN_EVENT -> "sign_event" val signerType = when (type) {
SignerType.NIP04_ENCRYPT -> "nip04_encrypt" SignerType.SIGN_EVENT -> "sign_event"
SignerType.NIP04_DECRYPT -> "nip04_decrypt" SignerType.NIP04_ENCRYPT -> "nip04_encrypt"
SignerType.NIP44_ENCRYPT -> "nip44_encrypt" SignerType.NIP04_DECRYPT -> "nip04_decrypt"
SignerType.NIP44_DECRYPT -> "nip44_decrypt" SignerType.NIP44_ENCRYPT -> "nip44_encrypt"
SignerType.GET_PUBLIC_KEY -> "get_public_key" SignerType.NIP44_DECRYPT -> "nip44_decrypt"
SignerType.DECRYPT_ZAP_EVENT -> "decrypt_zap_event" SignerType.GET_PUBLIC_KEY -> "get_public_key"
SignerType.DECRYPT_ZAP_EVENT -> "decrypt_zap_event"
}
intent.putExtra("type", signerType)
intent.putExtra("pubKey", pubKey)
intent.putExtra("id", id)
if (type !== SignerType.GET_PUBLIC_KEY) {
intent.putExtra("current_user", account.keyPair.pubKey.toNpub())
}
intent.`package` = "com.greenart7c3.nostrsigner"
intentResult.launch(intent)
} catch (e: Exception) {
Log.e("Amber", "Error opening amber", e)
GlobalScope.launch(Dispatchers.Main) {
Toast.makeText(
Amethyst.instance,
Amethyst.instance.getString(R.string.error_opening_amber),
Toast.LENGTH_SHORT
).show()
}
} }
intent.putExtra("type", signerType)
intent.putExtra("pubKey", pubKey)
intent.putExtra("id", id)
if (type !== SignerType.GET_PUBLIC_KEY) {
intent.putExtra("current_user", account.keyPair.pubKey.toNpub())
}
intent.`package` = "com.greenart7c3.nostrsigner"
intentResult.launch(intent)
} }
fun openAmber(event: EventInterface, columnName: String = "signature") { fun openAmber(event: EventInterface, columnName: String = "signature") {

View File

@@ -14,11 +14,7 @@ import androidx.compose.ui.text.input.TextFieldValue
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import com.fonfon.kgeohash.toGeoHash import com.fonfon.kgeohash.toGeoHash
import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.model.*
import com.vitorpamplona.amethyst.model.LocalCache
import com.vitorpamplona.amethyst.model.Note
import com.vitorpamplona.amethyst.model.ServersAvailable
import com.vitorpamplona.amethyst.model.User
import com.vitorpamplona.amethyst.service.FileHeader import com.vitorpamplona.amethyst.service.FileHeader
import com.vitorpamplona.amethyst.service.LocationUtil import com.vitorpamplona.amethyst.service.LocationUtil
import com.vitorpamplona.amethyst.service.NostrSearchEventOrUserDataSource import com.vitorpamplona.amethyst.service.NostrSearchEventOrUserDataSource
@@ -168,13 +164,12 @@ open class NewPostViewModel() : ViewModel() {
} }
fun sendPost(relayList: List<Relay>? = null) { fun sendPost(relayList: List<Relay>? = null) {
try { val tagger = NewMessageTagger(message.text, mentions, replyTos, originalNote?.channelHex())
val tagger = NewMessageTagger(message.text, mentions, replyTos, originalNote?.channelHex()) tagger.run()
tagger.run()
val toUsersTagger = NewMessageTagger(toUsers.text, null, null, null) val toUsersTagger = NewMessageTagger(toUsers.text, null, null, null)
toUsersTagger.run() toUsersTagger.run()
val dmUsers = toUsersTagger.mentions val dmUsers = toUsersTagger.mentions
val zapReceiver = if (wantsForwardZapTo) { val zapReceiver = if (wantsForwardZapTo) {
forwardZapTo?.items?.map { forwardZapTo?.items?.map {
@@ -185,117 +180,112 @@ open class NewPostViewModel() : ViewModel() {
isLnAddress = false isLnAddress = false
) )
} }
} else {
null
}
val geoLocation = locUtil?.locationStateFlow?.value val geoLocation = locUtil?.locationStateFlow?.value
val geoHash = if (wantsToAddGeoHash && geoLocation != null) { val geoHash = if (wantsToAddGeoHash && geoLocation != null) {
geoLocation.toGeoHash(GeohashPrecision.KM_5_X_5.digits).toString() geoLocation.toGeoHash(GeohashPrecision.KM_5_X_5.digits).toString()
} else {
null
}
val localZapRaiserAmount = if (wantsZapraiser) zapRaiserAmount else null
if (originalNote?.channelHex() != null) {
if (originalNote is AddressableEvent && originalNote?.address() != null) {
account?.sendLiveMessage(tagger.message, originalNote?.address()!!, tagger.replyTos, tagger.mentions, zapReceiver, wantsToMarkAsSensitive, localZapRaiserAmount, geoHash)
} else { } else {
null account?.sendChannelMessage(tagger.message, tagger.channelHex!!, tagger.replyTos, tagger.mentions, zapReceiver, wantsToMarkAsSensitive, localZapRaiserAmount, geoHash)
} }
} else if (originalNote?.event is PrivateDmEvent) {
account?.sendPrivateMessage(tagger.message, originalNote!!.author!!, originalNote!!, tagger.mentions, zapReceiver, wantsToMarkAsSensitive, localZapRaiserAmount, geoHash)
} else if (originalNote?.event is ChatMessageEvent) {
val receivers = (originalNote?.event as ChatMessageEvent).recipientsPubKey().plus(originalNote?.author?.pubkeyHex).filterNotNull().toSet().toList()
val localZapRaiserAmount = if (wantsZapraiser) zapRaiserAmount else null account?.sendNIP24PrivateMessage(
message = tagger.message,
if (originalNote?.channelHex() != null) { toUsers = receivers,
if (originalNote is AddressableEvent && originalNote?.address() != null) { subject = subject.text.ifBlank { null },
account?.sendLiveMessage(tagger.message, originalNote?.address()!!, tagger.replyTos, tagger.mentions, zapReceiver, wantsToMarkAsSensitive, localZapRaiserAmount, geoHash) replyingTo = originalNote!!,
} else { mentions = tagger.mentions,
account?.sendChannelMessage(tagger.message, tagger.channelHex!!, tagger.replyTos, tagger.mentions, zapReceiver, wantsToMarkAsSensitive, localZapRaiserAmount, geoHash) wantsToMarkAsSensitive = wantsToMarkAsSensitive,
} zapReceiver = zapReceiver,
} else if (originalNote?.event is PrivateDmEvent) { zapRaiserAmount = localZapRaiserAmount,
account?.sendPrivateMessage(tagger.message, originalNote!!.author!!, originalNote!!, tagger.mentions, zapReceiver, wantsToMarkAsSensitive, localZapRaiserAmount, geoHash) geohash = geoHash
} else if (originalNote?.event is ChatMessageEvent) { )
val receivers = (originalNote?.event as ChatMessageEvent).recipientsPubKey().plus(originalNote?.author?.pubkeyHex).filterNotNull().toSet().toList() } else if (!dmUsers.isNullOrEmpty()) {
if (nip24 || dmUsers.size > 1) {
account?.sendNIP24PrivateMessage( account?.sendNIP24PrivateMessage(
message = tagger.message, message = tagger.message,
toUsers = receivers, toUsers = dmUsers.map { it.pubkeyHex },
subject = subject.text.ifBlank { null }, subject = subject.text.ifBlank { null },
replyingTo = originalNote!!, replyingTo = tagger.replyTos?.firstOrNull(),
mentions = tagger.mentions, mentions = tagger.mentions,
wantsToMarkAsSensitive = wantsToMarkAsSensitive, wantsToMarkAsSensitive = wantsToMarkAsSensitive,
zapReceiver = zapReceiver, zapReceiver = zapReceiver,
zapRaiserAmount = localZapRaiserAmount, zapRaiserAmount = localZapRaiserAmount,
geohash = geoHash geohash = geoHash
) )
} else if (!dmUsers.isNullOrEmpty()) {
if (nip24 || dmUsers.size > 1) {
account?.sendNIP24PrivateMessage(
message = tagger.message,
toUsers = dmUsers.map { it.pubkeyHex },
subject = subject.text.ifBlank { null },
replyingTo = tagger.replyTos?.firstOrNull(),
mentions = tagger.mentions,
wantsToMarkAsSensitive = wantsToMarkAsSensitive,
zapReceiver = zapReceiver,
zapRaiserAmount = localZapRaiserAmount,
geohash = geoHash
)
} else {
account?.sendPrivateMessage(
message = tagger.message,
toUser = dmUsers.first().pubkeyHex,
replyingTo = originalNote,
mentions = tagger.mentions,
wantsToMarkAsSensitive = wantsToMarkAsSensitive,
zapReceiver = zapReceiver,
zapRaiserAmount = localZapRaiserAmount,
geohash = geoHash
)
}
} else { } else {
if (wantsPoll) { account?.sendPrivateMessage(
account?.sendPoll( message = tagger.message,
tagger.message, toUser = dmUsers.first().pubkeyHex,
tagger.replyTos, replyingTo = originalNote,
tagger.mentions, mentions = tagger.mentions,
pollOptions, wantsToMarkAsSensitive = wantsToMarkAsSensitive,
valueMaximum, zapReceiver = zapReceiver,
valueMinimum, zapRaiserAmount = localZapRaiserAmount,
consensusThreshold, geohash = geoHash
closedAt, )
zapReceiver, }
wantsToMarkAsSensitive, } else {
localZapRaiserAmount, if (wantsPoll) {
relayList, account?.sendPoll(
geoHash tagger.message,
) tagger.replyTos,
} else { tagger.mentions,
// adds markers pollOptions,
val rootId = valueMaximum,
(originalNote?.event as? TextNoteEvent)?.root() // if it has a marker as root valueMinimum,
?: originalNote?.replyTo?.firstOrNull { it.event != null && it.replyTo?.isEmpty() == true }?.idHex // if it has loaded events with zero replies in the reply list consensusThreshold,
?: originalNote?.replyTo?.firstOrNull()?.idHex // old rules, first item is root. closedAt,
val replyId = originalNote?.idHex zapReceiver,
wantsToMarkAsSensitive,
account?.sendPost( localZapRaiserAmount,
message = tagger.message, relayList,
replyTo = tagger.replyTos, geoHash
mentions = tagger.mentions, )
tags = null, } else {
zapReceiver = zapReceiver, // adds markers
wantsToMarkAsSensitive = wantsToMarkAsSensitive, val rootId =
zapRaiserAmount = localZapRaiserAmount, (originalNote?.event as? TextNoteEvent)?.root() // if it has a marker as root
replyingTo = replyId, ?: originalNote?.replyTo?.firstOrNull { it.event != null && it.replyTo?.isEmpty() == true }?.idHex // if it has loaded events with zero replies in the reply list
root = rootId, ?: originalNote?.replyTo?.firstOrNull()?.idHex // old rules, first item is root.
directMentions = tagger.directMentions, val replyId = originalNote?.idHex
relayList = relayList,
geohash = geoHash account?.sendPost(
) message = tagger.message,
} replyTo = tagger.replyTos,
mentions = tagger.mentions,
tags = null,
zapReceiver = zapReceiver,
wantsToMarkAsSensitive = wantsToMarkAsSensitive,
zapRaiserAmount = localZapRaiserAmount,
replyingTo = replyId,
root = rootId,
directMentions = tagger.directMentions,
relayList = relayList,
geohash = geoHash
)
} }
} finally {
cancel()
} }
cancel()
} }
fun upload( fun upload(galleryUri: Uri, description: String, sensitiveContent: Boolean, server: ServersAvailable, context: Context, relayList: List<Relay>? = null) {
galleryUri: Uri,
description: String,
sensitiveContent: Boolean,
server: ServersAvailable,
context: Context,
relayList: List<Relay>? = null
) {
isUploadingImage = true isUploadingImage = true
contentToAddUrl = null contentToAddUrl = null
@@ -313,35 +303,28 @@ open class NewPostViewModel() : ViewModel() {
createNIP95Record(it.readBytes(), contentType, description, sensitiveContent, relayList = relayList) createNIP95Record(it.readBytes(), contentType, description, sensitiveContent, relayList = relayList)
} }
} else { } else {
viewModelScope.launch(Dispatchers.IO) { ImageUploader.uploadImage(
ImageUploader.uploadImage( uri = fileUri,
uri = fileUri, contentType = contentType,
contentType = contentType, size = size,
size = size, server = server,
server = server, contentResolver = contentResolver,
contentResolver = contentResolver, onSuccess = { imageUrl, mimeType ->
onSuccess = { imageUrl, mimeType -> if (isNIP94Server(server)) {
if (isNIP94Server(server)) { createNIP94Record(imageUrl, mimeType, description, sensitiveContent)
createNIP94Record( } else {
imageUrl,
mimeType,
description,
sensitiveContent
)
} else {
isUploadingImage = false
message = TextFieldValue(message.text + "\n\n" + imageUrl)
urlPreview = findUrlInMessage()
}
},
onError = {
isUploadingImage = false isUploadingImage = false
viewModelScope.launch { message = TextFieldValue(message.text + "\n\n" + imageUrl)
imageUploadingError.emit("Failed to upload the image / video") urlPreview = findUrlInMessage()
}
} }
) },
} onError = {
isUploadingImage = false
viewModelScope.launch {
imageUploadingError.emit("Failed to upload the image / video")
}
}
)
} }
}, },
onError = { onError = {

View File

@@ -588,4 +588,6 @@
<string name="lightning_wallets_not_found2">Lightning wallets not found</string> <string name="lightning_wallets_not_found2">Lightning wallets not found</string>
<string name="paid">Paid</string> <string name="paid">Paid</string>
<string name="wallet_number">Wallet %1$s</string> <string name="wallet_number">Wallet %1$s</string>
<string name="error_opening_amber">Error opening Amber</string>
<string name="sign_request_rejected">Sign request rejected</string>
</resources> </resources>

View File

@@ -113,11 +113,12 @@ class LnZapRequestEvent(
pubKey: HexKey, pubKey: HexKey,
pollOption: Int?, pollOption: Int?,
message: String, message: String,
toUserPubHex: String?, // Overrides in case of Zap Splits
createdAt: Long = TimeUtils.now() createdAt: Long = TimeUtils.now()
): LnZapRequestEvent { ): LnZapRequestEvent {
var tags = listOf( var tags = listOf(
listOf("e", originalNote.id()), listOf("e", originalNote.id()),
listOf("p", originalNote.pubKey()), listOf("p", toUserPubHex ?: originalNote.pubKey()),
listOf("relays") + relays listOf("relays") + relays
) )
if (originalNote is AddressableEvent) { if (originalNote is AddressableEvent) {
@@ -137,12 +138,13 @@ class LnZapRequestEvent(
pubKey: HexKey, pubKey: HexKey,
pollOption: Int?, pollOption: Int?,
message: String, message: String,
toUserPubHex: String?,
createdAt: Long = TimeUtils.now() createdAt: Long = TimeUtils.now()
): LnZapRequestEvent { ): LnZapRequestEvent {
val content = message val content = message
var tags = listOf( var tags = listOf(
listOf("e", originalNote.id()), listOf("e", originalNote.id()),
listOf("p", originalNote.pubKey()), listOf("p", toUserPubHex ?: originalNote.pubKey()),
listOf("relays") + relays listOf("relays") + relays
) )
if (originalNote is AddressableEvent) { if (originalNote is AddressableEvent) {
@@ -162,11 +164,12 @@ class LnZapRequestEvent(
relays: Set<String>, relays: Set<String>,
pollOption: Int?, pollOption: Int?,
message: String, message: String,
toUserPubHex: String?, // Overrides in case of Zap Splits
createdAt: Long = TimeUtils.now() createdAt: Long = TimeUtils.now()
): LnZapRequestEvent { ): LnZapRequestEvent {
var tags = listOf( var tags = listOf(
listOf("e", originalNote.id()), listOf("e", originalNote.id()),
listOf("p", originalNote.pubKey()), listOf("p", toUserPubHex ?: originalNote.pubKey()),
listOf("relays") + relays listOf("relays") + relays
) )
if (originalNote is AddressableEvent) { if (originalNote is AddressableEvent) {