Manage permissions with dialog

Stephen Paul Weber created

Instead of submenu, to reduce the chance of fat fingering.

Change summary

src/main/java/eu/siacs/conversations/ui/util/MucDetailsContextMenuHelper.java | 155 
src/main/res/menu/muc_details_context.xml                                     |  33 
2 files changed, 97 insertions(+), 91 deletions(-)

Detailed changes

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

@@ -5,6 +5,7 @@ import android.preference.PreferenceManager;
 import android.text.SpannableString;
 import android.text.Spanned;
 import android.text.style.TypefaceSpan;
+import android.util.Pair;
 import android.view.ContextMenu;
 import android.view.Menu;
 import android.view.MenuItem;
@@ -12,6 +13,8 @@ import android.view.View;
 
 import androidx.appcompat.app.AlertDialog;
 
+import java.util.ArrayList;
+
 import eu.siacs.conversations.Config;
 import eu.siacs.conversations.R;
 import eu.siacs.conversations.entities.Account;
@@ -29,6 +32,13 @@ import eu.siacs.conversations.xmpp.Jid;
 
 
 public final class MucDetailsContextMenuHelper {
+    private static final int ACTION_BAN = 0;
+    private static final int ACTION_GRANT_MEMBERSHIP = 1;
+    private static final int ACTION_REMOVE_MEMBERSHIP = 2;
+    private static final int ACTION_GRANT_ADMIN = 3;
+    private static final int ACTION_REMOVE_ADMIN = 4;
+    private static final int ACTION_GRANT_OWNER = 5;
+    private static final int ACTION_REMOVE_OWNER = 6;
 
     public static void onCreateContextMenu(ContextMenu menu, View v) {
         final XmppActivity activity = XmppActivity.find(v);
@@ -50,6 +60,44 @@ public final class MucDetailsContextMenuHelper {
         }
     }
 
+    public static Pair<CharSequence[], Integer[]> getPermissionsChoices(Activity activity, Conversation conversation, User user) {
+        ArrayList<CharSequence> items = new ArrayList<>();
+        ArrayList<Integer> actions = new ArrayList<>();
+        final User self = conversation.getMucOptions().getSelf();
+        final MucOptions mucOptions = conversation.getMucOptions();
+        final boolean isGroupChat = mucOptions.isPrivateAndNonAnonymous();
+        if ((self.getAffiliation().ranks(MucOptions.Affiliation.ADMIN) && self.getAffiliation().outranks(user.getAffiliation())) || self.getAffiliation() == MucOptions.Affiliation.OWNER) {
+            if (!Config.DISABLE_BAN) {
+                items.add(activity.getString(isGroupChat ? R.string.ban_from_conference : R.string.ban_from_channel));
+                actions.add(ACTION_BAN);
+            }
+            if (!user.getAffiliation().ranks(MucOptions.Affiliation.MEMBER)) {
+                items.add(activity.getString(R.string.grant_membership));
+                actions.add(ACTION_GRANT_MEMBERSHIP);
+            } else if (user.getAffiliation() == MucOptions.Affiliation.MEMBER) {
+                items.add(activity.getString(R.string.remove_membership));
+                actions.add(ACTION_REMOVE_MEMBERSHIP);
+            }
+        }
+        if (self.getAffiliation().ranks(MucOptions.Affiliation.OWNER)) {
+            if (!user.getAffiliation().ranks(MucOptions.Affiliation.ADMIN)) {
+                items.add(activity.getString(R.string.grant_admin_privileges));
+                actions.add(ACTION_GRANT_ADMIN);
+            } else if (user.getAffiliation() == MucOptions.Affiliation.ADMIN) {
+                items.add(activity.getString(R.string.remove_admin_privileges));
+                actions.add(ACTION_REMOVE_ADMIN);
+            }
+            if (!user.getAffiliation().ranks(MucOptions.Affiliation.OWNER)) {
+                items.add(activity.getString(R.string.grant_owner_privileges));
+                actions.add(ACTION_GRANT_OWNER);
+            } else if (user.getAffiliation() == MucOptions.Affiliation.OWNER){
+                items.add(activity.getString(R.string.remove_owner_privileges));
+                actions.add(ACTION_REMOVE_OWNER);
+            }
+        }
+        return new Pair<>(items.toArray(new CharSequence[items.size()]), actions.toArray(new Integer[actions.size()]));
+    }
+
     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);
@@ -64,17 +112,9 @@ public final class MucDetailsContextMenuHelper {
         if (user != null && user.getRealJid() != null) {
             MenuItem showContactDetails = menu.findItem(R.id.action_contact_details);
             MenuItem startConversation = menu.findItem(R.id.start_conversation);
-            MenuItem giveMembership = menu.findItem(R.id.give_membership);
-            MenuItem removeMembership = menu.findItem(R.id.remove_membership);
-            MenuItem giveAdminPrivileges = menu.findItem(R.id.give_admin_privileges);
-            MenuItem giveOwnerPrivileges = menu.findItem(R.id.give_owner_privileges);
-            MenuItem removeOwnerPrivileges = menu.findItem(R.id.revoke_owner_privileges);
-            MenuItem removeAdminPrivileges = menu.findItem(R.id.remove_admin_privileges);
             MenuItem removeFromRoom = menu.findItem(R.id.remove_from_room);
             MenuItem managePermissions = menu.findItem(R.id.manage_permissions);
             removeFromRoom.setTitle(isGroupChat ? R.string.remove_from_room : R.string.remove_from_channel);
-            MenuItem banFromConference = menu.findItem(R.id.ban_from_conference);
-            banFromConference.setTitle(isGroupChat ? R.string.ban_from_conference : R.string.ban_from_channel);
             MenuItem invite = menu.findItem(R.id.invite);
             startConversation.setVisible(true);
             final Contact contact = user.getContact();
@@ -87,42 +127,25 @@ public final class MucDetailsContextMenuHelper {
             }
             boolean managePermissionsVisible = false;
             if ((self.getAffiliation().ranks(MucOptions.Affiliation.ADMIN) && self.getAffiliation().outranks(user.getAffiliation())) || self.getAffiliation() == MucOptions.Affiliation.OWNER) {
-                if (advancedMode) {
-                    if (!user.getAffiliation().ranks(MucOptions.Affiliation.MEMBER)) {
-                        managePermissionsVisible = true;
-                        giveMembership.setVisible(true);
-                    } else if (user.getAffiliation() == MucOptions.Affiliation.MEMBER) {
-                        managePermissionsVisible = true;
-                        removeMembership.setVisible(true);
-                    }
-                    if (!Config.DISABLE_BAN) {
-                        managePermissionsVisible = true;
-                        banFromConference.setVisible(true);
-                    }
-                } else {
-                    if (!Config.DISABLE_BAN || conversation.getMucOptions().membersOnly()) {
-                        removeFromRoom.setVisible(true);
-                    }
+                if (!user.getAffiliation().ranks(MucOptions.Affiliation.MEMBER)) {
+                    managePermissionsVisible = true;
+                } else if (user.getAffiliation() == MucOptions.Affiliation.MEMBER) {
+                    managePermissionsVisible = true;
+                }
+                if (!Config.DISABLE_BAN) {
+                    managePermissionsVisible = true;
                 }
             }
             if (self.getAffiliation().ranks(MucOptions.Affiliation.OWNER)) {
-                if (isGroupChat || advancedMode || user.getAffiliation() == MucOptions.Affiliation.OWNER) {
-                    if (!user.getAffiliation().ranks(MucOptions.Affiliation.OWNER)) {
-                        managePermissionsVisible = true;
-                        giveOwnerPrivileges.setVisible(true);
-                    } else if (user.getAffiliation() == MucOptions.Affiliation.OWNER){
-                        managePermissionsVisible = true;
-                        removeOwnerPrivileges.setVisible(true);
-                    }
+                if (!user.getAffiliation().ranks(MucOptions.Affiliation.OWNER)) {
+                    managePermissionsVisible = true;
+                } else if (user.getAffiliation() == MucOptions.Affiliation.OWNER){
+                    managePermissionsVisible = true;
                 }
-                if (!isGroupChat || advancedMode || user.getAffiliation() == MucOptions.Affiliation.ADMIN) {
-                    if (!user.getAffiliation().ranks(MucOptions.Affiliation.ADMIN)) {
-                        managePermissionsVisible = true;
-                        giveAdminPrivileges.setVisible(true);
-                    } else if (user.getAffiliation() == MucOptions.Affiliation.ADMIN) {
-                        managePermissionsVisible = true;
-                        removeAdminPrivileges.setVisible(true);
-                    }
+                if (!user.getAffiliation().ranks(MucOptions.Affiliation.ADMIN)) {
+                    managePermissionsVisible = true;
+                } else if (user.getAffiliation() == MucOptions.Affiliation.ADMIN) {
+                    managePermissionsVisible = true;
                 }
             }
             managePermissions.setVisible(managePermissionsVisible);
@@ -169,29 +192,43 @@ public final class MucDetailsContextMenuHelper {
             case R.id.start_conversation:
                 startConversation(user, activity);
                 return true;
-            case R.id.give_admin_privileges:
-                activity.xmppConnectionService.changeAffiliationInConference(conversation, jid, MucOptions.Affiliation.ADMIN, onAffiliationChanged);
-                return true;
-            case R.id.give_membership:
-            case R.id.remove_admin_privileges:
-            case R.id.revoke_owner_privileges:
-                activity.xmppConnectionService.changeAffiliationInConference(conversation, jid, MucOptions.Affiliation.MEMBER, onAffiliationChanged);
-                return true;
-            case R.id.give_owner_privileges:
-                activity.xmppConnectionService.changeAffiliationInConference(conversation, jid, MucOptions.Affiliation.OWNER, onAffiliationChanged);
-                return true;
-            case R.id.remove_membership:
-                activity.xmppConnectionService.changeAffiliationInConference(conversation, jid, MucOptions.Affiliation.NONE, onAffiliationChanged);
+            case R.id.manage_permissions:
+                Pair<CharSequence[], Integer[]> choices = getPermissionsChoices(activity, conversation, user);
+                int[] selected = new int[] { -1 };
+                new AlertDialog.Builder(activity)
+                    .setTitle(R.string.manage_permission)
+                    .setSingleChoiceItems(choices.first, -1, (dialog, whichItem) -> {
+                        selected[0] = whichItem;
+                    })
+                    .setPositiveButton(R.string.action_complete, (dialog, whichButton) -> {
+                        switch (selected[0] >= 0 ? choices.second[selected[0]] : -1) {
+                            case ACTION_BAN:
+                                activity.xmppConnectionService.changeAffiliationInConference(conversation, jid, MucOptions.Affiliation.OUTCAST, onAffiliationChanged);
+                                if (user.getRole() != MucOptions.Role.NONE) {
+                                    activity.xmppConnectionService.changeRoleInConference(conversation, user.getName(), MucOptions.Role.NONE);
+                                }
+                                break;
+                            case ACTION_GRANT_MEMBERSHIP:
+                            case ACTION_REMOVE_ADMIN:
+                            case ACTION_REMOVE_OWNER:
+                                activity.xmppConnectionService.changeAffiliationInConference(conversation, jid, MucOptions.Affiliation.MEMBER, onAffiliationChanged);
+                                break;
+                            case ACTION_GRANT_ADMIN:
+                                activity.xmppConnectionService.changeAffiliationInConference(conversation, jid, MucOptions.Affiliation.ADMIN, onAffiliationChanged);
+                                break;
+                            case ACTION_GRANT_OWNER:
+                                activity.xmppConnectionService.changeAffiliationInConference(conversation, jid, MucOptions.Affiliation.OWNER, onAffiliationChanged);
+                                break;
+                            case ACTION_REMOVE_MEMBERSHIP:
+                                activity.xmppConnectionService.changeAffiliationInConference(conversation, jid, MucOptions.Affiliation.NONE, onAffiliationChanged);
+                                break;
+                        }
+                    })
+                    .setNeutralButton(R.string.cancel, null).show();
                 return true;
             case R.id.remove_from_room:
                 removeFromRoom(user, activity, onAffiliationChanged);
                 return true;
-            case R.id.ban_from_conference:
-                activity.xmppConnectionService.changeAffiliationInConference(conversation, jid, MucOptions.Affiliation.OUTCAST, onAffiliationChanged);
-                if (user.getRole() != MucOptions.Role.NONE) {
-                    activity.xmppConnectionService.changeRoleInConference(conversation, user.getName(), MucOptions.Role.NONE);
-                }
-                return true;
             case R.id.send_private_message:
                 if (activity instanceof ConversationsActivity) {
                     ConversationFragment conversationFragment = ConversationFragment.get(activity);

src/main/res/menu/muc_details_context.xml 🔗

@@ -23,38 +23,7 @@
     <item
         android:id="@+id/manage_permissions"
         android:title="@string/manage_permission"
-        android:visible="false">
-        <menu>
-            <item
-                android:id="@+id/give_membership"
-                android:title="@string/grant_membership"
-                android:visible="false" />
-            <item
-                android:id="@+id/remove_membership"
-                android:title="@string/remove_membership"
-                android:visible="false" />
-            <item
-                android:id="@+id/give_admin_privileges"
-                android:title="@string/grant_admin_privileges"
-                android:visible="false" />
-            <item
-                android:id="@+id/remove_admin_privileges"
-                android:title="@string/remove_admin_privileges"
-                android:visible="false" />
-            <item
-                android:id="@+id/give_owner_privileges"
-                android:title="@string/grant_owner_privileges"
-                android:visible="false" />
-            <item
-                android:id="@+id/revoke_owner_privileges"
-                android:title="@string/remove_owner_privileges"
-                android:visible="false" />
-            <item
-                android:id="@+id/ban_from_conference"
-                android:title="@string/ban_from_conference"
-                android:visible="false" />
-        </menu>
-    </item>
+        android:visible="false" />
     <item
         android:id="@+id/remove_from_room"
         android:title="@string/remove_from_room"