Merge pull request #1032 from session-foundation/search-result-list-optimisation

[SES-3536] - Fix flashes on search result list
pull/1712/head
SessionHero01 2 weeks ago committed by GitHub
commit a312b901b2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -45,6 +45,7 @@ import org.session.libsession.utilities.StringSubstitutionConstants.GROUP_NAME_K
import org.session.libsession.utilities.StringSubstitutionConstants.NAME_KEY
import org.session.libsession.utilities.TextSecurePreferences
import org.session.libsession.utilities.recipients.Recipient
import org.session.libsignal.utilities.AccountId
import org.session.libsignal.utilities.Log
import org.thoughtcrime.securesms.ApplicationContext
import org.thoughtcrime.securesms.ScreenLockActionBarActivity
@ -67,6 +68,7 @@ import org.thoughtcrime.securesms.home.search.GlobalSearchAdapter
import org.thoughtcrime.securesms.home.search.GlobalSearchInputLayout
import org.thoughtcrime.securesms.home.search.GlobalSearchResult
import org.thoughtcrime.securesms.home.search.GlobalSearchViewModel
import org.thoughtcrime.securesms.home.search.getSearchName
import org.thoughtcrime.securesms.messagerequests.MessageRequestsActivity
import org.thoughtcrime.securesms.permissions.Permissions
import org.thoughtcrime.securesms.preferences.SettingsActivity
@ -135,11 +137,11 @@ class HomeActivity : ScreenLockActionBarActivity(),
is GlobalSearchAdapter.Model.Contact -> push<ConversationActivityV2> {
putExtra(
ConversationActivityV2.ADDRESS,
model.contact.accountID.let(Address::fromSerialized)
model.contact.hexString.let(Address::fromSerialized)
)
}
is GlobalSearchAdapter.Model.GroupConversation -> model.groupRecord.encodedId
is GlobalSearchAdapter.Model.GroupConversation -> model.groupId
.let { Recipient.from(this, Address.fromSerialized(it), false) }
.let(threadDb::getThreadIdIfExistsFor)
.takeIf { it >= 0 }
@ -352,13 +354,15 @@ class HomeActivity : ScreenLockActionBarActivity(),
.flatMap { (key, contacts) ->
listOf(
GlobalSearchAdapter.Model.SubHeader(key)
) + contacts.sortedBy { it.name ?: it.value.accountID }.map { it.value }.map { GlobalSearchAdapter.Model.Contact(it, it.nickname ?: it.name, it.accountID == publicKey) }
) + contacts.sortedBy { it.name ?: it.value.accountID }.map { it.value }.map { GlobalSearchAdapter.Model.Contact(it, it.accountID == publicKey) }
}
}
private val GlobalSearchResult.contactAndGroupList: List<GlobalSearchAdapter.Model> get() =
contacts.map { GlobalSearchAdapter.Model.Contact(it, it.nickname ?: it.name, it.accountID == publicKey) } +
threads.map(GlobalSearchAdapter.Model::GroupConversation)
contacts.map { GlobalSearchAdapter.Model.Contact(it, it.accountID == publicKey) } +
threads.map {
GlobalSearchAdapter.Model.GroupConversation(this@HomeActivity, it)
}
private val GlobalSearchResult.messageResults: List<GlobalSearchAdapter.Model> get() {
val unreadThreadMap = messages

@ -1,5 +1,6 @@
package org.thoughtcrime.securesms.home.search
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
@ -10,11 +11,13 @@ import network.loki.messenger.R
import network.loki.messenger.databinding.ViewGlobalSearchHeaderBinding
import network.loki.messenger.databinding.ViewGlobalSearchResultBinding
import network.loki.messenger.databinding.ViewGlobalSearchSubheaderBinding
import org.session.libsession.messaging.contacts.Contact
import org.session.libsession.utilities.GroupRecord
import org.session.libsession.utilities.recipients.Recipient
import org.session.libsignal.utilities.AccountId
import org.thoughtcrime.securesms.search.model.MessageResult
import org.thoughtcrime.securesms.ui.GetString
import java.security.InvalidParameterException
import org.session.libsession.messaging.contacts.Contact as ContactModel
class GlobalSearchAdapter(private val modelCallback: (Model)->Unit): RecyclerView.Adapter<RecyclerView.ViewHolder>() {
@ -125,18 +128,39 @@ class GlobalSearchAdapter(private val modelCallback: (Model)->Unit): RecyclerVie
}
}
sealed class Model {
data class Header(val title: GetString): Model() {
sealed interface Model {
data class Header(val title: GetString): Model {
constructor(@StringRes title: Int): this(GetString(title))
constructor(title: String): this(GetString(title))
}
data class SubHeader(val title: GetString): Model() {
data class SubHeader(val title: GetString): Model {
constructor(@StringRes title: Int): this(GetString(title))
constructor(title: String): this(GetString(title))
}
data class SavedMessages(val currentUserPublicKey: String): Model()
data class Contact(val contact: ContactModel, val name: String?, val isSelf: Boolean) : Model()
data class GroupConversation(val groupRecord: GroupRecord) : Model()
data class Message(val messageResult: MessageResult, val unread: Int, val isSelf: Boolean) : Model()
data class SavedMessages(val currentUserPublicKey: String): Model
data class Contact(val contact: AccountId, val name: String, val isSelf: Boolean) : Model {
constructor(contact: org.session.libsession.messaging.contacts.Contact, isSelf: Boolean):
this(AccountId(contact.accountID), contact.getSearchName(), isSelf)
}
data class GroupConversation(
val isLegacy: Boolean,
val groupId: String,
val title: String,
val legacyMembersString: String?,
) : Model {
constructor(context: Context, groupRecord: GroupRecord):
this(
isLegacy = groupRecord.isLegacyGroup,
groupId = groupRecord.encodedId,
title = groupRecord.title,
legacyMembersString = if (groupRecord.isLegacyGroup) {
val recipients = groupRecord.members.map { Recipient.from(context, it, false) }
recipients.joinToString(transform = Recipient::getSearchName)
} else {
null
}
)
}
data class Message(val messageResult: MessageResult, val unread: Int, val isSelf: Boolean) : Model
}
}

@ -48,7 +48,7 @@ fun ContentView.bindQuery(query: String, model: GlobalSearchAdapter.Model) {
is ContactModel -> {
binding.searchResultTitle.text = getHighlight(
query,
model.contact.getSearchName()
model.name
)
}
is Message -> {
@ -69,13 +69,10 @@ fun ContentView.bindQuery(query: String, model: GlobalSearchAdapter.Model) {
is GroupConversation -> {
binding.searchResultTitle.text = getHighlight(
query,
model.groupRecord.title
model.title
)
val membersString = model.groupRecord.members.joinToString { address ->
Recipient.from(binding.root.context, address, false).getSearchName()
}
binding.searchResultSubtitle.text = getHighlight(query, membersString)
binding.searchResultSubtitle.text = getHighlight(query, model.legacyMembersString.orEmpty())
}
is Header, // do nothing for header
is SubHeader, // do nothing for subheader
@ -89,18 +86,15 @@ private fun getHighlight(query: String?, toSearch: String): Spannable? {
fun ContentView.bindModel(query: String?, model: GroupConversation) {
binding.searchResultProfilePicture.isVisible = true
binding.searchResultSubtitle.isVisible = model.groupRecord.isLegacyGroup
binding.searchResultSubtitle.isVisible = model.isLegacy
binding.searchResultTimestamp.isVisible = false
val threadRecipient = Recipient.from(binding.root.context, Address.fromSerialized(model.groupRecord.encodedId), false)
val threadRecipient = Recipient.from(binding.root.context, Address.fromSerialized(model.groupId), false)
binding.searchResultProfilePicture.update(threadRecipient)
val nameString = model.groupRecord.title
val nameString = model.title
binding.searchResultTitle.text = getHighlight(query, nameString)
val groupRecipients = model.groupRecord.members.map { Recipient.from(binding.root.context, it, false) }
val membersString = groupRecipients.joinToString(transform = Recipient::getSearchName)
if (model.groupRecord.isLegacyGroup) {
binding.searchResultSubtitle.text = getHighlight(query, membersString)
if (model.legacyMembersString != null) {
binding.searchResultSubtitle.text = getHighlight(query, model.legacyMembersString)
}
}
@ -109,10 +103,10 @@ fun ContentView.bindModel(query: String?, model: ContactModel) = binding.run {
searchResultSubtitle.isVisible = false
searchResultTimestamp.isVisible = false
searchResultSubtitle.text = null
val recipient = Recipient.from(root.context, Address.fromSerialized(model.contact.accountID), false)
val recipient = Recipient.from(root.context, Address.fromSerialized(model.contact.hexString), false)
searchResultProfilePicture.update(recipient)
val nameString = if (model.isSelf) root.context.getString(R.string.noteToSelf)
else model.contact.getSearchName()
else model.name
searchResultTitle.text = getHighlight(query, nameString)
}

@ -4,6 +4,8 @@ import androidx.annotation.NonNull;
import org.session.libsession.utilities.recipients.Recipient;
import java.util.Objects;
/**
* Represents a search result for a message.
*/
@ -27,4 +29,15 @@ public class MessageResult {
this.threadId = threadId;
this.sentTimestampMs = sentTimestampMs;
}
@Override
public boolean equals(Object o) {
if (!(o instanceof MessageResult that)) return false;
return threadId == that.threadId && sentTimestampMs == that.sentTimestampMs && Objects.equals(conversationRecipient, that.conversationRecipient) && Objects.equals(messageRecipient, that.messageRecipient) && Objects.equals(bodySnippet, that.bodySnippet);
}
@Override
public int hashCode() {
return Objects.hash(conversationRecipient, messageRecipient, bodySnippet, threadId, sentTimestampMs);
}
}

Loading…
Cancel
Save