From 61ff68b532f7653377f29c262f1f07f18b0f58ed Mon Sep 17 00:00:00 2001 From: Ryan Zhao Date: Tue, 29 Jun 2021 11:49:10 +1000 Subject: [PATCH 01/10] add search bottom bar ui --- .../conversation/v2/ConversationActivityV2.kt | 10 +- .../v2/menus/ConversationMenuHelper.kt | 58 ++++++++- .../conversation/v2/search/SearchBottomBar.kt | 64 ++++++++++ .../conversation/v2/search/SearchViewModel.kt | 114 ++++++++++++++++++ .../res/layout/activity_conversation_v2.xml | 7 ++ .../res/layout/view_search_bottom_bar.xml | 68 +++++++++++ 6 files changed, 317 insertions(+), 4 deletions(-) create mode 100644 app/src/main/java/org/thoughtcrime/securesms/conversation/v2/search/SearchBottomBar.kt create mode 100644 app/src/main/java/org/thoughtcrime/securesms/conversation/v2/search/SearchViewModel.kt create mode 100644 app/src/main/res/layout/view_search_bottom_bar.xml diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt index 30fefabc4c..89953bcc04 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt @@ -39,7 +39,6 @@ import org.session.libsession.utilities.TextSecurePreferences import org.thoughtcrime.securesms.ApplicationContext import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity import org.thoughtcrime.securesms.contactshare.SimpleTextWatcher -import org.thoughtcrime.securesms.conversation.ConversationActivity import org.thoughtcrime.securesms.conversation.v2.dialogs.* import org.thoughtcrime.securesms.conversation.v2.input_bar.InputBarButton import org.thoughtcrime.securesms.conversation.v2.input_bar.InputBarDelegate @@ -291,7 +290,7 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe } override fun onPrepareOptionsMenu(menu: Menu): Boolean { - ConversationMenuHelper.onPrepareOptionsMenu(menu, menuInflater, thread, this) { onOptionsItemSelected(it) } + ConversationMenuHelper.onPrepareOptionsMenu(menu, menuInflater, thread, threadID, this) { onOptionsItemSelected(it) } super.onPrepareOptionsMenu(menu) return true } @@ -750,4 +749,11 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe draftDB.insertDrafts(threadID, drafts) } // endregion + + // region Search + fun onSearchQueryUpdated(query: String?) { + adapter.onSearchQueryUpdated(query) + } + + // endregion } \ No newline at end of file diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/menus/ConversationMenuHelper.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/menus/ConversationMenuHelper.kt index 7dc18130d7..3e81a502e4 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/menus/ConversationMenuHelper.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/menus/ConversationMenuHelper.kt @@ -6,17 +6,26 @@ import android.graphics.PorterDuffColorFilter import android.view.Menu import android.view.MenuInflater import android.view.MenuItem +import android.view.View import android.widget.ImageView import android.widget.TextView import androidx.annotation.ColorInt +import androidx.appcompat.widget.SearchView +import androidx.appcompat.widget.SearchView.OnQueryTextListener +import androidx.lifecycle.ViewModelProvider +import kotlinx.android.synthetic.main.activity_conversation_v2.* +import kotlinx.android.synthetic.main.session_logo_action_bar_content.* import network.loki.messenger.R import org.session.libsession.utilities.ExpirationUtil import org.session.libsession.utilities.recipients.Recipient +import org.thoughtcrime.securesms.components.ConversationSearchBottomBar +import org.thoughtcrime.securesms.conversation.v2.ConversationActivityV2 +import org.thoughtcrime.securesms.conversation.v2.search.SearchViewModel import org.thoughtcrime.securesms.loki.utilities.getColorWithID object ConversationMenuHelper { - fun onPrepareOptionsMenu(menu: Menu, inflater: MenuInflater, thread: Recipient, context: Context, onOptionsItemSelected: (MenuItem) -> Unit) { + fun onPrepareOptionsMenu(menu: Menu, inflater: MenuInflater, thread: Recipient, threadId: Long, context: Context, onOptionsItemSelected: (MenuItem) -> Unit) { // Prepare menu.clear() val isOpenGroup = thread.isOpenGroupRecipient @@ -61,6 +70,51 @@ object ConversationMenuHelper { } else { inflater.inflate(R.menu.menu_conversation_unmuted, menu) } - // TODO: Implement search + // Search + val searchViewItem = menu.findItem(R.id.menu_search) + val searchView = searchViewItem.actionView as SearchView + val searchViewModel:SearchViewModel = ViewModelProvider(context as ConversationActivityV2).get(SearchViewModel::class.java) + val queryListener = object : OnQueryTextListener { + override fun onQueryTextSubmit(query: String): Boolean { + searchViewModel.onQueryUpdated(query, threadId) + context.searchBottomBar.showLoading() + context.onSearchQueryUpdated(query) + return true + } + + override fun onQueryTextChange(query: String): Boolean { + searchViewModel.onQueryUpdated(query, threadId) + context.searchBottomBar.showLoading() + context.onSearchQueryUpdated(query) + return true + } + } + searchViewItem.setOnActionExpandListener(object : MenuItem.OnActionExpandListener { + override fun onMenuItemActionExpand(item: MenuItem): Boolean { + searchView.setOnQueryTextListener(queryListener) + searchViewModel.onSearchOpened() + context.searchBottomBar.visibility = View.VISIBLE + context.searchBottomBar.setData(0, 0) + context.inputBar.visibility = View.GONE + context.supportActionBar?.setDisplayHomeAsUpEnabled(false) + for (i in 0 until menu.size()) { + if (menu.getItem(i) != searchViewItem) { + menu.getItem(i).isVisible = false + } + } + return true + } + + override fun onMenuItemActionCollapse(item: MenuItem): Boolean { + searchView.setOnQueryTextListener(null) + searchViewModel.onSearchClosed() + context.searchBottomBar.visibility = View.GONE + context.inputBar.visibility = View.VISIBLE + context.supportActionBar?.setDisplayHomeAsUpEnabled(true) + context.onSearchQueryUpdated(null) + context.invalidateOptionsMenu() + return true + } + }) } } \ No newline at end of file diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/search/SearchBottomBar.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/search/SearchBottomBar.kt new file mode 100644 index 0000000000..93d24ff019 --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/search/SearchBottomBar.kt @@ -0,0 +1,64 @@ +package org.thoughtcrime.securesms.conversation.v2.search + +import android.content.Context +import android.util.AttributeSet +import android.view.LayoutInflater +import android.view.View +import android.widget.LinearLayout +import android.widget.RelativeLayout +import androidx.constraintlayout.widget.ConstraintLayout +import kotlinx.android.synthetic.main.view_search_bottom_bar.view.* +import network.loki.messenger.R + + +class SearchBottomBar : LinearLayout { + private var eventListener: EventListener? = null + + // region Lifecycle + constructor(context: Context) : super(context) { initialize() } + constructor(context: Context, attrs: AttributeSet) : super(context, attrs) { initialize() } + constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) { initialize() } + + fun initialize() { + LayoutInflater.from(context).inflate(R.layout.view_search_bottom_bar, this) + } + + fun setData(position: Int, count: Int) { + searchProgressWheel.visibility = GONE + searchUp.setOnClickListener { v: View? -> + if (eventListener != null) { + eventListener!!.onSearchMoveUpPressed() + } + } + searchDown.setOnClickListener { v: View? -> + if (eventListener != null) { + eventListener!!.onSearchMoveDownPressed() + } + } + if (count > 0) { + searchPosition.text = resources.getString(R.string.ConversationActivity_search_position, position + 1, count) + } else { + searchPosition.setText(R.string.ConversationActivity_no_results) + } + setViewEnabled(searchUp, position < count - 1) + setViewEnabled(searchDown, position > 0) + } + + fun showLoading() { + searchProgressWheel.visibility = VISIBLE + } + + private fun setViewEnabled(view: View, enabled: Boolean) { + view.isEnabled = enabled + view.alpha = if (enabled) 1f else 0.25f + } + + fun setEventListener(eventListener: EventListener?) { + this.eventListener = eventListener + } + + interface EventListener { + fun onSearchMoveUpPressed() + fun onSearchMoveDownPressed() + } +} \ No newline at end of file diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/search/SearchViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/search/SearchViewModel.kt new file mode 100644 index 0000000000..f1d7c8a610 --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/search/SearchViewModel.kt @@ -0,0 +1,114 @@ +package org.thoughtcrime.securesms.conversation.v2.search + +import android.app.Application +import androidx.lifecycle.AndroidViewModel +import androidx.lifecycle.LiveData +import org.session.libsession.utilities.Debouncer +import org.session.libsession.utilities.Util.runOnMain +import org.session.libsession.utilities.concurrent.SignalExecutors +import org.thoughtcrime.securesms.contacts.ContactAccessor +import org.thoughtcrime.securesms.database.CursorList +import org.thoughtcrime.securesms.database.DatabaseFactory +import org.thoughtcrime.securesms.search.SearchRepository +import org.thoughtcrime.securesms.search.model.MessageResult +import org.thoughtcrime.securesms.util.CloseableLiveData +import java.io.Closeable + + +class SearchViewModel(application: Application) : AndroidViewModel(application) { + private val searchRepository: SearchRepository + private val result: CloseableLiveData + private val debouncer: Debouncer + private var firstSearch = false + private var searchOpen = false + private var activeQuery: String? = null + private var activeThreadId: Long = 0 + val searchResults: LiveData + get() = result + + fun onQueryUpdated(query: String, threadId: Long) { + if (firstSearch && query.length < 2) { + result.postValue(SearchResult(CursorList.emptyList(), 0)) + return + } + if (query == activeQuery) { + return + } + updateQuery(query, threadId) + } + + fun onMissingResult() { + if (activeQuery != null) { + updateQuery(activeQuery!!, activeThreadId) + } + } + + fun onMoveUp() { + debouncer.clear() + val messages = result.value!!.getResults() as CursorList + val position = Math.min(result.value!!.position + 1, messages.size - 1) + result.setValue(SearchResult(messages, position), false) + } + + fun onMoveDown() { + debouncer.clear() + val messages = result.value!!.getResults() as CursorList + val position = Math.max(result.value!!.position - 1, 0) + result.setValue(SearchResult(messages, position), false) + } + + fun onSearchOpened() { + searchOpen = true + firstSearch = true + } + + fun onSearchClosed() { + searchOpen = false + debouncer.clear() + result.close() + } + + override fun onCleared() { + super.onCleared() + result.close() + } + + private fun updateQuery(query: String, threadId: Long) { + activeQuery = query + activeThreadId = threadId + debouncer.publish { + firstSearch = false + searchRepository.query(query, threadId) { messages: CursorList -> + runOnMain { + if (searchOpen && query == activeQuery) { + result.setValue(SearchResult(messages, 0)) + } else { + messages.close() + } + } + } + } + } + + class SearchResult(private val results: CursorList, val position: Int) : Closeable { + + fun getResults(): List { + return results + } + + override fun close() { + results.close() + } + } + + init { + val context = application.applicationContext + result = CloseableLiveData() + debouncer = Debouncer(500) + searchRepository = SearchRepository(context, + DatabaseFactory.getSearchDatabase(context), + DatabaseFactory.getThreadDatabase(context), + ContactAccessor.getInstance(), + SignalExecutors.SERIAL) + } +} \ No newline at end of file diff --git a/app/src/main/res/layout/activity_conversation_v2.xml b/app/src/main/res/layout/activity_conversation_v2.xml index 66d71f5cce..079c932e99 100644 --- a/app/src/main/res/layout/activity_conversation_v2.xml +++ b/app/src/main/res/layout/activity_conversation_v2.xml @@ -34,6 +34,13 @@ android:layout_height="wrap_content" android:layout_alignParentBottom="true" /> + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From f4d3a7359e35ebfc0fb7ad9b834388cb00073601 Mon Sep 17 00:00:00 2001 From: Ryan Zhao Date: Tue, 29 Jun 2021 11:49:45 +1000 Subject: [PATCH 02/10] highlight the search result --- .../conversation/v2/ConversationAdapter.kt | 8 ++++++- .../v2/messages/LinkPreviewView.kt | 4 ++-- .../v2/messages/VisibleMessageContentView.kt | 22 ++++++++++--------- .../v2/messages/VisibleMessageView.kt | 4 ++-- 4 files changed, 23 insertions(+), 15 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationAdapter.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationAdapter.kt index 63306b0c4f..690fd5acea 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationAdapter.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationAdapter.kt @@ -19,6 +19,7 @@ class ConversationAdapter(context: Context, cursor: Cursor, private val onItemPr : CursorRecyclerViewAdapter(context, cursor) { private val messageDB = DatabaseFactory.getMmsSmsDatabase(context) var selectedItems = mutableSetOf() + private var searchQuery: String? = null sealed class ViewType(val rawValue: Int) { object Visible : ViewType(0) @@ -67,7 +68,7 @@ class ConversationAdapter(context: Context, cursor: Cursor, private val onItemPr view.snIsSelected = isSelected view.messageTimestampTextView.isVisible = isSelected val position = viewHolder.adapterPosition - view.bind(message, getMessageBefore(position, cursor), getMessageAfter(position, cursor), glide) + view.bind(message, getMessageBefore(position, cursor), getMessageAfter(position, cursor), glide, searchQuery) view.onPress = { onItemPress(message, viewHolder.adapterPosition, view) } view.onSwipeToReply = { onItemSwipeToReply(message, viewHolder.adapterPosition) } view.onLongPress = { onItemLongPress(message, viewHolder.adapterPosition) } @@ -117,4 +118,9 @@ class ConversationAdapter(context: Context, cursor: Cursor, private val onItemPr } return null } + + fun onSearchQueryUpdated(query: String?) { + this.searchQuery = query + notifyDataSetChanged() + } } \ No newline at end of file diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/LinkPreviewView.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/LinkPreviewView.kt index 00a98d1d33..d6bbdd4066 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/LinkPreviewView.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/LinkPreviewView.kt @@ -31,7 +31,7 @@ class LinkPreviewView : LinearLayout { // endregion // region Updating - fun bind(message: MmsMessageRecord, glide: GlideRequests, isStartOfMessageCluster: Boolean, isEndOfMessageCluster: Boolean) { + fun bind(message: MmsMessageRecord, glide: GlideRequests, isStartOfMessageCluster: Boolean, isEndOfMessageCluster: Boolean, searchQuery: String?) { mainLinkPreviewContainer.background = background mainLinkPreviewContainer.outlineProvider = ViewOutlineProvider.BACKGROUND mainLinkPreviewContainer.clipToOutline = true @@ -50,7 +50,7 @@ class LinkPreviewView : LinearLayout { } titleTextView.setTextColor(ResourcesCompat.getColor(resources, textColorID, context.theme)) // Body - val bodyTextView = VisibleMessageContentView.getBodyTextView(context, message) + val bodyTextView = VisibleMessageContentView.getBodyTextView(context, message, searchQuery) mainLinkPreviewContainer.addView(bodyTextView) // Corner radii val cornerRadii = MessageBubbleUtilities.calculateRadii(context, isStartOfMessageCluster, isEndOfMessageCluster, message.isOutgoing) diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/VisibleMessageContentView.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/VisibleMessageContentView.kt index e242d6e6b5..afe50166ff 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/VisibleMessageContentView.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/VisibleMessageContentView.kt @@ -1,12 +1,12 @@ package org.thoughtcrime.securesms.conversation.v2.messages import android.content.Context -import android.content.res.ColorStateList import android.graphics.Color import android.graphics.drawable.Drawable +import android.text.style.BackgroundColorSpan +import android.text.style.ForegroundColorSpan import android.text.util.Linkify import android.util.AttributeSet -import android.util.Log import android.util.TypedValue import android.view.LayoutInflater import android.widget.LinearLayout @@ -19,8 +19,6 @@ import androidx.core.graphics.BlendModeCompat import androidx.core.text.toSpannable import kotlinx.android.synthetic.main.view_visible_message_content.view.* import network.loki.messenger.R -import org.session.libsession.messaging.utilities.UpdateMessageData -import org.session.libsession.messaging.utilities.UpdateMessageData.Companion.fromJSON import org.session.libsession.utilities.ThemeUtil import org.session.libsession.utilities.ViewUtil import org.session.libsession.utilities.recipients.Recipient @@ -28,8 +26,10 @@ import org.thoughtcrime.securesms.components.emoji.EmojiTextView import org.thoughtcrime.securesms.database.model.MessageRecord import org.thoughtcrime.securesms.database.model.MmsMessageRecord import org.thoughtcrime.securesms.loki.utilities.* -import org.thoughtcrime.securesms.loki.utilities.MentionUtilities.highlightMentions import org.thoughtcrime.securesms.mms.GlideRequests +import org.thoughtcrime.securesms.util.SearchUtil +import org.thoughtcrime.securesms.util.SearchUtil.StyleFactory +import java.util.* import kotlin.math.roundToInt class VisibleMessageContentView : LinearLayout { @@ -47,7 +47,7 @@ class VisibleMessageContentView : LinearLayout { // region Updating fun bind(message: MessageRecord, isStartOfMessageCluster: Boolean, isEndOfMessageCluster: Boolean, - glide: GlideRequests, maxWidth: Int, thread: Recipient) { + glide: GlideRequests, maxWidth: Int, thread: Recipient, searchQuery: String?) { // Background val background = getBackground(message.isOutgoing, isStartOfMessageCluster, isEndOfMessageCluster) val colorID = if (message.isOutgoing) R.attr.message_sent_background_color else R.attr.message_received_background_color @@ -60,7 +60,7 @@ class VisibleMessageContentView : LinearLayout { onContentClick = null if (message is MmsMessageRecord && message.linkPreviews.isNotEmpty()) { val linkPreviewView = LinkPreviewView(context) - linkPreviewView.bind(message, glide, isStartOfMessageCluster, isEndOfMessageCluster) + linkPreviewView.bind(message, glide, isStartOfMessageCluster, isEndOfMessageCluster, searchQuery) mainContainer.addView(linkPreviewView) // Body text view is inside the link preview for layout convenience } else if (message is MmsMessageRecord && message.quote != null) { @@ -73,7 +73,7 @@ class VisibleMessageContentView : LinearLayout { quoteView.bind(quote.author.toString(), quote.text, quote.attachment, thread, message.isOutgoing, maxContentWidth, message.isOpenGroupInvitation, message.threadId) mainContainer.addView(quoteView) - val bodyTextView = VisibleMessageContentView.getBodyTextView(context, message) + val bodyTextView = VisibleMessageContentView.getBodyTextView(context, message, searchQuery) ViewUtil.setPaddingTop(bodyTextView, 0) mainContainer.addView(bodyTextView) } else if (message is MmsMessageRecord && message.slideDeck.audioSlide != null) { @@ -96,7 +96,7 @@ class VisibleMessageContentView : LinearLayout { openGroupInvitationView.bind(message, VisibleMessageContentView.getTextColor(context, message)) mainContainer.addView(openGroupInvitationView) } else { - val bodyTextView = VisibleMessageContentView.getBodyTextView(context, message) + val bodyTextView = VisibleMessageContentView.getBodyTextView(context, message, searchQuery) mainContainer.addView(bodyTextView) } } @@ -124,7 +124,7 @@ class VisibleMessageContentView : LinearLayout { // region Convenience companion object { - fun getBodyTextView(context: Context, message: MessageRecord): TextView { + fun getBodyTextView(context: Context, message: MessageRecord, searchQuery: String?): TextView { val result = EmojiTextView(context) val vPadding = context.resources.getDimension(R.dimen.small_spacing).toInt() val hPadding = toPx(12, context.resources) @@ -136,6 +136,8 @@ class VisibleMessageContentView : LinearLayout { var body = message.body.toSpannable() Linkify.addLinks(body, Linkify.WEB_URLS) body = MentionUtilities.highlightMentions(body, message.isOutgoing, message.threadId, context); + body = SearchUtil.getHighlightedSpan(Locale.getDefault(), StyleFactory { BackgroundColorSpan(Color.WHITE) }, body, searchQuery) + body = SearchUtil.getHighlightedSpan(Locale.getDefault(), StyleFactory { ForegroundColorSpan(Color.BLACK) }, body, searchQuery) result.text = body return result } diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/VisibleMessageView.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/VisibleMessageView.kt index 3d665c5cbd..9cd29c9d46 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/VisibleMessageView.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/VisibleMessageView.kt @@ -74,7 +74,7 @@ class VisibleMessageView : LinearLayout { // endregion // region Updating - fun bind(message: MessageRecord, previous: MessageRecord?, next: MessageRecord?, glide: GlideRequests) { + fun bind(message: MessageRecord, previous: MessageRecord?, next: MessageRecord?, glide: GlideRequests, searchQuery: String?) { val sender = message.individualRecipient val senderSessionID = sender.address.serialize() val threadID = message.threadId @@ -142,7 +142,7 @@ class VisibleMessageView : LinearLayout { var maxWidth = screenWidth - messageContentContainerLayoutParams.leftMargin - messageContentContainerLayoutParams.rightMargin if (profilePictureContainer.visibility != View.GONE) { maxWidth -= profilePictureContainer.width } // Populate content view - messageContentView.bind(message, isStartOfMessageCluster, isEndOfMessageCluster, glide, maxWidth, thread) + messageContentView.bind(message, isStartOfMessageCluster, isEndOfMessageCluster, glide, maxWidth, thread, searchQuery) } private fun setMessageSpacing(isStartOfMessageCluster: Boolean, isEndOfMessageCluster: Boolean) { From 6b4acd023213fb65b65b82bf6eaa253e92a1e030 Mon Sep 17 00:00:00 2001 From: Ryan Zhao Date: Tue, 29 Jun 2021 11:51:04 +1000 Subject: [PATCH 03/10] clean --- .../securesms/conversation/v2/menus/ConversationMenuHelper.kt | 2 -- 1 file changed, 2 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/menus/ConversationMenuHelper.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/menus/ConversationMenuHelper.kt index 3e81a502e4..4c3a72a9ed 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/menus/ConversationMenuHelper.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/menus/ConversationMenuHelper.kt @@ -96,7 +96,6 @@ object ConversationMenuHelper { context.searchBottomBar.visibility = View.VISIBLE context.searchBottomBar.setData(0, 0) context.inputBar.visibility = View.GONE - context.supportActionBar?.setDisplayHomeAsUpEnabled(false) for (i in 0 until menu.size()) { if (menu.getItem(i) != searchViewItem) { menu.getItem(i).isVisible = false @@ -110,7 +109,6 @@ object ConversationMenuHelper { searchViewModel.onSearchClosed() context.searchBottomBar.visibility = View.GONE context.inputBar.visibility = View.VISIBLE - context.supportActionBar?.setDisplayHomeAsUpEnabled(true) context.onSearchQueryUpdated(null) context.invalidateOptionsMenu() return true From c294262ff313c322a6eeda6dcaa68fa5cd1f8e2f Mon Sep 17 00:00:00 2001 From: Ryan Zhao Date: Tue, 29 Jun 2021 14:00:30 +1000 Subject: [PATCH 04/10] fix spinner --- app/src/main/res/layout/view_search_bottom_bar.xml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/app/src/main/res/layout/view_search_bottom_bar.xml b/app/src/main/res/layout/view_search_bottom_bar.xml index b334fd485e..e794e75205 100644 --- a/app/src/main/res/layout/view_search_bottom_bar.xml +++ b/app/src/main/res/layout/view_search_bottom_bar.xml @@ -1,7 +1,7 @@ - From 628477f2fd8d7a691114e5c6ebb13e2e48852f08 Mon Sep 17 00:00:00 2001 From: Ryan Zhao Date: Tue, 29 Jun 2021 14:00:47 +1000 Subject: [PATCH 05/10] link event listener --- .../conversation/v2/ConversationActivityV2.kt | 34 ++++++++++++++++++- .../v2/menus/ConversationMenuHelper.kt | 3 +- .../conversation/v2/search/SearchBottomBar.kt | 2 -- 3 files changed, 34 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt index 89953bcc04..27b7f6a92a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt @@ -13,6 +13,8 @@ import android.util.TypedValue import android.view.* import android.widget.RelativeLayout import androidx.core.view.isVisible +import androidx.lifecycle.Observer +import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProviders import androidx.loader.app.LoaderManager import androidx.loader.content.Loader @@ -47,6 +49,8 @@ import org.thoughtcrime.securesms.conversation.v2.input_bar.mentions.MentionCand import org.thoughtcrime.securesms.conversation.v2.menus.ConversationActionModeCallback import org.thoughtcrime.securesms.conversation.v2.menus.ConversationMenuHelper import org.thoughtcrime.securesms.conversation.v2.messages.VisibleMessageView +import org.thoughtcrime.securesms.conversation.v2.search.SearchBottomBar +import org.thoughtcrime.securesms.conversation.v2.search.SearchViewModel import org.thoughtcrime.securesms.database.DatabaseFactory import org.thoughtcrime.securesms.database.DraftDatabase import org.thoughtcrime.securesms.database.DraftDatabase.Drafts @@ -70,8 +74,9 @@ import kotlin.math.* // price we pay is a bit of back and forth between the input bar and the conversation activity. class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDelegate, - InputBarRecordingViewDelegate, AttachmentManager.AttachmentListener { + InputBarRecordingViewDelegate, AttachmentManager.AttachmentListener, SearchBottomBar.EventListener { private val screenWidth = Resources.getSystem().displayMetrics.widthPixels + private var searchViewModel: SearchViewModel? = null private var linkPreviewViewModel: LinkPreviewViewModel? = null private var threadID: Long = -1 private var actionMode: ActionMode? = null @@ -151,6 +156,8 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe getLatestOpenGroupInfoIfNeeded() setUpBlockedBanner() setUpLinkPreviewObserver() + searchBottomBar.setEventListener(this) + setUpSearchResultObserver() scrollToFirstUnreadMessageIfNeeded() markAllAsRead() } @@ -751,9 +758,34 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe // endregion // region Search + private fun setUpSearchResultObserver() { + val searchViewModel = ViewModelProvider(this).get(SearchViewModel::class.java) + this.searchViewModel = searchViewModel + searchViewModel.searchResults.observe(this, Observer { result: SearchViewModel.SearchResult? -> + if (result == null) return@Observer + if (result.getResults().isNotEmpty()) { + conversationRecyclerView.scrollToPosition(result.position) + val messageResult = result.getResults()[result.position] +// fragment.jumpToMessage(messageResult.messageRecipient.address, messageResult.receivedTimestampMs, Runnable { searchViewModel.onMissingResult() }) + } + this.searchBottomBar.setData(result.position, result.getResults().size) + }) + } + + fun getSearchViewModel(): SearchViewModel? { + return this.searchViewModel + } + fun onSearchQueryUpdated(query: String?) { adapter.onSearchQueryUpdated(query) } + override fun onSearchMoveUpPressed() { + this.searchViewModel?.onMoveUp() + } + + override fun onSearchMoveDownPressed() { + this.searchViewModel?.onMoveDown() + } // endregion } \ No newline at end of file diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/menus/ConversationMenuHelper.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/menus/ConversationMenuHelper.kt index 4c3a72a9ed..226206d9d3 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/menus/ConversationMenuHelper.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/menus/ConversationMenuHelper.kt @@ -18,7 +18,6 @@ import kotlinx.android.synthetic.main.session_logo_action_bar_content.* import network.loki.messenger.R import org.session.libsession.utilities.ExpirationUtil import org.session.libsession.utilities.recipients.Recipient -import org.thoughtcrime.securesms.components.ConversationSearchBottomBar import org.thoughtcrime.securesms.conversation.v2.ConversationActivityV2 import org.thoughtcrime.securesms.conversation.v2.search.SearchViewModel import org.thoughtcrime.securesms.loki.utilities.getColorWithID @@ -73,7 +72,7 @@ object ConversationMenuHelper { // Search val searchViewItem = menu.findItem(R.id.menu_search) val searchView = searchViewItem.actionView as SearchView - val searchViewModel:SearchViewModel = ViewModelProvider(context as ConversationActivityV2).get(SearchViewModel::class.java) + val searchViewModel = (context as ConversationActivityV2).getSearchViewModel()!! val queryListener = object : OnQueryTextListener { override fun onQueryTextSubmit(query: String): Boolean { searchViewModel.onQueryUpdated(query, threadId) diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/search/SearchBottomBar.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/search/SearchBottomBar.kt index 93d24ff019..9565e6e107 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/search/SearchBottomBar.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/search/SearchBottomBar.kt @@ -5,8 +5,6 @@ import android.util.AttributeSet import android.view.LayoutInflater import android.view.View import android.widget.LinearLayout -import android.widget.RelativeLayout -import androidx.constraintlayout.widget.ConstraintLayout import kotlinx.android.synthetic.main.view_search_bottom_bar.view.* import network.loki.messenger.R From 1e787660a8f5a7822b5d3a04f741df0c1d61de45 Mon Sep 17 00:00:00 2001 From: Ryan Zhao Date: Tue, 29 Jun 2021 14:38:51 +1000 Subject: [PATCH 06/10] clean --- .../securesms/conversation/v2/search/SearchViewModel.kt | 4 ---- 1 file changed, 4 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/search/SearchViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/search/SearchViewModel.kt index f1d7c8a610..ac95af2fa1 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/search/SearchViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/search/SearchViewModel.kt @@ -27,10 +27,6 @@ class SearchViewModel(application: Application) : AndroidViewModel(application) get() = result fun onQueryUpdated(query: String, threadId: Long) { - if (firstSearch && query.length < 2) { - result.postValue(SearchResult(CursorList.emptyList(), 0)) - return - } if (query == activeQuery) { return } From 52305368bb9979fb366006c1359d291b762a5f58 Mon Sep 17 00:00:00 2001 From: Ryan Zhao Date: Tue, 29 Jun 2021 15:35:53 +1000 Subject: [PATCH 07/10] scroll to the position of a search result --- .../conversation/v2/ConversationActivityV2.kt | 23 ++++++++++++++++--- .../conversation/v2/search/SearchBottomBar.kt | 2 +- .../res/layout/view_search_bottom_bar.xml | 3 ++- 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt index 27b7f6a92a..36cd9d98dd 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt @@ -37,10 +37,13 @@ import org.session.libsession.messaging.messages.signal.OutgoingTextMessage import org.session.libsession.messaging.messages.visible.VisibleMessage import org.session.libsession.messaging.open_groups.OpenGroupAPIV2 import org.session.libsession.messaging.sending_receiving.MessageSender +import org.session.libsession.utilities.Address import org.session.libsession.utilities.TextSecurePreferences +import org.session.libsession.utilities.concurrent.SimpleTask import org.thoughtcrime.securesms.ApplicationContext import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity import org.thoughtcrime.securesms.contactshare.SimpleTextWatcher +import org.thoughtcrime.securesms.conversation.ConversationFragment import org.thoughtcrime.securesms.conversation.v2.dialogs.* import org.thoughtcrime.securesms.conversation.v2.input_bar.InputBarButton import org.thoughtcrime.securesms.conversation.v2.input_bar.InputBarDelegate @@ -764,9 +767,9 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe searchViewModel.searchResults.observe(this, Observer { result: SearchViewModel.SearchResult? -> if (result == null) return@Observer if (result.getResults().isNotEmpty()) { - conversationRecyclerView.scrollToPosition(result.position) - val messageResult = result.getResults()[result.position] -// fragment.jumpToMessage(messageResult.messageRecipient.address, messageResult.receivedTimestampMs, Runnable { searchViewModel.onMissingResult() }) + result.getResults()[result.position]?.let { + jumpToMessage(it.messageRecipient.address, it.receivedTimestampMs, Runnable { searchViewModel.onMissingResult() }) + } } this.searchBottomBar.setData(result.position, result.getResults().size) }) @@ -787,5 +790,19 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe override fun onSearchMoveDownPressed() { this.searchViewModel?.onMoveDown() } + + private fun jumpToMessage(author: Address, timestamp: Long, onMessageNotFound: Runnable?) { + SimpleTask.run(lifecycle, { + DatabaseFactory.getMmsSmsDatabase(this).getMessagePositionInConversation(threadID, timestamp, author) + }) { p: Int -> moveToMessagePosition(p, onMessageNotFound) } + } + + private fun moveToMessagePosition(position: Int, onMessageNotFound: Runnable?) { + if (position >= 0) { + conversationRecyclerView.scrollToPosition(position) + } else { + onMessageNotFound?.run() + } + } // endregion } \ No newline at end of file diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/search/SearchBottomBar.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/search/SearchBottomBar.kt index 9565e6e107..da8df0045a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/search/SearchBottomBar.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/search/SearchBottomBar.kt @@ -36,7 +36,7 @@ class SearchBottomBar : LinearLayout { if (count > 0) { searchPosition.text = resources.getString(R.string.ConversationActivity_search_position, position + 1, count) } else { - searchPosition.setText(R.string.ConversationActivity_no_results) + searchPosition.text = "" } setViewEnabled(searchUp, position < count - 1) setViewEnabled(searchDown, position > 0) diff --git a/app/src/main/res/layout/view_search_bottom_bar.xml b/app/src/main/res/layout/view_search_bottom_bar.xml index e794e75205..bb0395d28e 100644 --- a/app/src/main/res/layout/view_search_bottom_bar.xml +++ b/app/src/main/res/layout/view_search_bottom_bar.xml @@ -52,7 +52,8 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" - android:text="37 of 73" /> + android:text="37 of 73" + android:textStyle="bold"/> Date: Tue, 29 Jun 2021 16:20:55 +1000 Subject: [PATCH 08/10] fix spinning forever --- .../securesms/conversation/v2/menus/ConversationMenuHelper.kt | 3 --- 1 file changed, 3 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/menus/ConversationMenuHelper.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/menus/ConversationMenuHelper.kt index e708fa1ca9..c9f41c6511 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/menus/ConversationMenuHelper.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/menus/ConversationMenuHelper.kt @@ -99,9 +99,6 @@ object ConversationMenuHelper { val searchViewModel = (context as ConversationActivityV2).getSearchViewModel()!! val queryListener = object : OnQueryTextListener { override fun onQueryTextSubmit(query: String): Boolean { - searchViewModel.onQueryUpdated(query, threadId) - context.searchBottomBar.showLoading() - context.onSearchQueryUpdated(query) return true } From c5b117406e974f23e5a9a0b89aebc58717c21136 Mon Sep 17 00:00:00 2001 From: ryanzhao Date: Wed, 30 Jun 2021 10:59:35 +1000 Subject: [PATCH 09/10] fix spinner shows incorrectly the second time open search screen --- .../conversation/v2/menus/ConversationMenuHelper.kt | 11 ++++++----- .../conversation/v2/search/SearchViewModel.kt | 1 + 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/menus/ConversationMenuHelper.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/menus/ConversationMenuHelper.kt index c9f41c6511..ec58055a1d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/menus/ConversationMenuHelper.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/menus/ConversationMenuHelper.kt @@ -17,14 +17,14 @@ import android.widget.ImageView import android.widget.TextView import android.widget.Toast import androidx.annotation.ColorInt -import androidx.appcompat.widget.SearchView -import androidx.appcompat.widget.SearchView.OnQueryTextListener -import kotlinx.android.synthetic.main.activity_conversation_v2.* import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AppCompatActivity +import androidx.appcompat.widget.SearchView +import androidx.appcompat.widget.SearchView.OnQueryTextListener import androidx.core.content.pm.ShortcutInfoCompat import androidx.core.content.pm.ShortcutManagerCompat import androidx.core.graphics.drawable.IconCompat +import kotlinx.android.synthetic.main.activity_conversation_v2.* import network.loki.messenger.R import org.session.libsession.messaging.messages.control.ExpirationTimerUpdate import org.session.libsession.messaging.sending_receiving.MessageSender @@ -33,10 +33,10 @@ import org.session.libsession.utilities.ExpirationUtil import org.session.libsession.utilities.GroupUtil.doubleDecodeGroupID import org.session.libsession.utilities.TextSecurePreferences import org.session.libsession.utilities.recipients.Recipient -import org.thoughtcrime.securesms.conversation.v2.ConversationActivityV2 import org.session.libsignal.utilities.guava.Optional import org.session.libsignal.utilities.toHexString import org.thoughtcrime.securesms.* +import org.thoughtcrime.securesms.conversation.v2.ConversationActivityV2 import org.thoughtcrime.securesms.database.DatabaseFactory import org.thoughtcrime.securesms.loki.activities.EditClosedGroupActivity import org.thoughtcrime.securesms.loki.activities.EditClosedGroupActivity.Companion.groupIDKey @@ -163,7 +163,8 @@ object ConversationMenuHelper { } private fun search(context: Context) { - Toast.makeText(context, "Not yet implemented", Toast.LENGTH_LONG).show() // TODO: Implement + val searchViewModel = (context as ConversationActivityV2).getSearchViewModel()!! + searchViewModel.onSearchOpened() } @SuppressLint("StaticFieldLeak") diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/search/SearchViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/search/SearchViewModel.kt index ac95af2fa1..eb3dd50d98 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/search/SearchViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/search/SearchViewModel.kt @@ -60,6 +60,7 @@ class SearchViewModel(application: Application) : AndroidViewModel(application) fun onSearchClosed() { searchOpen = false + activeQuery = null debouncer.clear() result.close() } From 55ad96dcf71a9e6c99fa6be03afa6d76f29c0f38 Mon Sep 17 00:00:00 2001 From: ryanzhao Date: Wed, 30 Jun 2021 11:44:26 +1000 Subject: [PATCH 10/10] hide search screen when long pressing --- .../conversation/v2/ConversationActivityV2.kt | 22 +++++++++---------- .../v2/menus/ConversationMenuHelper.kt | 5 +++-- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt index 363fcab014..a6e94b294b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt @@ -3,15 +3,14 @@ package org.thoughtcrime.securesms.conversation.v2 import android.Manifest import android.animation.FloatEvaluator import android.animation.ValueAnimator -import android.content.Context import android.content.ClipData import android.content.ClipboardManager +import android.content.Context import android.content.Intent import android.content.res.Resources import android.database.Cursor import android.graphics.Rect import android.graphics.Typeface -import android.os.Bundle import android.net.Uri import android.os.* import android.text.TextUtils @@ -53,14 +52,14 @@ import org.session.libsession.messaging.messages.visible.OpenGroupInvitation import org.session.libsession.messaging.messages.visible.VisibleMessage import org.session.libsession.messaging.open_groups.OpenGroupAPIV2 import org.session.libsession.messaging.sending_receiving.MessageSender -import org.session.libsession.utilities.Address -import org.session.libsession.utilities.TextSecurePreferences -import org.session.libsession.utilities.concurrent.SimpleTask import org.session.libsession.messaging.sending_receiving.attachments.Attachment import org.session.libsession.messaging.sending_receiving.link_preview.LinkPreview import org.session.libsession.messaging.sending_receiving.quotes.QuoteModel +import org.session.libsession.utilities.Address import org.session.libsession.utilities.Address.Companion.fromSerialized import org.session.libsession.utilities.MediaTypes +import org.session.libsession.utilities.TextSecurePreferences +import org.session.libsession.utilities.concurrent.SimpleTask import org.session.libsession.utilities.recipients.Recipient import org.session.libsignal.utilities.ListenableFuture import org.session.libsignal.utilities.ThreadUtils @@ -90,11 +89,11 @@ import org.thoughtcrime.securesms.linkpreview.LinkPreviewRepository import org.thoughtcrime.securesms.linkpreview.LinkPreviewUtil import org.thoughtcrime.securesms.linkpreview.LinkPreviewViewModel import org.thoughtcrime.securesms.linkpreview.LinkPreviewViewModel.LinkPreviewState -import org.thoughtcrime.securesms.loki.utilities.ActivityDispatcher -import org.thoughtcrime.securesms.loki.utilities.push import org.thoughtcrime.securesms.loki.activities.SelectContactsActivity import org.thoughtcrime.securesms.loki.activities.SelectContactsActivity.Companion.selectedContactsKey +import org.thoughtcrime.securesms.loki.utilities.ActivityDispatcher import org.thoughtcrime.securesms.loki.utilities.MentionUtilities +import org.thoughtcrime.securesms.loki.utilities.push import org.thoughtcrime.securesms.loki.utilities.toPx import org.thoughtcrime.securesms.mediasend.Media import org.thoughtcrime.securesms.mediasend.MediaSendActivity @@ -116,7 +115,6 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe InputBarRecordingViewDelegate, AttachmentManager.AttachmentListener, ActivityDispatcher, ConversationActionModeCallbackDelegate, SearchBottomBar.EventListener { private val screenWidth = Resources.getSystem().displayMetrics.widthPixels - private var searchViewModel: SearchViewModel? = null private var linkPreviewViewModel: LinkPreviewViewModel? = null private var threadID: Long = -1 private var actionMode: ActionMode? = null @@ -134,6 +132,9 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe private var previousText: CharSequence = "" private var currentMentionStartIndex = -1 private var isShowingMentionCandidatesView = false + // Search + var searchViewModel: SearchViewModel? = null + var searchViewItem: MenuItem? = null private val layoutManager: LinearLayoutManager get() { return conversationRecyclerView.layoutManager as LinearLayoutManager } @@ -650,6 +651,7 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe val actionMode = this.actionMode val actionModeCallback = ConversationActionModeCallback(adapter, threadID, this) actionModeCallback.delegate = this + searchViewItem?.collapseActionView() if (actionMode == null) { // Nothing should be selected if this is the case adapter.toggleSelection(message, position) this.actionMode = if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) { @@ -1138,10 +1140,6 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe }) } - fun getSearchViewModel(): SearchViewModel? { - return this.searchViewModel - } - fun onSearchQueryUpdated(query: String?) { adapter.onSearchQueryUpdated(query) } diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/menus/ConversationMenuHelper.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/menus/ConversationMenuHelper.kt index ec58055a1d..23a1758656 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/menus/ConversationMenuHelper.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/menus/ConversationMenuHelper.kt @@ -95,8 +95,9 @@ object ConversationMenuHelper { // Search val searchViewItem = menu.findItem(R.id.menu_search) + (context as ConversationActivityV2).searchViewItem = searchViewItem val searchView = searchViewItem.actionView as SearchView - val searchViewModel = (context as ConversationActivityV2).getSearchViewModel()!! + val searchViewModel = context.searchViewModel!! val queryListener = object : OnQueryTextListener { override fun onQueryTextSubmit(query: String): Boolean { return true @@ -163,7 +164,7 @@ object ConversationMenuHelper { } private fun search(context: Context) { - val searchViewModel = (context as ConversationActivityV2).getSearchViewModel()!! + val searchViewModel = (context as ConversationActivityV2).searchViewModel!! searchViewModel.onSearchOpened() }