Add search by group membership.
This commit is contained in:
parent
777a91abc7
commit
a9fc5622cd
4 changed files with 82 additions and 4 deletions
|
@ -300,6 +300,11 @@ public class ContactSelectionListAdapter extends CursorRecyclerViewAdapter<ViewH
|
||||||
|
|
||||||
private @Nullable String getHeaderLetterForDisplayName(@NonNull Cursor cursor) {
|
private @Nullable String getHeaderLetterForDisplayName(@NonNull Cursor cursor) {
|
||||||
String name = CursorUtil.requireString(cursor, ContactRepository.NAME_COLUMN);
|
String name = CursorUtil.requireString(cursor, ContactRepository.NAME_COLUMN);
|
||||||
|
|
||||||
|
if (name == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
Iterator<String> characterIterator = new CharacterIterable(name).iterator();
|
Iterator<String> characterIterator = new CharacterIterable(name).iterator();
|
||||||
|
|
||||||
if (!TextUtils.isEmpty(name) && characterIterator.hasNext()) {
|
if (!TextUtils.isEmpty(name) && characterIterator.hasNext()) {
|
||||||
|
|
|
@ -22,18 +22,26 @@ import android.database.MatrixCursor;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
|
import org.signal.core.util.CursorUtil;
|
||||||
import org.signal.core.util.logging.Log;
|
import org.signal.core.util.logging.Log;
|
||||||
import org.thoughtcrime.securesms.R;
|
import org.thoughtcrime.securesms.R;
|
||||||
import org.thoughtcrime.securesms.database.GroupDatabase;
|
import org.thoughtcrime.securesms.database.GroupDatabase;
|
||||||
|
import org.thoughtcrime.securesms.database.RecipientDatabase;
|
||||||
import org.thoughtcrime.securesms.database.SignalDatabase;
|
import org.thoughtcrime.securesms.database.SignalDatabase;
|
||||||
import org.thoughtcrime.securesms.database.ThreadDatabase;
|
import org.thoughtcrime.securesms.database.ThreadDatabase;
|
||||||
import org.thoughtcrime.securesms.database.model.ThreadRecord;
|
import org.thoughtcrime.securesms.database.model.ThreadRecord;
|
||||||
import org.thoughtcrime.securesms.phonenumbers.NumberUtil;
|
import org.thoughtcrime.securesms.phonenumbers.NumberUtil;
|
||||||
|
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||||
import org.thoughtcrime.securesms.util.FeatureFlags;
|
import org.thoughtcrime.securesms.util.FeatureFlags;
|
||||||
import org.thoughtcrime.securesms.util.UsernameUtil;
|
import org.thoughtcrime.securesms.util.UsernameUtil;
|
||||||
|
import org.whispersystems.signalservice.internal.util.Util;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* CursorLoader that initializes a ContactsDatabase instance
|
* CursorLoader that initializes a ContactsDatabase instance
|
||||||
|
@ -214,12 +222,35 @@ public class ContactsCursorLoader extends AbstractContactsCursorLoader {
|
||||||
|
|
||||||
private Cursor getGroupsCursor() {
|
private Cursor getGroupsCursor() {
|
||||||
MatrixCursor groupContacts = ContactsCursorRows.createMatrixCursor();
|
MatrixCursor groupContacts = ContactsCursorRows.createMatrixCursor();
|
||||||
|
Map<RecipientId, GroupDatabase.GroupRecord> groups = new LinkedHashMap<>();
|
||||||
|
|
||||||
try (GroupDatabase.Reader reader = SignalDatabase.groups().queryGroupsByTitle(getFilter(), flagSet(mode, DisplayMode.FLAG_INACTIVE_GROUPS), hideGroupsV1(mode), !smsEnabled(mode))) {
|
try (GroupDatabase.Reader reader = SignalDatabase.groups().queryGroupsByTitle(getFilter(), flagSet(mode, DisplayMode.FLAG_INACTIVE_GROUPS), hideGroupsV1(mode), !smsEnabled(mode))) {
|
||||||
GroupDatabase.GroupRecord groupRecord;
|
GroupDatabase.GroupRecord groupRecord;
|
||||||
while ((groupRecord = reader.getNext()) != null) {
|
while ((groupRecord = reader.getNext()) != null) {
|
||||||
|
groups.put(groupRecord.getRecipientId(), groupRecord);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getFilter() != null && !Util.isEmpty(getFilter())) {
|
||||||
|
Set<RecipientId> filteredContacts = new HashSet<>();
|
||||||
|
try (Cursor cursor = SignalDatabase.recipients().queryAllContacts(getFilter())) {
|
||||||
|
while (cursor != null && cursor.moveToNext()) {
|
||||||
|
filteredContacts.add(RecipientId.from(CursorUtil.requireString(cursor, RecipientDatabase.ID)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try (GroupDatabase.Reader reader = SignalDatabase.groups().queryGroupsByMembership(filteredContacts, flagSet(mode, DisplayMode.FLAG_INACTIVE_GROUPS), hideGroupsV1(mode), !smsEnabled(mode))) {
|
||||||
|
GroupDatabase.GroupRecord groupRecord;
|
||||||
|
while ((groupRecord = reader.getNext()) != null) {
|
||||||
|
groups.put(groupRecord.getRecipientId(), groupRecord);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (GroupDatabase.GroupRecord groupRecord : groups.values()) {
|
||||||
groupContacts.addRow(ContactsCursorRows.forGroup(groupRecord));
|
groupContacts.addRow(ContactsCursorRows.forGroup(groupRecord));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return groupContacts;
|
return groupContacts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -294,6 +294,40 @@ public class GroupDatabase extends Database {
|
||||||
return new Reader(cursor);
|
return new Reader(cursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Reader queryGroupsByMembership(@NonNull Set<RecipientId> recipientIds, boolean includeInactive, boolean excludeV1, boolean excludeMms) {
|
||||||
|
if (recipientIds.isEmpty()) {
|
||||||
|
return new Reader(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> recipientLikeClauses = recipientIds.stream()
|
||||||
|
.map(RecipientId::toLong)
|
||||||
|
.map(id -> "(" + MEMBERS + " LIKE " + id + " || ',%' OR " + MEMBERS + " LIKE '%,' || " + id + " || ',%' OR " + MEMBERS + " LIKE '%,' || " + id + ")")
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
String query;
|
||||||
|
String[] queryArgs;
|
||||||
|
|
||||||
|
String membershipQuery = "(" + Util.join(recipientLikeClauses, " OR ") + ")";
|
||||||
|
|
||||||
|
if (includeInactive) {
|
||||||
|
query = membershipQuery + " AND (" + ACTIVE + " = ? OR " + RECIPIENT_ID + " IN (SELECT " + ThreadDatabase.RECIPIENT_ID + " FROM " + ThreadDatabase.TABLE_NAME + "))";
|
||||||
|
queryArgs = SqlUtil.buildArgs(1);
|
||||||
|
} else {
|
||||||
|
query = membershipQuery + " AND " + ACTIVE + " = ?";
|
||||||
|
queryArgs = SqlUtil.buildArgs(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (excludeV1) {
|
||||||
|
query += " AND " + EXPECTED_V2_ID + " IS NULL";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (excludeMms) {
|
||||||
|
query += " AND " + MMS + " = 0";
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Reader(getReadableDatabase().query(TABLE_NAME, null, query, queryArgs, null, null, null));
|
||||||
|
}
|
||||||
|
|
||||||
public Reader queryGroupsByRecency(@NonNull GroupQuery groupQuery) {
|
public Reader queryGroupsByRecency(@NonNull GroupQuery groupQuery) {
|
||||||
SqlUtil.Query query = getGroupQueryWhereStatement(groupQuery.searchQuery, groupQuery.includeInactive, !groupQuery.includeV1, !groupQuery.includeMms);
|
SqlUtil.Query query = getGroupQueryWhereStatement(groupQuery.searchQuery, groupQuery.includeInactive, !groupQuery.includeV1, !groupQuery.includeMms);
|
||||||
String sql = "SELECT * FROM " + TABLE_NAME +
|
String sql = "SELECT * FROM " + TABLE_NAME +
|
||||||
|
|
|
@ -10,6 +10,7 @@ import androidx.annotation.Nullable;
|
||||||
|
|
||||||
import com.annimon.stream.Stream;
|
import com.annimon.stream.Stream;
|
||||||
|
|
||||||
|
import org.signal.core.util.CursorUtil;
|
||||||
import org.signal.core.util.concurrent.LatestPrioritizedSerialExecutor;
|
import org.signal.core.util.concurrent.LatestPrioritizedSerialExecutor;
|
||||||
import org.signal.core.util.concurrent.SignalExecutors;
|
import org.signal.core.util.concurrent.SignalExecutors;
|
||||||
import org.signal.core.util.logging.Log;
|
import org.signal.core.util.logging.Log;
|
||||||
|
@ -29,7 +30,6 @@ import org.thoughtcrime.securesms.database.model.ThreadRecord;
|
||||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
||||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||||
import org.signal.core.util.CursorUtil;
|
|
||||||
import org.thoughtcrime.securesms.util.FtsUtil;
|
import org.thoughtcrime.securesms.util.FtsUtil;
|
||||||
import org.thoughtcrime.securesms.util.Util;
|
import org.thoughtcrime.securesms.util.Util;
|
||||||
import org.thoughtcrime.securesms.util.concurrent.SerialExecutor;
|
import org.thoughtcrime.securesms.util.concurrent.SerialExecutor;
|
||||||
|
@ -161,11 +161,13 @@ public class SearchRepository {
|
||||||
|
|
||||||
Set<RecipientId> recipientIds = new LinkedHashSet<>();
|
Set<RecipientId> recipientIds = new LinkedHashSet<>();
|
||||||
|
|
||||||
|
Set<RecipientId> filteredContacts = new LinkedHashSet<>();
|
||||||
try (Cursor cursor = SignalDatabase.recipients().queryAllContacts(query)) {
|
try (Cursor cursor = SignalDatabase.recipients().queryAllContacts(query)) {
|
||||||
while (cursor != null && cursor.moveToNext()) {
|
while (cursor != null && cursor.moveToNext()) {
|
||||||
recipientIds.add(RecipientId.from(CursorUtil.requireString(cursor, RecipientDatabase.ID)));
|
filteredContacts.add(RecipientId.from(CursorUtil.requireString(cursor, RecipientDatabase.ID)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
recipientIds.addAll(filteredContacts);
|
||||||
|
|
||||||
GroupDatabase.GroupRecord record;
|
GroupDatabase.GroupRecord record;
|
||||||
try (GroupDatabase.Reader reader = SignalDatabase.groups().queryGroupsByTitle(query, true, false, false)) {
|
try (GroupDatabase.Reader reader = SignalDatabase.groups().queryGroupsByTitle(query, true, false, false)) {
|
||||||
|
@ -174,6 +176,12 @@ public class SearchRepository {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try (GroupDatabase.Reader reader = SignalDatabase.groups().queryGroupsByMembership(filteredContacts, true, false, false)) {
|
||||||
|
while ((record = reader.getNext()) != null) {
|
||||||
|
recipientIds.add(record.getRecipientId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (noteToSelfTitle.toLowerCase().contains(query.toLowerCase())) {
|
if (noteToSelfTitle.toLowerCase().contains(query.toLowerCase())) {
|
||||||
recipientIds.add(Recipient.self().getId());
|
recipientIds.add(Recipient.self().getId());
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue