Moves UserProfile NewThreads, Conversations, Reports and App Recommendations to be additive filters

This commit is contained in:
Vitor Pamplona
2023-07-14 18:22:53 -04:00
parent 64a5071345
commit 46a4f360f7
8 changed files with 113 additions and 87 deletions
@@ -238,9 +238,6 @@ object LocalCache {
// Log.d("TN", "New Note (${notes.size},${users.size}) ${note.author?.toBestDisplayName()} ${note.event?.content()?.split("\n")?.take(100)} ${formattedDateTime(event.createdAt)}")
// Prepares user's profile view.
author.addNote(note)
// Counts the replies
replyTo.forEach {
it.addReply(note)
@@ -279,8 +276,6 @@ object LocalCache {
if (event.createdAt > (note.createdAt() ?: 0)) {
note.loadEvent(event, author, replyTo)
author.addNote(note)
refreshObservers(note)
}
}
@@ -310,9 +305,6 @@ object LocalCache {
// Log.d("TN", "New Note (${notes.size},${users.size}) ${note.author?.toBestDisplayName()} ${note.event?.content()?.split("\n")?.take(100)} ${formattedDateTime(event.createdAt)}")
// Prepares user's profile view.
author.addNote(note)
// Counts the replies
replyTo.forEach {
it.addReply(note)
@@ -634,8 +626,6 @@ object LocalCache {
event.deleteEvents().mapNotNull { notes[it] }.forEach { deleteNote ->
// must be the same author
if (deleteNote.author?.pubkeyHex == event.pubKey) {
deleteNote.author?.removeNote(deleteNote)
// reverts the add
val mentions = deleteNote.event?.tags()?.filter { it.firstOrNull() == "p" }
?.mapNotNull { it.getOrNull(1) }?.mapNotNull { checkGetOrCreateUser(it) }
@@ -697,9 +687,6 @@ object LocalCache {
note.loadEvent(event, author, repliesTo)
// Prepares user's profile view.
author.addNote(note)
// Counts the replies
repliesTo.forEach {
it.addBoost(note)
@@ -722,9 +709,6 @@ object LocalCache {
note.loadEvent(event, author, repliesTo)
// Prepares user's profile view.
author.addNote(note)
// Counts the replies
repliesTo.forEach {
it.addBoost(note)
@@ -750,9 +734,6 @@ object LocalCache {
note.loadEvent(event, author, eventsApproved)
// Prepares user's profile view.
author.addNote(note)
// Counts the replies
repliesTo.forEach {
it.addBoost(note)
@@ -1072,9 +1053,6 @@ object LocalCache {
note.loadEvent(event, author, emptyList())
// Adds to user profile
author.addNote(note)
refreshObservers(note)
}
@@ -1254,17 +1232,17 @@ object LocalCache {
fun pruneHiddenMessages(account: Account) {
checkNotInMainThread()
val toBeRemoved = account.hiddenUsers.map {
(users[it]?.notes ?: emptySet())
val toBeRemoved = account.hiddenUsers.map { userHex ->
(
notes.values.filter {
it.event?.pubKey() == userHex
} + addressables.values.filter {
it.event?.pubKey() == userHex
}
).toSet()
}.flatten()
account.hiddenUsers.forEach {
users[it]?.clearNotes()
}
toBeRemoved.forEach {
it.author?.removeNote(it)
// Counts the replies
it.replyTo?.forEach { masterNote ->
masterNote.removeReply(it)
@@ -32,9 +32,6 @@ class User(val pubkeyHex: String) {
var latestContactList: ContactListEvent? = null
var latestBookmarkList: BookmarkListEvent? = null
var notes = setOf<Note>()
private set
var reports = mapOf<User, Set<Note>>()
private set
@@ -105,21 +102,6 @@ class User(val pubkeyHex: String) {
liveSet?.relays?.invalidateData()
}
fun addNote(note: Note) {
if (note !in notes) {
notes = notes + note
// No need for Listener yet
}
}
fun removeNote(note: Note) {
notes = notes - note
}
fun clearNotes() {
notes = setOf<Note>()
}
fun addReport(note: Note) {
val author = note.author ?: return
@@ -5,21 +5,37 @@ import com.vitorpamplona.amethyst.model.Note
import com.vitorpamplona.amethyst.model.User
import com.vitorpamplona.amethyst.service.model.AppRecommendationEvent
class UserProfileAppRecommendationsFeedFilter(val user: User) : FeedFilter<Note>() {
class UserProfileAppRecommendationsFeedFilter(val user: User) : AdditiveFeedFilter<Note>() {
override fun feedKey(): String {
return user.pubkeyHex
}
override fun feed(): List<Note> {
val recommendations = LocalCache.addressables.values.filter {
(it.event as? AppRecommendationEvent)?.pubKey == user.pubkeyHex
}.mapNotNull {
(it.event as? AppRecommendationEvent)?.recommendations()
}.flatten()
.map {
return sort(innerApplyFilter(LocalCache.addressables.values))
}
override fun applyFilter(collection: Set<Note>): Set<Note> {
return innerApplyFilter(collection)
}
private fun innerApplyFilter(collection: Collection<Note>): Set<Note> {
val recommendations = collection.asSequence()
.filter { it.event is AppRecommendationEvent }
.mapNotNull {
val noteEvent = it.event as? AppRecommendationEvent
if (noteEvent != null && noteEvent.pubKey == user.pubkeyHex) {
noteEvent.recommendations()
} else {
null
}
}.flatten().map {
LocalCache.getOrCreateAddressableNote(it)
}.toSet().toList()
}.toSet()
return recommendations
}
override fun sort(collection: Set<Note>): List<Note> {
return collection.sortedWith(compareBy({ it.createdAt() }, { it.idHex }))
}
}
@@ -1,18 +1,43 @@
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.User
import com.vitorpamplona.amethyst.service.model.ChannelMessageEvent
import com.vitorpamplona.amethyst.service.model.LiveActivitiesChatMessageEvent
import com.vitorpamplona.amethyst.service.model.PollNoteEvent
import com.vitorpamplona.amethyst.service.model.TextNoteEvent
class UserProfileConversationsFeedFilter(val user: User, val account: Account) : FeedFilter<Note>() {
class UserProfileConversationsFeedFilter(val user: User, val account: Account) : AdditiveFeedFilter<Note>() {
override fun feedKey(): String {
return account.userProfile().pubkeyHex + "-" + user.pubkeyHex
}
override fun feed(): List<Note> {
return user.notes
.filter { account.isAcceptable(it) == true && !it.isNewThread() }
.sortedWith(compareBy({ it.createdAt() }, { it.idHex }))
.reversed() ?: emptyList()
return sort(innerApplyFilter(LocalCache.notes.values))
}
override fun applyFilter(collection: Set<Note>): Set<Note> {
return innerApplyFilter(collection)
}
private fun innerApplyFilter(collection: Collection<Note>): Set<Note> {
return collection
.filter {
it.author == user &&
(
it.event is TextNoteEvent ||
it.event is PollNoteEvent ||
it.event is ChannelMessageEvent ||
it.event is LiveActivitiesChatMessageEvent
) &&
!it.isNewThread() &&
account.isAcceptable(it) == true
}.toSet()
}
override fun sort(collection: Set<Note>): List<Note> {
return collection.sortedWith(compareBy({ it.createdAt() }, { it.idHex })).reversed()
}
}
@@ -8,7 +8,7 @@ import com.vitorpamplona.amethyst.service.model.ContactListEvent
class UserProfileFollowsFeedFilter(val user: User, val account: Account) : FeedFilter<User>() {
override fun feedKey(): String {
return account.userProfile()?.pubkeyHex + "-" + user.pubkeyHex
return account.userProfile().pubkeyHex + "-" + user.pubkeyHex
}
val cache: MutableMap<ContactListEvent, List<User>> = mutableMapOf()
@@ -4,32 +4,51 @@ import com.vitorpamplona.amethyst.model.Account
import com.vitorpamplona.amethyst.model.LocalCache
import com.vitorpamplona.amethyst.model.Note
import com.vitorpamplona.amethyst.model.User
import com.vitorpamplona.amethyst.service.model.AppRecommendationEvent
import com.vitorpamplona.amethyst.service.model.BookmarkListEvent
import com.vitorpamplona.amethyst.service.model.EmojiPackSelectionEvent
import com.vitorpamplona.amethyst.service.model.PeopleListEvent
import com.vitorpamplona.amethyst.service.model.AudioTrackEvent
import com.vitorpamplona.amethyst.service.model.ClassifiedsEvent
import com.vitorpamplona.amethyst.service.model.GenericRepostEvent
import com.vitorpamplona.amethyst.service.model.HighlightEvent
import com.vitorpamplona.amethyst.service.model.LongTextNoteEvent
import com.vitorpamplona.amethyst.service.model.PollNoteEvent
import com.vitorpamplona.amethyst.service.model.RepostEvent
import com.vitorpamplona.amethyst.service.model.TextNoteEvent
class UserProfileNewThreadFeedFilter(val user: User, val account: Account) : FeedFilter<Note>() {
class UserProfileNewThreadFeedFilter(val user: User, val account: Account) : AdditiveFeedFilter<Note>() {
override fun feedKey(): String {
return account.userProfile().pubkeyHex + "-" + user.pubkeyHex
}
override fun feed(): List<Note> {
val longFormNotes = LocalCache.addressables.values
val notes = innerApplyFilter(LocalCache.notes.values)
val longFormNotes = innerApplyFilter(LocalCache.addressables.values)
return sort(notes + longFormNotes)
}
override fun applyFilter(collection: Set<Note>): Set<Note> {
return innerApplyFilter(collection)
}
private fun innerApplyFilter(collection: Collection<Note>): Set<Note> {
return collection
.filter {
it.author == user &&
(
it.event !is PeopleListEvent &&
it.event !is BookmarkListEvent &&
it.event !is AppRecommendationEvent &&
it.event !is EmojiPackSelectionEvent
)
}
it.event is TextNoteEvent ||
it.event is ClassifiedsEvent ||
it.event is RepostEvent ||
it.event is GenericRepostEvent ||
it.event is LongTextNoteEvent ||
it.event is PollNoteEvent ||
it.event is HighlightEvent ||
it.event is AudioTrackEvent
) &&
it.isNewThread() &&
account.isAcceptable(it) == true
}.toSet()
}
return user.notes
.plus(longFormNotes)
.filter { account.isAcceptable(it) == true && it.isNewThread() }
.sortedWith(compareBy({ it.createdAt() }, { it.idHex }))
.reversed() ?: emptyList()
override fun sort(collection: Set<Note>): List<Note> {
return collection.sortedWith(compareBy({ it.createdAt() }, { it.idHex })).reversed()
}
}
@@ -1,20 +1,27 @@
package com.vitorpamplona.amethyst.ui.dal
import com.vitorpamplona.amethyst.model.LocalCache
import com.vitorpamplona.amethyst.model.Note
import com.vitorpamplona.amethyst.model.User
import com.vitorpamplona.amethyst.service.model.ReportEvent
class UserProfileReportsFeedFilter(val user: User) : FeedFilter<Note>() {
class UserProfileReportsFeedFilter(val user: User) : AdditiveFeedFilter<Note>() {
override fun feedKey(): String {
return user.pubkeyHex ?: ""
return user.pubkeyHex
}
override fun feed(): List<Note> {
val reportNotes = LocalCache.notes.values.filter { (it.event as? ReportEvent)?.isTaggedUser(user.pubkeyHex) == true }
return sort(innerApplyFilter(user.reports.values.flatten()))
}
return reportNotes
.sortedWith(compareBy({ it.createdAt() }, { it.idHex }))
.reversed()
override fun applyFilter(collection: Set<Note>): Set<Note> {
return innerApplyFilter(collection)
}
private fun innerApplyFilter(collection: Collection<Note>): Set<Note> {
return collection.filter { it.event is ReportEvent && it.event?.isTaggedUser(user.pubkeyHex) == true }.toSet()
}
override fun sort(collection: Set<Note>): List<Note> {
return collection.sortedWith(compareBy({ it.createdAt() }, { it.idHex })).reversed()
}
}
@@ -1115,7 +1115,6 @@ private fun WatchApp(baseApp: Note, nav: (String) -> Unit) {
}
@Composable
@OptIn(ExperimentalLayoutApi::class)
private fun DisplayBadges(
baseUser: User,
nav: (String) -> Unit