Making sure filters return similar orders when two posts are published at the same time.

This commit is contained in:
Vitor Pamplona
2023-05-16 11:10:17 -04:00
parent 1d5ff5bea9
commit 76df70c6f6
18 changed files with 26 additions and 26 deletions
@@ -57,7 +57,7 @@ class Channel(val idHex: String) {
fun pruneOldAndHiddenMessages(account: Account): Set<Note> { fun pruneOldAndHiddenMessages(account: Account): Set<Note> {
val important = notes.values val important = notes.values
.filter { it.author?.let { it1 -> account.isHidden(it1) } == false } .filter { it.author?.let { it1 -> account.isHidden(it1) } == false }
.sortedBy { it.createdAt() } .sortedWith(compareBy({ it.createdAt() }, { it.idHex }))
.reversed() .reversed()
.take(1000) .take(1000)
.toSet() .toSet()
@@ -19,7 +19,7 @@ object BookmarkPrivateFeedFilter : FeedFilter<Note>() {
?.map { LocalCache.getOrCreateAddressableNote(it) } ?: emptyList() ?.map { LocalCache.getOrCreateAddressableNote(it) } ?: emptyList()
return notes.plus(addresses).toSet() return notes.plus(addresses).toSet()
.sortedBy { it.createdAt() } .sortedWith(compareBy({ it.createdAt() }, { it.idHex }))
.reversed() .reversed()
} }
} }
@@ -14,7 +14,7 @@ object BookmarkPublicFeedFilter : FeedFilter<Note>() {
val addresses = bookmarks?.taggedAddresses()?.map { LocalCache.getOrCreateAddressableNote(it) } ?: emptyList() val addresses = bookmarks?.taggedAddresses()?.map { LocalCache.getOrCreateAddressableNote(it) } ?: emptyList()
return notes.plus(addresses).toSet() return notes.plus(addresses).toSet()
.sortedBy { it.createdAt() } .sortedWith(compareBy({ it.createdAt() }, { it.idHex }))
.reversed() .reversed()
} }
} }
@@ -21,7 +21,7 @@ object ChannelFeedFilter : AdditiveFeedFilter<Note>() {
return channel.notes return channel.notes
.values .values
.filter { account.isAcceptable(it) } .filter { account.isAcceptable(it) }
.sortedBy { it.createdAt() } .sortedWith(compareBy({ it.createdAt() }, { it.idHex }))
.reversed() .reversed()
} }
@@ -35,6 +35,6 @@ object ChannelFeedFilter : AdditiveFeedFilter<Note>() {
} }
override fun sort(collection: Set<Note>): List<Note> { override fun sort(collection: Set<Note>): List<Note> {
return collection.sortedBy { it.createdAt() }.reversed() return collection.sortedWith(compareBy({ it.createdAt() }, { it.idHex })).reversed()
} }
} }
@@ -28,7 +28,7 @@ object ChatroomFeedFilter : AdditiveFeedFilter<Note>() {
return messages.roomMessages return messages.roomMessages
.filter { myAccount.isAcceptable(it) } .filter { myAccount.isAcceptable(it) }
.sortedBy { it.createdAt() } .sortedWith(compareBy({ it.createdAt() }, { it.idHex }))
.reversed() .reversed()
} }
@@ -50,6 +50,6 @@ object ChatroomFeedFilter : AdditiveFeedFilter<Note>() {
} }
override fun sort(collection: Set<Note>): List<Note> { override fun sort(collection: Set<Note>): List<Note> {
return collection.sortedBy { it.createdAt() }.reversed() return collection.sortedWith(compareBy({ it.createdAt() }, { it.idHex })).reversed()
} }
} }
@@ -19,20 +19,20 @@ object ChatroomListKnownFeedFilter : FeedFilter<Note>() {
val privateMessages = messagingWith.mapNotNull { it -> val privateMessages = messagingWith.mapNotNull { it ->
privateChatrooms[it] privateChatrooms[it]
?.roomMessages ?.roomMessages
?.sortedBy { it.createdAt() } ?.sortedWith(compareBy({ it.createdAt() }, { it.idHex }))
?.lastOrNull { it.event != null } ?.lastOrNull { it.event != null }
} }
val publicChannels = account.followingChannels().map { it -> val publicChannels = account.followingChannels().map { it ->
it.notes.values it.notes.values
.filter { account.isAcceptable(it) } .filter { account.isAcceptable(it) }
.sortedBy { it.createdAt() } .sortedWith(compareBy({ it.createdAt() }, { it.idHex }))
.lastOrNull { it.event != null } .lastOrNull { it.event != null }
} }
return (privateMessages + publicChannels) return (privateMessages + publicChannels)
.filterNotNull() .filterNotNull()
.sortedBy { it.createdAt() } .sortedWith(compareBy({ it.createdAt() }, { it.idHex }))
.reversed() .reversed()
} }
} }
@@ -19,12 +19,12 @@ object ChatroomListNewFeedFilter : FeedFilter<Note>() {
val privateMessages = messagingWith.mapNotNull { it -> val privateMessages = messagingWith.mapNotNull { it ->
privateChatrooms[it] privateChatrooms[it]
?.roomMessages ?.roomMessages
?.sortedBy { it.createdAt() } ?.sortedWith(compareBy({ it.createdAt() }, { it.idHex }))
?.lastOrNull { it.event != null } ?.lastOrNull { it.event != null }
} }
return privateMessages return privateMessages
.sortedBy { it.createdAt() } .sortedWith(compareBy({ it.createdAt() }, { it.idHex }))
.reversed() .reversed()
} }
} }
@@ -44,6 +44,6 @@ object HashtagFeedFilter : AdditiveFeedFilter<Note>() {
} }
override fun sort(collection: Set<Note>): List<Note> { override fun sort(collection: Set<Note>): List<Note> {
return collection.sortedBy { it.createdAt() }.reversed() return collection.sortedWith(compareBy({ it.createdAt() }, { it.idHex })).reversed()
} }
} }
@@ -34,6 +34,6 @@ object HomeConversationsFeedFilter : AdditiveFeedFilter<Note>() {
} }
override fun sort(collection: Set<Note>): List<Note> { override fun sort(collection: Set<Note>): List<Note> {
return collection.sortedBy { it.createdAt() }.reversed() return collection.sortedWith(compareBy({ it.createdAt() }, { it.idHex })).reversed()
} }
} }
@@ -41,6 +41,6 @@ object HomeNewThreadFeedFilter : AdditiveFeedFilter<Note>() {
} }
override fun sort(collection: Set<Note>): List<Note> { override fun sort(collection: Set<Note>): List<Note> {
return collection.sortedBy { it.createdAt() }.reversed() return collection.sortedWith(compareBy({ it.createdAt() }, { it.idHex })).reversed()
} }
} }
@@ -41,7 +41,7 @@ object NotificationFeedFilter : AdditiveFeedFilter<Note>() {
} }
override fun sort(collection: Set<Note>): List<Note> { override fun sort(collection: Set<Note>): List<Note> {
return collection.sortedBy { it.createdAt() }.reversed() return collection.sortedWith(compareBy({ it.createdAt() }, { it.idHex })).reversed()
} }
fun tagsAnEventByUser(note: Note, author: User): Boolean { fun tagsAnEventByUser(note: Note, author: User): Boolean {
@@ -19,7 +19,7 @@ object PeopleListFeedFilter : FeedFilter<Note>() {
.toSet() .toSet()
return lists return lists
.sortedBy { it.createdAt() } .sortedWith(compareBy({ it.createdAt() }, { it.idHex }))
.reversed() .reversed()
} }
} }
@@ -25,7 +25,7 @@ object UserProfileBookmarksFeedFilter : FeedFilter<Note>() {
return (notes + addresses) return (notes + addresses)
.filter { account.isAcceptable(it) } .filter { account.isAcceptable(it) }
.sortedBy { it.createdAt() } .sortedWith(compareBy({ it.createdAt() }, { it.idHex }))
.reversed() .reversed()
} }
} }
@@ -16,7 +16,7 @@ object UserProfileConversationsFeedFilter : FeedFilter<Note>() {
override fun feed(): List<Note> { override fun feed(): List<Note> {
return user?.notes return user?.notes
?.filter { account?.isAcceptable(it) == true && !it.isNewThread() } ?.filter { account?.isAcceptable(it) == true && !it.isNewThread() }
?.sortedBy { it.createdAt() } ?.sortedWith(compareBy({ it.createdAt() }, { it.idHex }))
?.reversed() ?: emptyList() ?.reversed() ?: emptyList()
} }
} }
@@ -23,7 +23,7 @@ object UserProfileNewThreadFeedFilter : FeedFilter<Note>() {
return user?.notes return user?.notes
?.plus(longFormNotes) ?.plus(longFormNotes)
?.filter { account?.isAcceptable(it) == true && it.isNewThread() } ?.filter { account?.isAcceptable(it) == true && it.isNewThread() }
?.sortedBy { it.createdAt() } ?.sortedWith(compareBy({ it.createdAt() }, { it.idHex }))
?.reversed() ?: emptyList() ?.reversed() ?: emptyList()
} }
} }
@@ -14,7 +14,7 @@ object UserProfileReportsFeedFilter : FeedFilter<Note>() {
return user?.reports return user?.reports
?.values ?.values
?.flatten() ?.flatten()
?.sortedBy { it.createdAt() } ?.sortedWith(compareBy({ it.createdAt() }, { it.idHex }))
?.reversed() ?: emptyList() ?.reversed() ?: emptyList()
} }
} }
@@ -59,7 +59,7 @@ open class CardFeedViewModel(val localFilter: FeedFilter<Note>) : ViewModel() {
if (newCards.isNotEmpty()) { if (newCards.isNotEmpty()) {
lastNotes = notes lastNotes = notes
lastAccount = (localFilter as? NotificationFeedFilter)?.account lastAccount = (localFilter as? NotificationFeedFilter)?.account
updateFeed((oldNotesState.feed.value + newCards).distinctBy { it.id() }.sortedBy { it.createdAt() }.reversed()) updateFeed((oldNotesState.feed.value + newCards).distinctBy { it.id() }.sortedWith(compareBy({ it.createdAt() }, { it.id() })).reversed())
} }
} else { } else {
val cards = convertToCard(notes) val cards = convertToCard(notes)
@@ -129,7 +129,7 @@ open class CardFeedViewModel(val localFilter: FeedFilter<Note>) : ViewModel() {
val reactionsInCard = reactionsPerEvent[baseNote] ?: emptyList() val reactionsInCard = reactionsPerEvent[baseNote] ?: emptyList()
val zapsInCard = zapsPerEvent[baseNote] ?: emptyMap() val zapsInCard = zapsPerEvent[baseNote] ?: emptyMap()
val singleList = (boostsInCard + zapsInCard.values + reactionsInCard).sortedBy { it.createdAt() }.reversed() val singleList = (boostsInCard + zapsInCard.values + reactionsInCard).sortedWith(compareBy({ it.createdAt() }, { it.idHex })).reversed()
singleList.chunked(50).map { chunk -> singleList.chunked(50).map { chunk ->
MultiSetCard( MultiSetCard(
baseNote, baseNote,
@@ -157,7 +157,7 @@ open class CardFeedViewModel(val localFilter: FeedFilter<Note>) : ViewModel() {
} }
} }
return (multiCards + textNoteCards + userZaps).sortedBy { it.createdAt() }.reversed() return (multiCards + textNoteCards + userZaps).sortedWith(compareBy({ it.createdAt() }, { it.id() })).reversed()
} }
private fun updateFeed(notes: List<Card>) { private fun updateFeed(notes: List<Card>) {
@@ -190,7 +190,7 @@ open class CardFeedViewModel(val localFilter: FeedFilter<Note>) : ViewModel() {
if (newCards.isNotEmpty()) { if (newCards.isNotEmpty()) {
lastNotes = lastNotesCopy + newItems lastNotes = lastNotesCopy + newItems
lastAccount = (localFilter as? NotificationFeedFilter)?.account lastAccount = (localFilter as? NotificationFeedFilter)?.account
updateFeed((oldNotesState.feed.value + newCards).distinctBy { it.id() }.sortedBy { it.createdAt() }.reversed()) updateFeed((oldNotesState.feed.value + newCards).distinctBy { it.id() }.sortedWith(compareBy({ it.createdAt() }, { it.id() })).reversed())
} }
} else { } else {
// Refresh Everything // Refresh Everything
@@ -157,7 +157,7 @@ class SearchBarViewModel : ViewModel() {
hashtagResults.value = findHashtags(searchValue) hashtagResults.value = findHashtags(searchValue)
searchResults.value = LocalCache.findUsersStartingWith(searchValue) searchResults.value = LocalCache.findUsersStartingWith(searchValue)
searchResultsNotes.value = LocalCache.findNotesStartingWith(searchValue).sortedBy { it.createdAt() }.reversed() searchResultsNotes.value = LocalCache.findNotesStartingWith(searchValue).sortedWith(compareBy({ it.createdAt() }, { it.idHex })).reversed()
searchResultsChannels.value = LocalCache.findChannelsStartingWith(searchValue) searchResultsChannels.value = LocalCache.findChannelsStartingWith(searchValue)
} }