diff --git a/app/src/main/java/com/vitorpamplona/amethyst/model/Account.kt b/app/src/main/java/com/vitorpamplona/amethyst/model/Account.kt index 5239998bc..dcf4198d0 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/model/Account.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/model/Account.kt @@ -110,11 +110,10 @@ class Account( if (loginWithAmber) { val id = blockList?.id if (id != null) { - if (AmberUtils.cachedDecryptedContent[blockList.id] == null) { + if (blockList.decryptedContent == null) { GlobalScope.launch(Dispatchers.IO) { val content = blockList.content if (content.isEmpty()) return@launch - AmberUtils.content = "" AmberUtils.decryptBlockList( content, keyPair.pubKey.toHexKey(), @@ -222,10 +221,11 @@ class Account( if (loginWithAmber) { AmberUtils.openAmber(event) - if (AmberUtils.content.isBlank()) { + val content = AmberUtils.content[event.id] ?: "" + if (content.isBlank()) { return } - event = ContactListEvent.create(event, AmberUtils.content) + event = ContactListEvent.create(event, content) } Client.send(event) @@ -243,10 +243,11 @@ class Account( if (loginWithAmber) { AmberUtils.openAmber(event) - if (AmberUtils.content.isBlank()) { + val content = AmberUtils.content[event.id] + if (content.isBlank()) { return } - event = ContactListEvent.create(event, AmberUtils.content) + event = ContactListEvent.create(event, content) } // 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) if (loginWithAmber) { - AmberUtils.openAmber(event) - if (AmberUtils.content.isBlank()) { + val content = AmberUtils.content[event.id] + if (content.isBlank()) { return } - event = MetadataEvent.create(event, AmberUtils.content) + event = MetadataEvent.create(event, content) } Client.send(event) LocalCache.consume(event) @@ -314,21 +315,25 @@ class Account( ) AmberUtils.openAmber(senderReaction) - if (AmberUtils.content.isBlank()) return - senderReaction = ReactionEvent.create(senderReaction, AmberUtils.content) + val reactionContent = AmberUtils.content[event.id] + if (reactionContent.isBlank()) return + senderReaction = ReactionEvent.create(senderReaction, reactionContent) val giftWraps = users.plus(senderPublicKey).map { val gossip = Gossip.create(senderReaction) 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( - encryptedContent = AmberUtils.content, + encryptedContent = encryptedContent, pubKey = senderPublicKey ) AmberUtils.openAmber(sealedEvent) - if (AmberUtils.content.isBlank()) return - sealedEvent = SealedGossipEvent.create(sealedEvent, AmberUtils.content) + val eventContent = AmberUtils.content[sealedEvent.id] ?: "" + if (eventContent.isBlank()) return + sealedEvent = SealedGossipEvent.create(sealedEvent, eventContent) GiftWrapEvent.create( event = sealedEvent, @@ -363,23 +368,26 @@ class Account( ) AmberUtils.openAmber(senderReaction) - if (AmberUtils.content.isBlank()) return - senderReaction = ReactionEvent.create(senderReaction, AmberUtils.content) + val reactionContent = AmberUtils.content[senderReaction.id] ?: "" + if (reactionContent.isBlank()) return + senderReaction = ReactionEvent.create(senderReaction, reactionContent) val newUsers = users.plus(senderPublicKey) newUsers.forEach { val gossip = Gossip.create(senderReaction) val content = Gossip.toJson(gossip) - AmberUtils.content = "" - 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( - encryptedContent = AmberUtils.content, + encryptedContent = encryptedContent, pubKey = senderPublicKey ) AmberUtils.openAmber(sealedEvent) - if (AmberUtils.content.isBlank()) return - sealedEvent = SealedGossipEvent.create(sealedEvent, AmberUtils.content) + val sealedContent = AmberUtils.content[sealedEvent.id] ?: "" + if (sealedContent.isBlank()) return + sealedEvent = SealedGossipEvent.create(sealedEvent, sealedContent) val giftWraps = GiftWrapEvent.create( event = sealedEvent, @@ -511,8 +519,9 @@ class Account( if (privKey != null) return zapResponseEvent.response(privKey, pubKey) AmberUtils.decrypt(zapResponseEvent.content, pubKey.toHexKey(), zapResponseEvent.id) - if (AmberUtils.content.isBlank()) return null - return zapResponseEvent.response(AmberUtils.content) + val decryptedContent = AmberUtils.content[zapResponseEvent.id] ?: "" + if (decryptedContent.isBlank()) return null + return zapResponseEvent.response(decryptedContent) } fun calculateIfNoteWasZappedByAccount(zappedNote: Note?): Boolean { @@ -582,16 +591,16 @@ class Account( note.event?.let { var event = ReactionEvent.createWarning(it, keyPair) if (loginWithAmber) { - AmberUtils.content = "" AmberUtils.openAmber(event) - if (AmberUtils.content.isBlank()) return + val eventContent = AmberUtils.content[event.id] ?: "" + if (eventContent.isBlank()) return event = ReactionEvent( event.id, event.pubKey, event.createdAt, event.tags, event.content, - AmberUtils.content + eventContent ) } Client.send(event) @@ -601,16 +610,16 @@ class Account( note.event?.let { var event = ReportEvent.create(it, type, keyPair, content = content) if (loginWithAmber) { - AmberUtils.content = "" AmberUtils.openAmber(event) - if (AmberUtils.content.isBlank()) return + val eventContent = AmberUtils.content[event.id] ?: "" + if (eventContent.isBlank()) return event = ReportEvent( event.id, event.pubKey, event.createdAt, event.tags, event.content, - AmberUtils.content + eventContent ) } Client.send(event) @@ -628,16 +637,16 @@ class Account( var event = ReportEvent.create(user.pubkeyHex, type, keyPair) if (loginWithAmber) { - AmberUtils.content = "" AmberUtils.openAmber(event) - if (AmberUtils.content.isBlank()) return + val eventContent = AmberUtils.content[event.id] ?: "" + if (eventContent.isBlank()) return event = ReportEvent( event.id, event.pubKey, event.createdAt, event.tags, event.content, - AmberUtils.content + eventContent ) } Client.send(event) @@ -670,10 +679,11 @@ class Account( var event = HTTPAuthorizationEvent.create(url, method, body, keyPair) if (loginWithAmber) { AmberUtils.openAmber(event) - if (AmberUtils.content.isBlank()) { + val eventContent = AmberUtils.content[event.id] ?: "" + if (eventContent.isBlank()) { return null } - event = HTTPAuthorizationEvent.create(event, AmberUtils.content) + event = HTTPAuthorizationEvent.create(event, eventContent) } return event } @@ -734,10 +744,11 @@ class Account( keyPair ) AmberUtils.openAmber(unsignedEvent) - returningContactList = if (AmberUtils.content.isBlank()) { + val eventContent = AmberUtils.content[unsignedEvent.id] ?: "" + returningContactList = if (eventContent.isBlank()) { latestContactList } else { - ContactListEvent.create(unsignedEvent, AmberUtils.content) + ContactListEvent.create(unsignedEvent, eventContent) } } else { returningContactList = ContactListEvent.followAddressableEvent( @@ -782,10 +793,11 @@ class Account( if (loginWithAmber) { AmberUtils.openAmber(event) - if (AmberUtils.content.isBlank()) { + val eventContent = AmberUtils.content[event.id] ?: "" + if (eventContent.isBlank()) { return } - event = ContactListEvent.create(event, AmberUtils.content) + event = ContactListEvent.create(event, eventContent) } Client.send(event) @@ -813,10 +825,11 @@ class Account( if (loginWithAmber) { AmberUtils.openAmber(event) - if (AmberUtils.content.isBlank()) { + val eventContent = AmberUtils.content[event.id] ?: "" + if (eventContent.isBlank()) { return } - event = ContactListEvent.create(event, AmberUtils.content) + event = ContactListEvent.create(event, eventContent) } Client.send(event) @@ -845,10 +858,11 @@ class Account( if (loginWithAmber) { AmberUtils.openAmber(event) - if (AmberUtils.content.isBlank()) { + val eventContent = AmberUtils.content[event.id] ?: "" + if (eventContent.isBlank()) { return } - event = ContactListEvent.create(event, AmberUtils.content) + event = ContactListEvent.create(event, eventContent) } Client.send(event) @@ -880,10 +894,11 @@ class Account( if (loginWithAmber) { AmberUtils.openAmber(event) - if (AmberUtils.content.isBlank()) { + val eventContent = AmberUtils.content[event.id] ?: "" + if (eventContent.isBlank()) { return } - event = ContactListEvent.create(event, AmberUtils.content) + event = ContactListEvent.create(event, eventContent) } Client.send(event) @@ -915,10 +930,11 @@ class Account( if (loginWithAmber) { AmberUtils.openAmber(event) - if (AmberUtils.content.isBlank()) { + val eventContent = AmberUtils.content[event.id] ?: "" + if (eventContent.isBlank()) { return } - event = ContactListEvent.create(event, AmberUtils.content) + event = ContactListEvent.create(event, eventContent) } Client.send(event) @@ -939,10 +955,11 @@ class Account( if (loginWithAmber) { AmberUtils.openAmber(event) - if (AmberUtils.content.isBlank()) { + val eventContent = AmberUtils.content[event.id] ?: "" + if (eventContent.isBlank()) { return } - event = ContactListEvent.create(event, AmberUtils.content) + event = ContactListEvent.create(event, eventContent) } Client.send(event) @@ -964,10 +981,11 @@ class Account( if (loginWithAmber) { AmberUtils.openAmber(event) - if (AmberUtils.content.isBlank()) { + val eventContent = AmberUtils.content[event.id] ?: "" + if (eventContent.isBlank()) { return } - event = ContactListEvent.create(event, AmberUtils.content) + event = ContactListEvent.create(event, eventContent) } Client.send(event) @@ -989,10 +1007,11 @@ class Account( if (loginWithAmber) { AmberUtils.openAmber(event) - if (AmberUtils.content.isBlank()) { + val eventContent = AmberUtils.content[event.id] ?: "" + if (eventContent.isBlank()) { return } - event = ContactListEvent.create(event, AmberUtils.content) + event = ContactListEvent.create(event, eventContent) } Client.send(event) @@ -1014,10 +1033,11 @@ class Account( if (loginWithAmber) { AmberUtils.openAmber(event) - if (AmberUtils.content.isBlank()) { + val eventContent = AmberUtils.content[event.id] ?: "" + if (eventContent.isBlank()) { return } - event = ContactListEvent.create(event, AmberUtils.content) + event = ContactListEvent.create(event, eventContent) } Client.send(event) @@ -1039,10 +1059,11 @@ class Account( if (loginWithAmber) { AmberUtils.openAmber(event) - if (AmberUtils.content.isBlank()) { + val eventContent = AmberUtils.content[event.id] ?: "" + if (eventContent.isBlank()) { return } - event = ContactListEvent.create(event, AmberUtils.content) + event = ContactListEvent.create(event, eventContent) } Client.send(event) @@ -1061,14 +1082,15 @@ class Account( ) AmberUtils.openAmber(unsignedData) - if (AmberUtils.content.isBlank()) return null + val eventContent = AmberUtils.content[unsignedData.id] ?: "" + if (eventContent.isBlank()) return null val data = FileStorageEvent( unsignedData.id, unsignedData.pubKey, unsignedData.createdAt, unsignedData.tags, unsignedData.content, - AmberUtils.content + eventContent ) val unsignedEvent = FileStorageHeaderEvent.create( @@ -1084,14 +1106,15 @@ class Account( ) AmberUtils.openAmber(unsignedEvent) - if (AmberUtils.content.isBlank()) return null + val unsignedEventContent = AmberUtils.content[unsignedEvent.id] ?: "" + if (unsignedEventContent.isBlank()) return null val signedEvent = FileStorageHeaderEvent( unsignedEvent.id, unsignedEvent.pubKey, unsignedEvent.createdAt, unsignedEvent.tags, unsignedEvent.content, - AmberUtils.content + unsignedEventContent ) return Pair(data, signedEvent) @@ -1153,14 +1176,15 @@ class Account( keyPair = keyPair ) AmberUtils.openAmber(unsignedEvent) - if (AmberUtils.content.isBlank()) return null + val eventContent = AmberUtils.content[unsignedEvent.id] ?: "" + if (eventContent.isBlank()) return null val signedEvent = FileHeaderEvent( unsignedEvent.id, unsignedEvent.pubKey, unsignedEvent.createdAt, unsignedEvent.tags, unsignedEvent.content, - AmberUtils.content + eventContent ) return sendHeader(signedEvent, relayList = relayList) @@ -1219,10 +1243,11 @@ class Account( if (loginWithAmber) { AmberUtils.openAmber(signedEvent) - if (AmberUtils.content.isBlank()) { + val eventContent = AmberUtils.content[signedEvent.id] ?: "" + if (eventContent.isBlank()) { return } - signedEvent = TextNoteEvent.create(signedEvent, AmberUtils.content) + signedEvent = TextNoteEvent.create(signedEvent, eventContent) } Client.send(signedEvent, relayList = relayList) @@ -1288,10 +1313,11 @@ class Account( if (loginWithAmber) { AmberUtils.openAmber(signedEvent) - if (AmberUtils.content.isBlank()) { + val eventContent = AmberUtils.content[signedEvent.id] ?: "" + if (eventContent.isBlank()) { return } - signedEvent = PollNoteEvent.create(signedEvent, AmberUtils.content) + signedEvent = PollNoteEvent.create(signedEvent, eventContent) } Client.send(signedEvent, relayList = relayList) @@ -1339,10 +1365,11 @@ class Account( if (loginWithAmber) { AmberUtils.openAmber(signedEvent) - if (AmberUtils.content.isBlank()) { + val eventContent = AmberUtils.content[signedEvent.id] ?: "" + if (eventContent.isBlank()) { return } - signedEvent = ChannelMessageEvent.create(signedEvent, AmberUtils.content) + signedEvent = ChannelMessageEvent.create(signedEvent, eventContent) } Client.send(signedEvent) @@ -1379,10 +1406,11 @@ class Account( if (loginWithAmber) { AmberUtils.openAmber(signedEvent) - if (AmberUtils.content.isBlank()) { + val eventContent = AmberUtils.content[signedEvent.id] ?: "" + if (eventContent.isBlank()) { return } - signedEvent = LiveActivitiesChatMessageEvent.create(signedEvent, AmberUtils.content) + signedEvent = LiveActivitiesChatMessageEvent.create(signedEvent, eventContent) } Client.send(signedEvent) @@ -1410,10 +1438,11 @@ class Account( var localMessage = message if (loginWithAmber) { - AmberUtils.content = "" - AmberUtils.encrypt(localMessage, toUser) - if (AmberUtils.content.isBlank()) return - localMessage = AmberUtils.content + AmberUtils.encrypt(localMessage, toUser, "encrypt") + val eventContent = AmberUtils.content["encrypt"] ?: "" + if (eventContent.isBlank()) return + localMessage = eventContent + AmberUtils.content.remove("encrypt") } var signedEvent = PrivateDmEvent.create( @@ -1432,10 +1461,11 @@ class Account( if (loginWithAmber) { AmberUtils.openAmber(signedEvent) - if (AmberUtils.content.isBlank()) { + val eventContent = AmberUtils.content[signedEvent.id] ?: "" + if (eventContent.isBlank()) { return } - signedEvent = PrivateDmEvent.create(signedEvent, AmberUtils.content) + signedEvent = PrivateDmEvent.create(signedEvent, eventContent) } Client.send(signedEvent) @@ -1473,22 +1503,24 @@ class Account( ) AmberUtils.openAmber(chatMessageEvent) - if (AmberUtils.content.isBlank()) return - chatMessageEvent = ChatMessageEvent.create(chatMessageEvent, AmberUtils.content) + val eventContent = AmberUtils.content[chatMessageEvent.id] ?: "" + if (eventContent.isBlank()) return + chatMessageEvent = ChatMessageEvent.create(chatMessageEvent, eventContent) val senderPublicKey = keyPair.pubKey.toHexKey() toUsers.plus(senderPublicKey).toSet().forEach { val gossip = Gossip.create(chatMessageEvent) val content = Gossip.toJson(gossip) - AmberUtils.content = "" - AmberUtils.encrypt(content, it, SignerType.NIP44_ENCRYPT) - if (AmberUtils.content.isNotBlank()) { + AmberUtils.encrypt(content, it, gossip.id!!, SignerType.NIP44_ENCRYPT) + val gossipContent = AmberUtils.content[gossip.id] ?: "" + if (gossipContent.isNotBlank()) { var sealedEvent = SealedGossipEvent.create( - encryptedContent = AmberUtils.content, + encryptedContent = gossipContent, pubKey = senderPublicKey ) AmberUtils.openAmber(sealedEvent) - if (AmberUtils.content.isBlank()) return - sealedEvent = SealedGossipEvent.create(sealedEvent, AmberUtils.content) + val sealedEventContent = AmberUtils.content[sealedEvent.id] ?: "" + if (sealedEventContent.isBlank()) return + sealedEvent = SealedGossipEvent.create(sealedEvent, sealedEventContent) val giftWraps = GiftWrapEvent.create( event = sealedEvent, @@ -1522,13 +1554,11 @@ class Account( // Only keep in cache the GiftWrap for the account. if (it.recipientPubKey() == keyPair.pubKey.toHexKey()) { if (loginWithAmber) { - AmberUtils.content = "" AmberUtils.decrypt(it.content, it.pubKey, it.id, SignerType.NIP44_DECRYPT) val decryptedContent = AmberUtils.cachedDecryptedContent[it.id] ?: "" if (decryptedContent.isEmpty()) return it.cachedGift(keyPair.pubKey, decryptedContent)?.let { cached -> if (cached is SealedGossipEvent) { - AmberUtils.content = "" AmberUtils.decrypt(cached.content, cached.pubKey, cached.id, SignerType.NIP44_DECRYPT) val localDecryptedContent = AmberUtils.cachedDecryptedContent[cached.id] ?: "" if (localDecryptedContent.isEmpty()) return @@ -1572,10 +1602,11 @@ class Account( if (loginWithAmber) { AmberUtils.openAmber(event) - if (AmberUtils.content.isBlank()) { + val eventContent = AmberUtils.content[event.id] ?: "" + if (eventContent.isBlank()) { return } - event = ChannelCreateEvent.create(event, AmberUtils.content) + event = ChannelCreateEvent.create(event, eventContent) } Client.send(event) @@ -1593,10 +1624,11 @@ class Account( var event = StatusEvent.update(oldEvent, newStatus, keyPair) if (loginWithAmber) { AmberUtils.openAmber(event) - if (AmberUtils.content.isBlank()) { + val eventContent = AmberUtils.content[event.id] ?: "" + if (eventContent.isBlank()) { return } - event = StatusEvent.create(event, AmberUtils.content) + event = StatusEvent.create(event, eventContent) } Client.send(event) LocalCache.consume(event, null) @@ -1608,10 +1640,11 @@ class Account( var event = StatusEvent.create(newStatus, "general", expiration = null, keyPair) if (loginWithAmber) { AmberUtils.openAmber(event) - if (AmberUtils.content.isBlank()) { + val eventContent = AmberUtils.content[event.id] ?: "" + if (eventContent.isBlank()) { return } - event = StatusEvent.create(event, AmberUtils.content) + event = StatusEvent.create(event, eventContent) } Client.send(event) LocalCache.consume(event, null) @@ -1624,10 +1657,11 @@ class Account( var event = StatusEvent.clear(oldEvent, keyPair) if (loginWithAmber) { AmberUtils.openAmber(event) - if (AmberUtils.content.isBlank()) { + val eventContent = AmberUtils.content[event.id] ?: "" + if (eventContent.isBlank()) { return } - event = StatusEvent.create(event, AmberUtils.content) + event = StatusEvent.create(event, eventContent) } Client.send(event) LocalCache.consume(event, null) @@ -1635,10 +1669,11 @@ class Account( var event2 = DeletionEvent.create(listOf(event.id), keyPair) if (loginWithAmber) { AmberUtils.openAmber(event2) - if (AmberUtils.content.isBlank()) { + val event2Content = AmberUtils.content[event2.id] ?: "" + if (event2Content.isBlank()) { return } - event2 = DeletionEvent.create(event2, AmberUtils.content) + event2 = DeletionEvent.create(event2, event2Content) } Client.send(event2) LocalCache.consume(event2) @@ -1659,10 +1694,11 @@ class Account( if (loginWithAmber) { AmberUtils.openAmber(event) - if (AmberUtils.content.isBlank()) { + val eventContent = AmberUtils.content[event.id] ?: "" + if (eventContent.isBlank()) { return } - event = EmojiPackSelectionEvent.create(event, AmberUtils.content) + event = EmojiPackSelectionEvent.create(event, eventContent) } Client.send(event) @@ -1695,10 +1731,11 @@ class Account( if (loginWithAmber) { AmberUtils.openAmber(event) - if (AmberUtils.content.isBlank()) { + val eventContent = AmberUtils.content[event.id] ?: "" + if (eventContent.isBlank()) { return } - event = EmojiPackSelectionEvent.create(event, AmberUtils.content) + event = EmojiPackSelectionEvent.create(event, eventContent) } Client.send(event) @@ -1732,9 +1769,10 @@ class Account( } val msg = Event.mapper.writeValueAsString(privTags) - AmberUtils.encrypt(msg, keyPair.pubKey.toHexKey()) - - if (AmberUtils.content.isBlank()) { + AmberUtils.encrypt(msg, keyPair.pubKey.toHexKey(), "encrypt") + val encryptedContent = AmberUtils.content["encrypt"] ?: "" + AmberUtils.content.remove("encrypt") + if (encryptedContent.isBlank()) { return } @@ -1744,16 +1782,17 @@ class Account( bookmarks?.taggedUsers() ?: emptyList(), bookmarks?.taggedAddresses() ?: emptyList(), - AmberUtils.content, + encryptedContent, keyPair.pubKey.toHexKey() ) AmberUtils.openAmber(event) - if (AmberUtils.content.isBlank()) { + val eventContent = AmberUtils.content[event.id] ?: "" + if (eventContent.isBlank()) { return } - event = BookmarkListEvent.create(event, AmberUtils.content) + event = BookmarkListEvent.create(event, eventContent) Client.send(event) LocalCache.consume(event) @@ -1786,9 +1825,10 @@ class Account( } val msg = Event.mapper.writeValueAsString(privTags) - AmberUtils.encrypt(msg, keyPair.pubKey.toHexKey()) - - if (AmberUtils.content.isBlank()) { + AmberUtils.encrypt(msg, keyPair.pubKey.toHexKey(), "encrypt") + val encryptedContent = AmberUtils.content["encrypt"] ?: "" + AmberUtils.content.remove("encrypt") + if (encryptedContent.isBlank()) { return } @@ -1798,16 +1838,17 @@ class Account( bookmarks?.taggedUsers() ?: emptyList(), bookmarks?.taggedAddresses() ?: emptyList(), - AmberUtils.content, + encryptedContent, keyPair.pubKey.toHexKey() ) AmberUtils.openAmber(event) - if (AmberUtils.content.isBlank()) { + val eventContent = AmberUtils.content[event.id] ?: "" + if (eventContent.isBlank()) { return } - event = BookmarkListEvent.create(event, AmberUtils.content) + event = BookmarkListEvent.create(event, eventContent) Client.send(event) LocalCache.consume(event) @@ -1870,9 +1911,10 @@ class Account( } val msg = Event.mapper.writeValueAsString(privTags) - AmberUtils.encrypt(msg, keyPair.pubKey.toHexKey()) - - if (AmberUtils.content.isBlank()) { + AmberUtils.encrypt(msg, keyPair.pubKey.toHexKey(), "encrypt") + val encryptedContent = AmberUtils.content["encrypt"] ?: "" + AmberUtils.content.remove("encrypt") + if (encryptedContent.isBlank()) { return } @@ -1882,7 +1924,7 @@ class Account( bookmarks?.taggedEvents() ?: emptyList(), bookmarks?.taggedUsers() ?: emptyList(), bookmarks?.taggedAddresses()?.plus(note.address) ?: listOf(note.address), - AmberUtils.content, + encryptedContent, keyPair.pubKey.toHexKey() ) } else { @@ -1891,15 +1933,16 @@ class Account( bookmarks?.taggedEvents()?.plus(note.idHex) ?: listOf(note.idHex), bookmarks?.taggedUsers() ?: emptyList(), bookmarks?.taggedAddresses() ?: emptyList(), - AmberUtils.content, + encryptedContent, keyPair.pubKey.toHexKey() ) } AmberUtils.openAmber(event) - if (AmberUtils.content.isBlank()) { + val eventContent = AmberUtils.content[event.id] ?: "" + if (eventContent.isBlank()) { return } - event = BookmarkListEvent.create(event, AmberUtils.content) + event = BookmarkListEvent.create(event, encryptedContent) Client.send(event) LocalCache.consume(event) @@ -1985,10 +2028,11 @@ class Account( var event = RelayAuthEvent.create(relay.url, challenge, keyPair.pubKey.toHexKey(), keyPair.privKey) if (loginWithAmber) { AmberUtils.openAmber(event) - if (AmberUtils.content.isBlank()) { + val eventContent = AmberUtils.content[event.id] ?: "" + if (eventContent.isBlank()) { return null } - event = RelayAuthEvent.create(event, AmberUtils.content) + event = RelayAuthEvent.create(event, eventContent) } return event @@ -2051,9 +2095,10 @@ class Account( } val msg = Event.mapper.writeValueAsString(privTags) - AmberUtils.encrypt(msg, keyPair.pubKey.toHexKey()) - - if (AmberUtils.content.isBlank()) { + AmberUtils.encrypt(msg, keyPair.pubKey.toHexKey(), "encrypt") + val encryptedContent = AmberUtils.content["encrypt"] ?: "" + AmberUtils.content.remove("encrypt") + if (encryptedContent.isBlank()) { return } @@ -2063,7 +2108,7 @@ class Account( bookmarks?.taggedEvents() ?: emptyList(), bookmarks?.taggedUsers() ?: emptyList(), bookmarks?.taggedAddresses()?.minus(note.address), - AmberUtils.content, + encryptedContent, keyPair.pubKey.toHexKey() ) } else { @@ -2072,16 +2117,17 @@ class Account( bookmarks?.taggedEvents()?.minus(note.idHex), bookmarks?.taggedUsers() ?: emptyList(), bookmarks?.taggedAddresses() ?: emptyList(), - AmberUtils.content, + encryptedContent, keyPair.pubKey.toHexKey() ) } AmberUtils.openAmber(event) - if (AmberUtils.content.isBlank()) { + val eventContent = AmberUtils.content[event.id] ?: "" + if (eventContent.isBlank()) { return } - event = BookmarkListEvent.create(event, AmberUtils.content) + event = BookmarkListEvent.create(event, eventContent) Client.send(event) LocalCache.consume(event) @@ -2154,25 +2200,26 @@ class Account( val privateTags = listOf(listOf("p", pubkeyHex)) val msg = Event.mapper.writeValueAsString(privateTags) - AmberUtils.content = "" - AmberUtils.encrypt(msg, keyPair.pubKey.toHexKey()) - if (AmberUtils.content.isBlank()) return - AmberUtils.content + AmberUtils.encrypt(msg, keyPair.pubKey.toHexKey(), "encrypt") + val encryptedContent = AmberUtils.content["encrypted"] ?: "" + AmberUtils.content.remove("encrypted") + if (encryptedContent.isBlank()) return + encryptedContent } else { var decryptedContent = AmberUtils.cachedDecryptedContent[id] if (decryptedContent == null) { - AmberUtils.content = "" - AmberUtils.decrypt(blockList.content, keyPair.pubKey.toHexKey(), blockList.id) - if (AmberUtils.content.isBlank()) return - decryptedContent = AmberUtils.content + AmberUtils.decrypt(blockList.content, keyPair.pubKey.toHexKey(), id) + val content = AmberUtils.content[id] ?: "" + if (content.isBlank()) return + decryptedContent = content } val privateTags = blockList.privateTagsOrEmpty(decryptedContent).plus(element = listOf("p", pubkeyHex)) val msg = Event.mapper.writeValueAsString(privateTags) - AmberUtils.content = "" - AmberUtils.encrypt(msg, keyPair.pubKey.toHexKey()) - if (AmberUtils.content.isBlank()) return - AmberUtils.content + AmberUtils.encrypt(msg, keyPair.pubKey.toHexKey(), id) + val eventContent = AmberUtils.content[id] ?: "" + if (eventContent.isBlank()) return + eventContent } var event = if (blockList != null) { @@ -2193,15 +2240,16 @@ class Account( ) } - AmberUtils.content = "" AmberUtils.openAmber(event) + val eventContent = AmberUtils.content[event.id] ?: "" + if (eventContent.isBlank()) return event = PeopleListEvent( event.id, event.pubKey, event.createdAt, event.tags, event.content, - AmberUtils.content + eventContent ) Client.send(event) @@ -2241,25 +2289,24 @@ class Account( val privateTags = listOf(listOf("p", pubkeyHex)) val msg = Event.mapper.writeValueAsString(privateTags) - AmberUtils.content = "" - AmberUtils.encrypt(msg, keyPair.pubKey.toHexKey()) - if (AmberUtils.content.isBlank()) return - AmberUtils.content + AmberUtils.encrypt(msg, keyPair.pubKey.toHexKey(), blockList.id) + val eventContent = AmberUtils.content[blockList.id] ?: "" + if (eventContent.isBlank()) return + eventContent } else { var decryptedContent = AmberUtils.cachedDecryptedContent[blockList.id] if (decryptedContent == null) { - AmberUtils.content = "" AmberUtils.decrypt(blockList.content, keyPair.pubKey.toHexKey(), blockList.id) - if (AmberUtils.content.isBlank()) return - decryptedContent = AmberUtils.content + val eventContent = AmberUtils.content[blockList.id] ?: "" + if (eventContent.isBlank()) return + decryptedContent = eventContent } - AmberUtils.content = "" val privateTags = blockList.privateTagsOrEmpty(decryptedContent).minus(element = listOf("p", pubkeyHex)) val msg = Event.mapper.writeValueAsString(privateTags) - AmberUtils.content = "" - AmberUtils.encrypt(msg, keyPair.pubKey.toHexKey()) - if (AmberUtils.content.isBlank()) return - AmberUtils.content + AmberUtils.encrypt(msg, keyPair.pubKey.toHexKey(), blockList.id) + val eventContent = AmberUtils.content[blockList.id] ?: "" + if (eventContent.isBlank()) return + eventContent } var event = PeopleListEvent.addUser( @@ -2270,9 +2317,10 @@ class Account( encryptedContent ) - AmberUtils.content = "" 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) LocalCache.consume(event) @@ -2485,8 +2533,9 @@ class Account( ) if (loginWithAmber) { AmberUtils.openAmber(event) - if (AmberUtils.content.isBlank()) return - event = ChannelMetadataEvent.create(event, AmberUtils.content) + val eventContent = AmberUtils.content[event.id] ?: "" + if (eventContent.isBlank()) return + event = ChannelMetadataEvent.create(event, eventContent) } Client.send(event) @@ -2501,7 +2550,6 @@ class Account( if (loginWithAmber) { var decryptedContent = AmberUtils.cachedDecryptedContent[event.id] if (decryptedContent == null) { - AmberUtils.content = "" AmberUtils.decrypt(event.content, event.pubKey, event.id, SignerType.NIP44_DECRYPT) } decryptedContent = AmberUtils.cachedDecryptedContent[event.id] ?: "" @@ -2518,7 +2566,6 @@ class Account( if (loginWithAmber) { var decryptedContent = AmberUtils.cachedDecryptedContent[event.id] if (decryptedContent == null) { - AmberUtils.content = "" AmberUtils.decrypt(event.content, event.pubKey, event.id, SignerType.NIP44_DECRYPT) } decryptedContent = AmberUtils.cachedDecryptedContent[event.id] ?: "" @@ -2546,7 +2593,6 @@ class Account( return when (event) { is PrivateDmEvent -> { if (AmberUtils.cachedDecryptedContent[event.id] == null) { - AmberUtils.content = "" AmberUtils.decryptDM( event.content, event.talkingWith(userProfile().pubkeyHex), @@ -2571,25 +2617,16 @@ class Account( val loggedInPrivateKey = keyPair.privKey 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 -// 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()) { diff --git a/app/src/main/java/com/vitorpamplona/amethyst/model/LocalCache.kt b/app/src/main/java/com/vitorpamplona/amethyst/model/LocalCache.kt index b97551c4a..9d60225f9 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/model/LocalCache.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/model/LocalCache.kt @@ -214,7 +214,7 @@ object LocalCache { if (hexKey != null) { val pubKey = Hex.encode(hexKey) if (pubKey == event.pubKey) { - AmberUtils.content = "" + AmberUtils.content.remove(event.id) } } user.updateBookmark(event) @@ -466,6 +466,7 @@ object LocalCache { } fun consume(event: PrivateDmEvent, relay: Relay?): Note { + Log.e("isRunning", event.toJson()) val note = getOrCreateNote(event.id) val author = getOrCreateUser(event.pubKey) diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/AmberUtils.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/AmberUtils.kt index 51f9270f9..107e4faee 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/AmberUtils.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/AmberUtils.kt @@ -18,61 +18,20 @@ import com.vitorpamplona.quartz.encoders.HexKey import com.vitorpamplona.quartz.encoders.toHexKey import com.vitorpamplona.quartz.events.Event import com.vitorpamplona.quartz.events.EventInterface -import com.vitorpamplona.quartz.events.GiftWrapEvent import com.vitorpamplona.quartz.events.LnZapRequestEvent -import com.vitorpamplona.quartz.events.SealedGossipEvent import kotlinx.coroutines.DelicateCoroutinesApi import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch object AmberUtils { - var content: String = "" + val content = LruCache(10) var isActivityRunning: Boolean = false val cachedDecryptedContent = mutableMapOf() lateinit var account: Account lateinit var activityResultLauncher: ActivityResultLauncher - lateinit var decryptGossipResultLauncher: ActivityResultLauncher lateinit var blockListResultLauncher: ActivityResultLauncher lateinit var signEventResultLauncher: ActivityResultLauncher - val eventCache = LruCache(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) fun start(activity: MainActivity) { @@ -104,8 +63,6 @@ object AmberUtils { activityResultLauncher = activity.registerForActivityResult( ActivityResultContracts.StartActivityForResult() ) { - isActivityRunning = false - ServiceManager.shouldPauseService = true if (it.resultCode != Activity.RESULT_OK) { GlobalScope.launch(Dispatchers.Main) { Toast.makeText( @@ -116,12 +73,18 @@ object AmberUtils { } } else { val event = it.data?.getStringExtra("signature") ?: "" - content = event val id = it.data?.getStringExtra("id") ?: "" if (id.isNotBlank()) { + content.put(id, event) cachedDecryptedContent[id] = event } } + isActivityRunning = false + ServiceManager.shouldPauseService = true + GlobalScope.launch(Dispatchers.IO) { + isActivityRunning = false + ServiceManager.shouldPauseService = true + } } blockListResultLauncher = activity.registerForActivityResult( @@ -145,34 +108,10 @@ object AmberUtils { } isActivityRunning = false 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) { - AmberUtils.cachedDecryptedContent[event.id] = decryptedContent - consume(event) - } - } - } + GlobalScope.launch(Dispatchers.IO) { + isActivityRunning = false + ServiceManager.shouldPauseService = true } - isActivityRunning = false - ServiceManager.shouldPauseService = true } } @@ -203,6 +142,13 @@ object AmberUtils { fun openAmber(event: EventInterface) { checkNotInMainThread() + + val result = getDataFromResolver(SignerType.SIGN_EVENT, arrayOf(event.toJson(), event.pubKey())) + if (result !== null) { + content.put(event.id(), result) + return + } + ServiceManager.shouldPauseService = false isActivityRunning = true openAmber( @@ -231,6 +177,12 @@ object AmberUtils { } 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 openAmber( encryptedContent, @@ -241,23 +193,52 @@ object AmberUtils { ) } - fun decrypt(encryptedContent: String, pubKey: HexKey, id: String, signerType: SignerType = SignerType.NIP04_DECRYPT) { - if (content.isBlank()) { - isActivityRunning = true - openAmber( - encryptedContent, - signerType, - activityResultLauncher, - pubKey, - id - ) - while (isActivityRunning) { - // do nothing + fun getDataFromResolver(signerType: SignerType, data: Array, 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) { + val result = getDataFromResolver(signerType, arrayOf(encryptedContent, pubKey)) + if (result !== null) { + content.put(id, result) + cachedDecryptedContent[id] = result + return + } + + isActivityRunning = true + openAmber( + encryptedContent, + signerType, + activityResultLauncher, + pubKey, + id + ) + while (isActivityRunning) { + // do nothing + } } 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( encryptedContent, signerType, @@ -268,6 +249,12 @@ object AmberUtils { } 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( encryptedContent, signerType, @@ -277,21 +264,13 @@ object AmberUtils { ) } - fun decryptGossip(event: Event) { - if (eventCache.get(event.id) == null) { - eventCache.put(event.id, event) + fun encrypt(decryptedContent: String, pubKey: HexKey, id: String, signerType: SignerType = SignerType.NIP04_ENCRYPT) { + val result = getDataFromResolver(signerType, arrayOf(decryptedContent, pubKey)) + if (result !== null) { + content.put(id, result) + return } - isActivityRunning = true - openAmber( - event.content, - SignerType.NIP44_DECRYPT, - decryptGossipResultLauncher, - event.pubKey, - event.id - ) - } - fun encrypt(decryptedContent: String, pubKey: HexKey, signerType: SignerType = SignerType.NIP04_ENCRYPT) { isActivityRunning = true openAmber( decryptedContent, @@ -306,7 +285,12 @@ object AmberUtils { } 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( event.toJson(), SignerType.DECRYPT_ZAP_EVENT, @@ -314,8 +298,5 @@ object AmberUtils { event.pubKey, event.id ) - while (isActivityRunning) { - Thread.sleep(100) - } } } diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/NostrAccountDataSource.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/NostrAccountDataSource.kt index 0e709499a..c0c56b18f 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/NostrAccountDataSource.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/NostrAccountDataSource.kt @@ -8,6 +8,7 @@ import com.vitorpamplona.amethyst.service.relays.EOSEAccount import com.vitorpamplona.amethyst.service.relays.JsonFilter import com.vitorpamplona.amethyst.service.relays.Relay import com.vitorpamplona.amethyst.service.relays.TypedFilter +import com.vitorpamplona.amethyst.ui.actions.SignerType import com.vitorpamplona.quartz.encoders.toHexKey import com.vitorpamplona.quartz.events.AdvertisedRelayListEvent 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.StatusEvent import com.vitorpamplona.quartz.events.TextNoteEvent -import kotlinx.coroutines.DelicateCoroutinesApi object NostrAccountDataSource : NostrDataSource("AccountData") { lateinit var account: Account @@ -147,7 +147,6 @@ object NostrAccountDataSource : NostrDataSource("AccountData") { latestEOSEs.addOrUpdate(account.userProfile(), account.defaultNotificationFollowList, relayUrl, time) } - @OptIn(DelicateCoroutinesApi::class) override fun consume(event: Event, relay: Relay) { if (LocalCache.justVerify(event)) { if (event is GiftWrapEvent) { @@ -156,6 +155,20 @@ object NostrAccountDataSource : NostrDataSource("AccountData") { event.cachedGift(privateKey)?.let { 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 { 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. @@ -195,6 +222,15 @@ object NostrAccountDataSource : NostrDataSource("AccountData") { if (this::account.isInitialized) { if (account.loginWithAmber) { 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) } else { val event = account.createAuthEvent(relay, challenge) diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/notifications/EventNotificationConsumer.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/notifications/EventNotificationConsumer.kt index b99dec080..25826f923 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/notifications/EventNotificationConsumer.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/notifications/EventNotificationConsumer.kt @@ -45,7 +45,6 @@ class EventNotificationConsumer(private val applicationContext: Context) { if (account.loginWithAmber) { var cached = AmberUtils.cachedDecryptedContent[pushWrappedEvent.id] if (cached == null) { - AmberUtils.content = "" AmberUtils.decrypt( pushWrappedEvent.content, pushWrappedEvent.pubKey, @@ -100,6 +99,20 @@ class EventNotificationConsumer(private val applicationContext: Context) { event.cachedGift(key)?.let { 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 { null } @@ -112,6 +125,21 @@ class EventNotificationConsumer(private val applicationContext: Context) { LocalCache.justConsume(it, null) 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 { null } diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ChatroomHeaderCompose.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ChatroomHeaderCompose.kt index 1b180d330..5db559973 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ChatroomHeaderCompose.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ChatroomHeaderCompose.kt @@ -1,9 +1,5 @@ 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.foundation.background import androidx.compose.foundation.clickable @@ -25,13 +21,11 @@ import androidx.compose.material.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.MutableState -import androidx.compose.runtime.SideEffect import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue import androidx.compose.runtime.livedata.observeAsState import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember -import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -51,14 +45,11 @@ import androidx.compose.ui.unit.sp import androidx.lifecycle.distinctUntilChanged import androidx.lifecycle.map import com.patrykandpatrick.vico.core.extension.forEachIndexedExtended -import com.vitorpamplona.amethyst.Amethyst import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.model.Channel import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.model.Note 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.RobohashAsyncImageProxy 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.ChatroomKey import com.vitorpamplona.quartz.events.ChatroomKeyable -import com.vitorpamplona.quartz.events.PrivateDmEvent import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch @@ -255,7 +245,6 @@ private fun UserRoomCompose( accountViewModel: AccountViewModel, nav: (String) -> Unit ) { - val scope = rememberCoroutineScope() val hasNewMessages = remember { mutableStateOf(false) } val route = remember(room) { @@ -267,46 +256,12 @@ private fun UserRoomCompose( note.createdAt() } } - val decryptedContent = remember(note) { if (note.event == null) null else AmberUtils.cachedDecryptedContent[note.event!!.id()] } - var content by remember(note) { + val content by remember(note) { 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 -> if (hasNewMessages.value != newHasNewMessages) { hasNewMessages.value = newHasNewMessages diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ChatroomMessageCompose.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ChatroomMessageCompose.kt index be63e0cd5..93617ddea 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ChatroomMessageCompose.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ChatroomMessageCompose.kt @@ -1,9 +1,5 @@ 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.foundation.ExperimentalFoundationApi import androidx.compose.foundation.clickable @@ -26,13 +22,11 @@ import androidx.compose.material.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.MutableState -import androidx.compose.runtime.SideEffect import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue import androidx.compose.runtime.livedata.observeAsState import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember -import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment 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.unit.dp import androidx.lifecycle.map -import com.vitorpamplona.amethyst.Amethyst import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.model.Note 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.CreateTextWithEmoji import com.vitorpamplona.amethyst.ui.components.RobohashAsyncImageProxy @@ -636,43 +627,8 @@ private fun RenderRegularTextNote( nav: (String) -> Unit ) { 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()] } - var eventContent by remember { mutableStateOf(decryptedContent ?: accountViewModel.decrypt(note)) } + val eventContent by remember { mutableStateOf(accountViewModel.decrypt(note)) } 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) { SensitivityWarning( diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteCompose.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteCompose.kt index 4f59a3ea2..d8863325a 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteCompose.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteCompose.kt @@ -1,11 +1,7 @@ package com.vitorpamplona.amethyst.ui.note -import android.app.Activity import android.graphics.Bitmap 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.foundation.ExperimentalFoundationApi import androidx.compose.foundation.Image @@ -44,7 +40,6 @@ import androidx.compose.material.lightColors import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.MutableState -import androidx.compose.runtime.SideEffect import androidx.compose.runtime.Stable import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue @@ -81,7 +76,6 @@ import coil.compose.AsyncImage import coil.compose.AsyncImagePainter import coil.request.SuccessResult import com.fonfon.kgeohash.toGeoHash -import com.vitorpamplona.amethyst.Amethyst import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.model.AddressableNote 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.RelayBriefInfo import com.vitorpamplona.amethyst.model.User -import com.vitorpamplona.amethyst.service.AmberUtils import com.vitorpamplona.amethyst.service.OnlineChecker import com.vitorpamplona.amethyst.service.ReverseGeoLocationUtil import com.vitorpamplona.amethyst.service.connectivitystatus.ConnectivityStatus 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.CreateClickableTextWithEmoji import com.vitorpamplona.amethyst.ui.components.CreateTextWithEmoji @@ -1262,8 +1254,7 @@ fun RenderTextEvent( ) { val eventContent = remember(note.event) { val subject = (note.event as? TextNoteEvent)?.subject()?.ifEmpty { null } - val decryptedContent = if (note.event == null) null else AmberUtils.cachedDecryptedContent[note.event!!.id()] - val body = decryptedContent ?: accountViewModel.decrypt(note) + val body = accountViewModel.decrypt(note) if (!subject.isNullOrBlank() && body?.split("\n")?.get(0)?.contains(subject) == false) { "## $subject\n$body" @@ -1569,41 +1560,8 @@ private fun RenderPrivateMessage( val noteEvent = note.event as? PrivateDmEvent ?: return val withMe = remember { noteEvent.with(accountViewModel.userProfile().pubkeyHex) } - val scope = rememberCoroutineScope() - if (withMe) { - val decryptedContent = AmberUtils.cachedDecryptedContent[noteEvent.id] - 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 eventContent by remember { mutableStateOf(accountViewModel.decrypt(note)) } val hashtags = remember(note.event?.id()) { note.event?.hashtags()?.toImmutableList() ?: persistentListOf() } val modifier = remember(note.event?.id()) { Modifier.fillMaxWidth() } val isAuthorTheLoggedUser = remember(note.event?.id()) { accountViewModel.isLoggedUser(note.author) } diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/UserProfilePicture.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/UserProfilePicture.kt index 234e01d46..5c414a283 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/UserProfilePicture.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/UserProfilePicture.kt @@ -459,8 +459,7 @@ fun NoteDropDownMenu(note: Note, popupExpanded: MutableState, accountVi accountViewModel.account.keyPair.pubKey.toHexKey(), bookmarks?.id ?: "" ) - bookmarks?.decryptedContent = AmberUtils.content - AmberUtils.content = "" + bookmarks?.decryptedContent = AmberUtils.cachedDecryptedContent[bookmarks?.id ?: ""] ?: "" accountViewModel.removePrivateBookmark(note, bookmarks?.decryptedContent ?: "") } else { accountViewModel.removePrivateBookmark(note) @@ -482,8 +481,7 @@ fun NoteDropDownMenu(note: Note, popupExpanded: MutableState, accountVi accountViewModel.account.keyPair.pubKey.toHexKey(), bookmarks?.id ?: "" ) - bookmarks?.decryptedContent = AmberUtils.content - AmberUtils.content = "" + bookmarks?.decryptedContent = AmberUtils.cachedDecryptedContent[bookmarks?.id ?: ""] ?: "" accountViewModel.addPrivateBookmark(note, bookmarks?.decryptedContent ?: "") } else { accountViewModel.addPrivateBookmark(note) @@ -506,8 +504,7 @@ fun NoteDropDownMenu(note: Note, popupExpanded: MutableState, accountVi accountViewModel.account.keyPair.pubKey.toHexKey(), bookmarks?.id ?: "" ) - bookmarks?.decryptedContent = AmberUtils.content - AmberUtils.content = "" + bookmarks?.decryptedContent = AmberUtils.cachedDecryptedContent[bookmarks?.id ?: ""] ?: "" accountViewModel.removePublicBookmark( note, bookmarks?.decryptedContent ?: "" @@ -532,8 +529,7 @@ fun NoteDropDownMenu(note: Note, popupExpanded: MutableState, accountVi accountViewModel.account.keyPair.pubKey.toHexKey(), bookmarks?.id ?: "" ) - bookmarks?.decryptedContent = AmberUtils.content - AmberUtils.content = "" + bookmarks?.decryptedContent = AmberUtils.cachedDecryptedContent[bookmarks?.id ?: ""] ?: "" accountViewModel.addPublicBookmark( note, bookmarks?.decryptedContent ?: "" diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/BookmarkListScreen.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/BookmarkListScreen.kt index d4b5dc1bb..a8040c539 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/BookmarkListScreen.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/BookmarkListScreen.kt @@ -11,7 +11,6 @@ import androidx.compose.material.Tab import androidx.compose.material.TabRow import androidx.compose.material.Text import androidx.compose.runtime.Composable -import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.livedata.observeAsState @@ -21,7 +20,6 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import androidx.lifecycle.viewmodel.compose.viewModel import com.vitorpamplona.amethyst.R -import com.vitorpamplona.amethyst.service.AmberUtils import com.vitorpamplona.amethyst.ui.dal.BookmarkPrivateFeedFilter import com.vitorpamplona.amethyst.ui.dal.BookmarkPublicFeedFilter import com.vitorpamplona.amethyst.ui.screen.NostrBookmarkPrivateFeedViewModel @@ -93,11 +91,5 @@ fun BookmarkListScreen(accountViewModel: AccountViewModel, nav: (String) -> Unit } } } - - DisposableEffect(Unit) { - onDispose { - AmberUtils.content = "" - } - } } } diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/ChatroomListScreen.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/ChatroomListScreen.kt index 2fdd2f764..39b60a649 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/ChatroomListScreen.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/ChatroomListScreen.kt @@ -39,8 +39,6 @@ import androidx.compose.ui.unit.dp import androidx.lifecycle.Lifecycle import androidx.lifecycle.LifecycleEventObserver 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.ui.screen.ChatroomListFeedView 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.theme.TabRowHeight 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.launch @@ -70,19 +66,6 @@ fun ChatroomListScreen( 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 DisposableEffect(accountViewModel) { val observer = LifecycleEventObserver { _, event -> diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedOff/LoginScreen.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedOff/LoginScreen.kt index 734972693..25f3d9979 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedOff/LoginScreen.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedOff/LoginScreen.kt @@ -357,7 +357,34 @@ fun LoginPage( Box(modifier = Modifier.padding(40.dp, 40.dp, 40.dp, 0.dp)) { Button( onClick = { - loginWithAmber = true + val result = AmberUtils.getDataFromResolver(SignerType.GET_PUBLIC_KEY, arrayOf("login")) + if (result == null) { + 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), modifier = Modifier