diff --git a/README.md b/README.md index ba010569c..c4b82fcdd 100644 --- a/README.md +++ b/README.md @@ -82,13 +82,14 @@ height="80">](https://github.com/vitorpamplona/amethyst/releases) - [x] Private Messages and Small Groups (NIP-24) - [x] Gift Wraps & Seals (NIP-59) - [x] Versioned Encrypted Payloads (NIP-44) +- [x] Expiration Support (NIP-40) +- [x] Status Event (NIP-315) - [ ] Marketplace (NIP-15) - [ ] Image/Video Capture in the app - [ ] Local Database - [ ] Bookmarks, Pinned Posts, Muted Events (NIP-51) - [ ] Proof of Work in the Phone (NIP-13, NIP-20) - [ ] Workspaces -- [ ] Expiration Support (NIP-40) - [ ] Infinity Scroll - [ ] Relay List Metadata (NIP-65) - [ ] Signing Requests (NIP-46) diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ServiceManager.kt b/app/src/main/java/com/vitorpamplona/amethyst/ServiceManager.kt index 48b7fc4f4..a33cc2594 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ServiceManager.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ServiceManager.kt @@ -126,6 +126,7 @@ object ServiceManager { LocalCache.pruneContactLists(accounts) LocalCache.pruneRepliesAndReactions(accounts) LocalCache.prunePastVersionsOfReplaceables() + LocalCache.pruneExpiredEvents() } } } 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 88982e8cb..93cb83d99 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/model/LocalCache.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/model/LocalCache.kt @@ -14,6 +14,7 @@ import com.vitorpamplona.quartz.encoders.Nip19 import com.vitorpamplona.quartz.encoders.decodePublicKeyAsHexOrNull import com.vitorpamplona.quartz.encoders.toHexKey import com.vitorpamplona.quartz.events.* +import com.vitorpamplona.quartz.utils.TimeUtils import kotlinx.collections.immutable.persistentSetOf import kotlinx.collections.immutable.toImmutableSet import kotlinx.coroutines.* @@ -1269,6 +1270,39 @@ object LocalCache { } } + fun pruneExpiredEvents() { + checkNotInMainThread() + + val now = TimeUtils.now() + + val toBeRemoved = notes.filter { + (it.value.event?.expiration() ?: Long.MAX_VALUE) < now + }.values + + val childrenToBeRemoved = mutableListOf() + + toBeRemoved.forEach { + notes.remove(it.idHex) + + it.replyTo?.forEach { masterNote -> + masterNote.removeReply(it) + masterNote.removeBoost(it) + masterNote.removeReaction(it) + masterNote.removeZap(it) + masterNote.removeReport(it) + masterNote.clearEOSE() // allows reloading of these events + } + + childrenToBeRemoved.addAll(it.removeAllChildNotes()) + } + + removeChildrenOf(childrenToBeRemoved) + + if (toBeRemoved.size > 1) { + println("PRUNE: ${toBeRemoved.size} thread replies removed.") + } + } + fun pruneHiddenMessages(account: Account) { checkNotInMainThread()