mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-22 09:49:30 +01:00
Add mention detection to search flows.
This commit is contained in:
@@ -6,6 +6,9 @@ import android.database.Cursor;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.annimon.stream.Stream;
|
||||
|
||||
import net.sqlcipher.database.SQLiteDatabase;
|
||||
|
||||
@@ -15,7 +18,6 @@ import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.thoughtcrime.securesms.util.CursorUtil;
|
||||
import org.thoughtcrime.securesms.util.SqlUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
@@ -86,27 +88,58 @@ public class MentionDatabase extends Database {
|
||||
}
|
||||
|
||||
public @NonNull Map<Long, List<Mention>> getMentionsForMessages(@NonNull Collection<Long> messageIds) {
|
||||
SQLiteDatabase db = databaseHelper.getReadableDatabase();
|
||||
Map<Long, List<Mention>> mentions = new HashMap<>();
|
||||
|
||||
String ids = TextUtils.join(",", messageIds);
|
||||
SQLiteDatabase db = databaseHelper.getReadableDatabase();
|
||||
String ids = TextUtils.join(",", messageIds);
|
||||
|
||||
try (Cursor cursor = db.query(TABLE_NAME, null, MESSAGE_ID + " IN (" + ids + ")", null, null, null, null)) {
|
||||
while (cursor != null && cursor.moveToNext()) {
|
||||
long messageId = CursorUtil.requireLong(cursor, MESSAGE_ID);
|
||||
List<Mention> messageMentions = mentions.get(messageId);
|
||||
return readMentions(cursor);
|
||||
}
|
||||
}
|
||||
|
||||
if (messageMentions == null) {
|
||||
messageMentions = new LinkedList<>();
|
||||
mentions.put(messageId, messageMentions);
|
||||
}
|
||||
public @NonNull Map<Long, List<Mention>> getMentionsContainingRecipients(@NonNull Collection<RecipientId> recipientIds, long limit) {
|
||||
return getMentionsContainingRecipients(recipientIds, -1, limit);
|
||||
}
|
||||
|
||||
messageMentions.add(new Mention(RecipientId.from(CursorUtil.requireLong(cursor, RECIPIENT_ID)),
|
||||
CursorUtil.requireInt(cursor, RANGE_START),
|
||||
CursorUtil.requireInt(cursor, RANGE_LENGTH)));
|
||||
}
|
||||
public @NonNull Map<Long, List<Mention>> getMentionsContainingRecipients(@NonNull Collection<RecipientId> recipientIds, long threadId, long limit) {
|
||||
SQLiteDatabase db = databaseHelper.getReadableDatabase();
|
||||
String ids = TextUtils.join(",", Stream.of(recipientIds).map(RecipientId::serialize).toList());
|
||||
|
||||
String where = " WHERE " + RECIPIENT_ID + " IN (" + ids + ")";
|
||||
if (threadId != -1) {
|
||||
where += " AND " + THREAD_ID + " = " + threadId;
|
||||
}
|
||||
|
||||
String subSelect = "SELECT DISTINCT " + MESSAGE_ID +
|
||||
" FROM " + TABLE_NAME +
|
||||
where +
|
||||
" ORDER BY " + ID + " DESC" +
|
||||
" LIMIT " + limit;
|
||||
|
||||
String query = "SELECT *" +
|
||||
" FROM " + TABLE_NAME +
|
||||
" WHERE " + MESSAGE_ID +
|
||||
" IN (" + subSelect + ")";
|
||||
|
||||
try (Cursor cursor = db.rawQuery(query, null)) {
|
||||
return readMentions(cursor);
|
||||
}
|
||||
}
|
||||
|
||||
private @NonNull Map<Long, List<Mention>> readMentions(@Nullable Cursor cursor) {
|
||||
Map<Long, List<Mention>> mentions = new HashMap<>();
|
||||
while (cursor != null && cursor.moveToNext()) {
|
||||
long messageId = CursorUtil.requireLong(cursor, MESSAGE_ID);
|
||||
List<Mention> messageMentions = mentions.get(messageId);
|
||||
|
||||
if (messageMentions == null) {
|
||||
messageMentions = new LinkedList<>();
|
||||
mentions.put(messageId, messageMentions);
|
||||
}
|
||||
|
||||
messageMentions.add(new Mention(RecipientId.from(CursorUtil.requireLong(cursor, RECIPIENT_ID)),
|
||||
CursorUtil.requireInt(cursor, RANGE_START),
|
||||
CursorUtil.requireInt(cursor, RANGE_LENGTH)));
|
||||
}
|
||||
return mentions;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -470,6 +470,11 @@ public class MmsDatabase extends MessagingDatabase {
|
||||
}
|
||||
}
|
||||
|
||||
public Reader getMessages(Collection<Long> messageIds) {
|
||||
String ids = TextUtils.join(",", messageIds);
|
||||
return readerFor(rawQuery(MmsDatabase.TABLE_NAME + "." + MmsDatabase.ID + " IN (" + ids + ")", null));
|
||||
}
|
||||
|
||||
public Reader getExpireStartedMessages() {
|
||||
String where = EXPIRE_STARTED + " > 0";
|
||||
return readerFor(rawQuery(where, null));
|
||||
|
||||
@@ -1933,17 +1933,24 @@ public class RecipientDatabase extends Database {
|
||||
return databaseHelper.getReadableDatabase().query(TABLE_NAME, SEARCH_PROJECTION, selection, args, null, null, null);
|
||||
}
|
||||
|
||||
public @NonNull List<Recipient> queryRecipientsForMentions(@NonNull String query, @NonNull List<RecipientId> recipientIds) {
|
||||
if (TextUtils.isEmpty(query) || recipientIds.isEmpty()) {
|
||||
public @NonNull List<Recipient> queryRecipientsForMentions(@NonNull String query) {
|
||||
return queryRecipientsForMentions(query, null);
|
||||
}
|
||||
|
||||
public @NonNull List<Recipient> queryRecipientsForMentions(@NonNull String query, @Nullable List<RecipientId> recipientIds) {
|
||||
if (TextUtils.isEmpty(query)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
query = buildCaseInsensitiveGlobPattern(query);
|
||||
|
||||
String ids = TextUtils.join(",", Stream.of(recipientIds).map(RecipientId::serialize).toList());
|
||||
String ids = null;
|
||||
if (Util.hasItems(recipientIds)) {
|
||||
ids = TextUtils.join(",", Stream.of(recipientIds).map(RecipientId::serialize).toList());
|
||||
}
|
||||
|
||||
String selection = BLOCKED + " = 0 AND " +
|
||||
ID + " IN (" + ids + ") AND " +
|
||||
(ids != null ? ID + " IN (" + ids + ") AND " : "") +
|
||||
SORT_NAME + " GLOB ?";
|
||||
|
||||
List<Recipient> recipients = new ArrayList<>();
|
||||
|
||||
@@ -26,6 +26,10 @@ public class SearchDatabase extends Database {
|
||||
public static final String SNIPPET = "snippet";
|
||||
public static final String CONVERSATION_RECIPIENT = "conversation_recipient";
|
||||
public static final String MESSAGE_RECIPIENT = "message_recipient";
|
||||
public static final String IS_MMS = "is_mms";
|
||||
public static final String MESSAGE_ID = "message_id";
|
||||
|
||||
public static final String SNIPPET_WRAP = "...";
|
||||
|
||||
public static final String[] CREATE_TABLE = {
|
||||
"CREATE VIRTUAL TABLE " + SMS_FTS_TABLE_NAME + " USING fts5(" + BODY + ", " + THREAD_ID + " UNINDEXED, content=" + SmsDatabase.TABLE_NAME + ", content_rowid=" + SmsDatabase.ID + ");",
|
||||
@@ -60,9 +64,12 @@ public class SearchDatabase extends Database {
|
||||
"SELECT " +
|
||||
ThreadDatabase.TABLE_NAME + "." + ThreadDatabase.RECIPIENT_ID + " AS " + CONVERSATION_RECIPIENT + ", " +
|
||||
MmsSmsColumns.RECIPIENT_ID + " AS " + MESSAGE_RECIPIENT + ", " +
|
||||
"snippet(" + SMS_FTS_TABLE_NAME + ", -1, '', '', '...', 7) AS " + SNIPPET + ", " +
|
||||
"snippet(" + SMS_FTS_TABLE_NAME + ", -1, '', '', '" + SNIPPET_WRAP + "', 7) AS " + SNIPPET + ", " +
|
||||
SmsDatabase.TABLE_NAME + "." + SmsDatabase.DATE_RECEIVED + " AS " + MmsSmsColumns.NORMALIZED_DATE_RECEIVED + ", " +
|
||||
SMS_FTS_TABLE_NAME + "." + THREAD_ID + " " +
|
||||
SMS_FTS_TABLE_NAME + "." + THREAD_ID + ", " +
|
||||
SMS_FTS_TABLE_NAME + "." + BODY + ", " +
|
||||
SMS_FTS_TABLE_NAME + "." + ID + " AS " + MESSAGE_ID + ", " +
|
||||
"0 AS " + IS_MMS + " " +
|
||||
"FROM " + SmsDatabase.TABLE_NAME + " " +
|
||||
"INNER JOIN " + SMS_FTS_TABLE_NAME + " ON " + SMS_FTS_TABLE_NAME + "." + ID + " = " + SmsDatabase.TABLE_NAME + "." + SmsDatabase.ID + " " +
|
||||
"INNER JOIN " + ThreadDatabase.TABLE_NAME + " ON " + SMS_FTS_TABLE_NAME + "." + THREAD_ID + " = " + ThreadDatabase.TABLE_NAME + "." + ThreadDatabase.ID + " " +
|
||||
@@ -71,9 +78,12 @@ public class SearchDatabase extends Database {
|
||||
"SELECT " +
|
||||
ThreadDatabase.TABLE_NAME + "." + ThreadDatabase.RECIPIENT_ID + " AS " + CONVERSATION_RECIPIENT + ", " +
|
||||
MmsSmsColumns.RECIPIENT_ID + " AS " + MESSAGE_RECIPIENT + ", " +
|
||||
"snippet(" + MMS_FTS_TABLE_NAME + ", -1, '', '', '...', 7) AS " + SNIPPET + ", " +
|
||||
"snippet(" + MMS_FTS_TABLE_NAME + ", -1, '', '', '" + SNIPPET_WRAP + "', 7) AS " + SNIPPET + ", " +
|
||||
MmsDatabase.TABLE_NAME + "." + MmsDatabase.DATE_RECEIVED + " AS " + MmsSmsColumns.NORMALIZED_DATE_RECEIVED + ", " +
|
||||
MMS_FTS_TABLE_NAME + "." + THREAD_ID + " " +
|
||||
MMS_FTS_TABLE_NAME + "." + THREAD_ID + ", " +
|
||||
MMS_FTS_TABLE_NAME + "." + BODY + ", " +
|
||||
MMS_FTS_TABLE_NAME + "." + ID + " AS " + MESSAGE_ID + ", " +
|
||||
"1 AS " + IS_MMS + " " +
|
||||
"FROM " + MmsDatabase.TABLE_NAME + " " +
|
||||
"INNER JOIN " + MMS_FTS_TABLE_NAME + " ON " + MMS_FTS_TABLE_NAME + "." + ID + " = " + MmsDatabase.TABLE_NAME + "." + MmsDatabase.ID + " " +
|
||||
"INNER JOIN " + ThreadDatabase.TABLE_NAME + " ON " + MMS_FTS_TABLE_NAME + "." + THREAD_ID + " = " + ThreadDatabase.TABLE_NAME + "." + ThreadDatabase.ID + " " +
|
||||
@@ -85,9 +95,12 @@ public class SearchDatabase extends Database {
|
||||
"SELECT " +
|
||||
ThreadDatabase.TABLE_NAME + "." + ThreadDatabase.RECIPIENT_ID + " AS " + CONVERSATION_RECIPIENT + ", " +
|
||||
MmsSmsColumns.RECIPIENT_ID + " AS " + MESSAGE_RECIPIENT + ", " +
|
||||
"snippet(" + SMS_FTS_TABLE_NAME + ", -1, '', '', '...', 7) AS " + SNIPPET + ", " +
|
||||
"snippet(" + SMS_FTS_TABLE_NAME + ", -1, '', '', '" + SNIPPET_WRAP + "', 7) AS " + SNIPPET + ", " +
|
||||
SmsDatabase.TABLE_NAME + "." + SmsDatabase.DATE_RECEIVED + " AS " + MmsSmsColumns.NORMALIZED_DATE_RECEIVED + ", " +
|
||||
SMS_FTS_TABLE_NAME + "." + THREAD_ID + " " +
|
||||
SMS_FTS_TABLE_NAME + "." + THREAD_ID + ", " +
|
||||
SMS_FTS_TABLE_NAME + "." + BODY + ", " +
|
||||
SMS_FTS_TABLE_NAME + "." + ID + " AS " + MESSAGE_ID + ", " +
|
||||
"0 AS " + IS_MMS + " " +
|
||||
"FROM " + SmsDatabase.TABLE_NAME + " " +
|
||||
"INNER JOIN " + SMS_FTS_TABLE_NAME + " ON " + SMS_FTS_TABLE_NAME + "." + ID + " = " + SmsDatabase.TABLE_NAME + "." + SmsDatabase.ID + " " +
|
||||
"INNER JOIN " + ThreadDatabase.TABLE_NAME + " ON " + SMS_FTS_TABLE_NAME + "." + THREAD_ID + " = " + ThreadDatabase.TABLE_NAME + "." + ThreadDatabase.ID + " " +
|
||||
@@ -96,9 +109,12 @@ public class SearchDatabase extends Database {
|
||||
"SELECT " +
|
||||
ThreadDatabase.TABLE_NAME + "." + ThreadDatabase.RECIPIENT_ID + " AS " + CONVERSATION_RECIPIENT + ", " +
|
||||
MmsSmsColumns.RECIPIENT_ID + " AS " + MESSAGE_RECIPIENT + ", " +
|
||||
"snippet(" + MMS_FTS_TABLE_NAME + ", -1, '', '', '...', 7) AS " + SNIPPET + ", " +
|
||||
"snippet(" + MMS_FTS_TABLE_NAME + ", -1, '', '', '" + SNIPPET_WRAP + "', 7) AS " + SNIPPET + ", " +
|
||||
MmsDatabase.TABLE_NAME + "." + MmsDatabase.DATE_RECEIVED + " AS " + MmsSmsColumns.NORMALIZED_DATE_RECEIVED + ", " +
|
||||
MMS_FTS_TABLE_NAME + "." + THREAD_ID + " " +
|
||||
MMS_FTS_TABLE_NAME + "." + THREAD_ID + ", " +
|
||||
MMS_FTS_TABLE_NAME + "." + BODY + ", " +
|
||||
MMS_FTS_TABLE_NAME + "." + ID + " AS " + MESSAGE_ID + ", " +
|
||||
"1 AS " + IS_MMS + " " +
|
||||
"FROM " + MmsDatabase.TABLE_NAME + " " +
|
||||
"INNER JOIN " + MMS_FTS_TABLE_NAME + " ON " + MMS_FTS_TABLE_NAME + "." + ID + " = " + MmsDatabase.TABLE_NAME + "." + MmsDatabase.ID + " " +
|
||||
"INNER JOIN " + ThreadDatabase.TABLE_NAME + " ON " + MMS_FTS_TABLE_NAME + "." + THREAD_ID + " = " + ThreadDatabase.TABLE_NAME + "." + ThreadDatabase.ID + " " +
|
||||
|
||||
Reference in New Issue
Block a user