Compare commits

...

4 Commits

Author SHA1 Message Date
copilot-swe-agent[bot] deb4e356bd Fix race condition by tracking removed contacts explicitly
Instead of comparing current members at result time (which can change),
ContactMultiSelectionActivity now tracks preselected contacts and
explicitly returns which ones were removed. This eliminates the race
condition where member list changes could cause accidental removals.

Changes:
- ContactMultiSelectionActivity: Store preselected contacts, calculate and return removed contacts
- ProfileFragment: Use explicitly removed contacts instead of calculating from current member list

Co-authored-by: adbenitez <24558636+adbenitez@users.noreply.github.com>
2026-02-02 23:03:32 +00:00
copilot-swe-agent[bot] 88d6992a9e Optimize member removal with HashSet for O(1) lookup
- Use HashSet instead of List for checking member selection
- Improves performance from O(n²) to O(n) for large member lists

Co-authored-by: adbenitez <24558636+adbenitez@users.noreply.github.com>
2026-02-02 17:20:55 +00:00
copilot-swe-agent[bot] 5e6b09031a Fix member removal in Add Members screen
- Modified ProfileFragment.onActivityResult() to handle both adding and removing members
- When unchecking members in the Add Members screen, they are now properly removed from the group
- Preserves existing functionality for adding new members

Co-authored-by: adbenitez <24558636+adbenitez@users.noreply.github.com>
2026-02-02 17:19:59 +00:00
copilot-swe-agent[bot] 115ebf52b6 Initial plan 2026-02-02 17:17:22 +00:00
2 changed files with 33 additions and 1 deletions
@@ -23,7 +23,9 @@ import android.view.MenuInflater;
import android.view.MenuItem;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* Activity container for selecting a list of contacts.
@@ -34,6 +36,9 @@ import java.util.List;
public class ContactMultiSelectionActivity extends ContactSelectionActivity {
public static final String CONTACTS_EXTRA = "contacts_extra";
public static final String REMOVED_CONTACTS_EXTRA = "removed_contacts_extra";
private ArrayList<Integer> preselectedContacts;
@Override
protected void onCreate(Bundle icicle, boolean ready) {
@@ -44,6 +49,9 @@ public class ContactMultiSelectionActivity extends ContactSelectionActivity {
// it's a bit confusing having one "X" button on the left and one on the right -
// and the "clear search" button is not that important.
getToolbar().setUseClearButton(false);
// Store preselected contacts to track which ones were removed
preselectedContacts = getIntent().getIntegerArrayListExtra(ContactSelectionListFragment.PRESELECTED_CONTACTS);
}
@Override
@@ -72,6 +80,19 @@ public class ContactMultiSelectionActivity extends ContactSelectionActivity {
Intent resultIntent = getIntent();
List<Integer> selectedContacts = contactsFragment.getSelectedContacts();
resultIntent.putIntegerArrayListExtra(CONTACTS_EXTRA, new ArrayList<>(selectedContacts));
// Calculate which contacts were removed (preselected but not in final selection)
if (preselectedContacts != null) {
Set<Integer> selectedSet = new HashSet<>(selectedContacts);
ArrayList<Integer> removedContacts = new ArrayList<>();
for (Integer preselectedId : preselectedContacts) {
if (!selectedSet.contains(preselectedId)) {
removedContacts.add(preselectedId);
}
}
resultIntent.putIntegerArrayListExtra(REMOVED_CONTACTS_EXTRA, removedContacts);
}
setResult(RESULT_OK, resultIntent);
}
}
@@ -310,13 +310,24 @@ public class ProfileFragment extends Fragment
super.onActivityResult(requestCode, resultCode, data);
if (requestCode==REQUEST_CODE_PICK_CONTACT && resultCode==Activity.RESULT_OK && data!=null) {
List<Integer> selected = data.getIntegerArrayListExtra(ContactMultiSelectionActivity.CONTACTS_EXTRA);
List<Integer> removed = data.getIntegerArrayListExtra(ContactMultiSelectionActivity.REMOVED_CONTACTS_EXTRA);
if(selected == null) return;
Util.runOnAnyBackgroundThread(() -> {
// Add new members
for (Integer contactId : selected) {
if (contactId!=null) {
if (contactId != null) {
dcContext.addContactToChat(chatId, contactId);
}
}
// Remove members that were explicitly unchecked
if (removed != null) {
for (Integer contactId : removed) {
if (contactId != null) {
dcContext.removeContactFromChat(chatId, contactId);
}
}
}
});
}
}