From 571fb6af4b4cff49e996f24580e8032bd5395c52 Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Sat, 7 Feb 2026 18:20:50 -0500 Subject: [PATCH] Moves the new observables to commons --- .../amethyst/model/LocalCache.kt | 20 ++++------- .../ui/screen/loggedIn/AccountViewModel.kt | 2 +- .../NIP90ContentDiscoveryResponseFilter.kt | 2 +- .../model/observables/CreatedAtComparator.kt | 6 ++-- .../observables/EventListMatchingFilter.kt | 12 +++---- .../observables/NoteListMatchingFilter.kt | 12 +++---- .../commons/model/observables/Observable.kt | 33 +++++++++++++++++++ 7 files changed, 56 insertions(+), 31 deletions(-) rename {amethyst/src/main/java/com/vitorpamplona/amethyst => commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons}/model/observables/CreatedAtComparator.kt (94%) rename {amethyst/src/main/java/com/vitorpamplona/amethyst => commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons}/model/observables/EventListMatchingFilter.kt (88%) rename {amethyst/src/main/java/com/vitorpamplona/amethyst => commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons}/model/observables/NoteListMatchingFilter.kt (88%) create mode 100644 commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/model/observables/Observable.kt 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 baa34540e..a74194ded 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/LocalCache.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/LocalCache.kt @@ -28,13 +28,14 @@ import com.vitorpamplona.amethyst.commons.model.cache.ICacheProvider import com.vitorpamplona.amethyst.commons.model.emphChat.EphemeralChatChannel import com.vitorpamplona.amethyst.commons.model.nip28PublicChats.PublicChatChannel import com.vitorpamplona.amethyst.commons.model.nip53LiveActivities.LiveActivitiesChannel +import com.vitorpamplona.amethyst.commons.model.observables.CreatedAtIdHexComparator +import com.vitorpamplona.amethyst.commons.model.observables.EventListMatchingFilter +import com.vitorpamplona.amethyst.commons.model.observables.NoteListMatchingFilter +import com.vitorpamplona.amethyst.commons.model.observables.Observable import com.vitorpamplona.amethyst.commons.model.privateChats.ChatroomList import com.vitorpamplona.amethyst.commons.services.nwc.NwcPaymentTracker import com.vitorpamplona.amethyst.isDebug import com.vitorpamplona.amethyst.model.nip51Lists.HiddenUsersState -import com.vitorpamplona.amethyst.model.observables.CreatedAtIdHexComparator -import com.vitorpamplona.amethyst.model.observables.EventListMatchingFilter -import com.vitorpamplona.amethyst.model.observables.NoteListMatchingFilter import com.vitorpamplona.amethyst.service.BundledInsert import com.vitorpamplona.amethyst.service.checkNotInMainThread import com.vitorpamplona.amethyst.ui.note.dateFormatter @@ -221,15 +222,6 @@ interface ILocalCache { ) {} } -interface Observable { - fun new( - event: Event, - note: Note, - ) - - fun remove(note: Note) -} - object LocalCache : ILocalCache, ICacheProvider { val antiSpam = AntiSpamFilter() @@ -313,7 +305,7 @@ object LocalCache : ILocalCache, ICacheProvider { fun observeNotes(filter: Filter): Flow> = callbackFlow { val newFilter = - NoteListMatchingFilter(filter, this@LocalCache) { + NoteListMatchingFilter(filter, this@LocalCache::filter) { trySend(it) } @@ -329,7 +321,7 @@ object LocalCache : ILocalCache, ICacheProvider { fun observeEvents(filter: Filter): Flow> = callbackFlow { val cachedFilter = - EventListMatchingFilter(filter, this@LocalCache) { + EventListMatchingFilter(filter, this@LocalCache::filter) { trySend(it) } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/AccountViewModel.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/AccountViewModel.kt index 4b901a8c6..02c847fe4 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/AccountViewModel.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/AccountViewModel.kt @@ -43,6 +43,7 @@ import com.vitorpamplona.amethyst.commons.model.LiveHiddenUsers import com.vitorpamplona.amethyst.commons.model.emphChat.EphemeralChatChannel import com.vitorpamplona.amethyst.commons.model.nip28PublicChats.PublicChatChannel import com.vitorpamplona.amethyst.commons.model.nip53LiveActivities.LiveActivitiesChannel +import com.vitorpamplona.amethyst.commons.model.observables.CreatedAtComparator import com.vitorpamplona.amethyst.commons.ui.feeds.FeedState import com.vitorpamplona.amethyst.commons.ui.notifications.CardFeedState import com.vitorpamplona.amethyst.logTime @@ -54,7 +55,6 @@ import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.model.UiSettingsFlow import com.vitorpamplona.amethyst.model.UrlCachedPreviewer import com.vitorpamplona.amethyst.model.User -import com.vitorpamplona.amethyst.model.observables.CreatedAtComparator import com.vitorpamplona.amethyst.model.privacyOptions.EmptyRoleBasedHttpClientBuilder import com.vitorpamplona.amethyst.model.privacyOptions.IRoleBasedHttpClientBuilder import com.vitorpamplona.amethyst.model.privacyOptions.RoleBasedHttpClientBuilder diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/dvms/dal/NIP90ContentDiscoveryResponseFilter.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/dvms/dal/NIP90ContentDiscoveryResponseFilter.kt index 5e1102248..ccccb1ddc 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/dvms/dal/NIP90ContentDiscoveryResponseFilter.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/dvms/dal/NIP90ContentDiscoveryResponseFilter.kt @@ -20,10 +20,10 @@ */ package com.vitorpamplona.amethyst.ui.screen.loggedIn.dvms.dal +import com.vitorpamplona.amethyst.commons.model.observables.CreatedAtComparator import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.model.Note -import com.vitorpamplona.amethyst.model.observables.CreatedAtComparator import com.vitorpamplona.amethyst.ui.dal.AdditiveFeedFilter import com.vitorpamplona.amethyst.ui.dal.FilterByListParams import com.vitorpamplona.quartz.nip01Core.tags.events.isTaggedEvent diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/observables/CreatedAtComparator.kt b/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/model/observables/CreatedAtComparator.kt similarity index 94% rename from amethyst/src/main/java/com/vitorpamplona/amethyst/model/observables/CreatedAtComparator.kt rename to commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/model/observables/CreatedAtComparator.kt index f6350acf9..f3c3766a8 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/observables/CreatedAtComparator.kt +++ b/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/model/observables/CreatedAtComparator.kt @@ -18,10 +18,10 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.amethyst.model.observables +package com.vitorpamplona.amethyst.commons.model.observables -import com.vitorpamplona.amethyst.model.AddressableNote -import com.vitorpamplona.amethyst.model.Note +import com.vitorpamplona.amethyst.commons.model.AddressableNote +import com.vitorpamplona.amethyst.commons.model.Note val CreatedAtIdHexComparator: Comparator = Comparator { note1, note2 -> diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/observables/EventListMatchingFilter.kt b/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/model/observables/EventListMatchingFilter.kt similarity index 88% rename from amethyst/src/main/java/com/vitorpamplona/amethyst/model/observables/EventListMatchingFilter.kt rename to commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/model/observables/EventListMatchingFilter.kt index db13754c4..1d99412f1 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/observables/EventListMatchingFilter.kt +++ b/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/model/observables/EventListMatchingFilter.kt @@ -18,14 +18,14 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.amethyst.model.observables +package com.vitorpamplona.amethyst.commons.model.observables -import com.vitorpamplona.amethyst.model.LocalCache -import com.vitorpamplona.amethyst.model.Note -import com.vitorpamplona.amethyst.model.Observable +import com.vitorpamplona.amethyst.commons.model.Note import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter +import java.util.SortedSet import java.util.concurrent.ConcurrentSkipListSet +import kotlin.collections.mapNotNull /** * Creates a list of events (regular and addressable) @@ -34,7 +34,7 @@ import java.util.concurrent.ConcurrentSkipListSet */ class EventListMatchingFilter( private val filter: Filter, - private val cache: LocalCache, + private val atOnce: (filter: Filter) -> SortedSet, private val update: (List) -> Unit, ) : Observable { // Keeping this here blocks it from being cleared from memory @@ -62,7 +62,7 @@ class EventListMatchingFilter( } fun init() { - currentResults = ConcurrentSkipListSet(cache.filter(filter)) + currentResults = ConcurrentSkipListSet(atOnce(filter)) update(currentResults.mapNotNull { it.event }) } } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/observables/NoteListMatchingFilter.kt b/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/model/observables/NoteListMatchingFilter.kt similarity index 88% rename from amethyst/src/main/java/com/vitorpamplona/amethyst/model/observables/NoteListMatchingFilter.kt rename to commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/model/observables/NoteListMatchingFilter.kt index 7c3ca5922..2c62e3d31 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/observables/NoteListMatchingFilter.kt +++ b/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/model/observables/NoteListMatchingFilter.kt @@ -18,14 +18,14 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.amethyst.model.observables +package com.vitorpamplona.amethyst.commons.model.observables -import com.vitorpamplona.amethyst.model.LocalCache -import com.vitorpamplona.amethyst.model.Note -import com.vitorpamplona.amethyst.model.Observable +import com.vitorpamplona.amethyst.commons.model.Note import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter +import java.util.SortedSet import java.util.concurrent.ConcurrentSkipListSet +import kotlin.collections.toList /** * Creates a list of notes (regular and addressable) @@ -35,7 +35,7 @@ import java.util.concurrent.ConcurrentSkipListSet */ class NoteListMatchingFilter( private val filter: Filter, - private val cache: LocalCache, + private val atOnce: (filter: Filter) -> SortedSet, private val update: (List) -> Unit, ) : Observable { var currentResults: ConcurrentSkipListSet = ConcurrentSkipListSet(CreatedAtIdHexComparator) @@ -63,7 +63,7 @@ class NoteListMatchingFilter( } fun init() { - currentResults = ConcurrentSkipListSet(cache.filter(filter)) + currentResults = ConcurrentSkipListSet(atOnce(filter)) update(currentResults.toList()) } } diff --git a/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/model/observables/Observable.kt b/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/model/observables/Observable.kt new file mode 100644 index 000000000..792511525 --- /dev/null +++ b/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/model/observables/Observable.kt @@ -0,0 +1,33 @@ +/** + * Copyright (c) 2025 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.amethyst.commons.model.observables + +import com.vitorpamplona.amethyst.commons.model.Note +import com.vitorpamplona.quartz.nip01Core.core.Event + +interface Observable { + fun new( + event: Event, + note: Note, + ) + + fun remove(note: Note) +}