From 2c1226dc0220301bec8c9d9bce3cac4e18f6c2b8 Mon Sep 17 00:00:00 2001 From: jeffrey-signal Date: Fri, 27 Feb 2026 22:27:58 -0500 Subject: [PATCH] Fix groups v1 migration suggestions dialog crash. --- .../conversation/v2/ConversationFragment.kt | 4 +- .../GroupsV1MigrationSuggestionsDialog.java | 80 ++++++++++++------- 2 files changed, 53 insertions(+), 31 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationFragment.kt index 730085d139..8c26fee901 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationFragment.kt @@ -1252,7 +1252,7 @@ class ConversationFragment : groupJoinClickListener = conversationBannerListener::reviewJoinRequestsAction, onSuggestionAddMembers = { conversationGroupViewModel.groupRecordSnapshot?.let { groupRecord -> - GroupsV1MigrationSuggestionsDialog.show(requireActivity(), groupRecord.id.requireV2(), groupRecord.gv1MigrationSuggestions) + GroupsV1MigrationSuggestionsDialog.show(childFragmentManager, groupRecord.id.requireV2(), groupRecord.gv1MigrationSuggestions) } }, onSuggestionNoThanks = conversationGroupViewModel::onSuggestedMembersBannerDismissed, @@ -4293,7 +4293,7 @@ class ConversationFragment : override fun gv1SuggestionsAction(actionId: Int) { if (actionId == R.id.reminder_action_gv1_suggestion_add_members) { conversationGroupViewModel.groupRecordSnapshot?.let { groupRecord -> - GroupsV1MigrationSuggestionsDialog.show(requireActivity(), groupRecord.id.requireV2(), groupRecord.gv1MigrationSuggestions) + GroupsV1MigrationSuggestionsDialog.show(childFragmentManager, groupRecord.id.requireV2(), groupRecord.gv1MigrationSuggestions) } } else if (actionId == R.id.reminder_action_gv1_suggestion_no_thanks) { conversationGroupViewModel.onSuggestedMembersBannerDismissed() diff --git a/app/src/main/java/org/thoughtcrime/securesms/groups/ui/migration/GroupsV1MigrationSuggestionsDialog.java b/app/src/main/java/org/thoughtcrime/securesms/groups/ui/migration/GroupsV1MigrationSuggestionsDialog.java index b88a74e853..dd492bea21 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/groups/ui/migration/GroupsV1MigrationSuggestionsDialog.java +++ b/app/src/main/java/org/thoughtcrime/securesms/groups/ui/migration/GroupsV1MigrationSuggestionsDialog.java @@ -1,11 +1,15 @@ package org.thoughtcrime.securesms.groups.ui.migration; +import android.app.Dialog; import android.content.DialogInterface; +import android.os.Bundle; import android.widget.Toast; import androidx.annotation.NonNull; -import androidx.appcompat.app.AlertDialog; +import androidx.annotation.Nullable; +import androidx.fragment.app.DialogFragment; import androidx.fragment.app.FragmentActivity; +import androidx.fragment.app.FragmentManager; import com.google.android.material.dialog.MaterialAlertDialogBuilder; @@ -27,57 +31,75 @@ import org.thoughtcrime.securesms.recipients.RecipientId; import org.thoughtcrime.securesms.util.views.SimpleProgressDialog; import java.io.IOException; +import java.util.ArrayList; import java.util.List; +import java.util.Objects; /** * Shows a list of members that got lost when migrating from a V1->V2 group, giving you the chance * to add them back. */ -public final class GroupsV1MigrationSuggestionsDialog { +public final class GroupsV1MigrationSuggestionsDialog extends DialogFragment { - private static final String TAG = Log.tag(GroupsV1MigrationSuggestionsDialog.class); + private static final String TAG = Log.tag(GroupsV1MigrationSuggestionsDialog.class); + private static final String FRAGMENT_TAG = "GroupsV1MigrationSuggestionsDialog"; - private final FragmentActivity fragmentActivity; - private final GroupId.V2 groupId; - private final List suggestions; + private static final String ARG_GROUP_ID = "group_id"; + private static final String ARG_SUGGESTIONS = "suggestions"; - public static void show(@NonNull FragmentActivity activity, + private GroupId.V2 groupId; + private List suggestions; + + public static void show(@NonNull FragmentManager fragmentManager, @NonNull GroupId.V2 groupId, @NonNull List suggestions) { - new GroupsV1MigrationSuggestionsDialog(activity, groupId, suggestions).display(); + Bundle args = new Bundle(); + args.putParcelable(ARG_GROUP_ID, groupId); + args.putParcelableArrayList(ARG_SUGGESTIONS, new ArrayList<>(suggestions)); + + GroupsV1MigrationSuggestionsDialog fragment = new GroupsV1MigrationSuggestionsDialog(); + fragment.setArguments(args); + fragment.show(fragmentManager, FRAGMENT_TAG); } - private GroupsV1MigrationSuggestionsDialog(@NonNull FragmentActivity activity, - @NonNull GroupId.V2 groupId, - @NonNull List suggestions) - { - this.fragmentActivity = activity; - this.groupId = groupId; - this.suggestions = suggestions; + @Override + public void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + groupId = ((GroupId) Objects.requireNonNull(requireArguments().getParcelable(ARG_GROUP_ID))).requireV2(); + suggestions = Objects.requireNonNull(requireArguments().getParcelableArrayList(ARG_SUGGESTIONS)); } - private void display() { - AlertDialog dialog = new MaterialAlertDialogBuilder(fragmentActivity) - .setTitle(fragmentActivity.getResources().getQuantityString(R.plurals.GroupsV1MigrationSuggestionsDialog_add_members_question, suggestions.size())) - .setMessage(fragmentActivity.getResources().getQuantityString(R.plurals.GroupsV1MigrationSuggestionsDialog_these_members_couldnt_be_automatically_added, suggestions.size())) - .setView(R.layout.dialog_group_members) - .setPositiveButton(fragmentActivity.getResources().getQuantityString(R.plurals.GroupsV1MigrationSuggestionsDialog_add_members, suggestions.size()), (d, i) -> onAddClicked(d)) - .setNegativeButton(android.R.string.cancel, (d, i) -> d.dismiss()) - .show(); + @Override + public @NonNull Dialog onCreateDialog(@Nullable Bundle savedInstanceState) { + return new MaterialAlertDialogBuilder(requireContext()) + .setTitle(requireContext().getResources().getQuantityString(R.plurals.GroupsV1MigrationSuggestionsDialog_add_members_question, suggestions.size())) + .setMessage(requireContext().getResources().getQuantityString(R.plurals.GroupsV1MigrationSuggestionsDialog_these_members_couldnt_be_automatically_added, suggestions.size())) + .setView(R.layout.dialog_group_members) + .setPositiveButton(requireContext().getResources().getQuantityString(R.plurals.GroupsV1MigrationSuggestionsDialog_add_members, suggestions.size()), (d, i) -> onAddClicked(d)) + .setNegativeButton(android.R.string.cancel, (d, i) -> d.dismiss()) + .create(); + } - GroupMemberListView memberListView = dialog.findViewById(R.id.list_members); - memberListView.initializeAdapter(fragmentActivity); + @Override + public void onStart() { + super.onStart(); + + GroupMemberListView memberListView = requireDialog().findViewById(R.id.list_members); + + memberListView.initializeAdapter(this); SimpleTask.run(() -> Recipient.resolvedList(suggestions), memberListView::setDisplayOnlyMembers); } private void onAddClicked(@NonNull DialogInterface rootDialog) { - SimpleProgressDialog.DismissibleDialog progressDialog = SimpleProgressDialog.showDelayed(fragmentActivity, 300, 0); + FragmentActivity activity = requireActivity(); + + SimpleProgressDialog.DismissibleDialog progressDialog = SimpleProgressDialog.showDelayed(activity, 300, 0); SimpleTask.run(SignalExecutors.UNBOUNDED, () -> { try { - GroupManager.addMembers(fragmentActivity, groupId.requirePush(), suggestions); + GroupManager.addMembers(activity, groupId.requirePush(), suggestions); Log.i(TAG, "Successfully added members! Removing these dropped members from the list."); SignalDatabase.groups().removeUnmigratedV1Members(groupId); return Result.SUCCESS; @@ -95,10 +117,10 @@ public final class GroupsV1MigrationSuggestionsDialog { switch (result) { case NETWORK_ERROR: - Toast.makeText(fragmentActivity, fragmentActivity.getResources().getQuantityText(R.plurals.GroupsV1MigrationSuggestionsDialog_failed_to_add_members_try_again_later, suggestions.size()), Toast.LENGTH_SHORT).show(); + Toast.makeText(activity, activity.getResources().getQuantityText(R.plurals.GroupsV1MigrationSuggestionsDialog_failed_to_add_members_try_again_later, suggestions.size()), Toast.LENGTH_SHORT).show(); break; case IMPOSSIBLE: - Toast.makeText(fragmentActivity, fragmentActivity.getResources().getQuantityText(R.plurals.GroupsV1MigrationSuggestionsDialog_cannot_add_members, suggestions.size()), Toast.LENGTH_SHORT).show(); + Toast.makeText(activity, activity.getResources().getQuantityText(R.plurals.GroupsV1MigrationSuggestionsDialog_cannot_add_members, suggestions.size()), Toast.LENGTH_SHORT).show(); break; } });