SES-2237 Fix search sorting

This commit is contained in:
Andrew 2024-06-26 22:37:22 +09:30
parent 84efcd2f21
commit a52bafbf98
2 changed files with 34 additions and 13 deletions

View File

@ -138,8 +138,7 @@ class HomeActivity : PassphraseRequiredActionBarActivity(),
private val globalSearchViewModel by viewModels<GlobalSearchViewModel>()
private val homeViewModel by viewModels<HomeViewModel>()
private val publicKey: String
get() = textSecurePreferences.getLocalNumber()!!
private val publicKey: String by lazy { textSecurePreferences.getLocalNumber()!! }
private val homeAdapter: HomeAdapter by lazy {
HomeAdapter(context = this, configFactory = configFactory, listener = this, ::showMessageRequests, ::hideMessageRequests)
@ -289,12 +288,35 @@ class HomeActivity : PassphraseRequiredActionBarActivity(),
launch {
globalSearchViewModel.result.collect { result ->
if (result.query.isEmpty()) {
val hasNames = result.contacts.filter { it.nickname != null || it.name != null }
.groupByNotNull { (it.nickname?.firstOrNull() ?: it.name?.firstOrNull())?.uppercase() }
.toSortedMap(compareBy { it })
.flatMap { (key, contacts) -> listOf(GlobalSearchAdapter.Model.SubHeader(key)) + contacts.sortedBy { it.nickname ?: it.name }.map(GlobalSearchAdapter.Model::Contact) }
class NamedValue<T>(val name: String, val value: T)
val noNames = result.contacts.filter { it.nickname == null && it.name == null }
val hasNames = result.contacts
// Remove ourself, we're shown above.
.filter { it.accountID != publicKey }
// Get the name that we will display and sort by, and uppercase it to
// help with sorting and we need the char uppercased later.
.mapNotNull { (it.nickname?.takeIf { it.isNotEmpty() } ?: it.name?.takeIf { it.isNotEmpty() })
?.let { name -> NamedValue(name.uppercase(), it) } }
// Digits are all grouped under a #, the rest are grouped by their first character.uppercased()
.groupBy { (it.name.first().takeUnless(Char::isDigit) ?: '#') }
// place the # at the end, after all the names starting with alphabetic chars
.toSortedMap(compareBy {
when (it) {
'#' -> Char.MAX_VALUE - 1
else -> it
}
})
// Flatten the map of char to lists into an actual List that can be displayed.
.flatMap { (key, contacts) ->
listOf(
GlobalSearchAdapter.Model.SubHeader(key.toString())
) + contacts.sortedBy { it.name }.map { it.value }.map(GlobalSearchAdapter.Model::Contact)
}
// Similarly we want to display
val noNames = result.contacts
.filter { it.accountID != publicKey }
.filter { it.nickname.isNullOrEmpty() && it.name.isNullOrEmpty() }
.sortedBy { it.accountID }
.map { GlobalSearchAdapter.Model.Contact(it) }

View File

@ -10,6 +10,7 @@ import network.loki.messenger.R
import org.session.libsession.messaging.contacts.Contact
import org.session.libsession.utilities.Address
import org.session.libsession.utilities.recipients.Recipient
import org.session.libsession.utilities.truncateIdForDisplay
import org.thoughtcrime.securesms.home.search.GlobalSearchAdapter.ContentView
import org.thoughtcrime.securesms.home.search.GlobalSearchAdapter.Model.GroupConversation
import org.thoughtcrime.securesms.home.search.GlobalSearchAdapter.Model.Header
@ -100,8 +101,7 @@ fun ContentView.bindModel(query: String?, model: GroupConversation) {
val groupRecipients = model.groupRecord.members.map { Recipient.from(binding.root.context, it, false) }
val membersString = groupRecipients.joinToString {
val address = it.address.serialize()
it.name ?: "${address.take(4)}...${address.takeLast(4)}"
it.name ?: truncateIdForDisplay(it.address.serialize())
}
if (model.groupRecord.isClosedGroup) {
binding.searchResultSubtitle.text = getHighlight(query, membersString)
@ -153,8 +153,7 @@ fun ContentView.bindModel(query: String?, model: Message) {
binding.searchResultSubtitle.isVisible = true
}
fun Recipient.getSearchName(): String = name ?: address.serialize().let { address -> "${address.take(4)}...${address.takeLast(4)}" }
fun Recipient.getSearchName(): String = name ?: address.serialize().let(::truncateIdForDisplay)
fun Contact.getSearchName(): String =
if (nickname.isNullOrEmpty()) name ?: "${accountID.take(4)}...${accountID.takeLast(4)}"
else "${name ?: "${accountID.take(4)}...${accountID.takeLast(4)}"} ($nickname)"
fun Contact.getSearchName(): String = nickname?.takeIf { it.isNotEmpty() }
?: name?.takeIf { it.isNotEmpty() } ?: truncateIdForDisplay(accountID)