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 7e11368440..f040580b9e 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/model/LocalCache.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/model/LocalCache.kt @@ -65,11 +65,11 @@ object LocalCache { fun consume(event: MetadataEvent) { - //Log.d("MT", "New User ${users.size} ${event.contactMetaData.name}") - // new event val oldUser = getOrCreateUser(event.pubKey) if (event.createdAt > oldUser.updatedMetadataAt) { + //Log.d("MT", "New User ${users.size} ${event.contactMetaData.name}") + val newUser = try { metadataParser.readValue(ByteArrayInputStream(event.content.toByteArray(Charsets.UTF_8)), UserMetadata::class.java) } catch (e: Exception) { @@ -101,7 +101,7 @@ object LocalCache { note.loadEvent(event, author, mentions, replyTo) - //Log.d("TN", "New Note (${notes.size},${users.size}) ${note.author?.toBestDisplayName()} ${note.event?.content} ${formattedDateTime(event.createdAt)}") + //Log.d("TN", "New Note (${notes.size},${users.size}) ${note.author?.toBestDisplayName()} ${note.event?.content?.take(100)} ${formattedDateTime(event.createdAt)}") // Prepares user's profile view. author.notes.add(note) @@ -188,7 +188,7 @@ object LocalCache { // Already processed this event. if (note.event != null) return - //Log.d("TN", "New Boost (${notes.size},${users.size}) ${note.author.toBestDisplayName()} ${formattedDateTime(event.createdAt)}") + //Log.d("TN", "New Boost (${notes.size},${users.size}) ${note.author?.toBestDisplayName()} ${formattedDateTime(event.createdAt)}") val author = getOrCreateUser(event.pubKey) val mentions = event.originalAuthor.map { getOrCreateUser(decodePublicKey(it)) }.toList() diff --git a/app/src/main/java/com/vitorpamplona/amethyst/model/Note.kt b/app/src/main/java/com/vitorpamplona/amethyst/model/Note.kt index 45e48e8542..bffb292e82 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/model/Note.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/model/Note.kt @@ -102,14 +102,13 @@ class Note(val idHex: String) { } class NoteLiveData(val note: Note): LiveData(NoteState(note)) { - val scope = CoroutineScope(Job() + Dispatchers.Main) - fun refresh() { postValue(NoteState(note)) } override fun onActive() { super.onActive() + val scope = CoroutineScope(Job() + Dispatchers.Main) scope.launch { NostrSingleEventDataSource.add(note.idHex) } @@ -117,6 +116,7 @@ class NoteLiveData(val note: Note): LiveData(NoteState(note)) { override fun onInactive() { super.onInactive() + val scope = CoroutineScope(Job() + Dispatchers.Main) scope.launch { NostrSingleEventDataSource.remove(note.idHex) } diff --git a/app/src/main/java/com/vitorpamplona/amethyst/model/User.kt b/app/src/main/java/com/vitorpamplona/amethyst/model/User.kt index 247b2dbd00..5ab332b8dc 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/model/User.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/model/User.kt @@ -1,10 +1,15 @@ package com.vitorpamplona.amethyst.model import androidx.lifecycle.LiveData +import com.vitorpamplona.amethyst.service.NostrSingleEventDataSource import com.vitorpamplona.amethyst.service.NostrSingleUserDataSource import com.vitorpamplona.amethyst.ui.note.toShortenHex import java.util.Collections import java.util.concurrent.ConcurrentHashMap +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.Job +import kotlinx.coroutines.launch import nostr.postr.events.ContactListEvent class User(val pubkey: ByteArray) { @@ -138,12 +143,18 @@ class UserLiveData(val user: User): LiveData(UserState(user)) { override fun onActive() { super.onActive() - NostrSingleUserDataSource.add(user.pubkeyHex) + val scope = CoroutineScope(Job() + Dispatchers.Main) + scope.launch { + NostrSingleUserDataSource.add(user.pubkeyHex) + } } override fun onInactive() { super.onInactive() - NostrSingleUserDataSource.remove(user.pubkeyHex) + val scope = CoroutineScope(Job() + Dispatchers.Main) + scope.launch { + NostrSingleUserDataSource.remove(user.pubkeyHex) + } } } diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/Channel.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/Channel.kt index f2bdeada89..1f6d5296ce 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/Channel.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/Channel.kt @@ -6,5 +6,5 @@ import nostr.postr.JsonFilter data class Channel ( val id: String = UUID.randomUUID().toString().substring(0,4) ) { - var filter: JsonFilter? = null // Inactive when null + var filter: List? = null // Inactive when null } \ No newline at end of file diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/NostrAccountDataSource.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/NostrAccountDataSource.kt index 76d58d4c59..2b6a4736d0 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/NostrAccountDataSource.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/NostrAccountDataSource.kt @@ -29,31 +29,24 @@ object NostrAccountDataSource: NostrDataSource("AccountData") { account.userProfile().live.removeObserver(cacheListener) } - fun createAccountFilter(): JsonFilter { + fun createAccountContactListFilter(): JsonFilter { return JsonFilter( - kinds = listOf(MetadataEvent.kind, ContactListEvent.kind), + kinds = listOf(ContactListEvent.kind), authors = listOf(account.userProfile().pubkeyHex), - since = System.currentTimeMillis() / 1000 - (60 * 60 * 24 * 7), // 4 days + limit = 1 ) } - val accountChannel = requestNewChannel() - - fun equalsIgnoreOrder(list1:List?, list2:List?): Boolean { - if (list1 == null && list2 == null) return true - if (list1 == null) return false - if (list2 == null) return false - - return list1.size == list2.size && list1.toSet() == list2.toSet() + fun createAccountMetadataFilter(): JsonFilter { + return JsonFilter( + kinds = listOf(MetadataEvent.kind), + authors = listOf(account.userProfile().pubkeyHex), + limit = 1 + ) } - fun equalAuthors(list1:JsonFilter?, list2:JsonFilter?): Boolean { - if (list1 == null && list2 == null) return true - if (list1 == null) return false - if (list2 == null) return false - - return equalsIgnoreOrder(list1.authors, list2.authors) - } + val accountMetadataChannel = requestNewChannel() + val accountContactListChannel = requestNewChannel() override fun feed(): List { val user = account.userProfile() @@ -72,10 +65,10 @@ object NostrAccountDataSource: NostrDataSource("AccountData") { override fun updateChannelFilters() { // gets everthing about the user logged in - val newAccountFilter = createAccountFilter() + val newAccountMetadataFilter = createAccountMetadataFilter() + accountMetadataChannel.filter = listOf(newAccountMetadataFilter).ifEmpty { null } - if (!equalAuthors(newAccountFilter, accountChannel.filter)) { - accountChannel.filter = newAccountFilter - } + val newAccountContactListEvent = createAccountContactListFilter() + accountContactListChannel.filter = listOf(newAccountContactListEvent).ifEmpty { null } } } \ No newline at end of file diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/NostrChannelDataSource.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/NostrChannelDataSource.kt index 9fc7c22b3a..4d9a671a73 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/NostrChannelDataSource.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/NostrChannelDataSource.kt @@ -15,7 +15,7 @@ object NostrChannelDataSource: NostrDataSource("ChatroomFeed") { fun createMessagesToChannelFilter() = JsonFilter( kinds = listOf(ChannelMessageEvent.kind), tags = mapOf("e" to listOf(channel?.idHex).filterNotNull()), - since = System.currentTimeMillis() / 1000 - (60 * 60 * 24 * 1), // 24 hours + limit = 100 ) val messagesChannel = requestNewChannel() @@ -26,6 +26,6 @@ object NostrChannelDataSource: NostrDataSource("ChatroomFeed") { } override fun updateChannelFilters() { - messagesChannel.filter = createMessagesToChannelFilter() + messagesChannel.filter = listOf(createMessagesToChannelFilter()).ifEmpty { null } } } \ No newline at end of file diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/NostrChatRoomDataSource.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/NostrChatRoomDataSource.kt index 39fda38500..59afa45f62 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/NostrChatRoomDataSource.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/NostrChatRoomDataSource.kt @@ -39,7 +39,7 @@ object NostrChatRoomDataSource: NostrDataSource("ChatroomFeed") { } override fun updateChannelFilters() { - incomingChannel.filter = createMessagesToMeFilter() - outgoingChannel.filter = createMessagesFromMeFilter() + incomingChannel.filter = listOf(createMessagesToMeFilter()).ifEmpty { null } + outgoingChannel.filter = listOf(createMessagesFromMeFilter()).ifEmpty { null } } } \ No newline at end of file diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/NostrChatroomListDataSource.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/NostrChatroomListDataSource.kt index 6727663ebe..05fce8b5e5 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/NostrChatroomListDataSource.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/NostrChatroomListDataSource.kt @@ -26,16 +26,25 @@ object NostrChatroomListDataSource: NostrDataSource("MailBoxFeed") { ids = account.followingChannels.toList() ) - fun createMyChannelsInfoFilter() = JsonFilter( - kinds = listOf(ChannelMetadataEvent.kind), - tags = mapOf("e" to account.followingChannels.toList()) - ) + fun createLastChannelInfoFilter(): List { + return account.followingChannels.map { + JsonFilter( + kinds = listOf(ChannelMetadataEvent.kind), + tags = mapOf("e" to listOf(it)), + limit = 1 + ) + } + } - fun createMessagesToMyChannelsFilter() = JsonFilter( - kinds = listOf(ChannelMessageEvent.kind), - tags = mapOf("e" to account.followingChannels.toList()), - since = System.currentTimeMillis() / 1000 - (60 * 60 * 24 * 1), // 24 hours - ) + fun createLastMessageOfEachChannelFilter(): List { + return account.followingChannels.map { + JsonFilter( + kinds = listOf(ChannelMessageEvent.kind), + tags = mapOf("e" to listOf(it)), + limit = 1 + ) + } + } val incomingChannel = requestNewChannel() val outgoingChannel = requestNewChannel() @@ -61,10 +70,10 @@ object NostrChatroomListDataSource: NostrDataSource("MailBoxFeed") { } override fun updateChannelFilters() { - incomingChannel.filter = createMessagesToMeFilter() - outgoingChannel.filter = createMessagesFromMeFilter() - myChannelsChannel.filter = createMyChannelsFilter() - myChannelsInfoChannel.filter = createMyChannelsInfoFilter() - myChannelsMessagesChannel.filter = createMessagesToMyChannelsFilter() + incomingChannel.filter = listOf(createMessagesToMeFilter()).ifEmpty { null } + outgoingChannel.filter = listOf(createMessagesFromMeFilter()).ifEmpty { null } + myChannelsChannel.filter = listOf(createMyChannelsFilter()).ifEmpty { null } + myChannelsInfoChannel.filter = createLastChannelInfoFilter().ifEmpty { null } + myChannelsMessagesChannel.filter = createLastMessageOfEachChannelFilter().ifEmpty { null } } } \ No newline at end of file diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/NostrDataSource.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/NostrDataSource.kt index 7f00c40c30..f566686777 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/NostrDataSource.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/NostrDataSource.kt @@ -23,9 +23,25 @@ abstract class NostrDataSource(val debugName: String) { private val channels = Collections.synchronizedSet(mutableSetOf()) private val channelIds = Collections.synchronizedSet(mutableSetOf()) + private val eventCounter = mutableMapOf() + + fun printCounter() { + eventCounter.forEach { + println("AAA Count ${it.key}: ${it.value}") + } + } + private val clientListener = object : Client.Listener() { override fun onEvent(event: Event, subscriptionId: String, relay: Relay) { if (subscriptionId in channelIds) { + val key = "${debugName} ${subscriptionId} ${event.kind}" + if (eventCounter.contains(key)) { + eventCounter.put(key, eventCounter.get(key)!! + 1) + } else { + eventCounter.put(key, 1) + } + + //println("AAA ${debugName} ${subscriptionId} ${event.kind}") when (event) { is MetadataEvent -> LocalCache.consume(event) is TextNoteEvent -> LocalCache.consume(event) @@ -109,7 +125,7 @@ abstract class NostrDataSource(val debugName: String) { // saves the channels that are currently active val activeChannels = channels.filter { it.filter != null } // saves the current content to only update if it changes - val currentFilter = activeChannels.associate { it.id to it.filter!!.toJson() } + val currentFilter = activeChannels.associate { it.id to it.filter!!.joinToString("|") { it.toJson() } } updateChannelFilters() @@ -123,12 +139,12 @@ abstract class NostrDataSource(val debugName: String) { Client.close(channel.id) } else { // was active and is still active, check if it has changed. - if (channelsNewFilter.toJson() != currentFilter[channel.id]) { + if (channelsNewFilter.joinToString("|") { it.toJson() } != currentFilter[channel.id]) { Client.close(channel.id) - Client.sendFilter(channel.id, mutableListOf(channelsNewFilter)) + Client.sendFilter(channel.id, channelsNewFilter) } else { // hasn't changed, does nothing. - Client.sendFilterOnlyIfDisconnected(channel.id, mutableListOf(channelsNewFilter)) + Client.sendFilterOnlyIfDisconnected(channel.id, channelsNewFilter) } } } else { @@ -136,8 +152,8 @@ abstract class NostrDataSource(val debugName: String) { // was not active and is still not active, does nothing } else { // was not active and becomes active, sends the filter. - if (channelsNewFilter.toJson() != currentFilter[channel.id]) { - Client.sendFilter(channel.id, mutableListOf(channelsNewFilter)) + if (channelsNewFilter.joinToString("|") { it.toJson() } != currentFilter[channel.id]) { + Client.sendFilter(channel.id, channelsNewFilter) } } } diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/NostrGlobalDataSource.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/NostrGlobalDataSource.kt index 4b7339a186..32cfd52ec1 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/NostrGlobalDataSource.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/NostrGlobalDataSource.kt @@ -6,31 +6,13 @@ import nostr.postr.JsonFilter import nostr.postr.events.TextNoteEvent object NostrGlobalDataSource: NostrDataSource("GlobalFeed") { - val fifteenMinutes = (60*15) // 15 mins - fun createGlobalFilter() = JsonFilter( - kinds = listOf(TextNoteEvent.kind), - since = System.currentTimeMillis() / 1000 - fifteenMinutes - ) + kinds = listOf(TextNoteEvent.kind), + limit = 200 + ) val globalFeedChannel = requestNewChannel() - fun equalTime(list1:Long?, list2:Long?): Boolean { - if (list1 == null && list2 == null) return true - if (list1 == null) return false - if (list2 == null) return false - - return Math.abs(list1 - list2) < (4*fifteenMinutes) - } - - fun equalFilters(list1:JsonFilter?, list2:JsonFilter?): Boolean { - if (list1 == null && list2 == null) return true - if (list1 == null) return false - if (list2 == null) return false - - return equalTime(list1.since, list2.since) - } - override fun feed() = LocalCache.notes.values .filter { it.event is TextNoteEvent && (it.event as TextNoteEvent).replyTos.isEmpty() @@ -39,10 +21,6 @@ object NostrGlobalDataSource: NostrDataSource("GlobalFeed") { .reversed() override fun updateChannelFilters() { - val newFilter = createGlobalFilter() - - if (!equalFilters(newFilter, globalFeedChannel.filter)) { - globalFeedChannel.filter = newFilter - } + globalFeedChannel.filter = listOf(createGlobalFilter()).ifEmpty { null } } } \ No newline at end of file diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/NostrHomeDataSource.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/NostrHomeDataSource.kt index 41da73d0cd..3ead775bbf 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/NostrHomeDataSource.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/NostrHomeDataSource.kt @@ -28,7 +28,7 @@ object NostrHomeDataSource: NostrDataSource("HomeFeed") { account.userProfile().live.removeObserver(cacheListener) } - fun createFollowAccountsFilter(): JsonFilter? { + fun createFollowAccountsFilter(): JsonFilter { val follows = account.userProfile().follows ?: emptySet() val followKeys = synchronized(follows) { @@ -39,12 +39,10 @@ object NostrHomeDataSource: NostrDataSource("HomeFeed") { val followSet = followKeys.plus(account.userProfile().pubkeyHex.substring(0, 6)) - if (followSet.isEmpty()) return null - return JsonFilter( kinds = listOf(TextNoteEvent.kind, RepostEvent.kind), authors = followSet, - since = System.currentTimeMillis() / 1000 - (60 * 60 * 24 * 1), // 24 hours + limit = 200 ) } @@ -85,8 +83,8 @@ object NostrHomeDataSource: NostrDataSource("HomeFeed") { override fun updateChannelFilters() { val newFollowAccountsFilter = createFollowAccountsFilter() - if (!equalAuthors(newFollowAccountsFilter, followAccountChannel.filter)) { - followAccountChannel.filter = newFollowAccountsFilter + if (!equalAuthors(newFollowAccountsFilter, followAccountChannel.filter?.firstOrNull())) { + followAccountChannel.filter = listOf(newFollowAccountsFilter).ifEmpty { null } } } } \ No newline at end of file diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/NostrNotificationDataSource.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/NostrNotificationDataSource.kt index a02362fe5d..366ab85dfe 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/NostrNotificationDataSource.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/NostrNotificationDataSource.kt @@ -4,33 +4,16 @@ import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.model.Note import nostr.postr.JsonFilter -object NostrNotificationDataSource: NostrDataSource("GlobalFeed") { +object NostrNotificationDataSource: NostrDataSource("NotificationFeed") { lateinit var account: Account - fun createGlobalFilter() = JsonFilter( - since = System.currentTimeMillis() / 1000 - (60 * 60 * 24 * 7), // 7 days - tags = mapOf("p" to listOf(account.userProfile().pubkeyHex).filterNotNull()) + fun createNotificationFilter() = JsonFilter( + tags = mapOf("p" to listOf(account.userProfile().pubkeyHex)), + limit = 100 ) val notificationChannel = requestNewChannel() - fun equalsIgnoreOrder(list1:List?, list2:List?): Boolean { - if (list1 == null && list2 == null) return true - if (list1 == null) return false - if (list2 == null) return false - - return list1.size == list2.size && list1.toSet() == list2.toSet() - } - - fun equalFilters(list1:JsonFilter?, list2:JsonFilter?): Boolean { - if (list1 == null && list2 == null) return true - if (list1 == null) return false - if (list2 == null) return false - - return equalsIgnoreOrder(list1.tags?.get("p"), list2.tags?.get("p")) - && equalsIgnoreOrder(list1.tags?.get("e"), list2.tags?.get("e")) - } - override fun feed(): List { val set = account.userProfile().taggedPosts val filtered = synchronized(set) { @@ -41,10 +24,6 @@ object NostrNotificationDataSource: NostrDataSource("GlobalFeed") { } override fun updateChannelFilters() { - val newFilter = createGlobalFilter() - - if (!equalFilters(newFilter, notificationChannel.filter)) { - notificationChannel.filter = newFilter - } + notificationChannel.filter = listOf(createNotificationFilter()).ifEmpty { null } } } \ No newline at end of file diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/NostrSingleEventDataSource.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/NostrSingleEventDataSource.kt index cc81eb3ef4..4f90a1c981 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/NostrSingleEventDataSource.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/NostrSingleEventDataSource.kt @@ -9,7 +9,7 @@ import nostr.postr.JsonFilter import nostr.postr.events.TextNoteEvent object NostrSingleEventDataSource: NostrDataSource("SingleEventFeed") { - private var eventsToWatch = listOf() + private var eventsToWatch = setOf() private fun createRepliesAndReactionsFilter(): JsonFilter? { val reactionsToWatch = eventsToWatch.map { it.substring(0, 8) } @@ -46,6 +46,7 @@ object NostrSingleEventDataSource: NostrDataSource("SingleEventFeed") { // downloads linked events to this event. return JsonFilter( + kinds = listOf(TextNoteEvent.kind, ReactionEvent.kind, RepostEvent.kind), ids = interestedEvents ) } @@ -60,12 +61,16 @@ object NostrSingleEventDataSource: NostrDataSource("SingleEventFeed") { } override fun updateChannelFilters() { - repliesAndReactionsChannel.filter = createRepliesAndReactionsFilter() - loadEventsChannel.filter = createLoadEventsIfNotLoadedFilter() + val reactions = createRepliesAndReactionsFilter() + val missing = createLoadEventsIfNotLoadedFilter() + + repliesAndReactionsChannel.filter = listOfNotNull(reactions).ifEmpty { null } + loadEventsChannel.filter = listOfNotNull(missing).ifEmpty { null } } fun add(eventId: String) { eventsToWatch = eventsToWatch.plus(eventId) + println("AAA: Event Watching ${eventsToWatch.size}") resetFilters() } diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/NostrSingleUserDataSource.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/NostrSingleUserDataSource.kt index bdda0cf050..59a5dd1c9d 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/NostrSingleUserDataSource.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/NostrSingleUserDataSource.kt @@ -7,15 +7,18 @@ import nostr.postr.JsonFilter import nostr.postr.events.MetadataEvent object NostrSingleUserDataSource: NostrDataSource("SingleUserFeed") { - var usersToWatch = listOf() + var usersToWatch = setOf() - fun createUserFilter(): JsonFilter? { + fun createUserFilter(): List? { if (usersToWatch.isEmpty()) return null - return JsonFilter( - kinds = listOf(MetadataEvent.kind), - authors = usersToWatch.map { it.substring(0, 8) } - ) + return usersToWatch.map { + JsonFilter( + kinds = listOf(MetadataEvent.kind), + authors = listOf(it.substring(0, 8)), + limit = 1 + ) + } } val userChannel = requestNewChannel() @@ -32,6 +35,7 @@ object NostrSingleUserDataSource: NostrDataSource("SingleUserFeed") { fun add(userId: String) { usersToWatch = usersToWatch.plus(userId) + println("AAA: User Watching ${usersToWatch.size}") resetFilters() } diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/NostrThreadDataSource.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/NostrThreadDataSource.kt index 0ad387b65e..6180572418 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/NostrThreadDataSource.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/NostrThreadDataSource.kt @@ -2,8 +2,11 @@ package com.vitorpamplona.amethyst.service import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.model.Note +import com.vitorpamplona.amethyst.service.model.ReactionEvent +import com.vitorpamplona.amethyst.service.model.RepostEvent import java.util.Collections import nostr.postr.JsonFilter +import nostr.postr.events.TextNoteEvent object NostrThreadDataSource: NostrDataSource("SingleThreadFeed") { val eventsToWatch = Collections.synchronizedList(mutableListOf()) @@ -16,6 +19,7 @@ object NostrThreadDataSource: NostrDataSource("SingleThreadFeed") { } return JsonFilter( + kinds = listOf(TextNoteEvent.kind, ReactionEvent.kind, RepostEvent.kind), tags = mapOf("e" to reactionsToWatch) ) } @@ -46,8 +50,8 @@ object NostrThreadDataSource: NostrDataSource("SingleThreadFeed") { } override fun updateChannelFilters() { - repliesAndReactionsChannel.filter = createRepliesAndReactionsFilter() - loadEventsChannel.filter = createLoadEventsIfNotLoadedFilter() + repliesAndReactionsChannel.filter = listOfNotNull(createRepliesAndReactionsFilter()).ifEmpty { null } + loadEventsChannel.filter = listOfNotNull(createLoadEventsIfNotLoadedFilter()).ifEmpty { null } } fun loadThread(noteId: String) { diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/NostrUserProfileDataSource.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/NostrUserProfileDataSource.kt index 082dd661bc..b62d7edc46 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/NostrUserProfileDataSource.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/NostrUserProfileDataSource.kt @@ -19,7 +19,7 @@ object NostrUserProfileDataSource: NostrDataSource("UserProfileFeed") { return JsonFilter( kinds = listOf(MetadataEvent.kind), authors = listOf(user!!.pubkeyHex), - since = System.currentTimeMillis() / 1000 - (60 * 60 * 24 * 7) + limit = 1 ) } @@ -27,7 +27,7 @@ object NostrUserProfileDataSource: NostrDataSource("UserProfileFeed") { return JsonFilter( kinds = listOf(TextNoteEvent.kind), authors = listOf(user!!.pubkeyHex), - since = System.currentTimeMillis() / 1000 - (60 * 60 * 24 * 4) + limit = 100 ) } @@ -43,7 +43,7 @@ object NostrUserProfileDataSource: NostrDataSource("UserProfileFeed") { } override fun updateChannelFilters() { - userInfoChannel.filter = createUserInfoFilter() - notesChannel.filter = createUserPostsFilter() + userInfoChannel.filter = listOf(createUserInfoFilter()).ifEmpty { null } + notesChannel.filter = listOf(createUserPostsFilter()).ifEmpty { null } } } \ No newline at end of file diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/NostrUserProfileFollowersDataSource.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/NostrUserProfileFollowersDataSource.kt index 9f60858322..7291d7b687 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/NostrUserProfileFollowersDataSource.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/NostrUserProfileFollowersDataSource.kt @@ -15,8 +15,7 @@ object NostrUserProfileFollowersDataSource: NostrDataSource("UserProfileFo fun createFollowersFilter() = JsonFilter( kinds = listOf(ContactListEvent.kind), - since = System.currentTimeMillis() / 1000 - (60 * 60 * 24 * 7), // 7 days - tags = mapOf("p" to listOf(user!!.pubkeyHex).filterNotNull()) + tags = mapOf("p" to listOf(user!!.pubkeyHex)) ) val followerChannel = requestNewChannel() @@ -30,6 +29,6 @@ object NostrUserProfileFollowersDataSource: NostrDataSource("UserProfileFo } override fun updateChannelFilters() { - followerChannel.filter = createFollowersFilter() + followerChannel.filter = listOf(createFollowersFilter()).ifEmpty { null } } } \ No newline at end of file diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/NostrUserProfileFollowsDataSource.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/NostrUserProfileFollowsDataSource.kt index 771cbc15ea..8c32972b8b 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/NostrUserProfileFollowsDataSource.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/NostrUserProfileFollowsDataSource.kt @@ -17,7 +17,7 @@ object NostrUserProfileFollowsDataSource: NostrDataSource("UserProfileFoll return JsonFilter( kinds = listOf(ContactListEvent.kind), authors = listOf(user!!.pubkeyHex), - since = System.currentTimeMillis() / 1000 - (60 * 60 * 24 * 7), // 4 days + limit = 1 ) } @@ -28,6 +28,6 @@ object NostrUserProfileFollowsDataSource: NostrDataSource("UserProfileFoll } override fun updateChannelFilters() { - followChannel.filter = createFollowFilter() + followChannel.filter = listOf(createFollowFilter()).ifEmpty { null } } } \ No newline at end of file diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AppTopBar.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AppTopBar.kt index c8ddbcf837..3ff6aaa854 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AppTopBar.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AppTopBar.kt @@ -31,6 +31,19 @@ import androidx.lifecycle.viewmodel.compose.viewModel import androidx.navigation.NavHostController import coil.compose.AsyncImage import com.vitorpamplona.amethyst.R +import com.vitorpamplona.amethyst.service.NostrAccountDataSource +import com.vitorpamplona.amethyst.service.NostrChannelDataSource +import com.vitorpamplona.amethyst.service.NostrChatRoomDataSource +import com.vitorpamplona.amethyst.service.NostrChatroomListDataSource +import com.vitorpamplona.amethyst.service.NostrGlobalDataSource +import com.vitorpamplona.amethyst.service.NostrHomeDataSource +import com.vitorpamplona.amethyst.service.NostrNotificationDataSource +import com.vitorpamplona.amethyst.service.NostrSingleEventDataSource +import com.vitorpamplona.amethyst.service.NostrSingleUserDataSource +import com.vitorpamplona.amethyst.service.NostrThreadDataSource +import com.vitorpamplona.amethyst.service.NostrUserProfileDataSource +import com.vitorpamplona.amethyst.service.NostrUserProfileFollowersDataSource +import com.vitorpamplona.amethyst.service.NostrUserProfileFollowsDataSource import com.vitorpamplona.amethyst.service.relays.Client import com.vitorpamplona.amethyst.ui.screen.RelayPoolViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel @@ -71,6 +84,23 @@ fun MainTopBar(scaffoldState: ScaffoldState, accountViewModel: AccountViewModel) Client.allSubscriptions().map { "${it} ${Client.getSubscriptionFilters(it).joinToString { it.toJson() }}" }.forEach { Log.d("CURRENT FILTERS", it) } + + NostrAccountDataSource.printCounter() + NostrChannelDataSource.printCounter() + NostrChatRoomDataSource.printCounter() + NostrChatroomListDataSource.printCounter() + + NostrGlobalDataSource.printCounter() + NostrHomeDataSource.printCounter() + NostrNotificationDataSource.printCounter() + + NostrSingleEventDataSource.printCounter() + NostrSingleUserDataSource.printCounter() + NostrThreadDataSource.printCounter() + + NostrUserProfileDataSource.printCounter() + NostrUserProfileFollowersDataSource.printCounter() + NostrUserProfileFollowsDataSource.printCounter() } ) { Icon( diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteCompose.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteCompose.kt index 9d97ef9cce..cf13ce4192 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteCompose.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteCompose.kt @@ -107,13 +107,7 @@ fun NoteCompose(baseNote: Note, modifier: Modifier = Modifier, isInnerNote: Bool } } - Column(modifier = Modifier.padding(start = if (!isInnerNote) 10.dp else 0.dp) - .clickable(onClick = { - note.let { - navController.navigate("Note/${note.idHex}") - } - }) - ) { + Column(modifier = Modifier.padding(start = if (!isInnerNote) 10.dp else 0.dp)) { Row(verticalAlignment = Alignment.CenterVertically) { if (author != null) UserDisplay(author) diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/HomeScreen.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/HomeScreen.kt index 8aa5014957..3478deafbf 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/HomeScreen.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/HomeScreen.kt @@ -6,12 +6,14 @@ import androidx.compose.foundation.layout.padding import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.livedata.observeAsState +import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import androidx.lifecycle.viewmodel.compose.viewModel import androidx.navigation.NavController import com.vitorpamplona.amethyst.service.NostrHomeDataSource import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel +import java.lang.System.currentTimeMillis @Composable fun HomeScreen(accountViewModel: AccountViewModel, navController: NavController) { diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/ProfileScreen.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/ProfileScreen.kt index 49c86a67c6..ef7ad7b807 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/ProfileScreen.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/ProfileScreen.kt @@ -293,7 +293,7 @@ private fun MessageButton(user: User, navController: NavController) { painter = painterResource(R.drawable.ic_dm), "Send a Direct Message", modifier = Modifier.size(20.dp), - tint = Color.Unspecified + tint = Color.White ) } }