diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/LocalCache.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/LocalCache.kt index c74002477..dee64c791 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/LocalCache.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/LocalCache.kt @@ -1217,6 +1217,19 @@ object LocalCache { .deleteEvents() .mapNotNull { getNoteIfExists(it) } .forEach { deleteNote -> + val deleteNoteEvent = deleteNote.event + if (deleteNoteEvent is AddressableEvent) { + val addressableNote = getAddressableNoteIfExists(deleteNoteEvent.addressTag()) + if (addressableNote?.author?.pubkeyHex == event.pubKey && (addressableNote.createdAt() ?: 0) <= event.createdAt) { + // Counts the replies + deleteNote(addressableNote) + + addressables.remove(addressableNote.idHex) + + deletedAtLeastOne = true + } + } + // must be the same author if (deleteNote.author?.pubkeyHex == event.pubKey) { // reverts the add @@ -2505,7 +2518,28 @@ object LocalCache { event: Event, relay: Relay?, ) { - if (deletionIndex.hasBeenDeleted(event)) return + if (deletionIndex.hasBeenDeleted(event)) { + // update relay with deletion event from another. + if (relay != null) { + deletionIndex.hasBeenDeletedBy(event)?.let { + Log.d("LocalCache", "Updating ${relay.url} with a Deletion Event ${it.toJson()} because of ${event.toJson()}") + relay.send(it) + } + } + return + } + + if (event is AddressableEvent && relay != null) { + // updates relay with a new event. + getAddressableNoteIfExists(event.addressTag())?.let { + it.event?.let { existingEvent -> + if (existingEvent.createdAt() > event.createdAt) { + Log.d("LocalCache", "Updating ${relay.url} with a new version of ${event.toJson()} to ${existingEvent.toJson()}") + relay.send(existingEvent) + } + } + } + } checkNotInMainThread() diff --git a/commons/src/main/java/com/vitorpamplona/amethyst/commons/data/DeletionIndex.kt b/commons/src/main/java/com/vitorpamplona/amethyst/commons/data/DeletionIndex.kt index 01f777da8..e475cad4e 100644 --- a/commons/src/main/java/com/vitorpamplona/amethyst/commons/data/DeletionIndex.kt +++ b/commons/src/main/java/com/vitorpamplona/amethyst/commons/data/DeletionIndex.kt @@ -43,14 +43,14 @@ class DeletionIndex { // stores a set of id OR atags (kind:pubkey:dtag) by pubkey with the created at of the deletion event. // Anything newer than the date should not be deleted. - private val deletedReferencesBefore = LargeCache() + private val deletedReferencesBefore = LargeCache() fun add(event: DeletionEvent): Boolean { var atLeastOne = false event.tags.forEach { if (it.size > 1 && (it[0] == "a" || it[0] == "e")) { - if (add(it[1], event.pubKey, event.createdAt)) { + if (add(it[1], event.pubKey, event)) { atLeastOne = true } } @@ -62,18 +62,34 @@ class DeletionIndex { private fun add( ref: String, byPubKey: HexKey, - createdAt: Long, + deletionEvent: DeletionEvent, ): Boolean { val key = DeletionRequest(ref, byPubKey) - val previousDeletionTime = deletedReferencesBefore.get(key) + val previousDeletionEvent = deletedReferencesBefore.get(key) - if (previousDeletionTime == null || createdAt > previousDeletionTime) { - deletedReferencesBefore.put(key, createdAt) + if (previousDeletionEvent == null || deletionEvent.createdAt > previousDeletionEvent.createdAt) { + deletedReferencesBefore.put(key, deletionEvent) return true } return false } + fun hasBeenDeletedBy(event: Event): DeletionEvent? { + deletedReferencesBefore.get(DeletionRequest(event.id, event.pubKey))?.let { + return it + } + + if (event is AddressableEvent) { + deletedReferencesBefore.get(DeletionRequest(event.addressTag(), event.pubKey))?.let { + if (event.createdAt <= it.createdAt) { + return it + } + } + } + + return null + } + fun hasBeenDeleted(event: Event): Boolean { val key = DeletionRequest(event.id, event.pubKey) if (hasBeenDeleted(key)) return true @@ -91,7 +107,7 @@ class DeletionIndex { key: DeletionRequest, createdAt: Long, ): Boolean { - val deletionTime = deletedReferencesBefore.get(key) - return deletionTime != null && createdAt <= deletionTime + val deletionEvent = deletedReferencesBefore.get(key) + return deletionEvent != null && createdAt <= deletionEvent.createdAt } }