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 7e4d04904..9e007d3bc 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/model/LocalCache.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/model/LocalCache.kt @@ -1110,6 +1110,23 @@ object LocalCache { refreshObservers(note) } + private fun consume(event: ChatMessageEvent, relay: Relay?) { + val note = getOrCreateNote(event.id) + val author = getOrCreateUser(event.pubKey) + + if (relay != null) { + author.addRelayBeingUsed(relay, event.createdAt) + note.addRelay(relay) + } + + // Already processed this event. + if (note.event != null) return + + note.loadEvent(event, author, emptyList()) + + refreshObservers(note) + } + private fun consume(event: SealedGossipEvent, relay: Relay?) { val note = getOrCreateNote(event.id) val author = getOrCreateUser(event.pubKey) @@ -1359,6 +1376,7 @@ object LocalCache { is ChannelMessageEvent -> consume(event, relay) is ChannelMetadataEvent -> consume(event) is ChannelMuteUserEvent -> consume(event) + is ChatMessageEvent -> consume(event, relay) is ClassifiedsEvent -> consume(event) is CommunityDefinitionEvent -> consume(event, relay) is CommunityPostApprovalEvent -> { diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/model/EventFactory.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/model/EventFactory.kt index 42fa69c69..fcb5301c6 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/model/EventFactory.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/model/EventFactory.kt @@ -1,5 +1,7 @@ package com.vitorpamplona.amethyst.service.model +import com.vitorpamplona.amethyst.model.toHexKey + class EventFactory { companion object { fun create( @@ -24,6 +26,14 @@ class EventFactory { ChannelMessageEvent.kind -> ChannelMessageEvent(id, pubKey, createdAt, tags, content, sig) ChannelMetadataEvent.kind -> ChannelMetadataEvent(id, pubKey, createdAt, tags, content, sig) ChannelMuteUserEvent.kind -> ChannelMuteUserEvent(id, pubKey, createdAt, tags, content, sig) + ChatMessageEvent.kind -> { + if (id.isBlank()) { + val id = Event.generateId(pubKey, createdAt, kind, tags, content).toHexKey() + ChatMessageEvent(id, pubKey, createdAt, tags, content, sig) + } else { + ChatMessageEvent(id, pubKey, createdAt, tags, content, sig) + } + } ClassifiedsEvent.kind -> ClassifiedsEvent(id, pubKey, createdAt, tags, content, sig) CommunityDefinitionEvent.kind -> CommunityDefinitionEvent(id, pubKey, createdAt, tags, content, sig) CommunityPostApprovalEvent.kind -> CommunityPostApprovalEvent(id, pubKey, createdAt, tags, content, sig) diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/model/GiftWrapEvent.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/model/GiftWrapEvent.kt index 1365dd3c2..e33cec26a 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/model/GiftWrapEvent.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/model/GiftWrapEvent.kt @@ -19,13 +19,14 @@ class GiftWrapEvent( content: String, sig: HexKey ) : Event(id, pubKey, createdAt, kind, tags, content, sig) { - private var innerEvent: Event? = null + private var cachedInnerEvent: Map = mapOf() - fun cachedInnerEvent(privKey: ByteArray): Event? { - if (innerEvent != null) return innerEvent + fun cachedGossip(privKey: ByteArray): Event? { + val hex = privKey.toHexKey() + if (cachedInnerEvent.contains(hex)) return cachedInnerEvent[hex] val myInnerEvent = unwrap(privKey = privKey) - innerEvent = myInnerEvent + cachedInnerEvent = cachedInnerEvent + Pair(hex, myInnerEvent) return myInnerEvent } diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/model/SealedGossipEvent.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/model/SealedGossipEvent.kt index 4e12cfdd5..311b95065 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/model/SealedGossipEvent.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/model/SealedGossipEvent.kt @@ -8,6 +8,7 @@ import com.vitorpamplona.amethyst.model.hexToByteArray import com.vitorpamplona.amethyst.model.toHexKey import com.vitorpamplona.amethyst.service.CryptoUtils import com.vitorpamplona.amethyst.service.EncryptedInfo +import com.vitorpamplona.amethyst.service.relays.Client @Immutable class SealedGossipEvent( @@ -18,14 +19,16 @@ class SealedGossipEvent( content: String, sig: HexKey ) : Event(id, pubKey, createdAt, kind, tags, content, sig) { - private var innerEvent: Gossip? = null + private var cachedInnerEvent: Map = mapOf() - fun cachedGossip(privKey: ByteArray): Gossip? { - if (innerEvent != null) return innerEvent + fun cachedGossip(privKey: ByteArray): Event? { + val hex = privKey.toHexKey() + if (cachedInnerEvent.contains(hex)) return cachedInnerEvent[hex] - val myInnerEvent = unseal(privKey = privKey) - innerEvent = myInnerEvent - return myInnerEvent + val gossip = unseal(privKey = privKey) + val event = gossip?.mergeWith(this) + cachedInnerEvent = cachedInnerEvent + Pair(hex, event) + return event } fun unseal(privKey: ByteArray): Gossip? = try { @@ -88,14 +91,26 @@ class SealedGossipEvent( } } -open class Gossip( - val id: HexKey, - val pubKey: HexKey, - val createdAt: Long, - val kind: Int, - val tags: List>, - val content: String +class Gossip( + val id: HexKey?, + val pubKey: HexKey?, + val createdAt: Long?, + val kind: Int?, + val tags: List>?, + val content: String? ) { + fun mergeWith(event: SealedGossipEvent): Event { + val newPubKey = pubKey?.ifBlank { null } ?: event.pubKey + val newCreatedAt = if (createdAt != null && createdAt > 1000) createdAt else event.createdAt + val newKind = kind ?: 0 + val newTags = (tags ?: emptyList()).plus(event.tags) + val newContent = content ?: "" + val newID = id?.ifBlank { null } ?: Event.generateId(newPubKey, newCreatedAt, newKind, newTags, newContent).toHexKey() + val sig = "" + + return EventFactory.create(newID, newPubKey, newCreatedAt, newKind, newTags, newContent, sig, Client.lenient) + } + companion object { fun create(event: Event): Gossip { return Gossip(event.id, event.pubKey, event.createdAt, event.kind, event.tags, event.content)