Moves UserProfile NewThreads, Conversations, Reports and App Recommendations to be additive filters
This commit is contained in:
@@ -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)}")
|
// 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
|
// Counts the replies
|
||||||
replyTo.forEach {
|
replyTo.forEach {
|
||||||
it.addReply(note)
|
it.addReply(note)
|
||||||
@@ -279,8 +276,6 @@ object LocalCache {
|
|||||||
if (event.createdAt > (note.createdAt() ?: 0)) {
|
if (event.createdAt > (note.createdAt() ?: 0)) {
|
||||||
note.loadEvent(event, author, replyTo)
|
note.loadEvent(event, author, replyTo)
|
||||||
|
|
||||||
author.addNote(note)
|
|
||||||
|
|
||||||
refreshObservers(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)}")
|
// 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
|
// Counts the replies
|
||||||
replyTo.forEach {
|
replyTo.forEach {
|
||||||
it.addReply(note)
|
it.addReply(note)
|
||||||
@@ -634,8 +626,6 @@ object LocalCache {
|
|||||||
event.deleteEvents().mapNotNull { notes[it] }.forEach { deleteNote ->
|
event.deleteEvents().mapNotNull { notes[it] }.forEach { deleteNote ->
|
||||||
// must be the same author
|
// must be the same author
|
||||||
if (deleteNote.author?.pubkeyHex == event.pubKey) {
|
if (deleteNote.author?.pubkeyHex == event.pubKey) {
|
||||||
deleteNote.author?.removeNote(deleteNote)
|
|
||||||
|
|
||||||
// reverts the add
|
// reverts the add
|
||||||
val mentions = deleteNote.event?.tags()?.filter { it.firstOrNull() == "p" }
|
val mentions = deleteNote.event?.tags()?.filter { it.firstOrNull() == "p" }
|
||||||
?.mapNotNull { it.getOrNull(1) }?.mapNotNull { checkGetOrCreateUser(it) }
|
?.mapNotNull { it.getOrNull(1) }?.mapNotNull { checkGetOrCreateUser(it) }
|
||||||
@@ -697,9 +687,6 @@ object LocalCache {
|
|||||||
|
|
||||||
note.loadEvent(event, author, repliesTo)
|
note.loadEvent(event, author, repliesTo)
|
||||||
|
|
||||||
// Prepares user's profile view.
|
|
||||||
author.addNote(note)
|
|
||||||
|
|
||||||
// Counts the replies
|
// Counts the replies
|
||||||
repliesTo.forEach {
|
repliesTo.forEach {
|
||||||
it.addBoost(note)
|
it.addBoost(note)
|
||||||
@@ -722,9 +709,6 @@ object LocalCache {
|
|||||||
|
|
||||||
note.loadEvent(event, author, repliesTo)
|
note.loadEvent(event, author, repliesTo)
|
||||||
|
|
||||||
// Prepares user's profile view.
|
|
||||||
author.addNote(note)
|
|
||||||
|
|
||||||
// Counts the replies
|
// Counts the replies
|
||||||
repliesTo.forEach {
|
repliesTo.forEach {
|
||||||
it.addBoost(note)
|
it.addBoost(note)
|
||||||
@@ -750,9 +734,6 @@ object LocalCache {
|
|||||||
|
|
||||||
note.loadEvent(event, author, eventsApproved)
|
note.loadEvent(event, author, eventsApproved)
|
||||||
|
|
||||||
// Prepares user's profile view.
|
|
||||||
author.addNote(note)
|
|
||||||
|
|
||||||
// Counts the replies
|
// Counts the replies
|
||||||
repliesTo.forEach {
|
repliesTo.forEach {
|
||||||
it.addBoost(note)
|
it.addBoost(note)
|
||||||
@@ -1072,9 +1053,6 @@ object LocalCache {
|
|||||||
|
|
||||||
note.loadEvent(event, author, emptyList())
|
note.loadEvent(event, author, emptyList())
|
||||||
|
|
||||||
// Adds to user profile
|
|
||||||
author.addNote(note)
|
|
||||||
|
|
||||||
refreshObservers(note)
|
refreshObservers(note)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1254,17 +1232,17 @@ object LocalCache {
|
|||||||
fun pruneHiddenMessages(account: Account) {
|
fun pruneHiddenMessages(account: Account) {
|
||||||
checkNotInMainThread()
|
checkNotInMainThread()
|
||||||
|
|
||||||
val toBeRemoved = account.hiddenUsers.map {
|
val toBeRemoved = account.hiddenUsers.map { userHex ->
|
||||||
(users[it]?.notes ?: emptySet())
|
(
|
||||||
|
notes.values.filter {
|
||||||
|
it.event?.pubKey() == userHex
|
||||||
|
} + addressables.values.filter {
|
||||||
|
it.event?.pubKey() == userHex
|
||||||
|
}
|
||||||
|
).toSet()
|
||||||
}.flatten()
|
}.flatten()
|
||||||
|
|
||||||
account.hiddenUsers.forEach {
|
|
||||||
users[it]?.clearNotes()
|
|
||||||
}
|
|
||||||
|
|
||||||
toBeRemoved.forEach {
|
toBeRemoved.forEach {
|
||||||
it.author?.removeNote(it)
|
|
||||||
|
|
||||||
// Counts the replies
|
// Counts the replies
|
||||||
it.replyTo?.forEach { masterNote ->
|
it.replyTo?.forEach { masterNote ->
|
||||||
masterNote.removeReply(it)
|
masterNote.removeReply(it)
|
||||||
|
|||||||
@@ -32,9 +32,6 @@ class User(val pubkeyHex: String) {
|
|||||||
var latestContactList: ContactListEvent? = null
|
var latestContactList: ContactListEvent? = null
|
||||||
var latestBookmarkList: BookmarkListEvent? = null
|
var latestBookmarkList: BookmarkListEvent? = null
|
||||||
|
|
||||||
var notes = setOf<Note>()
|
|
||||||
private set
|
|
||||||
|
|
||||||
var reports = mapOf<User, Set<Note>>()
|
var reports = mapOf<User, Set<Note>>()
|
||||||
private set
|
private set
|
||||||
|
|
||||||
@@ -105,21 +102,6 @@ class User(val pubkeyHex: String) {
|
|||||||
liveSet?.relays?.invalidateData()
|
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) {
|
fun addReport(note: Note) {
|
||||||
val author = note.author ?: return
|
val author = note.author ?: return
|
||||||
|
|
||||||
|
|||||||
+24
-8
@@ -5,21 +5,37 @@ import com.vitorpamplona.amethyst.model.Note
|
|||||||
import com.vitorpamplona.amethyst.model.User
|
import com.vitorpamplona.amethyst.model.User
|
||||||
import com.vitorpamplona.amethyst.service.model.AppRecommendationEvent
|
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 {
|
override fun feedKey(): String {
|
||||||
return user.pubkeyHex
|
return user.pubkeyHex
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun feed(): List<Note> {
|
override fun feed(): List<Note> {
|
||||||
val recommendations = LocalCache.addressables.values.filter {
|
return sort(innerApplyFilter(LocalCache.addressables.values))
|
||||||
(it.event as? AppRecommendationEvent)?.pubKey == user.pubkeyHex
|
}
|
||||||
}.mapNotNull {
|
|
||||||
(it.event as? AppRecommendationEvent)?.recommendations()
|
override fun applyFilter(collection: Set<Note>): Set<Note> {
|
||||||
}.flatten()
|
return innerApplyFilter(collection)
|
||||||
.map {
|
}
|
||||||
|
|
||||||
|
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)
|
LocalCache.getOrCreateAddressableNote(it)
|
||||||
}.toSet().toList()
|
}.toSet()
|
||||||
|
|
||||||
return recommendations
|
return recommendations
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun sort(collection: Set<Note>): List<Note> {
|
||||||
|
return collection.sortedWith(compareBy({ it.createdAt() }, { it.idHex }))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+30
-5
@@ -1,18 +1,43 @@
|
|||||||
package com.vitorpamplona.amethyst.ui.dal
|
package com.vitorpamplona.amethyst.ui.dal
|
||||||
|
|
||||||
import com.vitorpamplona.amethyst.model.Account
|
import com.vitorpamplona.amethyst.model.Account
|
||||||
|
import com.vitorpamplona.amethyst.model.LocalCache
|
||||||
import com.vitorpamplona.amethyst.model.Note
|
import com.vitorpamplona.amethyst.model.Note
|
||||||
import com.vitorpamplona.amethyst.model.User
|
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 {
|
override fun feedKey(): String {
|
||||||
return account.userProfile().pubkeyHex + "-" + user.pubkeyHex
|
return account.userProfile().pubkeyHex + "-" + user.pubkeyHex
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun feed(): List<Note> {
|
override fun feed(): List<Note> {
|
||||||
return user.notes
|
return sort(innerApplyFilter(LocalCache.notes.values))
|
||||||
.filter { account.isAcceptable(it) == true && !it.isNewThread() }
|
}
|
||||||
.sortedWith(compareBy({ it.createdAt() }, { it.idHex }))
|
|
||||||
.reversed() ?: emptyList()
|
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>() {
|
class UserProfileFollowsFeedFilter(val user: User, val account: Account) : FeedFilter<User>() {
|
||||||
|
|
||||||
override fun feedKey(): String {
|
override fun feedKey(): String {
|
||||||
return account.userProfile()?.pubkeyHex + "-" + user.pubkeyHex
|
return account.userProfile().pubkeyHex + "-" + user.pubkeyHex
|
||||||
}
|
}
|
||||||
|
|
||||||
val cache: MutableMap<ContactListEvent, List<User>> = mutableMapOf()
|
val cache: MutableMap<ContactListEvent, List<User>> = mutableMapOf()
|
||||||
|
|||||||
+36
-17
@@ -4,32 +4,51 @@ import com.vitorpamplona.amethyst.model.Account
|
|||||||
import com.vitorpamplona.amethyst.model.LocalCache
|
import com.vitorpamplona.amethyst.model.LocalCache
|
||||||
import com.vitorpamplona.amethyst.model.Note
|
import com.vitorpamplona.amethyst.model.Note
|
||||||
import com.vitorpamplona.amethyst.model.User
|
import com.vitorpamplona.amethyst.model.User
|
||||||
import com.vitorpamplona.amethyst.service.model.AppRecommendationEvent
|
import com.vitorpamplona.amethyst.service.model.AudioTrackEvent
|
||||||
import com.vitorpamplona.amethyst.service.model.BookmarkListEvent
|
import com.vitorpamplona.amethyst.service.model.ClassifiedsEvent
|
||||||
import com.vitorpamplona.amethyst.service.model.EmojiPackSelectionEvent
|
import com.vitorpamplona.amethyst.service.model.GenericRepostEvent
|
||||||
import com.vitorpamplona.amethyst.service.model.PeopleListEvent
|
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 {
|
override fun feedKey(): String {
|
||||||
return account.userProfile().pubkeyHex + "-" + user.pubkeyHex
|
return account.userProfile().pubkeyHex + "-" + user.pubkeyHex
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun feed(): List<Note> {
|
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 {
|
.filter {
|
||||||
it.author == user &&
|
it.author == user &&
|
||||||
(
|
(
|
||||||
it.event !is PeopleListEvent &&
|
it.event is TextNoteEvent ||
|
||||||
it.event !is BookmarkListEvent &&
|
it.event is ClassifiedsEvent ||
|
||||||
it.event !is AppRecommendationEvent &&
|
it.event is RepostEvent ||
|
||||||
it.event !is EmojiPackSelectionEvent
|
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
|
override fun sort(collection: Set<Note>): List<Note> {
|
||||||
.plus(longFormNotes)
|
return collection.sortedWith(compareBy({ it.createdAt() }, { it.idHex })).reversed()
|
||||||
.filter { account.isAcceptable(it) == true && it.isNewThread() }
|
|
||||||
.sortedWith(compareBy({ it.createdAt() }, { it.idHex }))
|
|
||||||
.reversed() ?: emptyList()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+14
-7
@@ -1,20 +1,27 @@
|
|||||||
package com.vitorpamplona.amethyst.ui.dal
|
package com.vitorpamplona.amethyst.ui.dal
|
||||||
|
|
||||||
import com.vitorpamplona.amethyst.model.LocalCache
|
|
||||||
import com.vitorpamplona.amethyst.model.Note
|
import com.vitorpamplona.amethyst.model.Note
|
||||||
import com.vitorpamplona.amethyst.model.User
|
import com.vitorpamplona.amethyst.model.User
|
||||||
import com.vitorpamplona.amethyst.service.model.ReportEvent
|
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 {
|
override fun feedKey(): String {
|
||||||
return user.pubkeyHex ?: ""
|
return user.pubkeyHex
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun feed(): List<Note> {
|
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
|
override fun applyFilter(collection: Set<Note>): Set<Note> {
|
||||||
.sortedWith(compareBy({ it.createdAt() }, { it.idHex }))
|
return innerApplyFilter(collection)
|
||||||
.reversed()
|
}
|
||||||
|
|
||||||
|
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
|
@Composable
|
||||||
@OptIn(ExperimentalLayoutApi::class)
|
|
||||||
private fun DisplayBadges(
|
private fun DisplayBadges(
|
||||||
baseUser: User,
|
baseUser: User,
|
||||||
nav: (String) -> Unit
|
nav: (String) -> Unit
|
||||||
|
|||||||
Reference in New Issue
Block a user