Keeps Note level in a thread cached for ordering notes.

This commit is contained in:
Vitor Pamplona 2023-02-18 19:13:43 -05:00
parent 53a14d3a77
commit de2ec503da
3 changed files with 13 additions and 7 deletions

View File

@ -73,25 +73,30 @@ class Note(val idHex: String) {
.format(DateTimeFormatter.ofPattern("uuuu-MM-dd-HH:mm:ss"))
}
fun replyLevelSignature(): String {
/**
* This method caches signatures during each execution to avoid recalculation in longer threads
*/
fun replyLevelSignature(cachedSignatures: MutableMap<Note, String> = mutableMapOf()): String {
val replyTo = replyTo
if (replyTo == null || replyTo.isEmpty()) {
return "/" + formattedDateTime(event?.createdAt ?: 0) + ";"
}
return replyTo
.map { it.replyLevelSignature() }
.map {
cachedSignatures[it] ?: it.replyLevelSignature(cachedSignatures).apply { cachedSignatures.put(it, this) }
}
.maxBy { it.length }.removeSuffix(";") + "/" + formattedDateTime(event?.createdAt ?: 0) + ";"
}
fun replyLevel(): Int {
fun replyLevel(cachedLevels: MutableMap<Note, Int> = mutableMapOf()): Int {
val replyTo = replyTo
if (replyTo == null || replyTo.isEmpty()) {
return 0
}
return replyTo.maxOf {
it.replyLevel()
cachedLevels[it] ?: it.replyLevel(cachedLevels).apply { cachedLevels.put(it, this) }
} + 1
}

View File

@ -9,9 +9,10 @@ object ThreadFeedFilter: FeedFilter<Note>() {
var noteId: String? = null
override fun feed(): List<Note> {
val cachedSignatures: MutableMap<Note, String> = mutableMapOf()
val eventsToWatch = noteId?.let { ThreadAssembler().findThreadFor(it) } ?: emptySet()
// Currently orders by date of each event, descending, at each level of the reply stack
val order = compareByDescending<Note> { it.replyLevelSignature() }
val order = compareByDescending<Note> { it.replyLevelSignature(cachedSignatures) }
return eventsToWatch.sortedWith(order)
}

View File

@ -26,11 +26,11 @@ fun ThreadScreen(noteId: String?, accountViewModel: AccountViewModel, navControl
val lifeCycleOwner = LocalLifecycleOwner.current
if (account != null && noteId != null) {
ThreadFeedFilter.loadThread(noteId)
NostrThreadDataSource.loadThread(noteId)
val feedViewModel: NostrThreadFeedViewModel = viewModel()
LaunchedEffect(Unit) {
ThreadFeedFilter.loadThread(noteId)
NostrThreadDataSource.loadThread(noteId)
feedViewModel.invalidateData()
}