use content resolvers with amber

This commit is contained in:
greenart7c3
2023-09-15 11:56:07 -03:00
parent 21560d098e
commit bf9d318209
12 changed files with 405 additions and 455 deletions
@@ -110,11 +110,10 @@ class Account(
if (loginWithAmber) { if (loginWithAmber) {
val id = blockList?.id val id = blockList?.id
if (id != null) { if (id != null) {
if (AmberUtils.cachedDecryptedContent[blockList.id] == null) { if (blockList.decryptedContent == null) {
GlobalScope.launch(Dispatchers.IO) { GlobalScope.launch(Dispatchers.IO) {
val content = blockList.content val content = blockList.content
if (content.isEmpty()) return@launch if (content.isEmpty()) return@launch
AmberUtils.content = ""
AmberUtils.decryptBlockList( AmberUtils.decryptBlockList(
content, content,
keyPair.pubKey.toHexKey(), keyPair.pubKey.toHexKey(),
@@ -222,10 +221,11 @@ class Account(
if (loginWithAmber) { if (loginWithAmber) {
AmberUtils.openAmber(event) AmberUtils.openAmber(event)
if (AmberUtils.content.isBlank()) { val content = AmberUtils.content[event.id] ?: ""
if (content.isBlank()) {
return return
} }
event = ContactListEvent.create(event, AmberUtils.content) event = ContactListEvent.create(event, content)
} }
Client.send(event) Client.send(event)
@@ -243,10 +243,11 @@ class Account(
if (loginWithAmber) { if (loginWithAmber) {
AmberUtils.openAmber(event) AmberUtils.openAmber(event)
if (AmberUtils.content.isBlank()) { val content = AmberUtils.content[event.id]
if (content.isBlank()) {
return return
} }
event = ContactListEvent.create(event, AmberUtils.content) event = ContactListEvent.create(event, content)
} }
// Keep this local to avoid erasing a good contact list. // Keep this local to avoid erasing a good contact list.
@@ -260,11 +261,11 @@ class Account(
var event = MetadataEvent.create(toString, identities, keyPair.pubKey.toHexKey(), keyPair.privKey) var event = MetadataEvent.create(toString, identities, keyPair.pubKey.toHexKey(), keyPair.privKey)
if (loginWithAmber) { if (loginWithAmber) {
AmberUtils.openAmber(event) val content = AmberUtils.content[event.id]
if (AmberUtils.content.isBlank()) { if (content.isBlank()) {
return return
} }
event = MetadataEvent.create(event, AmberUtils.content) event = MetadataEvent.create(event, content)
} }
Client.send(event) Client.send(event)
LocalCache.consume(event) LocalCache.consume(event)
@@ -314,21 +315,25 @@ class Account(
) )
AmberUtils.openAmber(senderReaction) AmberUtils.openAmber(senderReaction)
if (AmberUtils.content.isBlank()) return val reactionContent = AmberUtils.content[event.id]
senderReaction = ReactionEvent.create(senderReaction, AmberUtils.content) if (reactionContent.isBlank()) return
senderReaction = ReactionEvent.create(senderReaction, reactionContent)
val giftWraps = users.plus(senderPublicKey).map { val giftWraps = users.plus(senderPublicKey).map {
val gossip = Gossip.create(senderReaction) val gossip = Gossip.create(senderReaction)
val content = Gossip.toJson(gossip) val content = Gossip.toJson(gossip)
AmberUtils.encrypt(content, it, SignerType.NIP44_ENCRYPT) AmberUtils.encrypt(content, it, gossip.id!!, SignerType.NIP44_ENCRYPT)
val encryptedContent = AmberUtils.content[gossip.id]
if (encryptedContent.isBlank()) return
var sealedEvent = SealedGossipEvent.create( var sealedEvent = SealedGossipEvent.create(
encryptedContent = AmberUtils.content, encryptedContent = encryptedContent,
pubKey = senderPublicKey pubKey = senderPublicKey
) )
AmberUtils.openAmber(sealedEvent) AmberUtils.openAmber(sealedEvent)
if (AmberUtils.content.isBlank()) return val eventContent = AmberUtils.content[sealedEvent.id] ?: ""
sealedEvent = SealedGossipEvent.create(sealedEvent, AmberUtils.content) if (eventContent.isBlank()) return
sealedEvent = SealedGossipEvent.create(sealedEvent, eventContent)
GiftWrapEvent.create( GiftWrapEvent.create(
event = sealedEvent, event = sealedEvent,
@@ -363,23 +368,26 @@ class Account(
) )
AmberUtils.openAmber(senderReaction) AmberUtils.openAmber(senderReaction)
if (AmberUtils.content.isBlank()) return val reactionContent = AmberUtils.content[senderReaction.id] ?: ""
senderReaction = ReactionEvent.create(senderReaction, AmberUtils.content) if (reactionContent.isBlank()) return
senderReaction = ReactionEvent.create(senderReaction, reactionContent)
val newUsers = users.plus(senderPublicKey) val newUsers = users.plus(senderPublicKey)
newUsers.forEach { newUsers.forEach {
val gossip = Gossip.create(senderReaction) val gossip = Gossip.create(senderReaction)
val content = Gossip.toJson(gossip) val content = Gossip.toJson(gossip)
AmberUtils.content = "" AmberUtils.encrypt(content, it, gossip.id!!, SignerType.NIP44_ENCRYPT)
AmberUtils.encrypt(content, it, SignerType.NIP44_ENCRYPT) val encryptedContent = AmberUtils.content[gossip.id]
if (encryptedContent.isBlank()) return
var sealedEvent = SealedGossipEvent.create( var sealedEvent = SealedGossipEvent.create(
encryptedContent = AmberUtils.content, encryptedContent = encryptedContent,
pubKey = senderPublicKey pubKey = senderPublicKey
) )
AmberUtils.openAmber(sealedEvent) AmberUtils.openAmber(sealedEvent)
if (AmberUtils.content.isBlank()) return val sealedContent = AmberUtils.content[sealedEvent.id] ?: ""
sealedEvent = SealedGossipEvent.create(sealedEvent, AmberUtils.content) if (sealedContent.isBlank()) return
sealedEvent = SealedGossipEvent.create(sealedEvent, sealedContent)
val giftWraps = GiftWrapEvent.create( val giftWraps = GiftWrapEvent.create(
event = sealedEvent, event = sealedEvent,
@@ -511,8 +519,9 @@ class Account(
if (privKey != null) return zapResponseEvent.response(privKey, pubKey) if (privKey != null) return zapResponseEvent.response(privKey, pubKey)
AmberUtils.decrypt(zapResponseEvent.content, pubKey.toHexKey(), zapResponseEvent.id) AmberUtils.decrypt(zapResponseEvent.content, pubKey.toHexKey(), zapResponseEvent.id)
if (AmberUtils.content.isBlank()) return null val decryptedContent = AmberUtils.content[zapResponseEvent.id] ?: ""
return zapResponseEvent.response(AmberUtils.content) if (decryptedContent.isBlank()) return null
return zapResponseEvent.response(decryptedContent)
} }
fun calculateIfNoteWasZappedByAccount(zappedNote: Note?): Boolean { fun calculateIfNoteWasZappedByAccount(zappedNote: Note?): Boolean {
@@ -582,16 +591,16 @@ class Account(
note.event?.let { note.event?.let {
var event = ReactionEvent.createWarning(it, keyPair) var event = ReactionEvent.createWarning(it, keyPair)
if (loginWithAmber) { if (loginWithAmber) {
AmberUtils.content = ""
AmberUtils.openAmber(event) AmberUtils.openAmber(event)
if (AmberUtils.content.isBlank()) return val eventContent = AmberUtils.content[event.id] ?: ""
if (eventContent.isBlank()) return
event = ReactionEvent( event = ReactionEvent(
event.id, event.id,
event.pubKey, event.pubKey,
event.createdAt, event.createdAt,
event.tags, event.tags,
event.content, event.content,
AmberUtils.content eventContent
) )
} }
Client.send(event) Client.send(event)
@@ -601,16 +610,16 @@ class Account(
note.event?.let { note.event?.let {
var event = ReportEvent.create(it, type, keyPair, content = content) var event = ReportEvent.create(it, type, keyPair, content = content)
if (loginWithAmber) { if (loginWithAmber) {
AmberUtils.content = ""
AmberUtils.openAmber(event) AmberUtils.openAmber(event)
if (AmberUtils.content.isBlank()) return val eventContent = AmberUtils.content[event.id] ?: ""
if (eventContent.isBlank()) return
event = ReportEvent( event = ReportEvent(
event.id, event.id,
event.pubKey, event.pubKey,
event.createdAt, event.createdAt,
event.tags, event.tags,
event.content, event.content,
AmberUtils.content eventContent
) )
} }
Client.send(event) Client.send(event)
@@ -628,16 +637,16 @@ class Account(
var event = ReportEvent.create(user.pubkeyHex, type, keyPair) var event = ReportEvent.create(user.pubkeyHex, type, keyPair)
if (loginWithAmber) { if (loginWithAmber) {
AmberUtils.content = ""
AmberUtils.openAmber(event) AmberUtils.openAmber(event)
if (AmberUtils.content.isBlank()) return val eventContent = AmberUtils.content[event.id] ?: ""
if (eventContent.isBlank()) return
event = ReportEvent( event = ReportEvent(
event.id, event.id,
event.pubKey, event.pubKey,
event.createdAt, event.createdAt,
event.tags, event.tags,
event.content, event.content,
AmberUtils.content eventContent
) )
} }
Client.send(event) Client.send(event)
@@ -670,10 +679,11 @@ class Account(
var event = HTTPAuthorizationEvent.create(url, method, body, keyPair) var event = HTTPAuthorizationEvent.create(url, method, body, keyPair)
if (loginWithAmber) { if (loginWithAmber) {
AmberUtils.openAmber(event) AmberUtils.openAmber(event)
if (AmberUtils.content.isBlank()) { val eventContent = AmberUtils.content[event.id] ?: ""
if (eventContent.isBlank()) {
return null return null
} }
event = HTTPAuthorizationEvent.create(event, AmberUtils.content) event = HTTPAuthorizationEvent.create(event, eventContent)
} }
return event return event
} }
@@ -734,10 +744,11 @@ class Account(
keyPair keyPair
) )
AmberUtils.openAmber(unsignedEvent) AmberUtils.openAmber(unsignedEvent)
returningContactList = if (AmberUtils.content.isBlank()) { val eventContent = AmberUtils.content[unsignedEvent.id] ?: ""
returningContactList = if (eventContent.isBlank()) {
latestContactList latestContactList
} else { } else {
ContactListEvent.create(unsignedEvent, AmberUtils.content) ContactListEvent.create(unsignedEvent, eventContent)
} }
} else { } else {
returningContactList = ContactListEvent.followAddressableEvent( returningContactList = ContactListEvent.followAddressableEvent(
@@ -782,10 +793,11 @@ class Account(
if (loginWithAmber) { if (loginWithAmber) {
AmberUtils.openAmber(event) AmberUtils.openAmber(event)
if (AmberUtils.content.isBlank()) { val eventContent = AmberUtils.content[event.id] ?: ""
if (eventContent.isBlank()) {
return return
} }
event = ContactListEvent.create(event, AmberUtils.content) event = ContactListEvent.create(event, eventContent)
} }
Client.send(event) Client.send(event)
@@ -813,10 +825,11 @@ class Account(
if (loginWithAmber) { if (loginWithAmber) {
AmberUtils.openAmber(event) AmberUtils.openAmber(event)
if (AmberUtils.content.isBlank()) { val eventContent = AmberUtils.content[event.id] ?: ""
if (eventContent.isBlank()) {
return return
} }
event = ContactListEvent.create(event, AmberUtils.content) event = ContactListEvent.create(event, eventContent)
} }
Client.send(event) Client.send(event)
@@ -845,10 +858,11 @@ class Account(
if (loginWithAmber) { if (loginWithAmber) {
AmberUtils.openAmber(event) AmberUtils.openAmber(event)
if (AmberUtils.content.isBlank()) { val eventContent = AmberUtils.content[event.id] ?: ""
if (eventContent.isBlank()) {
return return
} }
event = ContactListEvent.create(event, AmberUtils.content) event = ContactListEvent.create(event, eventContent)
} }
Client.send(event) Client.send(event)
@@ -880,10 +894,11 @@ class Account(
if (loginWithAmber) { if (loginWithAmber) {
AmberUtils.openAmber(event) AmberUtils.openAmber(event)
if (AmberUtils.content.isBlank()) { val eventContent = AmberUtils.content[event.id] ?: ""
if (eventContent.isBlank()) {
return return
} }
event = ContactListEvent.create(event, AmberUtils.content) event = ContactListEvent.create(event, eventContent)
} }
Client.send(event) Client.send(event)
@@ -915,10 +930,11 @@ class Account(
if (loginWithAmber) { if (loginWithAmber) {
AmberUtils.openAmber(event) AmberUtils.openAmber(event)
if (AmberUtils.content.isBlank()) { val eventContent = AmberUtils.content[event.id] ?: ""
if (eventContent.isBlank()) {
return return
} }
event = ContactListEvent.create(event, AmberUtils.content) event = ContactListEvent.create(event, eventContent)
} }
Client.send(event) Client.send(event)
@@ -939,10 +955,11 @@ class Account(
if (loginWithAmber) { if (loginWithAmber) {
AmberUtils.openAmber(event) AmberUtils.openAmber(event)
if (AmberUtils.content.isBlank()) { val eventContent = AmberUtils.content[event.id] ?: ""
if (eventContent.isBlank()) {
return return
} }
event = ContactListEvent.create(event, AmberUtils.content) event = ContactListEvent.create(event, eventContent)
} }
Client.send(event) Client.send(event)
@@ -964,10 +981,11 @@ class Account(
if (loginWithAmber) { if (loginWithAmber) {
AmberUtils.openAmber(event) AmberUtils.openAmber(event)
if (AmberUtils.content.isBlank()) { val eventContent = AmberUtils.content[event.id] ?: ""
if (eventContent.isBlank()) {
return return
} }
event = ContactListEvent.create(event, AmberUtils.content) event = ContactListEvent.create(event, eventContent)
} }
Client.send(event) Client.send(event)
@@ -989,10 +1007,11 @@ class Account(
if (loginWithAmber) { if (loginWithAmber) {
AmberUtils.openAmber(event) AmberUtils.openAmber(event)
if (AmberUtils.content.isBlank()) { val eventContent = AmberUtils.content[event.id] ?: ""
if (eventContent.isBlank()) {
return return
} }
event = ContactListEvent.create(event, AmberUtils.content) event = ContactListEvent.create(event, eventContent)
} }
Client.send(event) Client.send(event)
@@ -1014,10 +1033,11 @@ class Account(
if (loginWithAmber) { if (loginWithAmber) {
AmberUtils.openAmber(event) AmberUtils.openAmber(event)
if (AmberUtils.content.isBlank()) { val eventContent = AmberUtils.content[event.id] ?: ""
if (eventContent.isBlank()) {
return return
} }
event = ContactListEvent.create(event, AmberUtils.content) event = ContactListEvent.create(event, eventContent)
} }
Client.send(event) Client.send(event)
@@ -1039,10 +1059,11 @@ class Account(
if (loginWithAmber) { if (loginWithAmber) {
AmberUtils.openAmber(event) AmberUtils.openAmber(event)
if (AmberUtils.content.isBlank()) { val eventContent = AmberUtils.content[event.id] ?: ""
if (eventContent.isBlank()) {
return return
} }
event = ContactListEvent.create(event, AmberUtils.content) event = ContactListEvent.create(event, eventContent)
} }
Client.send(event) Client.send(event)
@@ -1061,14 +1082,15 @@ class Account(
) )
AmberUtils.openAmber(unsignedData) AmberUtils.openAmber(unsignedData)
if (AmberUtils.content.isBlank()) return null val eventContent = AmberUtils.content[unsignedData.id] ?: ""
if (eventContent.isBlank()) return null
val data = FileStorageEvent( val data = FileStorageEvent(
unsignedData.id, unsignedData.id,
unsignedData.pubKey, unsignedData.pubKey,
unsignedData.createdAt, unsignedData.createdAt,
unsignedData.tags, unsignedData.tags,
unsignedData.content, unsignedData.content,
AmberUtils.content eventContent
) )
val unsignedEvent = FileStorageHeaderEvent.create( val unsignedEvent = FileStorageHeaderEvent.create(
@@ -1084,14 +1106,15 @@ class Account(
) )
AmberUtils.openAmber(unsignedEvent) AmberUtils.openAmber(unsignedEvent)
if (AmberUtils.content.isBlank()) return null val unsignedEventContent = AmberUtils.content[unsignedEvent.id] ?: ""
if (unsignedEventContent.isBlank()) return null
val signedEvent = FileStorageHeaderEvent( val signedEvent = FileStorageHeaderEvent(
unsignedEvent.id, unsignedEvent.id,
unsignedEvent.pubKey, unsignedEvent.pubKey,
unsignedEvent.createdAt, unsignedEvent.createdAt,
unsignedEvent.tags, unsignedEvent.tags,
unsignedEvent.content, unsignedEvent.content,
AmberUtils.content unsignedEventContent
) )
return Pair(data, signedEvent) return Pair(data, signedEvent)
@@ -1153,14 +1176,15 @@ class Account(
keyPair = keyPair keyPair = keyPair
) )
AmberUtils.openAmber(unsignedEvent) AmberUtils.openAmber(unsignedEvent)
if (AmberUtils.content.isBlank()) return null val eventContent = AmberUtils.content[unsignedEvent.id] ?: ""
if (eventContent.isBlank()) return null
val signedEvent = FileHeaderEvent( val signedEvent = FileHeaderEvent(
unsignedEvent.id, unsignedEvent.id,
unsignedEvent.pubKey, unsignedEvent.pubKey,
unsignedEvent.createdAt, unsignedEvent.createdAt,
unsignedEvent.tags, unsignedEvent.tags,
unsignedEvent.content, unsignedEvent.content,
AmberUtils.content eventContent
) )
return sendHeader(signedEvent, relayList = relayList) return sendHeader(signedEvent, relayList = relayList)
@@ -1219,10 +1243,11 @@ class Account(
if (loginWithAmber) { if (loginWithAmber) {
AmberUtils.openAmber(signedEvent) AmberUtils.openAmber(signedEvent)
if (AmberUtils.content.isBlank()) { val eventContent = AmberUtils.content[signedEvent.id] ?: ""
if (eventContent.isBlank()) {
return return
} }
signedEvent = TextNoteEvent.create(signedEvent, AmberUtils.content) signedEvent = TextNoteEvent.create(signedEvent, eventContent)
} }
Client.send(signedEvent, relayList = relayList) Client.send(signedEvent, relayList = relayList)
@@ -1288,10 +1313,11 @@ class Account(
if (loginWithAmber) { if (loginWithAmber) {
AmberUtils.openAmber(signedEvent) AmberUtils.openAmber(signedEvent)
if (AmberUtils.content.isBlank()) { val eventContent = AmberUtils.content[signedEvent.id] ?: ""
if (eventContent.isBlank()) {
return return
} }
signedEvent = PollNoteEvent.create(signedEvent, AmberUtils.content) signedEvent = PollNoteEvent.create(signedEvent, eventContent)
} }
Client.send(signedEvent, relayList = relayList) Client.send(signedEvent, relayList = relayList)
@@ -1339,10 +1365,11 @@ class Account(
if (loginWithAmber) { if (loginWithAmber) {
AmberUtils.openAmber(signedEvent) AmberUtils.openAmber(signedEvent)
if (AmberUtils.content.isBlank()) { val eventContent = AmberUtils.content[signedEvent.id] ?: ""
if (eventContent.isBlank()) {
return return
} }
signedEvent = ChannelMessageEvent.create(signedEvent, AmberUtils.content) signedEvent = ChannelMessageEvent.create(signedEvent, eventContent)
} }
Client.send(signedEvent) Client.send(signedEvent)
@@ -1379,10 +1406,11 @@ class Account(
if (loginWithAmber) { if (loginWithAmber) {
AmberUtils.openAmber(signedEvent) AmberUtils.openAmber(signedEvent)
if (AmberUtils.content.isBlank()) { val eventContent = AmberUtils.content[signedEvent.id] ?: ""
if (eventContent.isBlank()) {
return return
} }
signedEvent = LiveActivitiesChatMessageEvent.create(signedEvent, AmberUtils.content) signedEvent = LiveActivitiesChatMessageEvent.create(signedEvent, eventContent)
} }
Client.send(signedEvent) Client.send(signedEvent)
@@ -1410,10 +1438,11 @@ class Account(
var localMessage = message var localMessage = message
if (loginWithAmber) { if (loginWithAmber) {
AmberUtils.content = "" AmberUtils.encrypt(localMessage, toUser, "encrypt")
AmberUtils.encrypt(localMessage, toUser) val eventContent = AmberUtils.content["encrypt"] ?: ""
if (AmberUtils.content.isBlank()) return if (eventContent.isBlank()) return
localMessage = AmberUtils.content localMessage = eventContent
AmberUtils.content.remove("encrypt")
} }
var signedEvent = PrivateDmEvent.create( var signedEvent = PrivateDmEvent.create(
@@ -1432,10 +1461,11 @@ class Account(
if (loginWithAmber) { if (loginWithAmber) {
AmberUtils.openAmber(signedEvent) AmberUtils.openAmber(signedEvent)
if (AmberUtils.content.isBlank()) { val eventContent = AmberUtils.content[signedEvent.id] ?: ""
if (eventContent.isBlank()) {
return return
} }
signedEvent = PrivateDmEvent.create(signedEvent, AmberUtils.content) signedEvent = PrivateDmEvent.create(signedEvent, eventContent)
} }
Client.send(signedEvent) Client.send(signedEvent)
@@ -1473,22 +1503,24 @@ class Account(
) )
AmberUtils.openAmber(chatMessageEvent) AmberUtils.openAmber(chatMessageEvent)
if (AmberUtils.content.isBlank()) return val eventContent = AmberUtils.content[chatMessageEvent.id] ?: ""
chatMessageEvent = ChatMessageEvent.create(chatMessageEvent, AmberUtils.content) if (eventContent.isBlank()) return
chatMessageEvent = ChatMessageEvent.create(chatMessageEvent, eventContent)
val senderPublicKey = keyPair.pubKey.toHexKey() val senderPublicKey = keyPair.pubKey.toHexKey()
toUsers.plus(senderPublicKey).toSet().forEach { toUsers.plus(senderPublicKey).toSet().forEach {
val gossip = Gossip.create(chatMessageEvent) val gossip = Gossip.create(chatMessageEvent)
val content = Gossip.toJson(gossip) val content = Gossip.toJson(gossip)
AmberUtils.content = "" AmberUtils.encrypt(content, it, gossip.id!!, SignerType.NIP44_ENCRYPT)
AmberUtils.encrypt(content, it, SignerType.NIP44_ENCRYPT) val gossipContent = AmberUtils.content[gossip.id] ?: ""
if (AmberUtils.content.isNotBlank()) { if (gossipContent.isNotBlank()) {
var sealedEvent = SealedGossipEvent.create( var sealedEvent = SealedGossipEvent.create(
encryptedContent = AmberUtils.content, encryptedContent = gossipContent,
pubKey = senderPublicKey pubKey = senderPublicKey
) )
AmberUtils.openAmber(sealedEvent) AmberUtils.openAmber(sealedEvent)
if (AmberUtils.content.isBlank()) return val sealedEventContent = AmberUtils.content[sealedEvent.id] ?: ""
sealedEvent = SealedGossipEvent.create(sealedEvent, AmberUtils.content) if (sealedEventContent.isBlank()) return
sealedEvent = SealedGossipEvent.create(sealedEvent, sealedEventContent)
val giftWraps = GiftWrapEvent.create( val giftWraps = GiftWrapEvent.create(
event = sealedEvent, event = sealedEvent,
@@ -1522,13 +1554,11 @@ class Account(
// Only keep in cache the GiftWrap for the account. // Only keep in cache the GiftWrap for the account.
if (it.recipientPubKey() == keyPair.pubKey.toHexKey()) { if (it.recipientPubKey() == keyPair.pubKey.toHexKey()) {
if (loginWithAmber) { if (loginWithAmber) {
AmberUtils.content = ""
AmberUtils.decrypt(it.content, it.pubKey, it.id, SignerType.NIP44_DECRYPT) AmberUtils.decrypt(it.content, it.pubKey, it.id, SignerType.NIP44_DECRYPT)
val decryptedContent = AmberUtils.cachedDecryptedContent[it.id] ?: "" val decryptedContent = AmberUtils.cachedDecryptedContent[it.id] ?: ""
if (decryptedContent.isEmpty()) return if (decryptedContent.isEmpty()) return
it.cachedGift(keyPair.pubKey, decryptedContent)?.let { cached -> it.cachedGift(keyPair.pubKey, decryptedContent)?.let { cached ->
if (cached is SealedGossipEvent) { if (cached is SealedGossipEvent) {
AmberUtils.content = ""
AmberUtils.decrypt(cached.content, cached.pubKey, cached.id, SignerType.NIP44_DECRYPT) AmberUtils.decrypt(cached.content, cached.pubKey, cached.id, SignerType.NIP44_DECRYPT)
val localDecryptedContent = AmberUtils.cachedDecryptedContent[cached.id] ?: "" val localDecryptedContent = AmberUtils.cachedDecryptedContent[cached.id] ?: ""
if (localDecryptedContent.isEmpty()) return if (localDecryptedContent.isEmpty()) return
@@ -1572,10 +1602,11 @@ class Account(
if (loginWithAmber) { if (loginWithAmber) {
AmberUtils.openAmber(event) AmberUtils.openAmber(event)
if (AmberUtils.content.isBlank()) { val eventContent = AmberUtils.content[event.id] ?: ""
if (eventContent.isBlank()) {
return return
} }
event = ChannelCreateEvent.create(event, AmberUtils.content) event = ChannelCreateEvent.create(event, eventContent)
} }
Client.send(event) Client.send(event)
@@ -1593,10 +1624,11 @@ class Account(
var event = StatusEvent.update(oldEvent, newStatus, keyPair) var event = StatusEvent.update(oldEvent, newStatus, keyPair)
if (loginWithAmber) { if (loginWithAmber) {
AmberUtils.openAmber(event) AmberUtils.openAmber(event)
if (AmberUtils.content.isBlank()) { val eventContent = AmberUtils.content[event.id] ?: ""
if (eventContent.isBlank()) {
return return
} }
event = StatusEvent.create(event, AmberUtils.content) event = StatusEvent.create(event, eventContent)
} }
Client.send(event) Client.send(event)
LocalCache.consume(event, null) LocalCache.consume(event, null)
@@ -1608,10 +1640,11 @@ class Account(
var event = StatusEvent.create(newStatus, "general", expiration = null, keyPair) var event = StatusEvent.create(newStatus, "general", expiration = null, keyPair)
if (loginWithAmber) { if (loginWithAmber) {
AmberUtils.openAmber(event) AmberUtils.openAmber(event)
if (AmberUtils.content.isBlank()) { val eventContent = AmberUtils.content[event.id] ?: ""
if (eventContent.isBlank()) {
return return
} }
event = StatusEvent.create(event, AmberUtils.content) event = StatusEvent.create(event, eventContent)
} }
Client.send(event) Client.send(event)
LocalCache.consume(event, null) LocalCache.consume(event, null)
@@ -1624,10 +1657,11 @@ class Account(
var event = StatusEvent.clear(oldEvent, keyPair) var event = StatusEvent.clear(oldEvent, keyPair)
if (loginWithAmber) { if (loginWithAmber) {
AmberUtils.openAmber(event) AmberUtils.openAmber(event)
if (AmberUtils.content.isBlank()) { val eventContent = AmberUtils.content[event.id] ?: ""
if (eventContent.isBlank()) {
return return
} }
event = StatusEvent.create(event, AmberUtils.content) event = StatusEvent.create(event, eventContent)
} }
Client.send(event) Client.send(event)
LocalCache.consume(event, null) LocalCache.consume(event, null)
@@ -1635,10 +1669,11 @@ class Account(
var event2 = DeletionEvent.create(listOf(event.id), keyPair) var event2 = DeletionEvent.create(listOf(event.id), keyPair)
if (loginWithAmber) { if (loginWithAmber) {
AmberUtils.openAmber(event2) AmberUtils.openAmber(event2)
if (AmberUtils.content.isBlank()) { val event2Content = AmberUtils.content[event2.id] ?: ""
if (event2Content.isBlank()) {
return return
} }
event2 = DeletionEvent.create(event2, AmberUtils.content) event2 = DeletionEvent.create(event2, event2Content)
} }
Client.send(event2) Client.send(event2)
LocalCache.consume(event2) LocalCache.consume(event2)
@@ -1659,10 +1694,11 @@ class Account(
if (loginWithAmber) { if (loginWithAmber) {
AmberUtils.openAmber(event) AmberUtils.openAmber(event)
if (AmberUtils.content.isBlank()) { val eventContent = AmberUtils.content[event.id] ?: ""
if (eventContent.isBlank()) {
return return
} }
event = EmojiPackSelectionEvent.create(event, AmberUtils.content) event = EmojiPackSelectionEvent.create(event, eventContent)
} }
Client.send(event) Client.send(event)
@@ -1695,10 +1731,11 @@ class Account(
if (loginWithAmber) { if (loginWithAmber) {
AmberUtils.openAmber(event) AmberUtils.openAmber(event)
if (AmberUtils.content.isBlank()) { val eventContent = AmberUtils.content[event.id] ?: ""
if (eventContent.isBlank()) {
return return
} }
event = EmojiPackSelectionEvent.create(event, AmberUtils.content) event = EmojiPackSelectionEvent.create(event, eventContent)
} }
Client.send(event) Client.send(event)
@@ -1732,9 +1769,10 @@ class Account(
} }
val msg = Event.mapper.writeValueAsString(privTags) val msg = Event.mapper.writeValueAsString(privTags)
AmberUtils.encrypt(msg, keyPair.pubKey.toHexKey()) AmberUtils.encrypt(msg, keyPair.pubKey.toHexKey(), "encrypt")
val encryptedContent = AmberUtils.content["encrypt"] ?: ""
if (AmberUtils.content.isBlank()) { AmberUtils.content.remove("encrypt")
if (encryptedContent.isBlank()) {
return return
} }
@@ -1744,16 +1782,17 @@ class Account(
bookmarks?.taggedUsers() ?: emptyList(), bookmarks?.taggedUsers() ?: emptyList(),
bookmarks?.taggedAddresses() ?: emptyList(), bookmarks?.taggedAddresses() ?: emptyList(),
AmberUtils.content, encryptedContent,
keyPair.pubKey.toHexKey() keyPair.pubKey.toHexKey()
) )
AmberUtils.openAmber(event) AmberUtils.openAmber(event)
if (AmberUtils.content.isBlank()) { val eventContent = AmberUtils.content[event.id] ?: ""
if (eventContent.isBlank()) {
return return
} }
event = BookmarkListEvent.create(event, AmberUtils.content) event = BookmarkListEvent.create(event, eventContent)
Client.send(event) Client.send(event)
LocalCache.consume(event) LocalCache.consume(event)
@@ -1786,9 +1825,10 @@ class Account(
} }
val msg = Event.mapper.writeValueAsString(privTags) val msg = Event.mapper.writeValueAsString(privTags)
AmberUtils.encrypt(msg, keyPair.pubKey.toHexKey()) AmberUtils.encrypt(msg, keyPair.pubKey.toHexKey(), "encrypt")
val encryptedContent = AmberUtils.content["encrypt"] ?: ""
if (AmberUtils.content.isBlank()) { AmberUtils.content.remove("encrypt")
if (encryptedContent.isBlank()) {
return return
} }
@@ -1798,16 +1838,17 @@ class Account(
bookmarks?.taggedUsers() ?: emptyList(), bookmarks?.taggedUsers() ?: emptyList(),
bookmarks?.taggedAddresses() ?: emptyList(), bookmarks?.taggedAddresses() ?: emptyList(),
AmberUtils.content, encryptedContent,
keyPair.pubKey.toHexKey() keyPair.pubKey.toHexKey()
) )
AmberUtils.openAmber(event) AmberUtils.openAmber(event)
if (AmberUtils.content.isBlank()) { val eventContent = AmberUtils.content[event.id] ?: ""
if (eventContent.isBlank()) {
return return
} }
event = BookmarkListEvent.create(event, AmberUtils.content) event = BookmarkListEvent.create(event, eventContent)
Client.send(event) Client.send(event)
LocalCache.consume(event) LocalCache.consume(event)
@@ -1870,9 +1911,10 @@ class Account(
} }
val msg = Event.mapper.writeValueAsString(privTags) val msg = Event.mapper.writeValueAsString(privTags)
AmberUtils.encrypt(msg, keyPair.pubKey.toHexKey()) AmberUtils.encrypt(msg, keyPair.pubKey.toHexKey(), "encrypt")
val encryptedContent = AmberUtils.content["encrypt"] ?: ""
if (AmberUtils.content.isBlank()) { AmberUtils.content.remove("encrypt")
if (encryptedContent.isBlank()) {
return return
} }
@@ -1882,7 +1924,7 @@ class Account(
bookmarks?.taggedEvents() ?: emptyList(), bookmarks?.taggedEvents() ?: emptyList(),
bookmarks?.taggedUsers() ?: emptyList(), bookmarks?.taggedUsers() ?: emptyList(),
bookmarks?.taggedAddresses()?.plus(note.address) ?: listOf(note.address), bookmarks?.taggedAddresses()?.plus(note.address) ?: listOf(note.address),
AmberUtils.content, encryptedContent,
keyPair.pubKey.toHexKey() keyPair.pubKey.toHexKey()
) )
} else { } else {
@@ -1891,15 +1933,16 @@ class Account(
bookmarks?.taggedEvents()?.plus(note.idHex) ?: listOf(note.idHex), bookmarks?.taggedEvents()?.plus(note.idHex) ?: listOf(note.idHex),
bookmarks?.taggedUsers() ?: emptyList(), bookmarks?.taggedUsers() ?: emptyList(),
bookmarks?.taggedAddresses() ?: emptyList(), bookmarks?.taggedAddresses() ?: emptyList(),
AmberUtils.content, encryptedContent,
keyPair.pubKey.toHexKey() keyPair.pubKey.toHexKey()
) )
} }
AmberUtils.openAmber(event) AmberUtils.openAmber(event)
if (AmberUtils.content.isBlank()) { val eventContent = AmberUtils.content[event.id] ?: ""
if (eventContent.isBlank()) {
return return
} }
event = BookmarkListEvent.create(event, AmberUtils.content) event = BookmarkListEvent.create(event, encryptedContent)
Client.send(event) Client.send(event)
LocalCache.consume(event) LocalCache.consume(event)
@@ -1985,10 +2028,11 @@ class Account(
var event = RelayAuthEvent.create(relay.url, challenge, keyPair.pubKey.toHexKey(), keyPair.privKey) var event = RelayAuthEvent.create(relay.url, challenge, keyPair.pubKey.toHexKey(), keyPair.privKey)
if (loginWithAmber) { if (loginWithAmber) {
AmberUtils.openAmber(event) AmberUtils.openAmber(event)
if (AmberUtils.content.isBlank()) { val eventContent = AmberUtils.content[event.id] ?: ""
if (eventContent.isBlank()) {
return null return null
} }
event = RelayAuthEvent.create(event, AmberUtils.content) event = RelayAuthEvent.create(event, eventContent)
} }
return event return event
@@ -2051,9 +2095,10 @@ class Account(
} }
val msg = Event.mapper.writeValueAsString(privTags) val msg = Event.mapper.writeValueAsString(privTags)
AmberUtils.encrypt(msg, keyPair.pubKey.toHexKey()) AmberUtils.encrypt(msg, keyPair.pubKey.toHexKey(), "encrypt")
val encryptedContent = AmberUtils.content["encrypt"] ?: ""
if (AmberUtils.content.isBlank()) { AmberUtils.content.remove("encrypt")
if (encryptedContent.isBlank()) {
return return
} }
@@ -2063,7 +2108,7 @@ class Account(
bookmarks?.taggedEvents() ?: emptyList(), bookmarks?.taggedEvents() ?: emptyList(),
bookmarks?.taggedUsers() ?: emptyList(), bookmarks?.taggedUsers() ?: emptyList(),
bookmarks?.taggedAddresses()?.minus(note.address), bookmarks?.taggedAddresses()?.minus(note.address),
AmberUtils.content, encryptedContent,
keyPair.pubKey.toHexKey() keyPair.pubKey.toHexKey()
) )
} else { } else {
@@ -2072,16 +2117,17 @@ class Account(
bookmarks?.taggedEvents()?.minus(note.idHex), bookmarks?.taggedEvents()?.minus(note.idHex),
bookmarks?.taggedUsers() ?: emptyList(), bookmarks?.taggedUsers() ?: emptyList(),
bookmarks?.taggedAddresses() ?: emptyList(), bookmarks?.taggedAddresses() ?: emptyList(),
AmberUtils.content, encryptedContent,
keyPair.pubKey.toHexKey() keyPair.pubKey.toHexKey()
) )
} }
AmberUtils.openAmber(event) AmberUtils.openAmber(event)
if (AmberUtils.content.isBlank()) { val eventContent = AmberUtils.content[event.id] ?: ""
if (eventContent.isBlank()) {
return return
} }
event = BookmarkListEvent.create(event, AmberUtils.content) event = BookmarkListEvent.create(event, eventContent)
Client.send(event) Client.send(event)
LocalCache.consume(event) LocalCache.consume(event)
@@ -2154,25 +2200,26 @@ class Account(
val privateTags = listOf(listOf("p", pubkeyHex)) val privateTags = listOf(listOf("p", pubkeyHex))
val msg = Event.mapper.writeValueAsString(privateTags) val msg = Event.mapper.writeValueAsString(privateTags)
AmberUtils.content = "" AmberUtils.encrypt(msg, keyPair.pubKey.toHexKey(), "encrypt")
AmberUtils.encrypt(msg, keyPair.pubKey.toHexKey()) val encryptedContent = AmberUtils.content["encrypted"] ?: ""
if (AmberUtils.content.isBlank()) return AmberUtils.content.remove("encrypted")
AmberUtils.content if (encryptedContent.isBlank()) return
encryptedContent
} else { } else {
var decryptedContent = AmberUtils.cachedDecryptedContent[id] var decryptedContent = AmberUtils.cachedDecryptedContent[id]
if (decryptedContent == null) { if (decryptedContent == null) {
AmberUtils.content = "" AmberUtils.decrypt(blockList.content, keyPair.pubKey.toHexKey(), id)
AmberUtils.decrypt(blockList.content, keyPair.pubKey.toHexKey(), blockList.id) val content = AmberUtils.content[id] ?: ""
if (AmberUtils.content.isBlank()) return if (content.isBlank()) return
decryptedContent = AmberUtils.content decryptedContent = content
} }
val privateTags = blockList.privateTagsOrEmpty(decryptedContent).plus(element = listOf("p", pubkeyHex)) val privateTags = blockList.privateTagsOrEmpty(decryptedContent).plus(element = listOf("p", pubkeyHex))
val msg = Event.mapper.writeValueAsString(privateTags) val msg = Event.mapper.writeValueAsString(privateTags)
AmberUtils.content = "" AmberUtils.encrypt(msg, keyPair.pubKey.toHexKey(), id)
AmberUtils.encrypt(msg, keyPair.pubKey.toHexKey()) val eventContent = AmberUtils.content[id] ?: ""
if (AmberUtils.content.isBlank()) return if (eventContent.isBlank()) return
AmberUtils.content eventContent
} }
var event = if (blockList != null) { var event = if (blockList != null) {
@@ -2193,15 +2240,16 @@ class Account(
) )
} }
AmberUtils.content = ""
AmberUtils.openAmber(event) AmberUtils.openAmber(event)
val eventContent = AmberUtils.content[event.id] ?: ""
if (eventContent.isBlank()) return
event = PeopleListEvent( event = PeopleListEvent(
event.id, event.id,
event.pubKey, event.pubKey,
event.createdAt, event.createdAt,
event.tags, event.tags,
event.content, event.content,
AmberUtils.content eventContent
) )
Client.send(event) Client.send(event)
@@ -2241,25 +2289,24 @@ class Account(
val privateTags = listOf(listOf("p", pubkeyHex)) val privateTags = listOf(listOf("p", pubkeyHex))
val msg = Event.mapper.writeValueAsString(privateTags) val msg = Event.mapper.writeValueAsString(privateTags)
AmberUtils.content = "" AmberUtils.encrypt(msg, keyPair.pubKey.toHexKey(), blockList.id)
AmberUtils.encrypt(msg, keyPair.pubKey.toHexKey()) val eventContent = AmberUtils.content[blockList.id] ?: ""
if (AmberUtils.content.isBlank()) return if (eventContent.isBlank()) return
AmberUtils.content eventContent
} else { } else {
var decryptedContent = AmberUtils.cachedDecryptedContent[blockList.id] var decryptedContent = AmberUtils.cachedDecryptedContent[blockList.id]
if (decryptedContent == null) { if (decryptedContent == null) {
AmberUtils.content = ""
AmberUtils.decrypt(blockList.content, keyPair.pubKey.toHexKey(), blockList.id) AmberUtils.decrypt(blockList.content, keyPair.pubKey.toHexKey(), blockList.id)
if (AmberUtils.content.isBlank()) return val eventContent = AmberUtils.content[blockList.id] ?: ""
decryptedContent = AmberUtils.content if (eventContent.isBlank()) return
decryptedContent = eventContent
} }
AmberUtils.content = ""
val privateTags = blockList.privateTagsOrEmpty(decryptedContent).minus(element = listOf("p", pubkeyHex)) val privateTags = blockList.privateTagsOrEmpty(decryptedContent).minus(element = listOf("p", pubkeyHex))
val msg = Event.mapper.writeValueAsString(privateTags) val msg = Event.mapper.writeValueAsString(privateTags)
AmberUtils.content = "" AmberUtils.encrypt(msg, keyPair.pubKey.toHexKey(), blockList.id)
AmberUtils.encrypt(msg, keyPair.pubKey.toHexKey()) val eventContent = AmberUtils.content[blockList.id] ?: ""
if (AmberUtils.content.isBlank()) return if (eventContent.isBlank()) return
AmberUtils.content eventContent
} }
var event = PeopleListEvent.addUser( var event = PeopleListEvent.addUser(
@@ -2270,9 +2317,10 @@ class Account(
encryptedContent encryptedContent
) )
AmberUtils.content = ""
AmberUtils.openAmber(event) AmberUtils.openAmber(event)
event = PeopleListEvent.create(event, AmberUtils.content) val eventContent = AmberUtils.content[event.id] ?: ""
if (eventContent.isBlank()) return
event = PeopleListEvent.create(event, eventContent)
Client.send(event) Client.send(event)
LocalCache.consume(event) LocalCache.consume(event)
@@ -2485,8 +2533,9 @@ class Account(
) )
if (loginWithAmber) { if (loginWithAmber) {
AmberUtils.openAmber(event) AmberUtils.openAmber(event)
if (AmberUtils.content.isBlank()) return val eventContent = AmberUtils.content[event.id] ?: ""
event = ChannelMetadataEvent.create(event, AmberUtils.content) if (eventContent.isBlank()) return
event = ChannelMetadataEvent.create(event, eventContent)
} }
Client.send(event) Client.send(event)
@@ -2501,7 +2550,6 @@ class Account(
if (loginWithAmber) { if (loginWithAmber) {
var decryptedContent = AmberUtils.cachedDecryptedContent[event.id] var decryptedContent = AmberUtils.cachedDecryptedContent[event.id]
if (decryptedContent == null) { if (decryptedContent == null) {
AmberUtils.content = ""
AmberUtils.decrypt(event.content, event.pubKey, event.id, SignerType.NIP44_DECRYPT) AmberUtils.decrypt(event.content, event.pubKey, event.id, SignerType.NIP44_DECRYPT)
} }
decryptedContent = AmberUtils.cachedDecryptedContent[event.id] ?: "" decryptedContent = AmberUtils.cachedDecryptedContent[event.id] ?: ""
@@ -2518,7 +2566,6 @@ class Account(
if (loginWithAmber) { if (loginWithAmber) {
var decryptedContent = AmberUtils.cachedDecryptedContent[event.id] var decryptedContent = AmberUtils.cachedDecryptedContent[event.id]
if (decryptedContent == null) { if (decryptedContent == null) {
AmberUtils.content = ""
AmberUtils.decrypt(event.content, event.pubKey, event.id, SignerType.NIP44_DECRYPT) AmberUtils.decrypt(event.content, event.pubKey, event.id, SignerType.NIP44_DECRYPT)
} }
decryptedContent = AmberUtils.cachedDecryptedContent[event.id] ?: "" decryptedContent = AmberUtils.cachedDecryptedContent[event.id] ?: ""
@@ -2546,7 +2593,6 @@ class Account(
return when (event) { return when (event) {
is PrivateDmEvent -> { is PrivateDmEvent -> {
if (AmberUtils.cachedDecryptedContent[event.id] == null) { if (AmberUtils.cachedDecryptedContent[event.id] == null) {
AmberUtils.content = ""
AmberUtils.decryptDM( AmberUtils.decryptDM(
event.content, event.content,
event.talkingWith(userProfile().pubkeyHex), event.talkingWith(userProfile().pubkeyHex),
@@ -2571,25 +2617,16 @@ class Account(
val loggedInPrivateKey = keyPair.privKey val loggedInPrivateKey = keyPair.privKey
if (loginWithAmber && event is LnZapRequestEvent && event.isPrivateZap()) { if (loginWithAmber && event is LnZapRequestEvent && event.isPrivateZap()) {
// never decrypt zaps for now, it keeps opening amber for very private zap event val decryptedContent = AmberUtils.cachedDecryptedContent[event.id]
if (decryptedContent != null) {
return try {
Event.fromJson(decryptedContent)
} catch (e: Exception) {
null
}
}
AmberUtils.decryptZapEvent(event)
return null return null
// val decryptedContent = AmberUtils.cachedDecryptedContent[event.id]
// if (decryptedContent != null) {
// return try {
// Event.fromJson(decryptedContent)
// } catch (e: Exception) {
// null
// }
// }
// AmberUtils.decryptZapEvent(event)
// if (AmberUtils.content.isBlank()) return null
// if (AmberUtils.content == "Could not decrypt the message") return null
// AmberUtils.cachedDecryptedContent[event.id] = AmberUtils.content
// return try {
// Event.fromJson(AmberUtils.content)
// } catch (e: Exception) {
// null
// }
} }
return if (event is LnZapRequestEvent && loggedInPrivateKey != null && event.isPrivateZap()) { return if (event is LnZapRequestEvent && loggedInPrivateKey != null && event.isPrivateZap()) {
@@ -214,7 +214,7 @@ object LocalCache {
if (hexKey != null) { if (hexKey != null) {
val pubKey = Hex.encode(hexKey) val pubKey = Hex.encode(hexKey)
if (pubKey == event.pubKey) { if (pubKey == event.pubKey) {
AmberUtils.content = "" AmberUtils.content.remove(event.id)
} }
} }
user.updateBookmark(event) user.updateBookmark(event)
@@ -466,6 +466,7 @@ object LocalCache {
} }
fun consume(event: PrivateDmEvent, relay: Relay?): Note { fun consume(event: PrivateDmEvent, relay: Relay?): Note {
Log.e("isRunning", event.toJson())
val note = getOrCreateNote(event.id) val note = getOrCreateNote(event.id)
val author = getOrCreateUser(event.pubKey) val author = getOrCreateUser(event.pubKey)
@@ -18,61 +18,20 @@ import com.vitorpamplona.quartz.encoders.HexKey
import com.vitorpamplona.quartz.encoders.toHexKey import com.vitorpamplona.quartz.encoders.toHexKey
import com.vitorpamplona.quartz.events.Event import com.vitorpamplona.quartz.events.Event
import com.vitorpamplona.quartz.events.EventInterface import com.vitorpamplona.quartz.events.EventInterface
import com.vitorpamplona.quartz.events.GiftWrapEvent
import com.vitorpamplona.quartz.events.LnZapRequestEvent import com.vitorpamplona.quartz.events.LnZapRequestEvent
import com.vitorpamplona.quartz.events.SealedGossipEvent
import kotlinx.coroutines.DelicateCoroutinesApi import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
object AmberUtils { object AmberUtils {
var content: String = "" val content = LruCache<String, String>(10)
var isActivityRunning: Boolean = false var isActivityRunning: Boolean = false
val cachedDecryptedContent = mutableMapOf<HexKey, String>() val cachedDecryptedContent = mutableMapOf<HexKey, String>()
lateinit var account: Account lateinit var account: Account
lateinit var activityResultLauncher: ActivityResultLauncher<Intent> lateinit var activityResultLauncher: ActivityResultLauncher<Intent>
lateinit var decryptGossipResultLauncher: ActivityResultLauncher<Intent>
lateinit var blockListResultLauncher: ActivityResultLauncher<Intent> lateinit var blockListResultLauncher: ActivityResultLauncher<Intent>
lateinit var signEventResultLauncher: ActivityResultLauncher<Intent> lateinit var signEventResultLauncher: ActivityResultLauncher<Intent>
val eventCache = LruCache<String, Event>(100)
@OptIn(DelicateCoroutinesApi::class)
fun consume(event: Event) {
if (LocalCache.justVerify(event)) {
if (event is GiftWrapEvent) {
GlobalScope.launch(Dispatchers.IO) {
val decryptedContent = cachedDecryptedContent[event.id] ?: ""
if (decryptedContent.isNotBlank()) {
event.cachedGift(
NostrAccountDataSource.account.keyPair.pubKey,
decryptedContent
)?.let {
consume(it)
}
} else {
decryptGossip(event)
}
}
}
if (event is SealedGossipEvent) {
GlobalScope.launch(Dispatchers.IO) {
val decryptedContent = cachedDecryptedContent[event.id] ?: ""
if (decryptedContent.isNotBlank()) {
event.cachedGossip(NostrAccountDataSource.account.keyPair.pubKey, decryptedContent)?.let {
LocalCache.justConsume(it, null)
}
} else {
decryptGossip(event)
}
}
// Don't store sealed gossips to avoid rebroadcasting by mistake.
} else {
LocalCache.justConsume(event, null)
}
}
}
@OptIn(DelicateCoroutinesApi::class) @OptIn(DelicateCoroutinesApi::class)
fun start(activity: MainActivity) { fun start(activity: MainActivity) {
@@ -104,8 +63,6 @@ object AmberUtils {
activityResultLauncher = activity.registerForActivityResult( activityResultLauncher = activity.registerForActivityResult(
ActivityResultContracts.StartActivityForResult() ActivityResultContracts.StartActivityForResult()
) { ) {
isActivityRunning = false
ServiceManager.shouldPauseService = true
if (it.resultCode != Activity.RESULT_OK) { if (it.resultCode != Activity.RESULT_OK) {
GlobalScope.launch(Dispatchers.Main) { GlobalScope.launch(Dispatchers.Main) {
Toast.makeText( Toast.makeText(
@@ -116,12 +73,18 @@ object AmberUtils {
} }
} else { } else {
val event = it.data?.getStringExtra("signature") ?: "" val event = it.data?.getStringExtra("signature") ?: ""
content = event
val id = it.data?.getStringExtra("id") ?: "" val id = it.data?.getStringExtra("id") ?: ""
if (id.isNotBlank()) { if (id.isNotBlank()) {
content.put(id, event)
cachedDecryptedContent[id] = event cachedDecryptedContent[id] = event
} }
} }
isActivityRunning = false
ServiceManager.shouldPauseService = true
GlobalScope.launch(Dispatchers.IO) {
isActivityRunning = false
ServiceManager.shouldPauseService = true
}
} }
blockListResultLauncher = activity.registerForActivityResult( blockListResultLauncher = activity.registerForActivityResult(
@@ -145,36 +108,12 @@ object AmberUtils {
} }
isActivityRunning = false isActivityRunning = false
ServiceManager.shouldPauseService = true ServiceManager.shouldPauseService = true
}
decryptGossipResultLauncher = activity.registerForActivityResult(
ActivityResultContracts.StartActivityForResult()
) {
if (it.resultCode != Activity.RESULT_OK) {
GlobalScope.launch(Dispatchers.Main) {
Toast.makeText(
Amethyst.instance,
"Sign request rejected",
Toast.LENGTH_SHORT
).show()
}
} else {
val decryptedContent = it.data?.getStringExtra("signature") ?: ""
val id = it.data?.getStringExtra("id") ?: ""
if (id.isNotBlank()) {
val event = eventCache.get(id)
if (event != null) {
GlobalScope.launch(Dispatchers.IO) { GlobalScope.launch(Dispatchers.IO) {
AmberUtils.cachedDecryptedContent[event.id] = decryptedContent
consume(event)
}
}
}
}
isActivityRunning = false isActivityRunning = false
ServiceManager.shouldPauseService = true ServiceManager.shouldPauseService = true
} }
} }
}
fun openAmber( fun openAmber(
data: String, data: String,
@@ -203,6 +142,13 @@ object AmberUtils {
fun openAmber(event: EventInterface) { fun openAmber(event: EventInterface) {
checkNotInMainThread() checkNotInMainThread()
val result = getDataFromResolver(SignerType.SIGN_EVENT, arrayOf(event.toJson(), event.pubKey()))
if (result !== null) {
content.put(event.id(), result)
return
}
ServiceManager.shouldPauseService = false ServiceManager.shouldPauseService = false
isActivityRunning = true isActivityRunning = true
openAmber( openAmber(
@@ -231,6 +177,12 @@ object AmberUtils {
} }
fun decryptBlockList(encryptedContent: String, pubKey: HexKey, id: String, signerType: SignerType = SignerType.NIP04_DECRYPT) { fun decryptBlockList(encryptedContent: String, pubKey: HexKey, id: String, signerType: SignerType = SignerType.NIP04_DECRYPT) {
val result = getDataFromResolver(signerType, arrayOf(encryptedContent, pubKey))
if (result !== null) {
content.put(id, result)
cachedDecryptedContent[id] = result
return
}
isActivityRunning = true isActivityRunning = true
openAmber( openAmber(
encryptedContent, encryptedContent,
@@ -241,8 +193,32 @@ object AmberUtils {
) )
} }
fun getDataFromResolver(signerType: SignerType, data: Array<out String>, columnName: String = "signature"): String? {
Amethyst.instance.contentResolver.query(
Uri.parse("content://com.greenart7c3.nostrsigner.$signerType"),
data,
null,
null,
null
).use {
if (it !== null) {
if (it.moveToFirst()) {
val index = it.getColumnIndex(columnName)
return it.getString(index)
}
}
}
return null
}
fun decrypt(encryptedContent: String, pubKey: HexKey, id: String, signerType: SignerType = SignerType.NIP04_DECRYPT) { fun decrypt(encryptedContent: String, pubKey: HexKey, id: String, signerType: SignerType = SignerType.NIP04_DECRYPT) {
if (content.isBlank()) { val result = getDataFromResolver(signerType, arrayOf(encryptedContent, pubKey))
if (result !== null) {
content.put(id, result)
cachedDecryptedContent[id] = result
return
}
isActivityRunning = true isActivityRunning = true
openAmber( openAmber(
encryptedContent, encryptedContent,
@@ -255,9 +231,14 @@ object AmberUtils {
// do nothing // do nothing
} }
} }
}
fun decryptDM(encryptedContent: String, pubKey: HexKey, id: String, signerType: SignerType = SignerType.NIP04_DECRYPT) { fun decryptDM(encryptedContent: String, pubKey: HexKey, id: String, signerType: SignerType = SignerType.NIP04_DECRYPT) {
val result = getDataFromResolver(signerType, arrayOf(encryptedContent, pubKey))
if (result !== null) {
content.put(id, result)
cachedDecryptedContent[id] = result
return
}
openAmber( openAmber(
encryptedContent, encryptedContent,
signerType, signerType,
@@ -268,6 +249,12 @@ object AmberUtils {
} }
fun decryptBookmark(encryptedContent: String, pubKey: HexKey, id: String, signerType: SignerType = SignerType.NIP04_DECRYPT) { fun decryptBookmark(encryptedContent: String, pubKey: HexKey, id: String, signerType: SignerType = SignerType.NIP04_DECRYPT) {
val result = getDataFromResolver(signerType, arrayOf(encryptedContent, pubKey))
if (result !== null) {
content.put(id, result)
cachedDecryptedContent[id] = result
return
}
openAmber( openAmber(
encryptedContent, encryptedContent,
signerType, signerType,
@@ -277,21 +264,13 @@ object AmberUtils {
) )
} }
fun decryptGossip(event: Event) { fun encrypt(decryptedContent: String, pubKey: HexKey, id: String, signerType: SignerType = SignerType.NIP04_ENCRYPT) {
if (eventCache.get(event.id) == null) { val result = getDataFromResolver(signerType, arrayOf(decryptedContent, pubKey))
eventCache.put(event.id, event) if (result !== null) {
} content.put(id, result)
isActivityRunning = true return
openAmber(
event.content,
SignerType.NIP44_DECRYPT,
decryptGossipResultLauncher,
event.pubKey,
event.id
)
} }
fun encrypt(decryptedContent: String, pubKey: HexKey, signerType: SignerType = SignerType.NIP04_ENCRYPT) {
isActivityRunning = true isActivityRunning = true
openAmber( openAmber(
decryptedContent, decryptedContent,
@@ -306,7 +285,12 @@ object AmberUtils {
} }
fun decryptZapEvent(event: LnZapRequestEvent) { fun decryptZapEvent(event: LnZapRequestEvent) {
isActivityRunning = true val result = getDataFromResolver(SignerType.DECRYPT_ZAP_EVENT, arrayOf(event.toJson()))
if (result !== null) {
content.put(event.id, result)
cachedDecryptedContent[event.id] = result
return
}
openAmber( openAmber(
event.toJson(), event.toJson(),
SignerType.DECRYPT_ZAP_EVENT, SignerType.DECRYPT_ZAP_EVENT,
@@ -314,8 +298,5 @@ object AmberUtils {
event.pubKey, event.pubKey,
event.id event.id
) )
while (isActivityRunning) {
Thread.sleep(100)
}
} }
} }
@@ -8,6 +8,7 @@ import com.vitorpamplona.amethyst.service.relays.EOSEAccount
import com.vitorpamplona.amethyst.service.relays.JsonFilter import com.vitorpamplona.amethyst.service.relays.JsonFilter
import com.vitorpamplona.amethyst.service.relays.Relay import com.vitorpamplona.amethyst.service.relays.Relay
import com.vitorpamplona.amethyst.service.relays.TypedFilter import com.vitorpamplona.amethyst.service.relays.TypedFilter
import com.vitorpamplona.amethyst.ui.actions.SignerType
import com.vitorpamplona.quartz.encoders.toHexKey import com.vitorpamplona.quartz.encoders.toHexKey
import com.vitorpamplona.quartz.events.AdvertisedRelayListEvent import com.vitorpamplona.quartz.events.AdvertisedRelayListEvent
import com.vitorpamplona.quartz.events.BadgeAwardEvent import com.vitorpamplona.quartz.events.BadgeAwardEvent
@@ -31,7 +32,6 @@ import com.vitorpamplona.quartz.events.RepostEvent
import com.vitorpamplona.quartz.events.SealedGossipEvent import com.vitorpamplona.quartz.events.SealedGossipEvent
import com.vitorpamplona.quartz.events.StatusEvent import com.vitorpamplona.quartz.events.StatusEvent
import com.vitorpamplona.quartz.events.TextNoteEvent import com.vitorpamplona.quartz.events.TextNoteEvent
import kotlinx.coroutines.DelicateCoroutinesApi
object NostrAccountDataSource : NostrDataSource("AccountData") { object NostrAccountDataSource : NostrDataSource("AccountData") {
lateinit var account: Account lateinit var account: Account
@@ -147,7 +147,6 @@ object NostrAccountDataSource : NostrDataSource("AccountData") {
latestEOSEs.addOrUpdate(account.userProfile(), account.defaultNotificationFollowList, relayUrl, time) latestEOSEs.addOrUpdate(account.userProfile(), account.defaultNotificationFollowList, relayUrl, time)
} }
@OptIn(DelicateCoroutinesApi::class)
override fun consume(event: Event, relay: Relay) { override fun consume(event: Event, relay: Relay) {
if (LocalCache.justVerify(event)) { if (LocalCache.justVerify(event)) {
if (event is GiftWrapEvent) { if (event is GiftWrapEvent) {
@@ -156,6 +155,20 @@ object NostrAccountDataSource : NostrDataSource("AccountData") {
event.cachedGift(privateKey)?.let { event.cachedGift(privateKey)?.let {
this.consume(it, relay) this.consume(it, relay)
} }
} else if (account.loginWithAmber) {
var cached = AmberUtils.cachedDecryptedContent[event.id]
if (cached == null) {
AmberUtils.decrypt(
event.content,
event.pubKey,
event.id,
SignerType.NIP44_DECRYPT
)
cached = AmberUtils.cachedDecryptedContent[event.id] ?: ""
}
event.cachedGift(account.keyPair.pubKey, cached)?.let {
this.consume(it, relay)
}
} }
} }
@@ -165,6 +178,20 @@ object NostrAccountDataSource : NostrDataSource("AccountData") {
event.cachedGossip(privateKey)?.let { event.cachedGossip(privateKey)?.let {
LocalCache.justConsume(it, relay) LocalCache.justConsume(it, relay)
} }
} else if (account.loginWithAmber) {
var cached = AmberUtils.cachedDecryptedContent[event.id]
if (cached == null) {
AmberUtils.decrypt(
event.content,
event.pubKey,
event.id,
SignerType.NIP44_DECRYPT
)
cached = AmberUtils.cachedDecryptedContent[event.id] ?: ""
}
event.cachedGossip(account.keyPair.pubKey, cached)?.let {
LocalCache.justConsume(it, relay)
}
} }
// Don't store sealed gossips to avoid rebroadcasting by mistake. // Don't store sealed gossips to avoid rebroadcasting by mistake.
@@ -195,6 +222,15 @@ object NostrAccountDataSource : NostrDataSource("AccountData") {
if (this::account.isInitialized) { if (this::account.isInitialized) {
if (account.loginWithAmber) { if (account.loginWithAmber) {
val event = RelayAuthEvent.create(relay.url, challenge, account.keyPair.pubKey.toHexKey(), account.keyPair.privKey) val event = RelayAuthEvent.create(relay.url, challenge, account.keyPair.pubKey.toHexKey(), account.keyPair.privKey)
val result = AmberUtils.getDataFromResolver(SignerType.SIGN_EVENT, arrayOf(event.toJson()), "event")
if (result !== null) {
val signedEvent = Event.fromJson(result)
Client.send(
signedEvent,
relay.url
)
return
}
AmberUtils.signEvent(event) AmberUtils.signEvent(event)
} else { } else {
val event = account.createAuthEvent(relay, challenge) val event = account.createAuthEvent(relay, challenge)
@@ -45,7 +45,6 @@ class EventNotificationConsumer(private val applicationContext: Context) {
if (account.loginWithAmber) { if (account.loginWithAmber) {
var cached = AmberUtils.cachedDecryptedContent[pushWrappedEvent.id] var cached = AmberUtils.cachedDecryptedContent[pushWrappedEvent.id]
if (cached == null) { if (cached == null) {
AmberUtils.content = ""
AmberUtils.decrypt( AmberUtils.decrypt(
pushWrappedEvent.content, pushWrappedEvent.content,
pushWrappedEvent.pubKey, pushWrappedEvent.pubKey,
@@ -100,6 +99,20 @@ class EventNotificationConsumer(private val applicationContext: Context) {
event.cachedGift(key)?.let { event.cachedGift(key)?.let {
unwrapAndConsume(it, account) unwrapAndConsume(it, account)
} }
} else if (account.loginWithAmber) {
var cached = AmberUtils.cachedDecryptedContent[event.id]
if (cached == null) {
AmberUtils.decrypt(
event.content,
event.pubKey,
event.id,
SignerType.NIP44_DECRYPT
)
cached = AmberUtils.cachedDecryptedContent[event.id] ?: ""
}
event.cachedGift(account.keyPair.pubKey, cached)?.let {
unwrapAndConsume(it, account)
}
} else { } else {
null null
} }
@@ -112,6 +125,21 @@ class EventNotificationConsumer(private val applicationContext: Context) {
LocalCache.justConsume(it, null) LocalCache.justConsume(it, null)
it it
} }
} else if (account.loginWithAmber) {
var cached = AmberUtils.cachedDecryptedContent[event.id]
if (cached == null) {
AmberUtils.decrypt(
event.content,
event.pubKey,
event.id,
SignerType.NIP44_DECRYPT
)
cached = AmberUtils.cachedDecryptedContent[event.id] ?: ""
}
event.cachedGossip(account.keyPair.pubKey, cached)?.let {
LocalCache.justConsume(it, null)
it
}
} else { } else {
null null
} }
@@ -1,9 +1,5 @@
package com.vitorpamplona.amethyst.ui.note package com.vitorpamplona.amethyst.ui.note
import android.app.Activity
import android.widget.Toast
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.animation.Crossfade import androidx.compose.animation.Crossfade
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
@@ -25,13 +21,11 @@ import androidx.compose.material.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.MutableState import androidx.compose.runtime.MutableState
import androidx.compose.runtime.SideEffect
import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
@@ -51,14 +45,11 @@ import androidx.compose.ui.unit.sp
import androidx.lifecycle.distinctUntilChanged import androidx.lifecycle.distinctUntilChanged
import androidx.lifecycle.map import androidx.lifecycle.map
import com.patrykandpatrick.vico.core.extension.forEachIndexedExtended import com.patrykandpatrick.vico.core.extension.forEachIndexedExtended
import com.vitorpamplona.amethyst.Amethyst
import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.model.Channel import com.vitorpamplona.amethyst.model.Channel
import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.model.LocalCache
import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.model.Note
import com.vitorpamplona.amethyst.model.User import com.vitorpamplona.amethyst.model.User
import com.vitorpamplona.amethyst.service.AmberUtils
import com.vitorpamplona.amethyst.ui.actions.SignerType
import com.vitorpamplona.amethyst.ui.components.CreateTextWithEmoji import com.vitorpamplona.amethyst.ui.components.CreateTextWithEmoji
import com.vitorpamplona.amethyst.ui.components.RobohashAsyncImageProxy import com.vitorpamplona.amethyst.ui.components.RobohashAsyncImageProxy
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
@@ -77,7 +68,6 @@ import com.vitorpamplona.quartz.events.ChannelCreateEvent
import com.vitorpamplona.quartz.events.ChannelMetadataEvent import com.vitorpamplona.quartz.events.ChannelMetadataEvent
import com.vitorpamplona.quartz.events.ChatroomKey import com.vitorpamplona.quartz.events.ChatroomKey
import com.vitorpamplona.quartz.events.ChatroomKeyable import com.vitorpamplona.quartz.events.ChatroomKeyable
import com.vitorpamplona.quartz.events.PrivateDmEvent
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@@ -255,7 +245,6 @@ private fun UserRoomCompose(
accountViewModel: AccountViewModel, accountViewModel: AccountViewModel,
nav: (String) -> Unit nav: (String) -> Unit
) { ) {
val scope = rememberCoroutineScope()
val hasNewMessages = remember { mutableStateOf<Boolean>(false) } val hasNewMessages = remember { mutableStateOf<Boolean>(false) }
val route = remember(room) { val route = remember(room) {
@@ -267,46 +256,12 @@ private fun UserRoomCompose(
note.createdAt() note.createdAt()
} }
} }
val decryptedContent = remember(note) { if (note.event == null) null else AmberUtils.cachedDecryptedContent[note.event!!.id()] } val content by remember(note) {
var content by remember(note) {
mutableStateOf( mutableStateOf(
decryptedContent ?: accountViewModel.decrypt(note) accountViewModel.decrypt(note)
) )
} }
val activityLauncher = rememberLauncherForActivityResult(
contract = ActivityResultContracts.StartActivityForResult(),
onResult = {
if (it.resultCode != Activity.RESULT_OK) {
scope.launch(Dispatchers.Main) {
Toast.makeText(
Amethyst.instance,
"Sign request rejected",
Toast.LENGTH_SHORT
).show()
}
return@rememberLauncherForActivityResult
}
val event = note.event
AmberUtils.cachedDecryptedContent[event!!.id()] = it.data?.getStringExtra("signature") ?: ""
content = AmberUtils.cachedDecryptedContent[event.id()]
}
)
if (accountViewModel.loggedInWithAmber() && decryptedContent == null && note.event is PrivateDmEvent) {
val event = note.event
SideEffect {
AmberUtils.openAmber(
event?.content() ?: "",
SignerType.NIP04_DECRYPT,
activityLauncher,
(event as PrivateDmEvent).talkingWith(accountViewModel.userProfile().pubkeyHex),
event.id
)
}
}
WatchNotificationChanges(note, route, accountViewModel) { newHasNewMessages -> WatchNotificationChanges(note, route, accountViewModel) { newHasNewMessages ->
if (hasNewMessages.value != newHasNewMessages) { if (hasNewMessages.value != newHasNewMessages) {
hasNewMessages.value = newHasNewMessages hasNewMessages.value = newHasNewMessages
@@ -1,9 +1,5 @@
package com.vitorpamplona.amethyst.ui.note package com.vitorpamplona.amethyst.ui.note
import android.app.Activity
import android.widget.Toast
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.animation.Crossfade import androidx.compose.animation.Crossfade
import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
@@ -26,13 +22,11 @@ import androidx.compose.material.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.MutableState import androidx.compose.runtime.MutableState
import androidx.compose.runtime.SideEffect
import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
@@ -47,12 +41,9 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.lifecycle.map import androidx.lifecycle.map
import com.vitorpamplona.amethyst.Amethyst
import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.model.Note
import com.vitorpamplona.amethyst.model.User import com.vitorpamplona.amethyst.model.User
import com.vitorpamplona.amethyst.service.AmberUtils
import com.vitorpamplona.amethyst.ui.actions.SignerType
import com.vitorpamplona.amethyst.ui.components.CreateClickableTextWithEmoji import com.vitorpamplona.amethyst.ui.components.CreateClickableTextWithEmoji
import com.vitorpamplona.amethyst.ui.components.CreateTextWithEmoji import com.vitorpamplona.amethyst.ui.components.CreateTextWithEmoji
import com.vitorpamplona.amethyst.ui.components.RobohashAsyncImageProxy import com.vitorpamplona.amethyst.ui.components.RobohashAsyncImageProxy
@@ -636,43 +627,8 @@ private fun RenderRegularTextNote(
nav: (String) -> Unit nav: (String) -> Unit
) { ) {
val tags = remember(note.event) { note.event?.tags()?.toImmutableListOfLists() ?: ImmutableListOfLists() } val tags = remember(note.event) { note.event?.tags()?.toImmutableListOfLists() ?: ImmutableListOfLists() }
val decryptedContent = remember(note.event) { if (note.event == null) null else AmberUtils.cachedDecryptedContent[note.event!!.id()] } val eventContent by remember { mutableStateOf(accountViewModel.decrypt(note)) }
var eventContent by remember { mutableStateOf(decryptedContent ?: accountViewModel.decrypt(note)) }
val modifier = remember { Modifier.padding(top = 5.dp) } val modifier = remember { Modifier.padding(top = 5.dp) }
val scope = rememberCoroutineScope()
val activityLauncher = rememberLauncherForActivityResult(
contract = ActivityResultContracts.StartActivityForResult(),
onResult = {
if (it.resultCode != Activity.RESULT_OK) {
scope.launch(Dispatchers.Main) {
Toast.makeText(
Amethyst.instance,
"Sign request rejected",
Toast.LENGTH_SHORT
).show()
}
return@rememberLauncherForActivityResult
}
val event = note.event
AmberUtils.cachedDecryptedContent[event!!.id()] = it.data?.getStringExtra("signature") ?: ""
eventContent = AmberUtils.cachedDecryptedContent[event.id()]
}
)
if (accountViewModel.loggedInWithAmber() && decryptedContent == null && note.event is PrivateDmEvent) {
val event = note.event
SideEffect {
AmberUtils.openAmber(
event?.content() ?: "",
SignerType.NIP04_DECRYPT,
activityLauncher,
(event as PrivateDmEvent).talkingWith(accountViewModel.userProfile().pubkeyHex),
event.id
)
}
}
if (eventContent != null) { if (eventContent != null) {
SensitivityWarning( SensitivityWarning(
@@ -1,11 +1,7 @@
package com.vitorpamplona.amethyst.ui.note package com.vitorpamplona.amethyst.ui.note
import android.app.Activity
import android.graphics.Bitmap import android.graphics.Bitmap
import android.util.Log import android.util.Log
import android.widget.Toast
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.animation.Crossfade import androidx.compose.animation.Crossfade
import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.Image import androidx.compose.foundation.Image
@@ -44,7 +40,6 @@ import androidx.compose.material.lightColors
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.MutableState import androidx.compose.runtime.MutableState
import androidx.compose.runtime.SideEffect
import androidx.compose.runtime.Stable import androidx.compose.runtime.Stable
import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
@@ -81,7 +76,6 @@ import coil.compose.AsyncImage
import coil.compose.AsyncImagePainter import coil.compose.AsyncImagePainter
import coil.request.SuccessResult import coil.request.SuccessResult
import com.fonfon.kgeohash.toGeoHash import com.fonfon.kgeohash.toGeoHash
import com.vitorpamplona.amethyst.Amethyst
import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.model.AddressableNote import com.vitorpamplona.amethyst.model.AddressableNote
import com.vitorpamplona.amethyst.model.Channel import com.vitorpamplona.amethyst.model.Channel
@@ -90,12 +84,10 @@ import com.vitorpamplona.amethyst.model.LocalCache
import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.model.Note
import com.vitorpamplona.amethyst.model.RelayBriefInfo import com.vitorpamplona.amethyst.model.RelayBriefInfo
import com.vitorpamplona.amethyst.model.User import com.vitorpamplona.amethyst.model.User
import com.vitorpamplona.amethyst.service.AmberUtils
import com.vitorpamplona.amethyst.service.OnlineChecker import com.vitorpamplona.amethyst.service.OnlineChecker
import com.vitorpamplona.amethyst.service.ReverseGeoLocationUtil import com.vitorpamplona.amethyst.service.ReverseGeoLocationUtil
import com.vitorpamplona.amethyst.service.connectivitystatus.ConnectivityStatus import com.vitorpamplona.amethyst.service.connectivitystatus.ConnectivityStatus
import com.vitorpamplona.amethyst.ui.actions.NewRelayListView import com.vitorpamplona.amethyst.ui.actions.NewRelayListView
import com.vitorpamplona.amethyst.ui.actions.SignerType
import com.vitorpamplona.amethyst.ui.components.ClickableUrl import com.vitorpamplona.amethyst.ui.components.ClickableUrl
import com.vitorpamplona.amethyst.ui.components.CreateClickableTextWithEmoji import com.vitorpamplona.amethyst.ui.components.CreateClickableTextWithEmoji
import com.vitorpamplona.amethyst.ui.components.CreateTextWithEmoji import com.vitorpamplona.amethyst.ui.components.CreateTextWithEmoji
@@ -1262,8 +1254,7 @@ fun RenderTextEvent(
) { ) {
val eventContent = remember(note.event) { val eventContent = remember(note.event) {
val subject = (note.event as? TextNoteEvent)?.subject()?.ifEmpty { null } val subject = (note.event as? TextNoteEvent)?.subject()?.ifEmpty { null }
val decryptedContent = if (note.event == null) null else AmberUtils.cachedDecryptedContent[note.event!!.id()] val body = accountViewModel.decrypt(note)
val body = decryptedContent ?: accountViewModel.decrypt(note)
if (!subject.isNullOrBlank() && body?.split("\n")?.get(0)?.contains(subject) == false) { if (!subject.isNullOrBlank() && body?.split("\n")?.get(0)?.contains(subject) == false) {
"## $subject\n$body" "## $subject\n$body"
@@ -1569,41 +1560,8 @@ private fun RenderPrivateMessage(
val noteEvent = note.event as? PrivateDmEvent ?: return val noteEvent = note.event as? PrivateDmEvent ?: return
val withMe = remember { noteEvent.with(accountViewModel.userProfile().pubkeyHex) } val withMe = remember { noteEvent.with(accountViewModel.userProfile().pubkeyHex) }
val scope = rememberCoroutineScope()
if (withMe) { if (withMe) {
val decryptedContent = AmberUtils.cachedDecryptedContent[noteEvent.id] val eventContent by remember { mutableStateOf(accountViewModel.decrypt(note)) }
var eventContent by remember { mutableStateOf(decryptedContent ?: accountViewModel.decrypt(note)) }
val activityLauncher = rememberLauncherForActivityResult(
contract = ActivityResultContracts.StartActivityForResult(),
onResult = {
if (it.resultCode != Activity.RESULT_OK) {
scope.launch(Dispatchers.Main) {
Toast.makeText(
Amethyst.instance,
"Sign request rejected",
Toast.LENGTH_SHORT
).show()
}
return@rememberLauncherForActivityResult
}
AmberUtils.cachedDecryptedContent[noteEvent.id] = it.data?.getStringExtra("signature") ?: ""
eventContent = AmberUtils.cachedDecryptedContent[noteEvent.id]
}
)
if (accountViewModel.loggedInWithAmber() && decryptedContent == null) {
val event = note.event
SideEffect {
AmberUtils.openAmber(
event?.content() ?: "",
SignerType.NIP04_DECRYPT,
activityLauncher,
(event as PrivateDmEvent).talkingWith(accountViewModel.userProfile().pubkeyHex),
event.id
)
}
}
val hashtags = remember(note.event?.id()) { note.event?.hashtags()?.toImmutableList() ?: persistentListOf() } val hashtags = remember(note.event?.id()) { note.event?.hashtags()?.toImmutableList() ?: persistentListOf() }
val modifier = remember(note.event?.id()) { Modifier.fillMaxWidth() } val modifier = remember(note.event?.id()) { Modifier.fillMaxWidth() }
val isAuthorTheLoggedUser = remember(note.event?.id()) { accountViewModel.isLoggedUser(note.author) } val isAuthorTheLoggedUser = remember(note.event?.id()) { accountViewModel.isLoggedUser(note.author) }
@@ -459,8 +459,7 @@ fun NoteDropDownMenu(note: Note, popupExpanded: MutableState<Boolean>, accountVi
accountViewModel.account.keyPair.pubKey.toHexKey(), accountViewModel.account.keyPair.pubKey.toHexKey(),
bookmarks?.id ?: "" bookmarks?.id ?: ""
) )
bookmarks?.decryptedContent = AmberUtils.content bookmarks?.decryptedContent = AmberUtils.cachedDecryptedContent[bookmarks?.id ?: ""] ?: ""
AmberUtils.content = ""
accountViewModel.removePrivateBookmark(note, bookmarks?.decryptedContent ?: "") accountViewModel.removePrivateBookmark(note, bookmarks?.decryptedContent ?: "")
} else { } else {
accountViewModel.removePrivateBookmark(note) accountViewModel.removePrivateBookmark(note)
@@ -482,8 +481,7 @@ fun NoteDropDownMenu(note: Note, popupExpanded: MutableState<Boolean>, accountVi
accountViewModel.account.keyPair.pubKey.toHexKey(), accountViewModel.account.keyPair.pubKey.toHexKey(),
bookmarks?.id ?: "" bookmarks?.id ?: ""
) )
bookmarks?.decryptedContent = AmberUtils.content bookmarks?.decryptedContent = AmberUtils.cachedDecryptedContent[bookmarks?.id ?: ""] ?: ""
AmberUtils.content = ""
accountViewModel.addPrivateBookmark(note, bookmarks?.decryptedContent ?: "") accountViewModel.addPrivateBookmark(note, bookmarks?.decryptedContent ?: "")
} else { } else {
accountViewModel.addPrivateBookmark(note) accountViewModel.addPrivateBookmark(note)
@@ -506,8 +504,7 @@ fun NoteDropDownMenu(note: Note, popupExpanded: MutableState<Boolean>, accountVi
accountViewModel.account.keyPair.pubKey.toHexKey(), accountViewModel.account.keyPair.pubKey.toHexKey(),
bookmarks?.id ?: "" bookmarks?.id ?: ""
) )
bookmarks?.decryptedContent = AmberUtils.content bookmarks?.decryptedContent = AmberUtils.cachedDecryptedContent[bookmarks?.id ?: ""] ?: ""
AmberUtils.content = ""
accountViewModel.removePublicBookmark( accountViewModel.removePublicBookmark(
note, note,
bookmarks?.decryptedContent ?: "" bookmarks?.decryptedContent ?: ""
@@ -532,8 +529,7 @@ fun NoteDropDownMenu(note: Note, popupExpanded: MutableState<Boolean>, accountVi
accountViewModel.account.keyPair.pubKey.toHexKey(), accountViewModel.account.keyPair.pubKey.toHexKey(),
bookmarks?.id ?: "" bookmarks?.id ?: ""
) )
bookmarks?.decryptedContent = AmberUtils.content bookmarks?.decryptedContent = AmberUtils.cachedDecryptedContent[bookmarks?.id ?: ""] ?: ""
AmberUtils.content = ""
accountViewModel.addPublicBookmark( accountViewModel.addPublicBookmark(
note, note,
bookmarks?.decryptedContent ?: "" bookmarks?.decryptedContent ?: ""
@@ -11,7 +11,6 @@ import androidx.compose.material.Tab
import androidx.compose.material.TabRow import androidx.compose.material.TabRow
import androidx.compose.material.Text import androidx.compose.material.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState import androidx.compose.runtime.livedata.observeAsState
@@ -21,7 +20,6 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel import androidx.lifecycle.viewmodel.compose.viewModel
import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.service.AmberUtils
import com.vitorpamplona.amethyst.ui.dal.BookmarkPrivateFeedFilter import com.vitorpamplona.amethyst.ui.dal.BookmarkPrivateFeedFilter
import com.vitorpamplona.amethyst.ui.dal.BookmarkPublicFeedFilter import com.vitorpamplona.amethyst.ui.dal.BookmarkPublicFeedFilter
import com.vitorpamplona.amethyst.ui.screen.NostrBookmarkPrivateFeedViewModel import com.vitorpamplona.amethyst.ui.screen.NostrBookmarkPrivateFeedViewModel
@@ -93,11 +91,5 @@ fun BookmarkListScreen(accountViewModel: AccountViewModel, nav: (String) -> Unit
} }
} }
} }
DisposableEffect(Unit) {
onDispose {
AmberUtils.content = ""
}
}
} }
} }
@@ -39,8 +39,6 @@ import androidx.compose.ui.unit.dp
import androidx.lifecycle.Lifecycle import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver import androidx.lifecycle.LifecycleEventObserver
import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.model.LocalCache
import com.vitorpamplona.amethyst.service.AmberUtils
import com.vitorpamplona.amethyst.service.NostrChatroomListDataSource import com.vitorpamplona.amethyst.service.NostrChatroomListDataSource
import com.vitorpamplona.amethyst.ui.screen.ChatroomListFeedView import com.vitorpamplona.amethyst.ui.screen.ChatroomListFeedView
import com.vitorpamplona.amethyst.ui.screen.FeedViewModel import com.vitorpamplona.amethyst.ui.screen.FeedViewModel
@@ -48,8 +46,6 @@ import com.vitorpamplona.amethyst.ui.screen.NostrChatroomListKnownFeedViewModel
import com.vitorpamplona.amethyst.ui.screen.NostrChatroomListNewFeedViewModel import com.vitorpamplona.amethyst.ui.screen.NostrChatroomListNewFeedViewModel
import com.vitorpamplona.amethyst.ui.theme.TabRowHeight import com.vitorpamplona.amethyst.ui.theme.TabRowHeight
import com.vitorpamplona.amethyst.ui.theme.placeholderText import com.vitorpamplona.amethyst.ui.theme.placeholderText
import com.vitorpamplona.quartz.events.Event
import com.vitorpamplona.quartz.events.GiftWrapEvent
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@@ -70,19 +66,6 @@ fun ChatroomListScreen(
WatchAccountForListScreen(knownFeedViewModel, newFeedViewModel, accountViewModel) WatchAccountForListScreen(knownFeedViewModel, newFeedViewModel, accountViewModel)
LaunchedEffect(Unit) {
if (accountViewModel.loggedInWithAmber()) {
coroutineScope.launch(Dispatchers.IO) {
val gifts = LocalCache.notes.elements().toList().filter { it.event is GiftWrapEvent }
gifts.forEach {
it.event?.let {
AmberUtils.consume(it as Event)
}
}
}
}
}
val lifeCycleOwner = LocalLifecycleOwner.current val lifeCycleOwner = LocalLifecycleOwner.current
DisposableEffect(accountViewModel) { DisposableEffect(accountViewModel) {
val observer = LifecycleEventObserver { _, event -> val observer = LifecycleEventObserver { _, event ->
@@ -357,7 +357,34 @@ fun LoginPage(
Box(modifier = Modifier.padding(40.dp, 40.dp, 40.dp, 0.dp)) { Box(modifier = Modifier.padding(40.dp, 40.dp, 40.dp, 0.dp)) {
Button( Button(
onClick = { onClick = {
val result = AmberUtils.getDataFromResolver(SignerType.GET_PUBLIC_KEY, arrayOf("login"))
if (result == null) {
loginWithAmber = true loginWithAmber = true
return@Button
}
key.value = TextFieldValue(result)
if (!acceptedTerms.value) {
termsAcceptanceIsRequired =
context.getString(R.string.acceptance_of_terms_is_required)
}
if (key.value.text.isBlank()) {
errorMessage = context.getString(R.string.key_is_required)
}
if (acceptedTerms.value && key.value.text.isNotBlank()) {
try {
accountViewModel.startUI(
key.value.text,
useProxy.value,
proxyPort.value.toInt(),
true
)
} catch (e: Exception) {
Log.e("Login", "Could not sign in", e)
errorMessage = context.getString(R.string.invalid_key)
}
}
}, },
shape = RoundedCornerShape(Size35dp), shape = RoundedCornerShape(Size35dp),
modifier = Modifier modifier = Modifier