Preparing to keep ChatMessages in the LocalCache.

This commit is contained in:
Vitor Pamplona
2023-07-30 13:06:33 -04:00
parent 4426ccada7
commit ffe1d737fb
4 changed files with 61 additions and 17 deletions
@@ -1110,6 +1110,23 @@ object LocalCache {
refreshObservers(note) 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?) { private fun consume(event: SealedGossipEvent, relay: Relay?) {
val note = getOrCreateNote(event.id) val note = getOrCreateNote(event.id)
val author = getOrCreateUser(event.pubKey) val author = getOrCreateUser(event.pubKey)
@@ -1359,6 +1376,7 @@ object LocalCache {
is ChannelMessageEvent -> consume(event, relay) is ChannelMessageEvent -> consume(event, relay)
is ChannelMetadataEvent -> consume(event) is ChannelMetadataEvent -> consume(event)
is ChannelMuteUserEvent -> consume(event) is ChannelMuteUserEvent -> consume(event)
is ChatMessageEvent -> consume(event, relay)
is ClassifiedsEvent -> consume(event) is ClassifiedsEvent -> consume(event)
is CommunityDefinitionEvent -> consume(event, relay) is CommunityDefinitionEvent -> consume(event, relay)
is CommunityPostApprovalEvent -> { is CommunityPostApprovalEvent -> {
@@ -1,5 +1,7 @@
package com.vitorpamplona.amethyst.service.model package com.vitorpamplona.amethyst.service.model
import com.vitorpamplona.amethyst.model.toHexKey
class EventFactory { class EventFactory {
companion object { companion object {
fun create( fun create(
@@ -24,6 +26,14 @@ class EventFactory {
ChannelMessageEvent.kind -> ChannelMessageEvent(id, pubKey, createdAt, tags, content, sig) ChannelMessageEvent.kind -> ChannelMessageEvent(id, pubKey, createdAt, tags, content, sig)
ChannelMetadataEvent.kind -> ChannelMetadataEvent(id, pubKey, createdAt, tags, content, sig) ChannelMetadataEvent.kind -> ChannelMetadataEvent(id, pubKey, createdAt, tags, content, sig)
ChannelMuteUserEvent.kind -> ChannelMuteUserEvent(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) ClassifiedsEvent.kind -> ClassifiedsEvent(id, pubKey, createdAt, tags, content, sig)
CommunityDefinitionEvent.kind -> CommunityDefinitionEvent(id, pubKey, createdAt, tags, content, sig) CommunityDefinitionEvent.kind -> CommunityDefinitionEvent(id, pubKey, createdAt, tags, content, sig)
CommunityPostApprovalEvent.kind -> CommunityPostApprovalEvent(id, pubKey, createdAt, tags, content, sig) CommunityPostApprovalEvent.kind -> CommunityPostApprovalEvent(id, pubKey, createdAt, tags, content, sig)
@@ -19,13 +19,14 @@ class GiftWrapEvent(
content: String, content: String,
sig: HexKey sig: HexKey
) : Event(id, pubKey, createdAt, kind, tags, content, sig) { ) : Event(id, pubKey, createdAt, kind, tags, content, sig) {
private var innerEvent: Event? = null private var cachedInnerEvent: Map<HexKey, Event?> = mapOf()
fun cachedInnerEvent(privKey: ByteArray): Event? { fun cachedGossip(privKey: ByteArray): Event? {
if (innerEvent != null) return innerEvent val hex = privKey.toHexKey()
if (cachedInnerEvent.contains(hex)) return cachedInnerEvent[hex]
val myInnerEvent = unwrap(privKey = privKey) val myInnerEvent = unwrap(privKey = privKey)
innerEvent = myInnerEvent cachedInnerEvent = cachedInnerEvent + Pair(hex, myInnerEvent)
return myInnerEvent return myInnerEvent
} }
@@ -8,6 +8,7 @@ import com.vitorpamplona.amethyst.model.hexToByteArray
import com.vitorpamplona.amethyst.model.toHexKey import com.vitorpamplona.amethyst.model.toHexKey
import com.vitorpamplona.amethyst.service.CryptoUtils import com.vitorpamplona.amethyst.service.CryptoUtils
import com.vitorpamplona.amethyst.service.EncryptedInfo import com.vitorpamplona.amethyst.service.EncryptedInfo
import com.vitorpamplona.amethyst.service.relays.Client
@Immutable @Immutable
class SealedGossipEvent( class SealedGossipEvent(
@@ -18,14 +19,16 @@ class SealedGossipEvent(
content: String, content: String,
sig: HexKey sig: HexKey
) : Event(id, pubKey, createdAt, kind, tags, content, sig) { ) : Event(id, pubKey, createdAt, kind, tags, content, sig) {
private var innerEvent: Gossip? = null private var cachedInnerEvent: Map<HexKey, Event?> = mapOf()
fun cachedGossip(privKey: ByteArray): Gossip? { fun cachedGossip(privKey: ByteArray): Event? {
if (innerEvent != null) return innerEvent val hex = privKey.toHexKey()
if (cachedInnerEvent.contains(hex)) return cachedInnerEvent[hex]
val myInnerEvent = unseal(privKey = privKey) val gossip = unseal(privKey = privKey)
innerEvent = myInnerEvent val event = gossip?.mergeWith(this)
return myInnerEvent cachedInnerEvent = cachedInnerEvent + Pair(hex, event)
return event
} }
fun unseal(privKey: ByteArray): Gossip? = try { fun unseal(privKey: ByteArray): Gossip? = try {
@@ -88,14 +91,26 @@ class SealedGossipEvent(
} }
} }
open class Gossip( class Gossip(
val id: HexKey, val id: HexKey?,
val pubKey: HexKey, val pubKey: HexKey?,
val createdAt: Long, val createdAt: Long?,
val kind: Int, val kind: Int?,
val tags: List<List<String>>, val tags: List<List<String>>?,
val content: String 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 { companion object {
fun create(event: Event): Gossip { fun create(event: Event): Gossip {
return Gossip(event.id, event.pubKey, event.createdAt, event.kind, event.tags, event.content) return Gossip(event.id, event.pubKey, event.createdAt, event.kind, event.tags, event.content)