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) {
|
||||
String name = CursorUtil.requireString(cursor, ContactRepository.NAME_COLUMN);
|
||||
|
||||
if (name == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Iterator<String> characterIterator = new CharacterIterable(name).iterator();
|
||||
|
||||
if (!TextUtils.isEmpty(name) && characterIterator.hasNext()) {
|
||||
|
|
|
@ -22,18 +22,26 @@ import android.database.MatrixCursor;
|
|||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import org.signal.core.util.CursorUtil;
|
||||
import org.signal.core.util.logging.Log;
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.database.GroupDatabase;
|
||||
import org.thoughtcrime.securesms.database.RecipientDatabase;
|
||||
import org.thoughtcrime.securesms.database.SignalDatabase;
|
||||
import org.thoughtcrime.securesms.database.ThreadDatabase;
|
||||
import org.thoughtcrime.securesms.database.model.ThreadRecord;
|
||||
import org.thoughtcrime.securesms.phonenumbers.NumberUtil;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.thoughtcrime.securesms.util.FeatureFlags;
|
||||
import org.thoughtcrime.securesms.util.UsernameUtil;
|
||||
import org.whispersystems.signalservice.internal.util.Util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* CursorLoader that initializes a ContactsDatabase instance
|
||||
|
@ -213,13 +221,36 @@ public class ContactsCursorLoader extends AbstractContactsCursorLoader {
|
|||
}
|
||||
|
||||
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))) {
|
||||
GroupDatabase.GroupRecord groupRecord;
|
||||
while ((groupRecord = reader.getNext()) != null) {
|
||||
groupContacts.addRow(ContactsCursorRows.forGroup(groupRecord));
|
||||
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));
|
||||
}
|
||||
|
||||
return groupContacts;
|
||||
}
|
||||
|
||||
|
|
|
@ -294,6 +294,40 @@ public class GroupDatabase extends Database {
|
|||
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) {
|
||||
SqlUtil.Query query = getGroupQueryWhereStatement(groupQuery.searchQuery, groupQuery.includeInactive, !groupQuery.includeV1, !groupQuery.includeMms);
|
||||
String sql = "SELECT * FROM " + TABLE_NAME +
|
||||
|
|
|
@ -10,6 +10,7 @@ import androidx.annotation.Nullable;
|
|||
|
||||
import com.annimon.stream.Stream;
|
||||
|
||||
import org.signal.core.util.CursorUtil;
|
||||
import org.signal.core.util.concurrent.LatestPrioritizedSerialExecutor;
|
||||
import org.signal.core.util.concurrent.SignalExecutors;
|
||||
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.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.signal.core.util.CursorUtil;
|
||||
import org.thoughtcrime.securesms.util.FtsUtil;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
import org.thoughtcrime.securesms.util.concurrent.SerialExecutor;
|
||||
|
@ -161,11 +161,13 @@ public class SearchRepository {
|
|||
|
||||
Set<RecipientId> recipientIds = new LinkedHashSet<>();
|
||||
|
||||
Set<RecipientId> filteredContacts = new LinkedHashSet<>();
|
||||
try (Cursor cursor = SignalDatabase.recipients().queryAllContacts(query)) {
|
||||
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;
|
||||
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())) {
|
||||
recipientIds.add(Recipient.self().getId());
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue