add context menu for muc user adapter

Daniel Gultsch created

Change summary

src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java        | 11 
src/main/java/eu/siacs/conversations/ui/ConversationFragment.java             |  2 
src/main/java/eu/siacs/conversations/ui/MucUsersActivity.java                 | 37 
src/main/java/eu/siacs/conversations/ui/adapter/ListItemAdapter.java          |  3 
src/main/java/eu/siacs/conversations/ui/adapter/UserAdapter.java              | 39 
src/main/java/eu/siacs/conversations/ui/adapter/UserPreviewAdapter.java       | 34 
src/main/java/eu/siacs/conversations/ui/util/MucDetailsContextMenuHelper.java | 40 
7 files changed, 108 insertions(+), 58 deletions(-)

Detailed changes

src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java 🔗

@@ -40,6 +40,7 @@ import eu.siacs.conversations.ui.util.Attachment;
 import eu.siacs.conversations.ui.util.AvatarWorkerTask;
 import eu.siacs.conversations.ui.util.GridManager;
 import eu.siacs.conversations.ui.util.MenuDoubleTabUtil;
+import eu.siacs.conversations.ui.util.MucDetailsContextMenuHelper;
 import eu.siacs.conversations.ui.util.MyLinkify;
 import eu.siacs.conversations.ui.util.SoftKeyboardUtils;
 import eu.siacs.conversations.utils.AccountUtils;
@@ -290,6 +291,14 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
         return super.onOptionsItemSelected(menuItem);
     }
 
+    @Override
+    public boolean onContextItemSelected(MenuItem item) {
+        if (!MucDetailsContextMenuHelper.onContextItemSelected(item, mUserPreviewAdapter.getSelectedUser(), this)) {
+            return super.onContextItemSelected(item);
+        }
+        return true;
+    }
+
     public void onMucEditButtonClicked(View v) {
         if (this.binding.mucEditor.getVisibility() == View.GONE) {
             final MucOptions mucOptions = mConversation.getMucOptions();
@@ -558,7 +567,7 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
                 }
             }
         });
-        this.mUserPreviewAdapter.setUserList(MucOptions.sub(users, GridManager.getCurrentColumnCount(binding.users)));
+        this.mUserPreviewAdapter.submitList(MucOptions.sub(users, GridManager.getCurrentColumnCount(binding.users)));
         this.binding.invite.setVisibility(mucOptions.canInvite() ? View.VISIBLE : View.GONE);
 
     }

src/main/java/eu/siacs/conversations/ui/ConversationFragment.java 🔗

@@ -2740,7 +2740,7 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke
                 popupMenu.inflate(R.menu.muc_details_context);
                 final Menu menu = popupMenu.getMenu();
                 MucDetailsContextMenuHelper.configureMucDetailsContextMenu(activity, menu, conversation, user);
-                popupMenu.setOnMenuItemClickListener(menuItem -> MucDetailsContextMenuHelper.onContextItemSelected(menuItem, user, conversation, activity));
+                popupMenu.setOnMenuItemClickListener(menuItem -> MucDetailsContextMenuHelper.onContextItemSelected(menuItem, user, activity));
             } else {
                 final Contact contact = message.getContact();
                 if (contact.isSelf()) {

src/main/java/eu/siacs/conversations/ui/MucUsersActivity.java 🔗

@@ -5,10 +5,12 @@ import android.databinding.DataBindingUtil;
 import android.os.Bundle;
 import android.support.v7.widget.Toolbar;
 import android.view.MenuItem;
+import android.widget.Toast;
 
 import java.util.ArrayList;
 import java.util.Collections;
 
+import eu.siacs.conversations.Config;
 import eu.siacs.conversations.R;
 import eu.siacs.conversations.databinding.ActivityMucUsersBinding;
 import eu.siacs.conversations.entities.Conversation;
@@ -16,8 +18,9 @@ import eu.siacs.conversations.entities.MucOptions;
 import eu.siacs.conversations.services.XmppConnectionService;
 import eu.siacs.conversations.ui.adapter.UserAdapter;
 import eu.siacs.conversations.ui.util.MucDetailsContextMenuHelper;
+import rocks.xmpp.addr.Jid;
 
-public class MucUsersActivity extends XmppActivity implements XmppConnectionService.OnRosterUpdate {
+public class MucUsersActivity extends XmppActivity implements XmppConnectionService.OnMucRosterUpdate, XmppConnectionService.OnAffiliationChanged, XmppConnectionService.OnRoleChanged {
 
     private UserAdapter userAdapter;
 
@@ -45,9 +48,9 @@ public class MucUsersActivity extends XmppActivity implements XmppConnectionServ
         }
     }
 
-     @Override
+    @Override
     public boolean onContextItemSelected(MenuItem item) {
-        if (!MucDetailsContextMenuHelper.onContextItemSelected(item, userAdapter.getSelectedUser(), mConversation, this)) {
+        if (!MucDetailsContextMenuHelper.onContextItemSelected(item, userAdapter.getSelectedUser(), this)) {
             return super.onContextItemSelected(item);
         }
         return true;
@@ -59,13 +62,37 @@ public class MucUsersActivity extends XmppActivity implements XmppConnectionServ
         ActivityMucUsersBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_muc_users);
         setSupportActionBar((Toolbar) binding.toolbar);
         configureActionBar(getSupportActionBar(), true);
-        this.userAdapter = new UserAdapter(true);
+        this.userAdapter = new UserAdapter(getPreferences().getBoolean("advanced_muc_mode", false));
         binding.list.setAdapter(this.userAdapter);
     }
 
 
     @Override
-    public void onRosterUpdate() {
+    public void onMucRosterUpdate() {
         loadAndSubmitUsers();
     }
+
+     private void displayToast(final String msg) {
+        runOnUiThread(() -> Toast.makeText(this, msg, Toast.LENGTH_SHORT).show());
+    }
+
+    @Override
+    public void onAffiliationChangedSuccessful(Jid jid) {
+
+    }
+
+    @Override
+    public void onAffiliationChangeFailed(Jid jid, int resId) {
+        displayToast(getString(resId, jid.asBareJid().toString()));
+    }
+
+    @Override
+    public void onRoleChangedSuccessful(String nick) {
+
+    }
+
+    @Override
+    public void onRoleChangeFailed(String nick, int resId) {
+        displayToast(getString(resId, nick));
+    }
 }

src/main/java/eu/siacs/conversations/ui/adapter/ListItemAdapter.java 🔗

@@ -27,8 +27,10 @@ import eu.siacs.conversations.entities.ListItem;
 import eu.siacs.conversations.ui.SettingsActivity;
 import eu.siacs.conversations.ui.XmppActivity;
 import eu.siacs.conversations.ui.util.AvatarWorkerTask;
+import eu.siacs.conversations.ui.util.StyledAttributes;
 import eu.siacs.conversations.utils.EmojiWrapper;
 import eu.siacs.conversations.utils.IrregularUnicodeDetector;
+import eu.siacs.conversations.utils.ThemeHelper;
 import eu.siacs.conversations.utils.UIHelper;
 import rocks.xmpp.addr.Jid;
 
@@ -68,6 +70,7 @@ public class ListItemAdapter extends ArrayAdapter<ListItem> {
 		} else {
 			viewHolder = (ViewHolder) view.getTag();
 		}
+		view.setBackground(StyledAttributes.getDrawable(view.getContext(),R.attr.list_item_background));
 
 		List<ListItem.Tag> tags = item.getTags(activity);
 		if (tags.size() == 0 || !this.showDynamicTags) {

src/main/java/eu/siacs/conversations/ui/adapter/UserAdapter.java 🔗

@@ -9,19 +9,14 @@ import android.support.v7.util.DiffUtil;
 import android.support.v7.widget.RecyclerView;
 import android.view.ContextMenu;
 import android.view.LayoutInflater;
-import android.view.Menu;
 import android.view.View;
 import android.view.ViewGroup;
-import android.widget.PopupMenu;
 
 import org.openintents.openpgp.util.OpenPgpUtils;
 
-import java.util.List;
-
 import eu.siacs.conversations.R;
 import eu.siacs.conversations.crypto.PgpEngine;
 import eu.siacs.conversations.databinding.ContactBinding;
-import eu.siacs.conversations.databinding.UserPreviewBinding;
 import eu.siacs.conversations.entities.Contact;
 import eu.siacs.conversations.entities.MucOptions;
 import eu.siacs.conversations.services.XmppConnectionService;
@@ -29,15 +24,24 @@ import eu.siacs.conversations.ui.ConferenceDetailsActivity;
 import eu.siacs.conversations.ui.XmppActivity;
 import eu.siacs.conversations.ui.util.AvatarWorkerTask;
 import eu.siacs.conversations.ui.util.MucDetailsContextMenuHelper;
+import rocks.xmpp.addr.Jid;
 
 public class UserAdapter extends ListAdapter<MucOptions.User, UserAdapter.ViewHolder> implements View.OnCreateContextMenuListener {
 
-    private MucOptions.User selectedUser = null;
-
     static final DiffUtil.ItemCallback<MucOptions.User> DIFF = new DiffUtil.ItemCallback<MucOptions.User>() {
         @Override
         public boolean areItemsTheSame(@NonNull MucOptions.User a, @NonNull MucOptions.User b) {
-            return a == b;
+            final Jid fullA = a.getFullJid();
+            final Jid fullB = b.getFullJid();
+            final Jid realA = a.getRealJid();
+            final Jid realB = b.getRealJid();
+            if (fullA != null && fullB != null) {
+                return fullA.equals(fullB);
+            } else if (realA != null && realB != null) {
+                return realA.equals(realB);
+            } else {
+                return false;
+            }
         }
 
         @Override
@@ -46,6 +50,7 @@ public class UserAdapter extends ListAdapter<MucOptions.User, UserAdapter.ViewHo
         }
     };
     private final boolean advancedMode;
+    private MucOptions.User selectedUser = null;
 
     public UserAdapter(final boolean advancedMode) {
         super(DIFF);
@@ -116,23 +121,7 @@ public class UserAdapter extends ListAdapter<MucOptions.User, UserAdapter.ViewHo
 
     @Override
     public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
-        final XmppActivity activity = XmppActivity.find(v);
-        final Object tag = v.getTag();
-        if (tag instanceof MucOptions.User && activity != null) {
-            activity.getMenuInflater().inflate(R.menu.muc_details_context, menu);
-            final MucOptions.User user = (MucOptions.User) tag;
-            String name;
-            final Contact contact = user.getContact();
-            if (contact != null && contact.showInContactList()) {
-                name = contact.getDisplayName();
-            } else if (user.getRealJid() != null) {
-                name = user.getRealJid().asBareJid().toString();
-            } else {
-                name = user.getName();
-            }
-            menu.setHeaderTitle(name);
-            MucDetailsContextMenuHelper.configureMucDetailsContextMenu(activity, menu, user.getConversation(), user);
-        }
+        MucDetailsContextMenuHelper.onCreateContextMenu(menu,v);
     }
 
     class ViewHolder extends RecyclerView.ViewHolder {

src/main/java/eu/siacs/conversations/ui/adapter/UserPreviewAdapter.java 🔗

@@ -4,22 +4,21 @@ import android.databinding.DataBindingUtil;
 import android.support.annotation.NonNull;
 import android.support.v7.recyclerview.extensions.ListAdapter;
 import android.support.v7.widget.RecyclerView;
+import android.view.ContextMenu;
 import android.view.LayoutInflater;
-import android.view.Menu;
+import android.view.View;
 import android.view.ViewGroup;
-import android.widget.PopupMenu;
-
-import java.util.List;
 
 import eu.siacs.conversations.R;
 import eu.siacs.conversations.databinding.UserPreviewBinding;
-import eu.siacs.conversations.entities.Contact;
 import eu.siacs.conversations.entities.MucOptions;
 import eu.siacs.conversations.ui.XmppActivity;
 import eu.siacs.conversations.ui.util.AvatarWorkerTask;
 import eu.siacs.conversations.ui.util.MucDetailsContextMenuHelper;
 
-public class UserPreviewAdapter extends ListAdapter<MucOptions.User,UserPreviewAdapter.ViewHolder> {
+public class UserPreviewAdapter extends ListAdapter<MucOptions.User, UserPreviewAdapter.ViewHolder> implements View.OnCreateContextMenuListener {
+
+    private MucOptions.User selectedUser = null;
 
     public UserPreviewAdapter() {
         super(UserAdapter.DIFF);
@@ -41,25 +40,22 @@ public class UserPreviewAdapter extends ListAdapter<MucOptions.User,UserPreviewA
                 activity.highlightInMuc(user.getConversation(), user.getName());
             }
         });
+        viewHolder.binding.getRoot().setOnCreateContextMenuListener(this);
+        viewHolder.binding.getRoot().setTag(user);
         viewHolder.binding.getRoot().setOnLongClickListener(v -> {
-            final XmppActivity activity = XmppActivity.find(v);
-            if (activity == null) {
-                return true;
-            }
-            final PopupMenu popupMenu = new PopupMenu(activity, v);
-            popupMenu.inflate(R.menu.muc_details_context);
-            final Menu menu = popupMenu.getMenu();
-            MucDetailsContextMenuHelper.configureMucDetailsContextMenu(activity, menu, user.getConversation(), user);
-            popupMenu.setOnMenuItemClickListener(menuItem -> MucDetailsContextMenuHelper.onContextItemSelected(menuItem, user, user.getConversation(), activity));
-            popupMenu.show();
-            return true;
+            selectedUser = user;
+            return false;
         });
     }
 
-    public void setUserList(List<MucOptions.User> users) {
-        submitList(users);
+    @Override
+    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
+        MucDetailsContextMenuHelper.onCreateContextMenu(menu, v);
     }
 
+    public MucOptions.User getSelectedUser() {
+        return selectedUser;
+    }
 
     class ViewHolder extends RecyclerView.ViewHolder {
 

src/main/java/eu/siacs/conversations/ui/util/MucDetailsContextMenuHelper.java 🔗

@@ -7,8 +7,10 @@ import android.support.v7.app.AlertDialog;
 import android.text.SpannableString;
 import android.text.Spanned;
 import android.text.style.TypefaceSpan;
+import android.view.ContextMenu;
 import android.view.Menu;
 import android.view.MenuItem;
+import android.view.View;
 
 import eu.siacs.conversations.Config;
 import eu.siacs.conversations.entities.Contact;
@@ -20,11 +22,33 @@ import eu.siacs.conversations.services.XmppConnectionService;
 import eu.siacs.conversations.ui.ConferenceDetailsActivity;
 import eu.siacs.conversations.ui.ConversationFragment;
 import eu.siacs.conversations.ui.ConversationsActivity;
+import eu.siacs.conversations.ui.MucUsersActivity;
 import eu.siacs.conversations.ui.XmppActivity;
 import rocks.xmpp.addr.Jid;
 
 
 public final class MucDetailsContextMenuHelper {
+
+    public static void onCreateContextMenu(ContextMenu menu, View v) {
+        final XmppActivity activity = XmppActivity.find(v);
+        final Object tag = v.getTag();
+        if (tag instanceof MucOptions.User && activity != null) {
+            activity.getMenuInflater().inflate(R.menu.muc_details_context, menu);
+            final MucOptions.User user = (MucOptions.User) tag;
+            String name;
+            final Contact contact = user.getContact();
+            if (contact != null && contact.showInContactList()) {
+                name = contact.getDisplayName();
+            } else if (user.getRealJid() != null) {
+                name = user.getRealJid().asBareJid().toString();
+            } else {
+                name = user.getName();
+            }
+            menu.setHeaderTitle(name);
+            MucDetailsContextMenuHelper.configureMucDetailsContextMenu(activity, menu, user.getConversation(), user);
+        }
+    }
+
     public static void configureMucDetailsContextMenu(Activity activity, Menu menu, Conversation conversation, User user) {
         final MucOptions mucOptions = conversation.getMucOptions();
         final boolean advancedMode = PreferenceManager.getDefaultSharedPreferences(activity).getBoolean("advanced_muc_mode", false);
@@ -45,7 +69,7 @@ public final class MucDetailsContextMenuHelper {
             if (contact != null && contact.showInRoster()) {
                 showContactDetails.setVisible(!contact.isSelf());
             }
-            if (activity instanceof ConferenceDetailsActivity && user.getRole() == MucOptions.Role.NONE) {
+            if ((activity instanceof ConferenceDetailsActivity || activity instanceof MucUsersActivity) && user.getRole() == MucOptions.Role.NONE) {
                 invite.setVisible(true);
             }
             if (self.getAffiliation().ranks(MucOptions.Affiliation.ADMIN) &&
@@ -77,7 +101,8 @@ public final class MucDetailsContextMenuHelper {
         }
     }
 
-    public static boolean onContextItemSelected(MenuItem item, User user, Conversation conversation, XmppActivity activity) {
+    public static boolean onContextItemSelected(MenuItem item, User user, XmppActivity activity) {
+        final Conversation conversation = user.getConversation();
         final XmppConnectionService.OnAffiliationChanged onAffiliationChanged = activity instanceof XmppConnectionService.OnAffiliationChanged ? (XmppConnectionService.OnAffiliationChanged) activity : null;
         final XmppConnectionService.OnRoleChanged onRoleChanged = activity instanceof XmppConnectionService.OnRoleChanged ? (XmppConnectionService.OnRoleChanged) activity : null;
         Jid jid = user.getRealJid();
@@ -89,7 +114,7 @@ public final class MucDetailsContextMenuHelper {
                 }
                 return true;
             case R.id.start_conversation:
-                startConversation(user, conversation, activity);
+                startConversation(user, activity);
                 return true;
             case R.id.give_admin_privileges:
                 activity.xmppConnectionService.changeAffiliationInConference(conversation, jid, MucOptions.Affiliation.ADMIN, onAffiliationChanged);
@@ -104,7 +129,7 @@ public final class MucDetailsContextMenuHelper {
                 activity.xmppConnectionService.changeAffiliationInConference(conversation, jid, MucOptions.Affiliation.MEMBER, onAffiliationChanged);
                 return true;
             case R.id.remove_from_room:
-                removeFromRoom(user, conversation, activity, onAffiliationChanged, onRoleChanged);
+                removeFromRoom(user, activity, onAffiliationChanged, onRoleChanged);
                 return true;
             case R.id.ban_from_conference:
                 activity.xmppConnectionService.changeAffiliationInConference(conversation, jid, MucOptions.Affiliation.OUTCAST, onAffiliationChanged);
@@ -130,7 +155,8 @@ public final class MucDetailsContextMenuHelper {
         }
     }
 
-    public static void removeFromRoom(final User user, Conversation conversation, XmppActivity activity, XmppConnectionService.OnAffiliationChanged onAffiliationChanged, XmppConnectionService.OnRoleChanged onRoleChanged) {
+    private static void removeFromRoom(final User user, XmppActivity activity, XmppConnectionService.OnAffiliationChanged onAffiliationChanged, XmppConnectionService.OnRoleChanged onRoleChanged) {
+        final Conversation conversation = user.getConversation();
         if (conversation.getMucOptions().membersOnly()) {
             activity.xmppConnectionService.changeAffiliationInConference(conversation, user.getRealJid(), MucOptions.Affiliation.NONE, onAffiliationChanged);
             if (user.getRole() != MucOptions.Role.NONE) {
@@ -157,9 +183,9 @@ public final class MucDetailsContextMenuHelper {
         }
     }
 
-    public static void startConversation(User user, Conversation conversation, XmppActivity activity) {
+    private static void startConversation(User user, XmppActivity activity) {
         if (user.getRealJid() != null) {
-            Conversation newConversation = activity.xmppConnectionService.findOrCreateConversation(conversation.getAccount(), user.getRealJid().asBareJid(), false, true);
+            Conversation newConversation = activity.xmppConnectionService.findOrCreateConversation(user.getAccount(), user.getRealJid().asBareJid(), false, true);
             activity.switchToConversation(newConversation);
         }
     }