From 72050dbe64c174102e045037ed37b14fa0335ca7 Mon Sep 17 00:00:00 2001 From: Greyson Parrelli Date: Tue, 23 Jun 2026 15:54:35 -0400 Subject: [PATCH] Make same-group-membership helper available for all users. --- .../settings/app/labs/LabsSettingsEvents.kt | 1 - .../settings/app/labs/LabsSettingsFragment.kt | 9 --- .../settings/app/labs/LabsSettingsState.kt | 1 - .../app/labs/LabsSettingsViewModel.kt | 5 -- .../details/AddGroupDetailsFragment.java | 58 +++++++++++++------ .../securesms/keyvalue/LabsValues.kt | 3 - .../res/layout/add_group_details_fragment.xml | 5 +- app/src/main/res/values/strings.xml | 13 ++++- 8 files changed, 54 insertions(+), 41 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/labs/LabsSettingsEvents.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/labs/LabsSettingsEvents.kt index 76a4d217d6..355d528679 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/labs/LabsSettingsEvents.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/labs/LabsSettingsEvents.kt @@ -9,7 +9,6 @@ sealed interface LabsSettingsEvents { data class ToggleIndividualChatPlaintextExport(val enabled: Boolean) : LabsSettingsEvents data class ToggleStoryArchive(val enabled: Boolean) : LabsSettingsEvents data class ToggleIncognito(val enabled: Boolean) : LabsSettingsEvents - data class ToggleGroupSuggestionsForMembers(val enabled: Boolean) : LabsSettingsEvents data class ToggleBetterSearch(val enabled: Boolean) : LabsSettingsEvents data class ToggleAutoLowerHand(val enabled: Boolean) : LabsSettingsEvents data class ToggleStarredMessages(val enabled: Boolean) : LabsSettingsEvents diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/labs/LabsSettingsFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/labs/LabsSettingsFragment.kt index 01fb0915fc..e68d950901 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/labs/LabsSettingsFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/labs/LabsSettingsFragment.kt @@ -116,15 +116,6 @@ private fun LabsSettingsContent( ) } - item { - Rows.ToggleRow( - checked = state.groupSuggestionsForMembers, - text = "Group Suggestions for Members", - label = "When creating a group, show existing groups that have the exact same members.", - onCheckChanged = { onEvent(LabsSettingsEvents.ToggleGroupSuggestionsForMembers(it)) } - ) - } - item { Rows.ToggleRow( checked = state.betterSearch, diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/labs/LabsSettingsState.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/labs/LabsSettingsState.kt index b5a2fbbcb5..195389d998 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/labs/LabsSettingsState.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/labs/LabsSettingsState.kt @@ -12,7 +12,6 @@ data class LabsSettingsState( val individualChatPlaintextExport: Boolean = false, val storyArchive: Boolean = false, val incognito: Boolean = false, - val groupSuggestionsForMembers: Boolean = false, val betterSearch: Boolean = false, val autoLowerHand: Boolean = false, val starredMessages: Boolean = false diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/labs/LabsSettingsViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/labs/LabsSettingsViewModel.kt index d931769b0a..18add3164f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/labs/LabsSettingsViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/labs/LabsSettingsViewModel.kt @@ -29,10 +29,6 @@ class LabsSettingsViewModel : ViewModel() { SignalStore.labs.incognito = event.enabled _state.value = _state.value.copy(incognito = event.enabled) } - is LabsSettingsEvents.ToggleGroupSuggestionsForMembers -> { - SignalStore.labs.groupSuggestionsForMembers = event.enabled - _state.value = _state.value.copy(groupSuggestionsForMembers = event.enabled) - } is LabsSettingsEvents.ToggleBetterSearch -> { SignalStore.labs.betterSearch = event.enabled _state.value = _state.value.copy(betterSearch = event.enabled) @@ -54,7 +50,6 @@ class LabsSettingsViewModel : ViewModel() { individualChatPlaintextExport = SignalStore.labs.individualChatPlaintextExport, storyArchive = SignalStore.labs.storyArchive, incognito = SignalStore.labs.incognito, - groupSuggestionsForMembers = SignalStore.labs.groupSuggestionsForMembers, betterSearch = SignalStore.labs.betterSearch, autoLowerHand = SignalStore.labs.autoLowerHand, starredMessages = SignalStore.labs.starredMessages diff --git a/app/src/main/java/org/thoughtcrime/securesms/groups/ui/creategroup/details/AddGroupDetailsFragment.java b/app/src/main/java/org/thoughtcrime/securesms/groups/ui/creategroup/details/AddGroupDetailsFragment.java index 1c15b812a5..5faeccc9c3 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/groups/ui/creategroup/details/AddGroupDetailsFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/groups/ui/creategroup/details/AddGroupDetailsFragment.java @@ -3,6 +3,7 @@ package org.thoughtcrime.securesms.groups.ui.creategroup.details; import android.app.Activity; import android.content.Context; import android.content.Intent; +import android.content.res.ColorStateList; import android.graphics.Bitmap; import android.graphics.drawable.Drawable; import android.graphics.drawable.InsetDrawable; @@ -155,27 +156,35 @@ public class AddGroupDetailsFragment extends LoggingFragment { }); View sameGroupsSection = view.findViewById(R.id.same_groups_section); + TextView sameGroupsHeader = view.findViewById(R.id.same_groups_header); ChipGroup sameGroupsChipGroup = view.findViewById(R.id.same_groups_chip_group); - if (SignalStore.labs().getGroupSuggestionsForMembers()) { - viewModel.getSameGroups().observe(getViewLifecycleOwner(), groups -> { - sameGroupsChipGroup.removeAllViews(); - if (groups.isEmpty()) { - sameGroupsSection.setVisibility(View.GONE); - } else { - sameGroupsSection.setVisibility(View.VISIBLE); - RequestManager requestManager = Glide.with(this); - for (Recipient group : groups) { - ContactChip chip = new ContactChip(requireContext()); - chip.setText(group.getDisplayName(requireContext())); - chip.setAvatar(requestManager, group, null); - chip.setCloseIconVisible(false); - chip.setOnClickListener(v -> navigateToConversation(group.getId())); - sameGroupsChipGroup.addView(chip); - } + viewModel.getSameGroups().observe(getViewLifecycleOwner(), groups -> { + sameGroupsChipGroup.removeAllViews(); + if (groups.isEmpty()) { + sameGroupsSection.setVisibility(View.GONE); + } else { + sameGroupsSection.setVisibility(View.VISIBLE); + sameGroupsHeader.setText(getResources().getQuantityString(R.plurals.AddGroupDetailsFragment__d_groups_with_same_members, groups.size(), groups.size())); + + RequestManager requestManager = Glide.with(this); + ColorStateList chevronTint = ColorStateList.valueOf(ContextCompat.getColor(requireContext(), org.signal.core.ui.R.color.signal_colorOnSurface)); + for (Recipient group : groups) { + ContactChip chip = new ContactChip(requireContext()); + chip.setText(group.getDisplayName(requireContext())); + chip.setAvatar(requestManager, group, null); + chip.setCloseIcon(ContextCompat.getDrawable(requireContext(), R.drawable.symbol_chevron_right_compact_bold_16)); + chip.setCloseIconSize(ViewUtil.dpToPx(14)); + chip.setCloseIconEndPadding(0); + chip.setCloseIconStartPadding(0); + chip.setCloseIconTint(chevronTint); + chip.setCloseIconVisible(true); + chip.setOnClickListener(v -> confirmNavigateToConversation(group)); + chip.setOnCloseIconClickListener(v -> confirmNavigateToConversation(group)); + sameGroupsChipGroup.addView(chip); } - }); - } + } + }); name.requestFocus(); @@ -293,6 +302,19 @@ public class AddGroupDetailsFragment extends LoggingFragment { create.setEnabled(isEnabled); } + private void confirmNavigateToConversation(@NonNull Recipient group) { + new MaterialAlertDialogBuilder(requireContext()) + .setTitle(R.string.AddGroupDetailsFragment__discard_group) + .setMessage(getString(R.string.AddGroupDetailsFragment__if_you_continue_to_the_group_s_your_changes_wont_be_saved, group.getDisplayName(requireContext()))) + .setCancelable(true) + .setNegativeButton(android.R.string.cancel, (dialog, which) -> dialog.cancel()) + .setPositiveButton(R.string.AddGroupDetailsFragment__discard, (dialog, which) -> { + dialog.dismiss(); + navigateToConversation(group.getId()); + }) + .show(); + } + private void navigateToConversation(@NonNull RecipientId groupRecipientId) { ConversationIntents.createBuilder(requireContext(), groupRecipientId, -1L) .subscribe(builder -> { diff --git a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/LabsValues.kt b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/LabsValues.kt index 73f70e208f..5cce588892 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/LabsValues.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/LabsValues.kt @@ -7,7 +7,6 @@ class LabsValues internal constructor(store: KeyValueStore) : SignalStoreValues( const val INDIVIDUAL_CHAT_PLAINTEXT_EXPORT: String = "labs.individual_chat_plaintext_export" const val STORY_ARCHIVE: String = "labs.story_archive" const val INCOGNITO: String = "labs.incognito" - const val GROUP_SUGGESTIONS_FOR_MEMBERS: String = "labs.group_suggestions_for_members" const val BETTER_SEARCH: String = "labs.better_search" const val AUTO_LOWER_HAND: String = "labs.auto_lower_hand" const val STARRED_MESSAGES: String = "labs.starred_messages" @@ -23,8 +22,6 @@ class LabsValues internal constructor(store: KeyValueStore) : SignalStoreValues( var incognito by booleanValue(INCOGNITO, true).falseForExternalUsers() - var groupSuggestionsForMembers by booleanValue(GROUP_SUGGESTIONS_FOR_MEMBERS, true).falseForExternalUsers() - var betterSearch by booleanValue(BETTER_SEARCH, true).falseForExternalUsers() var autoLowerHand by booleanValue(AUTO_LOWER_HAND, true).falseForExternalUsers() diff --git a/app/src/main/res/layout/add_group_details_fragment.xml b/app/src/main/res/layout/add_group_details_fragment.xml index ba211dd714..ddcae6b9af 100644 --- a/app/src/main/res/layout/add_group_details_fragment.xml +++ b/app/src/main/res/layout/add_group_details_fragment.xml @@ -128,13 +128,14 @@ tools:visibility="visible"> + android:textAppearance="@style/Signal.Text.TitleSmall" + tools:text="4 groups with the same members" /> Remove SMS contact Remove %1$s from this group? + + Discard group? + + If you continue to the group \"%1$s\" your changes won\'t be saved. + + Discard You\'ve selected a contact that doesn\'t support Signal groups, so this group will be MMS. Custom MMS group names and photos will only be visible to you. @@ -9840,8 +9846,11 @@ In this group, your Member Label will be displayed beside your photo in place of your About. - - Groups with same members (Labs) + + + %1$d group with the same members + %1$d groups with the same members + Can\'t restore backup