New Conversation v2 - Fix find by username/phone options disappearing after rotation.

This commit is contained in:
jeffrey-signal
2025-10-09 14:01:40 -04:00
committed by Cody Henthorne
parent eea89d3b62
commit b49074a786
14 changed files with 175 additions and 135 deletions

View File

@@ -29,6 +29,7 @@ import org.signal.core.util.logging.Log;
import org.thoughtcrime.securesms.components.ContactFilterView;
import org.thoughtcrime.securesms.contacts.ContactSelectionDisplayMode;
import org.thoughtcrime.securesms.contacts.paged.ChatType;
import org.thoughtcrime.securesms.contacts.selection.ContactSelectionArguments;
import org.thoughtcrime.securesms.contacts.sync.ContactDiscovery;
import org.thoughtcrime.securesms.recipients.RecipientId;
import org.thoughtcrime.securesms.util.DynamicNoActionBarTheme;
@@ -69,9 +70,9 @@ public abstract class ContactSelectionActivity extends PassphraseRequiredActivit
@Override
protected void onCreate(Bundle icicle, boolean ready) {
if (!getIntent().hasExtra(ContactSelectionListFragment.DISPLAY_MODE)) {
if (!getIntent().hasExtra(ContactSelectionArguments.DISPLAY_MODE)) {
int displayMode = ContactSelectionDisplayMode.FLAG_PUSH | ContactSelectionDisplayMode.FLAG_ACTIVE_GROUPS | ContactSelectionDisplayMode.FLAG_INACTIVE_GROUPS | ContactSelectionDisplayMode.FLAG_SELF;
getIntent().putExtra(ContactSelectionListFragment.DISPLAY_MODE, displayMode);
getIntent().putExtra(ContactSelectionArguments.DISPLAY_MODE, displayMode);
}
setContentView(getIntent().getIntExtra(EXTRA_LAYOUT_RES_ID, R.layout.contact_selection_activity));

View File

@@ -20,7 +20,6 @@ package org.thoughtcrime.securesms;
import android.Manifest;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.graphics.Rect;
import android.os.AsyncTask;
import android.os.Bundle;
@@ -66,6 +65,7 @@ import org.thoughtcrime.securesms.contacts.paged.ContactSearchKey;
import org.thoughtcrime.securesms.contacts.paged.ContactSearchMediator;
import org.thoughtcrime.securesms.contacts.paged.ContactSearchSortOrder;
import org.thoughtcrime.securesms.contacts.paged.ContactSearchState;
import org.thoughtcrime.securesms.contacts.selection.ContactSelectionArguments;
import org.thoughtcrime.securesms.contacts.sync.ContactDiscovery;
import org.thoughtcrime.securesms.database.RecipientTable;
import org.thoughtcrime.securesms.groups.SelectionLimits;
@@ -86,7 +86,6 @@ import org.thoughtcrime.securesms.util.views.SimpleProgressDialog;
import java.io.IOException;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
@@ -97,7 +96,7 @@ import io.reactivex.rxjava3.disposables.Disposable;
import kotlin.Unit;
/**
* Fragment for selecting a one or more contacts from a list.
* Fragment for selecting one or more contacts from a list.
*
* @author Moxie Marlinspike
*/
@@ -110,17 +109,7 @@ public final class ContactSelectionListFragment extends LoggingFragment {
public static final int NO_LIMIT = Integer.MAX_VALUE;
public static final String DISPLAY_MODE = "display_mode";
public static final String REFRESHABLE = "refreshable";
public static final String RECENTS = "recents";
public static final String SELECTION_LIMITS = "selection_limits";
public static final String CURRENT_SELECTION = "current_selection";
public static final String HIDE_COUNT = "hide_count";
public static final String CAN_SELECT_SELF = "can_select_self";
public static final String DISPLAY_CHIPS = "display_chips";
public static final String RV_PADDING_BOTTOM = "recycler_view_padding_bottom";
public static final String RV_CLIP = "recycler_view_clipping";
public static final String INCLUDE_CHAT_TYPES = "include_chat_types";
private ContactSelectionArguments fragmentArgs;
private ConstraintLayout constraintLayout;
private TextView emptyText;
@@ -161,7 +150,7 @@ public final class ContactSelectionListFragment extends LoggingFragment {
}
if (context instanceof FindByCallback) {
showFindByUsernameAndPhoneOptions((FindByCallback) context);
setFindByCallback((FindByCallback) context);
}
if (context instanceof NewCallCallback) {
@@ -209,7 +198,7 @@ public final class ContactSelectionListFragment extends LoggingFragment {
}
}
public void showFindByUsernameAndPhoneOptions(@Nullable FindByCallback callback) {
public void setFindByCallback(@Nullable FindByCallback callback) {
this.findByCallback = callback;
}
@@ -275,28 +264,20 @@ public final class ContactSelectionListFragment extends LoggingFragment {
lifecycleDisposable.add(disposable);
Intent intent = requireActivity().getIntent();
Bundle arguments = safeArguments();
fragmentArgs = ContactSelectionArguments.fromBundle(safeArguments(), requireActivity().getIntent());
int recyclerViewPadBottom = arguments.getInt(RV_PADDING_BOTTOM, intent.getIntExtra(RV_PADDING_BOTTOM, -1));
boolean recyclerViewClipping = arguments.getBoolean(RV_CLIP, intent.getBooleanExtra(RV_CLIP, true));
if (recyclerViewPadBottom != -1) {
ViewUtil.setPaddingBottom(recyclerView, recyclerViewPadBottom);
if (fragmentArgs.getRecyclerPadBottom() != -1) {
ViewUtil.setPaddingBottom(recyclerView, fragmentArgs.getRecyclerPadBottom());
}
recyclerView.setClipToPadding(recyclerViewClipping);
recyclerView.setClipToPadding(fragmentArgs.getRecyclerChildClipping());
boolean isRefreshable = arguments.getBoolean(REFRESHABLE, intent.getBooleanExtra(REFRESHABLE, true));
swipeRefresh.setNestedScrollingEnabled(isRefreshable);
swipeRefresh.setEnabled(isRefreshable);
swipeRefresh.setNestedScrollingEnabled(fragmentArgs.isRefreshable());
swipeRefresh.setEnabled(fragmentArgs.isRefreshable());
selectionLimit = arguments.getParcelable(SELECTION_LIMITS);
if (selectionLimit == null) {
selectionLimit = intent.getParcelableExtra(SELECTION_LIMITS);
}
isMulti = selectionLimit != null;
canSelectSelf = arguments.getBoolean(CAN_SELECT_SELF, intent.getBooleanExtra(CAN_SELECT_SELF, !isMulti));
selectionLimit = fragmentArgs.getSelectionLimits();
isMulti = selectionLimit != null;
canSelectSelf = fragmentArgs.getCanSelectSelf();
if (!isMulti) {
selectionLimit = SelectionLimits.NO_LIMITS;
@@ -494,13 +475,7 @@ public final class ContactSelectionListFragment extends LoggingFragment {
}
private Set<RecipientId> getCurrentSelection() {
List<RecipientId> currentSelection = safeArguments().getParcelableArrayList(CURRENT_SELECTION);
if (currentSelection == null) {
currentSelection = requireActivity().getIntent().getParcelableArrayListExtra(CURRENT_SELECTION);
}
return currentSelection == null ? Collections.emptySet()
: Collections.unmodifiableSet(new HashSet<>(currentSelection));
return Set.copyOf(fragmentArgs.getCurrentSelection());
}
public boolean isMulti() {
@@ -617,7 +592,7 @@ public final class ContactSelectionListFragment extends LoggingFragment {
}
private boolean shouldDisplayRecents() {
return safeArguments().getBoolean(RECENTS, requireActivity().getIntent().getBooleanExtra(RECENTS, false));
return fragmentArgs.getIncludeRecents();
}
@SuppressLint("StaticFieldLeak")
@@ -869,7 +844,7 @@ public final class ContactSelectionListFragment extends LoggingFragment {
}
private void setChipGroupVisibility(int visibility) {
if (!safeArguments().getBoolean(DISPLAY_CHIPS, requireActivity().getIntent().getBooleanExtra(DISPLAY_CHIPS, true))) {
if (!fragmentArgs.getDisplayChips()) {
return;
}
@@ -896,9 +871,9 @@ public final class ContactSelectionListFragment extends LoggingFragment {
}
private @NonNull ContactSearchConfiguration mapStateToConfiguration(@NonNull ContactSearchState contactSearchState) {
int displayMode = safeArguments().getInt(DISPLAY_MODE, requireActivity().getIntent().getIntExtra(DISPLAY_MODE, ContactSelectionDisplayMode.FLAG_ALL));
int displayMode = fragmentArgs.getDisplayMode();
boolean includeRecents = safeArguments().getBoolean(RECENTS, requireActivity().getIntent().getBooleanExtra(RECENTS, false));
boolean includeRecents = fragmentArgs.getIncludeRecents();
boolean includePushContacts = flagSet(displayMode, ContactSelectionDisplayMode.FLAG_PUSH);
boolean includeSmsContacts = flagSet(displayMode, ContactSelectionDisplayMode.FLAG_SMS);
boolean includeActiveGroups = flagSet(displayMode, ContactSelectionDisplayMode.FLAG_ACTIVE_GROUPS);
@@ -910,7 +885,7 @@ public final class ContactSelectionListFragment extends LoggingFragment {
boolean includeGroupsAfterContacts = flagSet(displayMode, ContactSelectionDisplayMode.FLAG_GROUPS_AFTER_CONTACTS);
boolean blocked = flagSet(displayMode, ContactSelectionDisplayMode.FLAG_BLOCK);
boolean includeGroupMembers = flagSet(displayMode, ContactSelectionDisplayMode.FLAG_GROUP_MEMBERS);
boolean includeChatTypes = safeArguments().getBoolean(INCLUDE_CHAT_TYPES);
boolean includeChatTypes = fragmentArgs.getIncludeChatTypes();
boolean hasQuery = !TextUtils.isEmpty(contactSearchState.getQuery());
ContactSearchConfiguration.TransportType transportType = resolveTransportType(includePushContacts, includeSmsContacts);
@@ -932,8 +907,11 @@ public final class ContactSelectionListFragment extends LoggingFragment {
builder.arbitrary(ContactSelectionListAdapter.ArbitraryRepository.ArbitraryRow.NEW_GROUP.getCode());
}
if (findByCallback != null && !hasQuery) {
if (fragmentArgs.getEnableFindByUsername() && !hasQuery) {
builder.arbitrary(ContactSelectionListAdapter.ArbitraryRepository.ArbitraryRow.FIND_BY_USERNAME.getCode());
}
if (fragmentArgs.getEnableFindByPhoneNumber() && !hasQuery) {
builder.arbitrary(ContactSelectionListAdapter.ArbitraryRepository.ArbitraryRow.FIND_BY_PHONE_NUMBER.getCode());
}

View File

@@ -21,6 +21,7 @@ import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.components.ContactFilterView;
import org.thoughtcrime.securesms.contacts.ContactSelectionDisplayMode;
import org.thoughtcrime.securesms.contacts.paged.ChatType;
import org.thoughtcrime.securesms.contacts.selection.ContactSelectionArguments;
import org.thoughtcrime.securesms.database.SignalDatabase;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.RecipientId;
@@ -172,10 +173,9 @@ public class BlockedUsersActivity extends PassphraseRequiredActivity implements
ContactSelectionListFragment fragment = new ContactSelectionListFragment();
Intent intent = getIntent();
intent.putExtra(ContactSelectionListFragment.REFRESHABLE, false);
intent.putExtra(ContactSelectionListFragment.SELECTION_LIMITS, 1);
intent.putExtra(ContactSelectionListFragment.HIDE_COUNT, true);
intent.putExtra(ContactSelectionListFragment.DISPLAY_MODE,
intent.putExtra(ContactSelectionArguments.REFRESHABLE, false);
intent.putExtra(ContactSelectionArguments.SELECTION_LIMITS, 1);
intent.putExtra(ContactSelectionArguments.DISPLAY_MODE,
ContactSelectionDisplayMode.FLAG_PUSH |
ContactSelectionDisplayMode.FLAG_SMS |
ContactSelectionDisplayMode.FLAG_ACTIVE_GROUPS |

View File

@@ -18,6 +18,7 @@ import org.thoughtcrime.securesms.calls.YouAreAlreadyInACallSnackbar
import org.thoughtcrime.securesms.components.settings.app.AppSettingsActivity
import org.thoughtcrime.securesms.contacts.ContactSelectionDisplayMode
import org.thoughtcrime.securesms.contacts.paged.ChatType
import org.thoughtcrime.securesms.contacts.selection.ContactSelectionArguments
import org.thoughtcrime.securesms.keyvalue.SignalStore
import org.thoughtcrime.securesms.recipients.Recipient
import org.thoughtcrime.securesms.recipients.RecipientId
@@ -100,7 +101,7 @@ class NewCallActivity : ContactSelectionActivity(), ContactSelectionListFragment
fun createIntent(context: Context): Intent {
return Intent(context, NewCallActivity::class.java)
.putExtra(
ContactSelectionListFragment.DISPLAY_MODE,
ContactSelectionArguments.DISPLAY_MODE,
ContactSelectionDisplayMode.none()
.withPush()
.withActiveGroups()

View File

@@ -16,6 +16,7 @@ import org.thoughtcrime.securesms.components.ContactFilterView
import org.thoughtcrime.securesms.contacts.ContactSelectionDisplayMode
import org.thoughtcrime.securesms.contacts.SelectedContact
import org.thoughtcrime.securesms.contacts.paged.ChatType
import org.thoughtcrime.securesms.contacts.selection.ContactSelectionArguments
import org.thoughtcrime.securesms.groups.SelectionLimits
import org.thoughtcrime.securesms.recipients.RecipientId
import org.thoughtcrime.securesms.util.ViewUtil
@@ -41,19 +42,18 @@ class ChooseChatsFragment : LoggingFragment(), ContactSelectionListFragment.OnCo
}
childFragmentManager.addFragmentOnAttachListener { _, fragment ->
fragment.arguments = Bundle().apply {
putInt(ContactSelectionListFragment.DISPLAY_MODE, getDefaultDisplayMode())
putBoolean(ContactSelectionListFragment.REFRESHABLE, false)
putBoolean(ContactSelectionListFragment.RECENTS, true)
putParcelable(ContactSelectionListFragment.SELECTION_LIMITS, SelectionLimits.NO_LIMITS)
putParcelableArrayList(ContactSelectionListFragment.CURRENT_SELECTION, ArrayList<RecipientId>(currentSelection))
putBoolean(ContactSelectionListFragment.INCLUDE_CHAT_TYPES, includeChatsMode)
putBoolean(ContactSelectionListFragment.HIDE_COUNT, true)
putBoolean(ContactSelectionListFragment.DISPLAY_CHIPS, true)
putBoolean(ContactSelectionListFragment.CAN_SELECT_SELF, true)
putBoolean(ContactSelectionListFragment.RV_CLIP, false)
putInt(ContactSelectionListFragment.RV_PADDING_BOTTOM, ViewUtil.dpToPx(60))
}
fragment.arguments = ContactSelectionArguments(
displayMode = getDefaultDisplayMode(),
isRefreshable = false,
includeRecents = true,
selectionLimits = SelectionLimits.NO_LIMITS,
currentSelection = currentSelection,
includeChatTypes = includeChatsMode,
displayChips = true,
canSelectSelf = true,
recyclerChildClipping = false,
recyclerPadBottom = ViewUtil.dpToPx(60)
).toArgumentBundle()
}
return inflater.inflate(R.layout.choose_chats_fragment, container, false)

View File

@@ -16,6 +16,7 @@ import org.thoughtcrime.securesms.R
import org.thoughtcrime.securesms.components.ContactFilterView
import org.thoughtcrime.securesms.contacts.ContactSelectionDisplayMode
import org.thoughtcrime.securesms.contacts.paged.ChatType
import org.thoughtcrime.securesms.contacts.selection.ContactSelectionArguments
import org.thoughtcrime.securesms.groups.SelectionLimits
import org.thoughtcrime.securesms.recipients.RecipientId
import org.thoughtcrime.securesms.util.ViewUtil
@@ -46,18 +47,17 @@ class SelectRecipientsFragment : LoggingFragment(), ContactSelectionListFragment
}
childFragmentManager.addFragmentOnAttachListener { _, fragment ->
fragment.arguments = Bundle().apply {
putInt(ContactSelectionListFragment.DISPLAY_MODE, getDefaultDisplayMode())
putBoolean(ContactSelectionListFragment.REFRESHABLE, false)
putBoolean(ContactSelectionListFragment.RECENTS, true)
putParcelable(ContactSelectionListFragment.SELECTION_LIMITS, SelectionLimits.NO_LIMITS)
putParcelableArrayList(ContactSelectionListFragment.CURRENT_SELECTION, selectionList)
putBoolean(ContactSelectionListFragment.HIDE_COUNT, true)
putBoolean(ContactSelectionListFragment.DISPLAY_CHIPS, true)
putBoolean(ContactSelectionListFragment.CAN_SELECT_SELF, false)
putBoolean(ContactSelectionListFragment.RV_CLIP, false)
putInt(ContactSelectionListFragment.RV_PADDING_BOTTOM, ViewUtil.dpToPx(60))
}
fragment.arguments = ContactSelectionArguments(
displayMode = getDefaultDisplayMode(),
isRefreshable = false,
includeRecents = true,
selectionLimits = SelectionLimits.NO_LIMITS,
currentSelection = selectionList.toSet(),
displayChips = true,
canSelectSelf = false,
recyclerChildClipping = false,
recyclerPadBottom = ViewUtil.dpToPx(60)
).toArgumentBundle()
}
return inflater.inflate(R.layout.fragment_select_recipients_fragment, container, false)

View File

@@ -1,52 +1,101 @@
package org.thoughtcrime.securesms.contacts.selection
import android.content.Intent
import android.os.Bundle
import org.thoughtcrime.securesms.R
import org.signal.core.util.getParcelableArrayListCompat
import org.signal.core.util.getParcelableArrayListExtraCompat
import org.signal.core.util.getParcelableCompat
import org.signal.core.util.getParcelableExtraCompat
import org.thoughtcrime.securesms.contacts.ContactSelectionDisplayMode
import org.thoughtcrime.securesms.groups.SelectionLimits
import org.thoughtcrime.securesms.recipients.RecipientId
@Suppress("KotlinConstantConditions")
data class ContactSelectionArguments(
val displayMode: Int = ContactSelectionDisplayMode.FLAG_ALL,
val isRefreshable: Boolean = true,
val displayRecents: Boolean = false,
val selectionLimits: SelectionLimits? = null,
val currentSelection: List<RecipientId> = emptyList(),
val displaySelectionCount: Boolean = true,
val canSelectSelf: Boolean = selectionLimits == null,
val displayChips: Boolean = true,
val recyclerPadBottom: Int = -1,
val recyclerChildClipping: Boolean = true,
val checkboxResource: Int = R.drawable.contact_selection_checkbox
val displayMode: Int = Defaults.DISPLAY_MODE,
val isRefreshable: Boolean = Defaults.IS_REFRESHABLE,
val enableFindByUsername: Boolean = Defaults.ENABLE_FIND_BY_USERNAME,
val enableFindByPhoneNumber: Boolean = Defaults.ENABLE_FIND_BY_PHONE_NUMBER,
val includeRecents: Boolean = Defaults.INCLUDE_RECENTS,
val includeChatTypes: Boolean = Defaults.INCLUDE_CHAT_TYPES,
val selectionLimits: SelectionLimits? = Defaults.SELECTION_LIMITS,
val currentSelection: Set<RecipientId> = Defaults.CURRENT_SELECTION,
val canSelectSelf: Boolean = Defaults.canSelectSelf(selectionLimits),
val displayChips: Boolean = Defaults.DISPLAY_CHIPS,
val recyclerPadBottom: Int = Defaults.RECYCLER_PADDING_BOTTOM,
val recyclerChildClipping: Boolean = Defaults.RECYCLER_CHILD_CLIPPING
) {
fun toArgumentBundle(): Bundle {
return Bundle().apply {
putInt(DISPLAY_MODE, displayMode)
putBoolean(REFRESHABLE, isRefreshable)
putBoolean(RECENTS, displayRecents)
putBoolean(ENABLE_FIND_BY_USERNAME, enableFindByUsername)
putBoolean(ENABLE_FIND_BY_PHONE_NUMBER, enableFindByPhoneNumber)
putBoolean(RECENTS, includeRecents)
putBoolean(INCLUDE_CHAT_TYPES, includeChatTypes)
putParcelable(SELECTION_LIMITS, selectionLimits)
putBoolean(HIDE_COUNT, !displaySelectionCount)
putParcelableArrayList(CURRENT_SELECTION, ArrayList(currentSelection))
putBoolean(CAN_SELECT_SELF, canSelectSelf)
putBoolean(DISPLAY_CHIPS, displayChips)
putInt(RV_PADDING_BOTTOM, recyclerPadBottom)
putBoolean(RV_CLIP, recyclerChildClipping)
putInt(CHECKBOX_RESOURCE, checkboxResource)
putParcelableArrayList(CURRENT_SELECTION, ArrayList(currentSelection))
}
}
companion object {
const val DISPLAY_MODE = "display_mode"
const val REFRESHABLE = "refreshable"
const val ENABLE_FIND_BY_USERNAME = "enable_find_by_username"
const val ENABLE_FIND_BY_PHONE_NUMBER = "enable_find_by_phone"
const val RECENTS = "recents"
const val INCLUDE_CHAT_TYPES = "include_chat_types"
const val SELECTION_LIMITS = "selection_limits"
const val CURRENT_SELECTION = "current_selection"
const val HIDE_COUNT = "hide_count"
const val CAN_SELECT_SELF = "can_select_self"
const val DISPLAY_CHIPS = "display_chips"
const val RV_PADDING_BOTTOM = "recycler_view_padding_bottom"
const val RV_CLIP = "recycler_view_clipping"
const val CHECKBOX_RESOURCE = "checkbox_resource"
@JvmStatic
fun fromBundle(bundle: Bundle, intent: Intent): ContactSelectionArguments {
val selectionLimits = bundle.getParcelableCompat(SELECTION_LIMITS, SelectionLimits::class.java)
?: intent.getParcelableExtraCompat(SELECTION_LIMITS, SelectionLimits::class.java)
val currentSelection = bundle.getParcelableArrayListCompat(CURRENT_SELECTION, RecipientId::class.java)
?: intent.getParcelableArrayListExtraCompat(CURRENT_SELECTION, RecipientId::class.java)
?: emptyList()
return ContactSelectionArguments(
displayMode = bundle.getInt(DISPLAY_MODE, intent.getIntExtra(DISPLAY_MODE, Defaults.DISPLAY_MODE)),
isRefreshable = bundle.getBoolean(REFRESHABLE, intent.getBooleanExtra(REFRESHABLE, Defaults.IS_REFRESHABLE)),
enableFindByUsername = bundle.getBoolean(ENABLE_FIND_BY_USERNAME, intent.getBooleanExtra(ENABLE_FIND_BY_USERNAME, Defaults.ENABLE_FIND_BY_USERNAME)),
enableFindByPhoneNumber = bundle.getBoolean(ENABLE_FIND_BY_PHONE_NUMBER, intent.getBooleanExtra(ENABLE_FIND_BY_PHONE_NUMBER, Defaults.ENABLE_FIND_BY_PHONE_NUMBER)),
includeRecents = bundle.getBoolean(RECENTS, intent.getBooleanExtra(RECENTS, Defaults.INCLUDE_RECENTS)),
includeChatTypes = bundle.getBoolean(INCLUDE_CHAT_TYPES, intent.getBooleanExtra(INCLUDE_CHAT_TYPES, Defaults.INCLUDE_CHAT_TYPES)),
selectionLimits = selectionLimits,
currentSelection = currentSelection.toSet(),
canSelectSelf = bundle.getBoolean(CAN_SELECT_SELF, intent.getBooleanExtra(CAN_SELECT_SELF, Defaults.canSelectSelf(selectionLimits))),
displayChips = bundle.getBoolean(DISPLAY_CHIPS, intent.getBooleanExtra(DISPLAY_CHIPS, Defaults.DISPLAY_CHIPS)),
recyclerPadBottom = bundle.getInt(RV_PADDING_BOTTOM, intent.getIntExtra(RV_PADDING_BOTTOM, Defaults.RECYCLER_PADDING_BOTTOM)),
recyclerChildClipping = bundle.getBoolean(RV_CLIP, intent.getBooleanExtra(RV_CLIP, Defaults.RECYCLER_CHILD_CLIPPING))
)
}
}
}
private object Defaults {
const val DISPLAY_MODE = ContactSelectionDisplayMode.FLAG_ALL
const val IS_REFRESHABLE = true
const val ENABLE_FIND_BY_USERNAME = false
const val ENABLE_FIND_BY_PHONE_NUMBER = false
const val INCLUDE_RECENTS = false
const val INCLUDE_CHAT_TYPES = false
val SELECTION_LIMITS: SelectionLimits? = null
val CURRENT_SELECTION: Set<RecipientId> = emptySet()
const val DISPLAY_CHIPS = true
const val RECYCLER_PADDING_BOTTOM = -1
const val RECYCLER_CHILD_CLIPPING = true
fun canSelectSelf(selectionLimits: SelectionLimits?): Boolean = selectionLimits == null
}

View File

@@ -130,7 +130,8 @@ private fun RecipientPicker(
modifier: Modifier = Modifier
) {
RecipientPicker(
showFindByUsernameAndPhoneOptions = true,
enableFindByUsername = true,
enableFindByPhoneNumber = true,
callbacks = RecipientPickerCallbacks.Empty, // TODO(jeffrey) implement callbacks
modifier = modifier
.fillMaxSize()

View File

@@ -27,6 +27,7 @@ import org.signal.core.ui.compose.DayNightPreviews
import org.signal.core.ui.compose.Fragments
import org.thoughtcrime.securesms.ContactSelectionListFragment
import org.thoughtcrime.securesms.components.ContactFilterView
import org.thoughtcrime.securesms.contacts.selection.ContactSelectionArguments
import org.thoughtcrime.securesms.recipients.RecipientId
/**
@@ -34,7 +35,8 @@ import org.thoughtcrime.securesms.recipients.RecipientId
*/
@Composable
fun RecipientPicker(
showFindByUsernameAndPhoneOptions: Boolean,
enableFindByUsername: Boolean,
enableFindByPhoneNumber: Boolean,
callbacks: RecipientPickerCallbacks,
modifier: Modifier = Modifier
) {
@@ -54,7 +56,8 @@ fun RecipientPicker(
RecipientSearchResultsList(
searchQuery = searchQuery,
showFindByUsernameAndPhoneOptions = showFindByUsernameAndPhoneOptions,
enableFindByUsername = enableFindByUsername,
enableFindByPhoneNumber = enableFindByPhoneNumber,
callbacks = callbacks,
modifier = Modifier
.fillMaxSize()
@@ -97,25 +100,30 @@ private fun RecipientSearchField(
@Composable
private fun RecipientSearchResultsList(
searchQuery: String,
showFindByUsernameAndPhoneOptions: Boolean,
enableFindByUsername: Boolean,
enableFindByPhoneNumber: Boolean,
callbacks: RecipientPickerCallbacks,
modifier: Modifier = Modifier
) {
val fragmentArgs = ContactSelectionArguments(
enableFindByUsername = enableFindByUsername,
enableFindByPhoneNumber = enableFindByPhoneNumber
).toArgumentBundle()
val fragmentState = rememberFragmentState()
var currentFragment by remember { mutableStateOf<ContactSelectionListFragment?>(null) }
Fragments.Fragment<ContactSelectionListFragment>(
arguments = fragmentArgs,
fragmentState = fragmentState,
onUpdate = { fragment ->
currentFragment = fragment
currentFragment?.view?.setPadding(0, 0, 0, 0)
if (showFindByUsernameAndPhoneOptions) {
fragment.showFindByUsernameAndPhoneOptions(object : ContactSelectionListFragment.FindByCallback {
override fun onFindByUsername() = callbacks.onFindByUsernameClicked()
override fun onFindByPhoneNumber() = callbacks.onFindByPhoneNumberClicked()
})
}
fragment.setFindByCallback(object : ContactSelectionListFragment.FindByCallback {
override fun onFindByUsername() = callbacks.onFindByUsername()
override fun onFindByPhoneNumber() = callbacks.onFindByPhoneNumber()
})
},
modifier = modifier
)
@@ -137,19 +145,20 @@ private fun RecipientSearchResultsList(
@Composable
private fun RecipientPickerPreview() {
RecipientPicker(
showFindByUsernameAndPhoneOptions = true,
enableFindByUsername = true,
enableFindByPhoneNumber = true,
callbacks = RecipientPickerCallbacks.Empty
)
}
interface RecipientPickerCallbacks {
fun onFindByUsernameClicked()
fun onFindByPhoneNumberClicked()
fun onRecipientClicked(id: RecipientId)
fun onFindByUsername()
fun onFindByPhoneNumber()
fun onRecipientClick(id: RecipientId)
object Empty : RecipientPickerCallbacks {
override fun onFindByUsernameClicked() = Unit
override fun onFindByPhoneNumberClicked() = Unit
override fun onRecipientClicked(id: RecipientId) = Unit
override fun onFindByUsername() = Unit
override fun onFindByPhoneNumber() = Unit
override fun onRecipientClick(id: RecipientId) = Unit
}
}

View File

@@ -20,6 +20,7 @@ import org.thoughtcrime.securesms.ContactSelectionListFragment;
import org.thoughtcrime.securesms.PushContactSelectionActivity;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.contacts.paged.ChatType;
import org.thoughtcrime.securesms.contacts.selection.ContactSelectionArguments;
import org.thoughtcrime.securesms.groups.GroupId;
import org.thoughtcrime.securesms.groups.SelectionLimits;
import org.thoughtcrime.securesms.recipients.Recipient;
@@ -55,11 +56,11 @@ public class AddMembersActivity extends PushContactSelectionActivity implements
intent.putExtra(GROUP_ID, groupId.toString());
intent.putExtra(ANNOUNCEMENT_GROUP, isAnnouncementGroup);
intent.putExtra(ContactSelectionListFragment.DISPLAY_MODE, displayModeFlags);
intent.putExtra(ContactSelectionListFragment.SELECTION_LIMITS, new SelectionLimits(selectionWarning, selectionLimit));
intent.putParcelableArrayListExtra(ContactSelectionListFragment.CURRENT_SELECTION, new ArrayList<>(membersWithoutSelf));
intent.putExtra(ContactSelectionListFragment.RV_PADDING_BOTTOM, (int) DimensionUnit.DP.toPixels(64f));
intent.putExtra(ContactSelectionListFragment.RV_CLIP, false);
intent.putExtra(ContactSelectionArguments.DISPLAY_MODE, displayModeFlags);
intent.putExtra(ContactSelectionArguments.SELECTION_LIMITS, new SelectionLimits(selectionWarning, selectionLimit));
intent.putParcelableArrayListExtra(ContactSelectionArguments.CURRENT_SELECTION, new ArrayList<>(membersWithoutSelf));
intent.putExtra(ContactSelectionArguments.RV_PADDING_BOTTOM, (int) DimensionUnit.DP.toPixels(64f));
intent.putExtra(ContactSelectionArguments.RV_CLIP, false);
return intent;
}

View File

@@ -14,10 +14,10 @@ import com.annimon.stream.Stream;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import org.thoughtcrime.securesms.ContactSelectionActivity;
import org.thoughtcrime.securesms.ContactSelectionListFragment;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.contacts.ContactSelectionDisplayMode;
import org.thoughtcrime.securesms.contacts.paged.ChatType;
import org.thoughtcrime.securesms.contacts.selection.ContactSelectionArguments;
import org.thoughtcrime.securesms.groups.ui.addtogroup.AddToGroupViewModel.Event;
import org.thoughtcrime.securesms.recipients.RecipientId;
@@ -46,14 +46,14 @@ public final class AddToGroupsActivity extends ContactSelectionActivity {
{
Intent intent = new Intent(context, AddToGroupsActivity.class);
intent.putExtra(ContactSelectionListFragment.REFRESHABLE, false);
intent.putExtra(ContactSelectionListFragment.RECENTS, true);
intent.putExtra(ContactSelectionArguments.REFRESHABLE, false);
intent.putExtra(ContactSelectionArguments.RECENTS, true);
intent.putExtra(ContactSelectionActivity.EXTRA_LAYOUT_RES_ID, R.layout.add_to_group_activity);
intent.putExtra(EXTRA_RECIPIENT_ID, recipientId);
intent.putExtra(ContactSelectionListFragment.DISPLAY_MODE, ContactSelectionDisplayMode.FLAG_ACTIVE_GROUPS | ContactSelectionDisplayMode.FLAG_GROUPS_AFTER_CONTACTS);
intent.putExtra(ContactSelectionArguments.DISPLAY_MODE, ContactSelectionDisplayMode.FLAG_ACTIVE_GROUPS | ContactSelectionDisplayMode.FLAG_GROUPS_AFTER_CONTACTS);
intent.putParcelableArrayListExtra(ContactSelectionListFragment.CURRENT_SELECTION, new ArrayList<>(currentGroupsMemberOf));
intent.putParcelableArrayListExtra(ContactSelectionArguments.CURRENT_SELECTION, new ArrayList<>(currentGroupsMemberOf));
return intent;
}

View File

@@ -24,6 +24,7 @@ import org.thoughtcrime.securesms.ContactSelectionListFragment;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.contacts.ContactSelectionDisplayMode;
import org.thoughtcrime.securesms.contacts.paged.ChatType;
import org.thoughtcrime.securesms.contacts.selection.ContactSelectionArguments;
import org.thoughtcrime.securesms.contacts.sync.ContactDiscovery;
import org.thoughtcrime.securesms.groups.ui.creategroup.details.AddGroupDetailsActivity;
import org.thoughtcrime.securesms.recipients.Recipient;
@@ -56,15 +57,15 @@ public class CreateGroupActivity extends ContactSelectionActivity implements Con
public static Intent newIntent(@NonNull Context context) {
Intent intent = new Intent(context, CreateGroupActivity.class);
intent.putExtra(ContactSelectionListFragment.REFRESHABLE, false);
intent.putExtra(ContactSelectionArguments.REFRESHABLE, false);
intent.putExtra(ContactSelectionActivity.EXTRA_LAYOUT_RES_ID, R.layout.create_group_activity);
int displayMode = ContactSelectionDisplayMode.FLAG_PUSH;
intent.putExtra(ContactSelectionListFragment.DISPLAY_MODE, displayMode);
intent.putExtra(ContactSelectionListFragment.SELECTION_LIMITS, RemoteConfig.groupLimits().excludingSelf());
intent.putExtra(ContactSelectionListFragment.RV_PADDING_BOTTOM, (int) DimensionUnit.DP.toPixels(64f));
intent.putExtra(ContactSelectionListFragment.RV_CLIP, false);
intent.putExtra(ContactSelectionArguments.DISPLAY_MODE, displayMode);
intent.putExtra(ContactSelectionArguments.SELECTION_LIMITS, RemoteConfig.groupLimits().excludingSelf());
intent.putExtra(ContactSelectionArguments.RV_PADDING_BOTTOM, (int) DimensionUnit.DP.toPixels(64f));
intent.putExtra(ContactSelectionArguments.RV_CLIP, false);
return intent;
}

View File

@@ -17,6 +17,7 @@ import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.components.ContactFilterView;
import org.thoughtcrime.securesms.contacts.ContactSelectionDisplayMode;
import org.thoughtcrime.securesms.contacts.paged.ChatType;
import org.thoughtcrime.securesms.contacts.selection.ContactSelectionArguments;
import org.thoughtcrime.securesms.conversation.ConversationIntents;
import org.thoughtcrime.securesms.database.SignalDatabase;
import org.thoughtcrime.securesms.payments.CanNotSendPaymentDialog;
@@ -49,9 +50,9 @@ public class PaymentRecipientSelectionFragment extends LoggingFragment implement
contactFilterView = view.findViewById(R.id.contact_filter_edit_text);
Bundle arguments = new Bundle();
arguments.putBoolean(ContactSelectionListFragment.REFRESHABLE, false);
arguments.putInt(ContactSelectionListFragment.DISPLAY_MODE, ContactSelectionDisplayMode.FLAG_PUSH | ContactSelectionDisplayMode.FLAG_HIDE_NEW);
arguments.putBoolean(ContactSelectionListFragment.CAN_SELECT_SELF, false);
arguments.putBoolean(ContactSelectionArguments.REFRESHABLE, false);
arguments.putInt(ContactSelectionArguments.DISPLAY_MODE, ContactSelectionDisplayMode.FLAG_PUSH | ContactSelectionDisplayMode.FLAG_HIDE_NEW);
arguments.putBoolean(ContactSelectionArguments.CAN_SELECT_SELF, false);
Fragment child = getChildFragmentManager().findFragmentById(R.id.contact_selection_list_fragment_holder);
if (child == null) {

View File

@@ -154,13 +154,11 @@ abstract class BaseStoryRecipientSelectionFragment : Fragment(R.layout.stories_b
val arguments = ContactSelectionArguments(
displayMode = ContactSelectionDisplayMode.FLAG_PUSH or ContactSelectionDisplayMode.FLAG_HIDE_NEW,
isRefreshable = false,
displayRecents = false,
includeRecents = false,
selectionLimits = SelectionLimits.NO_LIMITS,
canSelectSelf = false,
currentSelection = emptyList(),
displaySelectionCount = false,
currentSelection = emptySet(),
displayChips = true,
checkboxResource = checkboxResource,
recyclerPadBottom = 76.dp,
recyclerChildClipping = false
)