Track who is banned and allow unban

Stephen Paul Weber created

Change summary

src/main/java/eu/siacs/conversations/entities/MucOptions.java                 | 18 
src/main/java/eu/siacs/conversations/services/XmppConnectionService.java      | 15 
src/main/java/eu/siacs/conversations/ui/util/MucDetailsContextMenuHelper.java |  3 
3 files changed, 20 insertions(+), 16 deletions(-)

Detailed changes

src/main/java/eu/siacs/conversations/entities/MucOptions.java 🔗

@@ -76,13 +76,13 @@ public class MucOptions {
     public void changeAffiliation(Jid jid, Affiliation affiliation) {
         User user = findUserByRealJid(jid);
         synchronized (users) {
-            if (user != null && user.getRole() == Role.NONE) {
-                users.remove(user);
-                if (affiliation.ranks(Affiliation.MEMBER)) {
-                    user.affiliation = affiliation;
-                    users.add(user);
-                }
+            if (user == null) {
+                user = new User(this, null, null, null, new HashSet<>());
+                user.setRealJid(jid);
+                user.setOnline(false);
+                users.add(user);
             }
+            user.affiliation = affiliation;
         }
     }
 
@@ -290,9 +290,7 @@ public class MucOptions {
                 if (old.avatar != null && user.avatar == null) user.avatar = old.avatar;
             }
             boolean fullJidIsSelf = isOnline && user.getFullJid() != null && user.getFullJid().equals(self.getFullJid());
-            if ((!membersOnly() || user.getAffiliation().ranks(Affiliation.MEMBER))
-                    && user.getAffiliation().outranks(Affiliation.OUTCAST)
-                    && !fullJidIsSelf) {
+            if (!fullJidIsSelf) {
                 this.users.add(user);
                 return !realJidFound && user.realJid != null;
             }
@@ -404,7 +402,7 @@ public class MucOptions {
         synchronized (users) {
             ArrayList<User> users = new ArrayList<>();
             for (User user : this.users) {
-                if (!user.isDomain() && (includeOffline || user.getRole().ranks(Role.PARTICIPANT))) {
+                if (!user.isDomain() && (includeOffline ? user.getAffiliation().ranks(Affiliation.NONE) : user.getRole().ranks(Role.PARTICIPANT))) {
                     users.add(user);
                 }
             }

src/main/java/eu/siacs/conversations/services/XmppConnectionService.java 🔗

@@ -3671,9 +3671,8 @@ public class XmppConnectionService extends Service {
                     if (mucOptions.mamSupport()) {
                         getMessageArchiveService().catchupMUC(conversation);
                     }
+                    fetchConferenceMembers(conversation);
                     if (mucOptions.isPrivateAndNonAnonymous()) {
-                        fetchConferenceMembers(conversation);
-
                         if (followedInvite) {
                             final Bookmark bookmark = conversation.getBookmark();
                             if (bookmark != null) {
@@ -3733,7 +3732,9 @@ public class XmppConnectionService extends Service {
     private void fetchConferenceMembers(final Conversation conversation) {
         final Account account = conversation.getAccount();
         final AxolotlService axolotlService = account.getAxolotlService();
-        final String[] affiliations = {"member", "admin", "owner"};
+        final var affiliations = new ArrayList<String>();
+        affiliations.add("outcast");
+        if (conversation.getMucOptions().isPrivateAndNonAnonymous()) affiliations.addAll(List.of("member", "admin", "owner"));
         OnIqPacketReceived callback = new OnIqPacketReceived() {
 
             private int i = 0;
@@ -3747,6 +3748,7 @@ public class XmppConnectionService extends Service {
                     for (Element child : query.getChildren()) {
                         if ("item".equals(child.getName())) {
                             MucOptions.User user = AbstractParser.parseItem(conversation, child);
+                            user.setOnline(false);
                             if (!user.realJidMatchesAccount()) {
                                 boolean isNew = conversation.getMucOptions().updateUser(user);
                                 Contact contact = user.getContact();
@@ -3762,10 +3764,10 @@ public class XmppConnectionService extends Service {
                     }
                 } else {
                     success = false;
-                    Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": could not request affiliation " + affiliations[i] + " in " + conversation.getJid().asBareJid());
+                    Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": could not request affiliation " + affiliations.get(i) + " in " + conversation.getJid().asBareJid());
                 }
                 ++i;
-                if (i >= affiliations.length) {
+                if (i >= affiliations.size()) {
                     List<Jid> members = conversation.getMucOptions().getMembers(true);
                     if (success) {
                         List<Jid> cryptoTargets = conversation.getAcceptedCryptoTargets();
@@ -3790,7 +3792,8 @@ public class XmppConnectionService extends Service {
             }
         };
         for (String affiliation : affiliations) {
-            sendIqPacket(account, mIqGenerator.queryAffiliation(conversation, affiliation), callback);
+            final var x = mIqGenerator.queryAffiliation(conversation, affiliation);
+            sendIqPacket(account, x, callback);
         }
         Log.d(Config.LOGTAG, account.getJid().asBareJid() + ": fetching members for " + conversation.getName());
     }

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

@@ -77,6 +77,9 @@ public final class MucDetailsContextMenuHelper {
             if (!Config.DISABLE_BAN && user.getAffiliation() != MucOptions.Affiliation.OUTCAST) {
                 items.add(activity.getString(isGroupChat ? R.string.ban_from_conference : R.string.ban_from_channel));
                 actions.add(ACTION_BAN);
+            } else if (!Config.DISABLE_BAN) {
+                items.add(isGroupChat ? "Unban from group chat" : "Unban from channel");
+                actions.add(ACTION_REMOVE_MEMBERSHIP);
             }
             if (!user.getAffiliation().ranks(MucOptions.Affiliation.MEMBER)) {
                 items.add(activity.getString(R.string.grant_membership));