mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-02-28 21:57:17 +00:00
Add Recency support for contact search ordering.
This commit is contained in:
@@ -919,7 +919,8 @@ public final class ContactSelectionListFragment extends LoggingFragment {
|
||||
transportType,
|
||||
!hideHeader,
|
||||
null,
|
||||
!hideLetterHeaders()
|
||||
!hideLetterHeaders(),
|
||||
newConversationCallback != null ? ContactSearchSortOrder.RECENCY : ContactSearchSortOrder.NATURAL
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ import androidx.annotation.NonNull;
|
||||
import androidx.annotation.WorkerThread;
|
||||
|
||||
import org.signal.libsignal.protocol.util.Pair;
|
||||
import org.thoughtcrime.securesms.contacts.paged.ContactSearchSortOrder;
|
||||
import org.thoughtcrime.securesms.database.RecipientTable;
|
||||
import org.thoughtcrime.securesms.database.SignalDatabase;
|
||||
import org.thoughtcrime.securesms.phonenumbers.PhoneNumberFormatter;
|
||||
@@ -108,15 +109,15 @@ public class ContactRepository {
|
||||
|
||||
@WorkerThread
|
||||
public @NonNull Cursor querySignalContacts(@NonNull String query) {
|
||||
return querySignalContacts(query, true);
|
||||
return querySignalContacts(new RecipientTable.ContactSearchQuery(query, true, ContactSearchSortOrder.NATURAL));
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
public @NonNull Cursor querySignalContacts(@NonNull String query, boolean includeSelf) {
|
||||
Cursor cursor = TextUtils.isEmpty(query) ? recipientTable.getSignalContacts(includeSelf)
|
||||
: recipientTable.querySignalContacts(query, includeSelf);
|
||||
public @NonNull Cursor querySignalContacts(@NonNull RecipientTable.ContactSearchQuery contactSearchQuery) {
|
||||
Cursor cursor = TextUtils.isEmpty(contactSearchQuery.getQuery()) ? recipientTable.getSignalContacts(contactSearchQuery.getIncludeSelf())
|
||||
: recipientTable.querySignalContacts(contactSearchQuery);
|
||||
|
||||
cursor = handleNoteToSelfQuery(query, includeSelf, cursor);
|
||||
cursor = handleNoteToSelfQuery(contactSearchQuery.getQuery(), contactSearchQuery.getIncludeSelf(), cursor);
|
||||
|
||||
return new SearchCursorWrapper(cursor, SEARCH_CURSOR_MAPPERS);
|
||||
}
|
||||
|
||||
@@ -69,6 +69,8 @@ class ContactSearchConfiguration private constructor(
|
||||
/**
|
||||
* 1:1 Recipients with whom the user has started a conversation.
|
||||
*
|
||||
* Note that sort order is only respected when returning a query result for signal-only contacts. In all other cases, natural ordering is used.
|
||||
*
|
||||
* Key: [ContactSearchKey.RecipientSearchKey]
|
||||
* Data: [ContactSearchData.KnownRecipient]
|
||||
* Model: [ContactSearchAdapter.RecipientModel]
|
||||
@@ -78,7 +80,8 @@ class ContactSearchConfiguration private constructor(
|
||||
val transportType: TransportType,
|
||||
override val includeHeader: Boolean,
|
||||
override val expandConfig: ExpandConfig? = null,
|
||||
val includeLetterHeaders: Boolean = false
|
||||
val includeLetterHeaders: Boolean = false,
|
||||
val pushSearchResultsSortOrder: ContactSearchSortOrder = ContactSearchSortOrder.NATURAL
|
||||
) : Section(SectionKey.INDIVIDUALS)
|
||||
|
||||
/**
|
||||
|
||||
@@ -9,6 +9,7 @@ import org.thoughtcrime.securesms.contacts.paged.collections.ContactSearchIterat
|
||||
import org.thoughtcrime.securesms.contacts.paged.collections.CursorSearchIterator
|
||||
import org.thoughtcrime.securesms.contacts.paged.collections.StoriesSearchCollection
|
||||
import org.thoughtcrime.securesms.database.GroupTable
|
||||
import org.thoughtcrime.securesms.database.RecipientTable
|
||||
import org.thoughtcrime.securesms.database.model.DistributionListPrivacyMode
|
||||
import org.thoughtcrime.securesms.database.model.GroupRecord
|
||||
import org.thoughtcrime.securesms.database.model.ThreadRecord
|
||||
@@ -210,7 +211,10 @@ class ContactSearchPagedDataSource(
|
||||
|
||||
private fun getNonGroupSearchIterator(section: ContactSearchConfiguration.Section.Individuals, query: String?): ContactSearchIterator<Cursor> {
|
||||
return when (section.transportType) {
|
||||
ContactSearchConfiguration.TransportType.PUSH -> CursorSearchIterator(wrapRecipientCursor(contactSearchPagedDataSourceRepository.querySignalContacts(query, section.includeSelf)))
|
||||
ContactSearchConfiguration.TransportType.PUSH -> {
|
||||
val searchQuery = RecipientTable.ContactSearchQuery(query ?: "", section.includeSelf, section.pushSearchResultsSortOrder)
|
||||
CursorSearchIterator(wrapRecipientCursor(contactSearchPagedDataSourceRepository.querySignalContacts(searchQuery)))
|
||||
}
|
||||
ContactSearchConfiguration.TransportType.SMS -> CursorSearchIterator(wrapRecipientCursor(contactSearchPagedDataSourceRepository.queryNonSignalContacts(query)))
|
||||
ContactSearchConfiguration.TransportType.ALL -> CursorSearchIterator(wrapRecipientCursor(contactSearchPagedDataSourceRepository.queryNonGroupContacts(query, section.includeSelf)))
|
||||
}
|
||||
|
||||
@@ -34,8 +34,8 @@ open class ContactSearchPagedDataSourceRepository(
|
||||
.getLatestActiveStorySendTimestamps(System.currentTimeMillis() - activeStoryCutoffDuration)
|
||||
}
|
||||
|
||||
open fun querySignalContacts(query: String?, includeSelf: Boolean): Cursor? {
|
||||
return contactRepository.querySignalContacts(query ?: "", includeSelf)
|
||||
open fun querySignalContacts(contactsSearchQuery: RecipientTable.ContactSearchQuery): Cursor? {
|
||||
return contactRepository.querySignalContacts(contactsSearchQuery)
|
||||
}
|
||||
|
||||
open fun querySignalContactLetterHeaders(query: String?, includeSelf: Boolean, includePush: Boolean, includeSms: Boolean): Map<RecipientId, String> {
|
||||
|
||||
@@ -46,6 +46,7 @@ import org.thoughtcrime.securesms.badges.Badges.toDatabaseBadge
|
||||
import org.thoughtcrime.securesms.badges.models.Badge
|
||||
import org.thoughtcrime.securesms.color.MaterialColor
|
||||
import org.thoughtcrime.securesms.color.MaterialColor.UnknownColorException
|
||||
import org.thoughtcrime.securesms.contacts.paged.ContactSearchSortOrder
|
||||
import org.thoughtcrime.securesms.conversation.colors.AvatarColor
|
||||
import org.thoughtcrime.securesms.conversation.colors.AvatarColorHash
|
||||
import org.thoughtcrime.securesms.conversation.colors.ChatColors
|
||||
@@ -3238,7 +3239,7 @@ open class RecipientTable(context: Context, databaseHelper: SignalDatabase) : Da
|
||||
return getSignalContacts(includeSelf)?.count ?: 0
|
||||
}
|
||||
|
||||
fun getSignalContacts(includeSelf: Boolean, orderBy: String? = null): Cursor? {
|
||||
private fun getSignalContacts(includeSelf: Boolean, orderBy: String? = null): Cursor? {
|
||||
val searchSelection = ContactSearchSelection.Builder()
|
||||
.withRegistered(true)
|
||||
.withGroups(false)
|
||||
@@ -3249,20 +3250,39 @@ open class RecipientTable(context: Context, databaseHelper: SignalDatabase) : Da
|
||||
return readableDatabase.query(TABLE_NAME, SEARCH_PROJECTION, selection, args, null, null, orderBy)
|
||||
}
|
||||
|
||||
fun querySignalContacts(inputQuery: String, includeSelf: Boolean): Cursor? {
|
||||
val query = SqlUtil.buildCaseInsensitiveGlobPattern(inputQuery)
|
||||
fun querySignalContacts(contactSearchQuery: ContactSearchQuery): Cursor? {
|
||||
val query = SqlUtil.buildCaseInsensitiveGlobPattern(contactSearchQuery.query)
|
||||
|
||||
val searchSelection = ContactSearchSelection.Builder()
|
||||
.withRegistered(true)
|
||||
.withGroups(false)
|
||||
.excludeId(if (includeSelf) null else Recipient.self().id)
|
||||
.excludeId(if (contactSearchQuery.includeSelf) null else Recipient.self().id)
|
||||
.withSearchQuery(query)
|
||||
.build()
|
||||
val selection = searchSelection.where
|
||||
val args = searchSelection.args
|
||||
val orderBy = "$SORT_NAME, $SYSTEM_JOINED_NAME, $SEARCH_PROFILE_NAME, $E164"
|
||||
val orderBy = "${if (contactSearchQuery.contactSearchSortOrder == ContactSearchSortOrder.RECENCY) "${ThreadTable.TABLE_NAME}.${ThreadTable.DATE} DESC, " else ""}$SORT_NAME, $SYSTEM_JOINED_NAME, $SEARCH_PROFILE_NAME, $E164"
|
||||
|
||||
return readableDatabase.query(TABLE_NAME, SEARCH_PROJECTION, selection, args, null, null, orderBy)
|
||||
return if (contactSearchQuery.contactSearchSortOrder == ContactSearchSortOrder.RECENCY) {
|
||||
val ambiguous = listOf(ID)
|
||||
val projection = SEARCH_PROJECTION.map {
|
||||
if (it in ambiguous) "$TABLE_NAME.$it" else it
|
||||
} + "${ThreadTable.TABLE_NAME}.${ThreadTable.DATE}"
|
||||
|
||||
//language=roomsql
|
||||
readableDatabase.query(
|
||||
"""
|
||||
SELECT ${projection.joinToString(",")}
|
||||
FROM $TABLE_NAME
|
||||
JOIN ${ThreadTable.TABLE_NAME} ON ${ThreadTable.TABLE_NAME}.${ThreadTable.RECIPIENT_ID} = $TABLE_NAME.$ID
|
||||
WHERE $selection
|
||||
ORDER BY $orderBy
|
||||
""".trimIndent(),
|
||||
args
|
||||
)
|
||||
} else {
|
||||
readableDatabase.query(TABLE_NAME, SEARCH_PROJECTION, selection, args, null, null, orderBy)
|
||||
}
|
||||
}
|
||||
|
||||
fun querySignalContactLetterHeaders(inputQuery: String, includeSelf: Boolean, includePush: Boolean, includeSms: Boolean): Map<RecipientId, String> {
|
||||
@@ -4337,6 +4357,12 @@ open class RecipientTable(context: Context, databaseHelper: SignalDatabase) : Da
|
||||
|
||||
private class GetOrInsertResult(val recipientId: RecipientId, val neededInsert: Boolean)
|
||||
|
||||
data class ContactSearchQuery(
|
||||
val query: String,
|
||||
val includeSelf: Boolean,
|
||||
val contactSearchSortOrder: ContactSearchSortOrder = ContactSearchSortOrder.NATURAL
|
||||
)
|
||||
|
||||
@VisibleForTesting
|
||||
internal class ContactSearchSelection private constructor(val where: String, val args: Array<String>) {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user