diff --git a/app/src/main/java/org/thoughtcrime/securesms/home/HomeActivity.kt b/app/src/main/java/org/thoughtcrime/securesms/home/HomeActivity.kt index 917fc13fcf..ebb5a90da2 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/home/HomeActivity.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/home/HomeActivity.kt @@ -12,6 +12,7 @@ import android.os.Build import android.os.Bundle import android.text.SpannableString import android.widget.Toast + import androidx.activity.viewModels import androidx.core.os.bundleOf import androidx.core.view.isVisible @@ -21,20 +22,25 @@ import androidx.lifecycle.repeatOnLifecycle import androidx.localbroadcastmanager.content.LocalBroadcastManager import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView + import dagger.hilt.android.AndroidEntryPoint + import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch import kotlinx.coroutines.withContext + import network.loki.messenger.R import network.loki.messenger.databinding.ActivityHomeBinding import network.loki.messenger.databinding.ViewMessageRequestBannerBinding import network.loki.messenger.libsession_util.ConfigBase + import org.greenrobot.eventbus.EventBus import org.greenrobot.eventbus.Subscribe import org.greenrobot.eventbus.ThreadMode + import org.session.libsession.messaging.MessagingModuleConfiguration import org.session.libsession.messaging.jobs.JobQueue import org.session.libsession.messaging.sending_receiving.MessageSender @@ -47,6 +53,7 @@ import org.session.libsession.utilities.recipients.Recipient import org.session.libsignal.utilities.Log import org.session.libsignal.utilities.ThreadUtils import org.session.libsignal.utilities.toHexString + import org.thoughtcrime.securesms.ApplicationContext import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity import org.thoughtcrime.securesms.conversation.start.NewConversationFragment @@ -82,8 +89,10 @@ import org.thoughtcrime.securesms.util.disableClipping import org.thoughtcrime.securesms.util.push import org.thoughtcrime.securesms.util.show import org.thoughtcrime.securesms.util.themeState + import java.io.IOException import java.util.Locale + import javax.inject.Inject @AndroidEntryPoint diff --git a/app/src/main/java/org/thoughtcrime/securesms/home/search/GlobalSearchViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/home/search/GlobalSearchViewModel.kt index 712e8819d1..4a917fd291 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/home/search/GlobalSearchViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/home/search/GlobalSearchViewModel.kt @@ -2,7 +2,9 @@ package org.thoughtcrime.securesms.home.search import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope + import dagger.hilt.android.lifecycle.HiltViewModel + import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.channels.BufferOverflow import kotlinx.coroutines.delay @@ -13,11 +15,14 @@ import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.mapLatest import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.plus -import org.session.libsignal.utilities.Log + import org.session.libsignal.utilities.SettableFuture + import org.thoughtcrime.securesms.search.SearchRepository import org.thoughtcrime.securesms.search.model.SearchResult + import java.util.concurrent.TimeUnit + import javax.inject.Inject @HiltViewModel @@ -25,8 +30,7 @@ class GlobalSearchViewModel @Inject constructor(private val searchRepository: Se private val executor = viewModelScope + SupervisorJob() - private val _result: MutableStateFlow = - MutableStateFlow(GlobalSearchResult.EMPTY) + private val _result: MutableStateFlow = MutableStateFlow(GlobalSearchResult.EMPTY) val result: StateFlow = _result @@ -34,7 +38,6 @@ class GlobalSearchViewModel @Inject constructor(private val searchRepository: Se private var settableFuture = SettableFuture() - fun postQuery(charSequence: CharSequence?) { charSequence ?: return _queryText.value = charSequence @@ -45,7 +48,7 @@ class GlobalSearchViewModel @Inject constructor(private val searchRepository: Se _queryText .buffer(onBufferOverflow = BufferOverflow.DROP_OLDEST) .mapLatest { query -> - // Minimum search term is 2 characters - for a single char we do nothing + // Minimum search term is 2 characters if (query.trim().length < 2) { SearchResult.EMPTY } else { @@ -55,9 +58,7 @@ class GlobalSearchViewModel @Inject constructor(private val searchRepository: Se delay(300) // If we already have a search running then stop it - if (!settableFuture.isDone) { - Log.w("[ACL]", "Cancelling settable future..") - settableFuture.cancel(true); } + if (!settableFuture.isDone) { settableFuture.cancel(true) } settableFuture = SettableFuture() searchRepository.query(query.toString(), settableFuture::set) diff --git a/app/src/main/java/org/thoughtcrime/securesms/search/SearchRepository.java b/app/src/main/java/org/thoughtcrime/securesms/search/SearchRepository.java index ba4535e1ac..11ce07d06a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/search/SearchRepository.java +++ b/app/src/main/java/org/thoughtcrime/securesms/search/SearchRepository.java @@ -4,7 +4,6 @@ import android.content.Context; import android.database.Cursor; import android.database.DatabaseUtils; import android.database.MergeCursor; -import android.text.TextUtils; import androidx.annotation.NonNull; @@ -36,28 +35,18 @@ import java.util.concurrent.Executor; import kotlin.Pair; -/** - * Manages data retrieval for search. - */ +// Class to manage data retrieval for search public class SearchRepository { - private static final String TAG = SearchRepository.class.getSimpleName(); private static final Set BANNED_CHARACTERS = new HashSet<>(); static { - // Several ranges of invalid ASCII characters - for (int i = 33; i <= 47; i++) { - BANNED_CHARACTERS.add((char) i); - } - for (int i = 58; i <= 64; i++) { - BANNED_CHARACTERS.add((char) i); - } - for (int i = 91; i <= 96; i++) { - BANNED_CHARACTERS.add((char) i); - } - for (int i = 123; i <= 126; i++) { - BANNED_CHARACTERS.add((char) i); - } + // Construct a list containing several ranges of invalid ASCII characters + // See: https://www.ascii-code.com/ + for (int i = 33; i <= 47; i++) { BANNED_CHARACTERS.add((char) i); } // !, ", #, $, %, &, ', (, ), *, +, ,, -, ., / + for (int i = 58; i <= 64; i++) { BANNED_CHARACTERS.add((char) i); } // :, ;, <, =, >, ?, @ + for (int i = 91; i <= 96; i++) { BANNED_CHARACTERS.add((char) i); } // [, \, ], ^, _, ` + for (int i = 123; i <= 126; i++) { BANNED_CHARACTERS.add((char) i); } // {, |, }, ~ } private final Context context; @@ -86,54 +75,25 @@ public class SearchRepository { } public void query(@NonNull String query, @NonNull Callback callback) { - - Log.w("[ACL]", "Hit SearchRepository.query - query string is: \"" + query + "\""); - - String cleanQuery = sanitizeQuery(query).trim(); - Log.w("[ACL]", "When sanitized and trimmed this is: \"" + cleanQuery + "\""); - // If the sanitized search is empty or is less than 2 chars then abort + String cleanQuery = sanitizeQuery(query).trim(); if (cleanQuery.isEmpty() || cleanQuery.length() < 2) { - Log.w("[ACL]", "Trimmed query is empty or less than 2 chars so returning empty SearchResult"); callback.onResult(SearchResult.EMPTY); return; } executor.execute(() -> { Stopwatch timer = new Stopwatch("FtsQuery"); - - // ACL - //String cleanQuery = sanitizeQuery(query).trim(); - - - /* - if (cleanQuery.isEmpty()) - { - Log.w("[ACL]", "Aborting empty search query."); - Log.d(TAG, "Aborting empty search query."); - timer.stop(TAG); - return; - } - else { - Log.w("[ACL]", "Clean query is non-empty and is: \"" + cleanQuery + "\""); - } - */ - - timer.split("clean"); - Log.w("[ACL]", "About to query contacts."); Pair, List> contacts = queryContacts(cleanQuery); - timer.split("contacts"); + timer.split("Contacts"); - - Log.w("[ACL]", "About to query conversations."); CursorList conversations = queryConversations(cleanQuery, contacts.getSecond()); - timer.split("conversations"); + timer.split("Conversations"); - Log.w("[ACL]", "About to query messages."); CursorList messages = queryMessages(cleanQuery); - timer.split("messages"); + timer.split("Messages"); timer.stop(TAG); @@ -182,11 +142,10 @@ public class SearchRepository { MergeCursor merged = new MergeCursor(new Cursor[]{addressThreads, individualRecipients}); return new Pair<>(new CursorList<>(merged, new ContactModelBuilder(contactDatabase, threadDatabase)), contactStrings); - } private CursorList queryConversations(@NonNull String query, List matchingAddresses) { - List numbers = contactAccessor.getNumbersForThreadSearchFilter(context, query); + List numbers = contactAccessor.getNumbersForThreadSearchFilter(context, query); String localUserNumber = TextSecurePreferences.getLocalNumber(context); if (localUserNumber != null) { matchingAddresses.remove(localUserNumber); @@ -270,9 +229,7 @@ public class SearchRepository { private final Context context; - RecipientModelBuilder(@NonNull Context context) { - this.context = context; - } + RecipientModelBuilder(@NonNull Context context) { this.context = context; } @Override public Recipient build(@NonNull Cursor cursor) { @@ -315,9 +272,7 @@ public class SearchRepository { private final Context context; - MessageModelBuilder(@NonNull Context context) { - this.context = context; - } + MessageModelBuilder(@NonNull Context context) { this.context = context; } @Override public MessageResult build(@NonNull Cursor cursor) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/Stopwatch.java b/app/src/main/java/org/thoughtcrime/securesms/util/Stopwatch.java index 75bc760c31..d92fc7546d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/Stopwatch.java +++ b/app/src/main/java/org/thoughtcrime/securesms/util/Stopwatch.java @@ -39,13 +39,9 @@ public class Stopwatch { out.append(splits.get(i).time - splits.get(i - 1).time); out.append("ms "); } - out.append("total: ").append(splits.get(splits.size() - 1).time - startTime).append("ms."); } - Log.d(tag, out.toString()); - - Log.w("[ACL]", out.toString()); } private static class Split {