From 9990f458bf54767031486ce625237b8d763e7781 Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Sat, 23 Mar 2024 17:21:02 -0400 Subject: [PATCH] Moves Channel to LargeCache Fixes filter for Chat Messages in discovery --- .../amethyst/model/LocalCache.kt | 54 +++++++++---------- .../amethyst/ui/dal/DiscoverChatFeedFilter.kt | 37 ++++++++++--- .../amethyst/ui/dal/DiscoverLiveFeedFilter.kt | 4 +- 3 files changed, 57 insertions(+), 38 deletions(-) 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 eb4f270c3..874593c96 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/model/LocalCache.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/model/LocalCache.kt @@ -129,7 +129,7 @@ object LocalCache { val notes = LargeCache() val addressables = LargeCache() - val channels = ConcurrentHashMap() + val channels = LargeCache() val awaitingPaymentRequests = ConcurrentHashMap Unit>>(10) fun checkGetOrCreateUser(key: String): User? { @@ -164,7 +164,7 @@ object LocalCache { } fun getChannelIfExists(key: String): Channel? { - return channels[key] + return channels.get(key) } fun checkGetOrCreateNote(key: String): Note? { @@ -217,15 +217,24 @@ object LocalCache { } } + fun getOrCreateChannel( + key: String, + channelFactory: (String) -> Channel, + ): Channel { + checkNotInMainThread() + + return channels.getOrCreate(key, channelFactory) + } + fun checkGetOrCreateChannel(key: String): Channel? { checkNotInMainThread() if (isValidHex(key)) { - return getOrCreateChannel(key) { PublicChatChannel(key) } + return channels.getOrCreate(key) { PublicChatChannel(key) } } val aTag = ATag.parse(key, null) if (aTag != null) { - return getOrCreateChannel(aTag.toTag()) { LiveActivitiesChannel(aTag) } + return channels.getOrCreate(aTag.toTag()) { LiveActivitiesChannel(aTag) } } return null } @@ -237,19 +246,6 @@ object LocalCache { return HexValidator.isHex(key) } - fun getOrCreateChannel( - key: String, - channelFactory: (String) -> Channel, - ): Channel { - checkNotInMainThread() - - return channels[key] - ?: run { - val newObject = channelFactory(key) - channels.putIfAbsent(key, newObject) ?: newObject - } - } - fun checkGetOrCreateAddressableNote(key: String): AddressableNote? { return try { val addr = ATag.parse(key, null) // relay doesn't matter for the index. @@ -941,10 +937,10 @@ object LocalCache { masterNote.removeReport(deleteNote) } - deleteNote.channelHex()?.let { channels[it]?.removeNote(deleteNote) } + deleteNote.channelHex()?.let { getChannelIfExists(it)?.removeNote(deleteNote) } (deleteNote.event as? LiveActivitiesChatMessageEvent)?.activity()?.let { - channels[it.toTag()]?.removeNote(deleteNote) + getChannelIfExists(it.toTag())?.removeNote(deleteNote) } if (deleteNote.event is PrivateDmEvent) { @@ -1681,14 +1677,14 @@ object LocalCache { checkNotInMainThread() val key = decodeEventIdAsHexOrNull(text) - if (key != null && channels[key] != null) { - return listOfNotNull(channels[key]) + if (key != null && getChannelIfExists(key) != null) { + return listOfNotNull(getChannelIfExists(key)) } - return channels.values.filter { - it.anyNameStartsWith(text) || - it.idHex.startsWith(text, true) || - it.idNote().startsWith(text, true) + return channels.filter { _, channel -> + channel.anyNameStartsWith(text) || + channel.idHex.startsWith(text, true) || + channel.idNote().startsWith(text, true) } } @@ -1767,8 +1763,8 @@ object LocalCache { fun pruneOldAndHiddenMessages(account: Account) { checkNotInMainThread() - channels.forEach { it -> - val toBeRemoved = it.value.pruneOldAndHiddenMessages(account) + channels.forEach { _, channel -> + val toBeRemoved = channel.pruneOldAndHiddenMessages(account) val childrenToBeRemoved = mutableListOf() @@ -1780,9 +1776,9 @@ object LocalCache { removeFromCache(childrenToBeRemoved) - if (toBeRemoved.size > 100 || it.value.notes.size() > 100) { + if (toBeRemoved.size > 100 || channel.notes.size() > 100) { println( - "PRUNE: ${toBeRemoved.size} messages removed from ${it.value.toBestDisplayName()}. ${it.value.notes.size()} kept", + "PRUNE: ${toBeRemoved.size} messages removed from ${channel.toBestDisplayName()}. ${channel.notes.size()} kept", ) } } diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/DiscoverChatFeedFilter.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/DiscoverChatFeedFilter.kt index 82eee98a3..0eabe3422 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/DiscoverChatFeedFilter.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/DiscoverChatFeedFilter.kt @@ -23,7 +23,7 @@ package com.vitorpamplona.amethyst.ui.dal import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.model.Note -import com.vitorpamplona.amethyst.model.ParticipantListBuilder +import com.vitorpamplona.amethyst.model.PublicChatChannel import com.vitorpamplona.quartz.events.ChannelCreateEvent import com.vitorpamplona.quartz.events.IsInPublicChatChannel import com.vitorpamplona.quartz.events.MuteListEvent @@ -42,12 +42,25 @@ open class DiscoverChatFeedFilter(val account: Account) : AdditiveFeedFilter { + val params = buildFilterParams(account) + val allChannelNotes = - LocalCache.channels.values.mapNotNull { LocalCache.getNoteIfExists(it.idHex) } + LocalCache.channels.mapNotNullIntoSet { _, channel -> + if (channel is PublicChatChannel) { + val note = LocalCache.getNoteIfExists(channel.idHex) + val noteEvent = note?.event - val notes = innerApplyFilter(allChannelNotes) + if (noteEvent == null || params.match(noteEvent)) { + note + } else { + null + } + } else { + null + } + } - return sort(notes) + return sort(allChannelNotes) } override fun applyFilter(collection: Set): Set { @@ -70,11 +83,21 @@ open class DiscoverChatFeedFilter(val account: Account) : AdditiveFeedFilter 0) { + note + } else { + null + } } else if (noteEvent is IsInPublicChatChannel) { val channel = noteEvent.channel()?.let { LocalCache.checkGetOrCreateNote(it) } - if (channel != null && (channel.event == null || params.match(channel.event))) { - channel + if (channel != null && + (channel.event == null || (channel.event is ChannelCreateEvent && params.match(channel.event))) + ) { + if ((LocalCache.getChannelIfExists(channel.idHex)?.notes?.size() ?: 0) > 0) { + channel + } else { + null + } } else { null } diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/DiscoverLiveFeedFilter.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/DiscoverLiveFeedFilter.kt index 30aa19176..ebce2500a 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/DiscoverLiveFeedFilter.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/dal/DiscoverLiveFeedFilter.kt @@ -48,8 +48,8 @@ open class DiscoverLiveFeedFilter( } override fun feed(): List { - val allChannelNotes = LocalCache.channels.values.mapNotNull { LocalCache.getNoteIfExists(it.idHex) } - val allMessageNotes = LocalCache.channels.values.map { it.notes.filter { key, it -> it.event is LiveActivitiesEvent } }.flatten() + val allChannelNotes = LocalCache.channels.mapNotNull { _, channel -> LocalCache.getNoteIfExists(channel.idHex) } + val allMessageNotes = LocalCache.channels.map { _, channel -> channel.notes.filter { key, it -> it.event is LiveActivitiesEvent } }.flatten() val notes = innerApplyFilter(allChannelNotes + allMessageNotes)