From 3b3ef0d54516af102edb8cc064d96b12235abcea Mon Sep 17 00:00:00 2001 From: Greyson Parrelli Date: Tue, 10 Feb 2026 11:30:05 -0500 Subject: [PATCH] Allow some context menu actions in search. --- .../ConversationListFragment.java | 39 ++++++++++++------- .../ConversationListSearchAdapter.kt | 8 +++- 2 files changed, 33 insertions(+), 14 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversationlist/ConversationListFragment.java b/app/src/main/java/org/thoughtcrime/securesms/conversationlist/ConversationListFragment.java index 32c629b41a..00181825f0 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversationlist/ConversationListFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/conversationlist/ConversationListFragment.java @@ -1267,6 +1267,10 @@ public class ConversationListFragment extends MainFragment implements Conversati @Override public boolean onConversationLongClick(@NonNull Conversation conversation, @NonNull View view) { + return showConversationContextMenu(conversation, view, false); + } + + private boolean showConversationContextMenu(@NonNull Conversation conversation, @NonNull View view, boolean isFromSearch) { if (list == null) { Log.w(TAG, "List is null, ignoring long click."); return true; @@ -1308,23 +1312,27 @@ public class ConversationListFragment extends MainFragment implements Conversati } } - items.add(new ActionItem(org.signal.core.ui.R.drawable.symbol_check_circle_24, getString(R.string.ConversationListFragment_select), () -> { - viewModel.startSelection(conversation); - startActionMode(); - })); + if (!isFromSearch) { + items.add(new ActionItem(org.signal.core.ui.R.drawable.symbol_check_circle_24, getString(R.string.ConversationListFragment_select), () -> { + viewModel.startSelection(conversation); + startActionMode(); + })); + } if (conversation.getThreadRecord().isArchived()) { items.add(new ActionItem(R.drawable.symbol_archive_up_24, getResources().getString(R.string.ConversationListFragment_unarchive), () -> handleArchive(id))); } else { - if (viewModel.getCurrentFolder().getFolderType() == ChatFolderRecord.FolderType.ALL && - (conversation.getThreadRecord().getRecipient().isIndividual() || - conversation.getThreadRecord().getRecipient().isPushV2Group())) - { - items.add(new ActionItem(R.drawable.symbol_folder_add, getString(R.string.ConversationListFragment_add_to_folder), () -> - showAddToFolderBottomSheet(conversation) - )); - } else if (viewModel.getCurrentFolder().getFolderType() != ChatFolderRecord.FolderType.ALL) { - items.add(new ActionItem(R.drawable.symbol_folder_minus, getString(R.string.ConversationListFragment_remove_from_folder), () -> viewModel.removeChatFromFolder(conversation.getThreadRecord().getThreadId()))); + if (!isFromSearch) { + if (viewModel.getCurrentFolder().getFolderType() == ChatFolderRecord.FolderType.ALL && + (conversation.getThreadRecord().getRecipient().isIndividual() || + conversation.getThreadRecord().getRecipient().isPushV2Group())) + { + items.add(new ActionItem(R.drawable.symbol_folder_add, getString(R.string.ConversationListFragment_add_to_folder), () -> + showAddToFolderBottomSheet(conversation) + )); + } else if (viewModel.getCurrentFolder().getFolderType() != ChatFolderRecord.FolderType.ALL) { + items.add(new ActionItem(R.drawable.symbol_folder_minus, getString(R.string.ConversationListFragment_remove_from_folder), () -> viewModel.removeChatFromFolder(conversation.getThreadRecord().getThreadId()))); + } } items.add(new ActionItem(R.drawable.symbol_archive_24, getResources().getString(R.string.ConversationListFragment_archive), () -> handleArchive(id))); } @@ -1845,6 +1853,11 @@ public class ConversationListFragment extends MainFragment implements Conversati onConversationClicked(thread.getThreadRecord()); } + @Override + public boolean onThreadLongClicked(@NonNull View view, @NonNull ContactSearchData.Thread thread) { + return showConversationContextMenu(new Conversation(thread.getThreadRecord()), view, true); + } + @Override public void onMessageClicked(@NonNull View view, @NonNull ContactSearchData.Message thread, boolean isSelected) { ConversationListFragment.this.onMessageClicked(thread.getMessageResult()); diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversationlist/ConversationListSearchAdapter.kt b/app/src/main/java/org/thoughtcrime/securesms/conversationlist/ConversationListSearchAdapter.kt index 8312871e37..ef360d16fb 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversationlist/ConversationListSearchAdapter.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversationlist/ConversationListSearchAdapter.kt @@ -42,7 +42,7 @@ class ConversationListSearchAdapter( init { registerFactory( ThreadModel::class.java, - LayoutFactory({ ThreadViewHolder(onClickedCallbacks::onThreadClicked, lifecycleOwner, requestManager, it) }, R.layout.conversation_list_item_view) + LayoutFactory({ ThreadViewHolder(onClickedCallbacks::onThreadClicked, onClickedCallbacks::onThreadLongClicked, lifecycleOwner, requestManager, it) }, R.layout.conversation_list_item_view) ) registerFactory( MessageModel::class.java, @@ -104,6 +104,7 @@ class ConversationListSearchAdapter( private class ThreadViewHolder( private val threadListener: OnClickedCallback, + private val threadLongClickListener: (View, ContactSearchData.Thread) -> Boolean, private val lifecycleOwner: LifecycleOwner, private val requestManager: RequestManager, itemView: View @@ -113,6 +114,10 @@ class ConversationListSearchAdapter( threadListener.onClicked(itemView, model.thread, false) } + itemView.setOnLongClickListener { + threadLongClickListener(itemView, model.thread) + } + (itemView as ConversationListItem).bindThread( lifecycleOwner, model.thread.threadRecord, @@ -231,6 +236,7 @@ class ConversationListSearchAdapter( interface ConversationListSearchClickCallbacks : ClickCallbacks { fun onThreadClicked(view: View, thread: ContactSearchData.Thread, isSelected: Boolean) + fun onThreadLongClicked(view: View, thread: ContactSearchData.Thread): Boolean fun onMessageClicked(view: View, thread: ContactSearchData.Message, isSelected: Boolean) fun onGroupWithMembersClicked(view: View, groupWithMembers: ContactSearchData.GroupWithMembers, isSelected: Boolean) fun onClearFilterClicked()