mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-24 19:00:26 +01:00
Fix chip jank and other groups v2 ux issues.
This commit is contained in:
committed by
Greyson Parrelli
parent
00996f0d7a
commit
903c3989b9
@@ -35,8 +35,7 @@ public abstract class GroupMemberEntry {
|
||||
|
||||
public final static class NewGroupCandidate extends GroupMemberEntry {
|
||||
|
||||
private final DefaultValueLiveData<Boolean> isSelected = new DefaultValueLiveData<>(false);
|
||||
private final Recipient member;
|
||||
private final Recipient member;
|
||||
|
||||
public NewGroupCandidate(@NonNull Recipient member) {
|
||||
this.member = member;
|
||||
@@ -46,14 +45,6 @@ public abstract class GroupMemberEntry {
|
||||
return member;
|
||||
}
|
||||
|
||||
public @NonNull LiveData<Boolean> isSelected() {
|
||||
return isSelected;
|
||||
}
|
||||
|
||||
public void setSelected(boolean isSelected) {
|
||||
this.isSelected.postValue(isSelected);
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean sameId(@NonNull GroupMemberEntry newItem) {
|
||||
if (getClass() != newItem.getClass()) return false;
|
||||
|
||||
@@ -246,9 +246,6 @@ final class GroupMemberListAdapter extends LifecycleRecyclerAdapter<GroupMemberL
|
||||
bindRecipient(newGroupCandidate.getMember());
|
||||
bindRecipientClick(newGroupCandidate.getMember());
|
||||
|
||||
itemView.setSelected(false);
|
||||
newGroupCandidate.isSelected().observe(this, itemView::setSelected);
|
||||
|
||||
int smsWarningVisibility = newGroupCandidate.getMember().isRegistered() ? View.GONE : View.VISIBLE;
|
||||
|
||||
smsContact.setVisibility(smsWarningVisibility);
|
||||
|
||||
@@ -20,6 +20,7 @@ import android.widget.Toast;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.StringRes;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.lifecycle.ViewModelProviders;
|
||||
@@ -58,38 +59,6 @@ public class AddGroupDetailsFragment extends Fragment {
|
||||
private Drawable avatarPlaceholder;
|
||||
private EditText name;
|
||||
private Toolbar toolbar;
|
||||
private ActionMode actionMode;
|
||||
|
||||
private ActionMode.Callback recipientActionModeCallback = new ActionMode.Callback() {
|
||||
@Override
|
||||
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
|
||||
mode.getMenuInflater().inflate(R.menu.add_group_details_fragment_context_menu, menu);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
|
||||
if (item.getItemId() == R.id.action_delete) {
|
||||
viewModel.deleteSelected();
|
||||
mode.finish();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyActionMode(ActionMode mode) {
|
||||
actionMode = null;
|
||||
viewModel.clearSelected();
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public void onAttach(@NonNull Context context) {
|
||||
@@ -142,7 +111,6 @@ public class AddGroupDetailsFragment extends Fragment {
|
||||
|
||||
avatar.setOnClickListener(v -> AvatarSelectionBottomSheetDialogFragment.create(viewModel.hasAvatar(), true, REQUEST_CODE_AVATAR, true)
|
||||
.show(getChildFragmentManager(), "BOTTOM"));
|
||||
members.setRecipientLongClickListener(this::handleRecipientLongClick);
|
||||
members.setRecipientClickListener(this::handleRecipientClick);
|
||||
name.addTextChangedListener(new AfterTextChanged(editable -> viewModel.setName(editable.toString())));
|
||||
toolbar.setNavigationOnClickListener(unused -> callback.onNavigationButtonPressed());
|
||||
@@ -219,29 +187,15 @@ public class AddGroupDetailsFragment extends Fragment {
|
||||
}
|
||||
|
||||
private void handleRecipientClick(@NonNull Recipient recipient) {
|
||||
if (actionMode == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
int size = viewModel.toggleSelected(recipient);
|
||||
if (size == 0) {
|
||||
actionMode.finish();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean handleRecipientLongClick(@NonNull Recipient recipient) {
|
||||
if (actionMode != null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
actionMode = toolbar.startActionMode(recipientActionModeCallback);
|
||||
|
||||
if (actionMode != null) {
|
||||
viewModel.toggleSelected(recipient);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
new AlertDialog.Builder(requireContext())
|
||||
.setMessage(getString(R.string.AddGroupDetailsFragment__remove_s_from_this_group, recipient.getDisplayName(requireContext())))
|
||||
.setCancelable(true)
|
||||
.setNegativeButton(android.R.string.cancel, (dialog, which) -> dialog.cancel())
|
||||
.setPositiveButton(R.string.AddGroupDetailsFragment__remove, (dialog, which) -> {
|
||||
viewModel.delete(recipient.getId());
|
||||
dialog.dismiss();
|
||||
})
|
||||
.show();
|
||||
}
|
||||
|
||||
private void handleGroupCreateResult(@NonNull GroupCreateResult groupCreateResult) {
|
||||
|
||||
@@ -18,6 +18,7 @@ import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.thoughtcrime.securesms.util.DefaultValueLiveData;
|
||||
import org.thoughtcrime.securesms.util.SingleLiveEvent;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
import org.thoughtcrime.securesms.util.livedata.LiveDataUtil;
|
||||
|
||||
import java.util.HashSet;
|
||||
@@ -28,7 +29,6 @@ import java.util.Set;
|
||||
public final class AddGroupDetailsViewModel extends ViewModel {
|
||||
|
||||
private final LiveData<List<GroupMemberEntry.NewGroupCandidate>> members;
|
||||
private final DefaultValueLiveData<Set<RecipientId>> selected = new DefaultValueLiveData<>(new HashSet<>());
|
||||
private final DefaultValueLiveData<Set<RecipientId>> deleted = new DefaultValueLiveData<>(new HashSet<>());
|
||||
private final MutableLiveData<String> name = new MutableLiveData<>("");
|
||||
private final MutableLiveData<byte[]> avatar = new MutableLiveData<>();
|
||||
@@ -37,17 +37,14 @@ public final class AddGroupDetailsViewModel extends ViewModel {
|
||||
private final LiveData<Boolean> canSubmitForm = Transformations.map(name, name -> !TextUtils.isEmpty(name));
|
||||
private final AddGroupDetailsRepository repository;
|
||||
|
||||
AddGroupDetailsViewModel(@NonNull RecipientId[] recipientIds,
|
||||
@NonNull AddGroupDetailsRepository repository)
|
||||
private AddGroupDetailsViewModel(@NonNull RecipientId[] recipientIds,
|
||||
@NonNull AddGroupDetailsRepository repository)
|
||||
{
|
||||
this.repository = repository;
|
||||
|
||||
MutableLiveData<List<GroupMemberEntry.NewGroupCandidate>> initialMembers = new MutableLiveData<>();
|
||||
LiveData<List<GroupMemberEntry.NewGroupCandidate>> membersWithoutDeleted = LiveDataUtil.combineLatest(initialMembers,
|
||||
deleted,
|
||||
AddGroupDetailsViewModel::filterDeletedMembers);
|
||||
MutableLiveData<List<GroupMemberEntry.NewGroupCandidate>> initialMembers = new MutableLiveData<>();
|
||||
|
||||
members = LiveDataUtil.combineLatest(membersWithoutDeleted, selected, AddGroupDetailsViewModel::updateSelectedMembers);
|
||||
members = LiveDataUtil.combineLatest(initialMembers, deleted, AddGroupDetailsViewModel::filterDeletedMembers);
|
||||
isMms = Transformations.map(members, this::isAnyForcedSms);
|
||||
|
||||
repository.resolveMembers(recipientIds, initialMembers::postValue);
|
||||
@@ -85,27 +82,10 @@ public final class AddGroupDetailsViewModel extends ViewModel {
|
||||
this.name.setValue(name);
|
||||
}
|
||||
|
||||
int toggleSelected(@NonNull Recipient recipient) {
|
||||
Set<RecipientId> selected = this.selected.getValue();
|
||||
|
||||
if (!selected.add(recipient.getId())) {
|
||||
selected.remove(recipient.getId());
|
||||
}
|
||||
|
||||
this.selected.setValue(selected);
|
||||
|
||||
return selected.size();
|
||||
}
|
||||
|
||||
void clearSelected() {
|
||||
this.selected.setValue(new HashSet<>());
|
||||
}
|
||||
|
||||
void deleteSelected() {
|
||||
Set<RecipientId> selected = this.selected.getValue();
|
||||
void delete(@NonNull RecipientId recipientId) {
|
||||
Set<RecipientId> deleted = this.deleted.getValue();
|
||||
|
||||
deleted.addAll(selected);
|
||||
deleted.add(recipientId);
|
||||
this.deleted.setValue(deleted);
|
||||
}
|
||||
|
||||
@@ -139,14 +119,6 @@ public final class AddGroupDetailsViewModel extends ViewModel {
|
||||
.toList();
|
||||
}
|
||||
|
||||
private static @NonNull List<GroupMemberEntry.NewGroupCandidate> updateSelectedMembers(@NonNull List<GroupMemberEntry.NewGroupCandidate> members, @NonNull Set<RecipientId> selected) {
|
||||
for (GroupMemberEntry.NewGroupCandidate member : members) {
|
||||
member.setSelected(selected.contains(member.getMember().getId()));
|
||||
}
|
||||
|
||||
return members;
|
||||
}
|
||||
|
||||
private boolean isAnyForcedSms(@NonNull List<GroupMemberEntry.NewGroupCandidate> members) {
|
||||
return Stream.of(members)
|
||||
.anyMatch(member -> !member.getMember().isRegistered());
|
||||
|
||||
Reference in New Issue
Block a user