diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Account.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Account.kt index 79b71775f..1c8a45196 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Account.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Account.kt @@ -246,9 +246,10 @@ class Account( ) { nip65RelayList, dmRelayList, searchRelayList, privateOutBox, userProfile -> checkNotInMainThread() - val baseRelaySet = activeRelays() ?: convertLocalRelays() + val localRelays = convertLocalRelays() + val baseRelaySet = activeRelays() ?: localRelays val newDMRelaySet = (dmRelayList.note.event as? ChatMessageRelayListEvent)?.relays()?.map { RelayUrlFormatter.normalize(it) }?.toSet() ?: emptySet() - val searchRelaySet = (searchRelayList.note.event as? SearchRelayListEvent)?.relays()?.map { RelayUrlFormatter.normalize(it) }?.toSet() ?: Constants.defaultSearchRelaySet + val searchRelaySet = ((searchRelayList.note.event as? SearchRelayListEvent)?.relays() ?: Constants.defaultSearchRelaySet).map { RelayUrlFormatter.normalize(it) }.toSet() val nip65RelaySet = (nip65RelayList.note.event as? AdvertisedRelayListEvent)?.relays()?.map { AdvertisedRelayListEvent.AdvertisedRelayInfo( @@ -343,7 +344,7 @@ class Account( } // -------------- - // PRIVATE OUTBOX + // Local Storage // -------------- mappedRelaySet = @@ -2972,7 +2973,7 @@ class Account( val localFeedTypes = localRelays.firstOrNull { localRelay -> RelayUrlFormatter.normalize(localRelay.url) == url }?.feedTypes?.minus(setOf(FeedType.SEARCH, FeedType.WALLET_CONNECT)) ?: Constants.defaultRelays - .filter { defaultRelay -> defaultRelay.url == url } + .filter { defaultRelay -> RelayUrlFormatter.normalize(defaultRelay.url) == url } .firstOrNull() ?.feedTypes ?: Constants.activeTypesGlobalChats @@ -2983,7 +2984,16 @@ class Account( return usersRelayList.toTypedArray() } - fun convertLocalRelays(): Array = localRelays.map { RelaySetupInfo(RelayUrlFormatter.normalize(it.url), it.read, it.write, it.feedTypes.minus(setOf(FeedType.SEARCH, FeedType.WALLET_CONNECT))) }.toTypedArray() + fun convertLocalRelays(): Array = + localRelays + .map { + RelaySetupInfo( + RelayUrlFormatter.normalize(it.url), + it.read, + it.write, + it.feedTypes.minus(setOf(FeedType.SEARCH, FeedType.WALLET_CONNECT)), + ) + }.toTypedArray() fun activeGlobalRelays(): Array = connectToRelays.value diff --git a/ammolite/src/main/java/com/vitorpamplona/ammolite/relays/NostrDataSource.kt b/ammolite/src/main/java/com/vitorpamplona/ammolite/relays/NostrDataSource.kt index 4cbd22dc9..b3280e4cf 100644 --- a/ammolite/src/main/java/com/vitorpamplona/ammolite/relays/NostrDataSource.kt +++ b/ammolite/src/main/java/com/vitorpamplona/ammolite/relays/NostrDataSource.kt @@ -83,7 +83,7 @@ abstract class NostrDataSource( eventCounter = eventCounter + Pair(key, Counter(subscriptionId, event.kind, 1)) } - // Log.d(this@NostrDataSource.javaClass.simpleName, "Relay ${relay.url}: ${event.kind}") + // Log.d(this@NostrDataSource.javaClass.simpleName, "Relay ${relay.url}: $subscriptionId ${event.kind} ") consume(event, relay) if (afterEOSE) { diff --git a/ammolite/src/main/java/com/vitorpamplona/ammolite/relays/Relay.kt b/ammolite/src/main/java/com/vitorpamplona/ammolite/relays/Relay.kt index 00e25406c..9db550415 100644 --- a/ammolite/src/main/java/com/vitorpamplona/ammolite/relays/Relay.kt +++ b/ammolite/src/main/java/com/vitorpamplona/ammolite/relays/Relay.kt @@ -389,7 +389,7 @@ class Relay( if (isReady) { val relayFilters = filters.filter { filter -> - activeTypes.any { it in filter.types } + activeTypes.any { it in filter.types } && filter.filter.isValidFor(url) } if (relayFilters.isNotEmpty()) { diff --git a/ammolite/src/main/java/com/vitorpamplona/ammolite/relays/filters/IPerRelayFilter.kt b/ammolite/src/main/java/com/vitorpamplona/ammolite/relays/filters/IPerRelayFilter.kt index 873ce36fe..7599ea51d 100644 --- a/ammolite/src/main/java/com/vitorpamplona/ammolite/relays/filters/IPerRelayFilter.kt +++ b/ammolite/src/main/java/com/vitorpamplona/ammolite/relays/filters/IPerRelayFilter.kt @@ -31,4 +31,7 @@ interface IPerRelayFilter { ): Boolean fun toDebugJson(): String + + // This only exists because some relays confuse empty lists with null lists + fun isValidFor(url: String): Boolean } diff --git a/ammolite/src/main/java/com/vitorpamplona/ammolite/relays/filters/SinceAuthorPerRelayFilter.kt b/ammolite/src/main/java/com/vitorpamplona/ammolite/relays/filters/SinceAuthorPerRelayFilter.kt index 884401519..ad31a341b 100644 --- a/ammolite/src/main/java/com/vitorpamplona/ammolite/relays/filters/SinceAuthorPerRelayFilter.kt +++ b/ammolite/src/main/java/com/vitorpamplona/ammolite/relays/filters/SinceAuthorPerRelayFilter.kt @@ -36,7 +36,22 @@ class SinceAuthorPerRelayFilter( val limit: Int? = null, val search: String? = null, ) : IPerRelayFilter { - override fun toJson(forRelay: String) = FilterSerializer.toJson(ids, authors?.get(forRelay), kinds, tags, since?.get(forRelay)?.time, until, limit, search) + // This only exists because some relays consider empty arrays as null and return everything. + // So, if there is an author list, but no list for the specific relay or if the list is empty + // don't send it. + override fun isValidFor(forRelay: String) = authors == null || !authors[forRelay].isNullOrEmpty() + + override fun toJson(forRelay: String): String { + // if authors is empty, but not null + val authorsForThisRelay = + if (authors != null) { + authors[forRelay]?.ifEmpty { null } + } else { + null + } + + return FilterSerializer.toJson(ids, authors?.get(forRelay), kinds, tags, since?.get(forRelay)?.time, until, limit, search) + } override fun match( event: Event, diff --git a/ammolite/src/main/java/com/vitorpamplona/ammolite/relays/filters/SincePerRelayFilter.kt b/ammolite/src/main/java/com/vitorpamplona/ammolite/relays/filters/SincePerRelayFilter.kt index 3bb9187a4..8d5a5c5c9 100644 --- a/ammolite/src/main/java/com/vitorpamplona/ammolite/relays/filters/SincePerRelayFilter.kt +++ b/ammolite/src/main/java/com/vitorpamplona/ammolite/relays/filters/SincePerRelayFilter.kt @@ -35,6 +35,8 @@ class SincePerRelayFilter( val limit: Int? = null, val search: String? = null, ) : IPerRelayFilter { + override fun isValidFor(url: String) = true + override fun toJson(forRelay: String) = FilterSerializer.toJson(ids, authors, kinds, tags, since?.get(forRelay)?.time, until, limit, search) override fun match(