show different room settings for channels and groups

Daniel Gultsch created

Change summary

src/main/java/eu/siacs/conversations/entities/MucOptions.java            |  16 
src/main/java/eu/siacs/conversations/generator/IqGenerator.java          |   3 
src/main/java/eu/siacs/conversations/parser/PresenceParser.java          |   2 
src/main/java/eu/siacs/conversations/services/XmppConnectionService.java |   5 
src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java   |  73 
src/main/java/eu/siacs/conversations/ui/util/MucConfiguration.java       | 111 
src/main/res/layout/activity_muc_details.xml                             |  10 
src/main/res/values/strings.xml                                          |  22 
8 files changed, 183 insertions(+), 59 deletions(-)

Detailed changes

src/main/java/eu/siacs/conversations/entities/MucOptions.java πŸ”—

@@ -154,13 +154,21 @@ public class MucOptions {
     }
 
     public boolean canInvite() {
-        Field field = getRoomInfoForm().getFieldByName("muc#roomconfig_allowinvites");
-        return !membersOnly() || self.getRole().ranks(Role.MODERATOR) || (field != null && "1".equals(field.getValue()));
+        return !membersOnly() || self.getRole().ranks(Role.MODERATOR) || allowInvites();
+    }
+
+    public boolean allowInvites() {
+        final Field field = getRoomInfoForm().getFieldByName("muc#roomconfig_allowinvites");
+        return field != null && "1".equals(field.getValue());
     }
 
     public boolean canChangeSubject() {
-        Field field = getRoomInfoForm().getFieldByName("muc#roominfo_changesubject");
-        return self.getRole().ranks(Role.MODERATOR) || (field != null && "1".equals(field.getValue()));
+        return self.getRole().ranks(Role.MODERATOR) || participantsCanChangeSubject();
+    }
+
+    public boolean participantsCanChangeSubject() {
+        final Field field = getRoomInfoForm().getFieldByName("muc#roominfo_changesubject");
+        return field != null && "1".equals(field.getValue());
     }
 
     public boolean allowPm() {

src/main/java/eu/siacs/conversations/generator/IqGenerator.java πŸ”—

@@ -462,6 +462,8 @@ public class IqGenerator extends AbstractGenerator {
 		options.putString("muc#roomconfig_membersonly", "1");
 		options.putString("muc#roomconfig_publicroom", "0");
 		options.putString("muc#roomconfig_whois", "anyone");
+		options.putString("muc#roomconfig_changesubject", "0");
+		options.putString("muc#roomconfig_allowinvites", "0");
 		options.putString("muc#roomconfig_enablearchiving", "1"); //prosody
 		options.putString("mam", "1"); //ejabberd community
 		options.putString("muc#roomconfig_mam","1"); //ejabberd saas
@@ -474,6 +476,7 @@ public class IqGenerator extends AbstractGenerator {
 		options.putString("muc#roomconfig_membersonly", "0");
 		options.putString("muc#roomconfig_publicroom", "1");
 		options.putString("muc#roomconfig_whois", "moderators");
+		options.putString("muc#roomconfig_changesubject", "0");
 		options.putString("muc#roomconfig_enablearchiving", "1"); //prosody
 		options.putString("mam", "1"); //ejabberd community
 		options.putString("muc#roomconfig_mam","1"); //ejabberd saas

src/main/java/eu/siacs/conversations/parser/PresenceParser.java πŸ”—

@@ -97,7 +97,7 @@ public class PresenceParser extends AbstractParser implements
 									+mucOptions.getConversation().getJid().asBareJid()
 									+"' created. pushing default configuration");
 							mXmppConnectionService.pushConferenceConfiguration(mucOptions.getConversation(),
-									IqGenerator.defaultGroupChatConfiguration(),
+									IqGenerator.defaultChannelConfiguration(),
 									null);
 						}
 						if (mXmppConnectionService.getPgpEngine() != null) {

src/main/java/eu/siacs/conversations/services/XmppConnectionService.java πŸ”—

@@ -2882,6 +2882,10 @@ public class XmppConnectionService extends Service {
 	}
 
 	public void pushConferenceConfiguration(final Conversation conversation, final Bundle options, final OnConfigurationPushed callback) {
+	    if (options.getString("muc#roomconfig_whois","moderators").equals("anyone")) {
+	        conversation.setAttribute("accept_non_anonymous",true);
+            updateConversation(conversation);
+        }
 		IqPacket request = new IqPacket(IqPacket.TYPE.GET);
 		request.setTo(conversation.getJid().asBareJid());
 		request.query("http://jabber.org/protocol/muc#owner");
@@ -2891,6 +2895,7 @@ public class XmppConnectionService extends Service {
 				if (packet.getType() == IqPacket.TYPE.RESULT) {
 					Data data = Data.parse(packet.query().findChild("x", Namespace.DATA));
 					data.submit(options);
+					Log.d(Config.LOGTAG,data.toString());
 					IqPacket set = new IqPacket(IqPacket.TYPE.SET);
 					set.setTo(conversation.getJid().asBareJid());
 					set.query("http://jabber.org/protocol/muc#owner").addChild(data);

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.MucConfiguration;
 import eu.siacs.conversations.ui.util.MucDetailsContextMenuHelper;
 import eu.siacs.conversations.ui.util.MyLinkify;
 import eu.siacs.conversations.ui.util.SoftKeyboardUtils;
@@ -124,53 +125,16 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
         public void onClick(View v) {
             final MucOptions mucOptions = mConversation.getMucOptions();
             AlertDialog.Builder builder = new AlertDialog.Builder(ConferenceDetailsActivity.this);
-            builder.setTitle(R.string.conference_options);
-            final String[] options;
-            final boolean[] values;
-            if (mAdvancedMode) {
-                options = new String[]{
-                        getString(R.string.members_only),
-                        getString(R.string.moderated),
-                        getString(R.string.non_anonymous)
-                };
-                values = new boolean[]{
-                        mucOptions.membersOnly(),
-                        mucOptions.moderated(),
-                        mucOptions.nonanonymous()
-                };
-            } else {
-                options = new String[]{
-                        getString(R.string.members_only),
-                        getString(R.string.non_anonymous)
-                };
-                values = new boolean[]{
-                        mucOptions.membersOnly(),
-                        mucOptions.nonanonymous()
-                };
-            }
-            builder.setMultiChoiceItems(options, values, (dialog, which, isChecked) -> values[which] = isChecked);
+            MucConfiguration configuration = MucConfiguration.get(ConferenceDetailsActivity.this, mucOptions);
+            builder.setTitle(configuration.title);
+            final boolean[] values = configuration.values;
+            builder.setMultiChoiceItems(configuration.names, values, (dialog, which, isChecked) -> values[which] = isChecked);
             builder.setNegativeButton(R.string.cancel, null);
             builder.setPositiveButton(R.string.confirm, (dialog, which) -> {
-                if (!mucOptions.membersOnly() && values[0]) {
-                    xmppConnectionService.changeAffiliationsInConference(mConversation,
-                            MucOptions.Affiliation.NONE,
-                            MucOptions.Affiliation.MEMBER);
-                }
-                Bundle options1 = new Bundle();
-                options1.putString("muc#roomconfig_membersonly", values[0] ? "1" : "0");
-                if (values.length == 2) {
-                    options1.putString("muc#roomconfig_whois", values[1] ? "anyone" : "moderators");
-                } else if (values.length == 3) {
-                    options1.putString("muc#roomconfig_moderatedroom", values[1] ? "1" : "0");
-                    options1.putString("muc#roomconfig_whois", values[2] ? "anyone" : "moderators");
-                }
-                options1.putString("muc#roomconfig_persistentroom", "1");
-                final boolean whois = values.length == 2 ? values[1] : values[2];
-                if (values[0] == whois) {
-                    options1.putString("muc#roomconfig_publicroom", whois ? "0" : "1");
-                }
+                Bundle options = configuration.toBundle(values);
+                options.putString("muc#roomconfig_persistentroom", "1");
                 xmppConnectionService.pushConferenceConfiguration(mConversation,
-                        options1,
+                        options,
                         ConferenceDetailsActivity.this);
             });
             builder.create().show();
@@ -508,14 +472,17 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
         this.binding.mucYourNick.setText(mucOptions.getActualNick());
         if (mucOptions.online()) {
             this.binding.usersWrapper.setVisibility(View.VISIBLE);
-            this.binding.mucSettings.setVisibility(View.VISIBLE);
             this.binding.mucInfoMore.setVisibility(this.mAdvancedMode ? View.VISIBLE : View.GONE);
             this.binding.mucRole.setVisibility(View.VISIBLE);
             this.binding.mucRole.setText(getStatus(self));
-            if (mucOptions.membersOnly()) {
-                this.binding.mucConferenceType.setText(R.string.private_conference);
+            if (mucOptions.getSelf().getAffiliation().ranks(MucOptions.Affiliation.OWNER)) {
+                this.binding.mucSettings.setVisibility(View.VISIBLE);
+                this.binding.mucConferenceType.setText(MucConfiguration.describe(this,mucOptions));
+            } else if (!mucOptions.isPrivateAndNonAnonymous() && mucOptions.nonanonymous()) {
+                this.binding.mucSettings.setVisibility(View.VISIBLE);
+                this.binding.mucConferenceType.setText(R.string.group_chat_will_make_your_jabber_id_public);
             } else {
-                this.binding.mucConferenceType.setText(R.string.public_conference);
+                this.binding.mucSettings.setVisibility(View.GONE);
             }
             if (mucOptions.mamSupport()) {
                 this.binding.mucInfoMam.setText(R.string.server_info_available);
@@ -552,7 +519,7 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
             this.binding.notificationStatusText.setText(R.string.notify_only_when_highlighted);
             this.binding.notificationStatusButton.setImageResource(ic_notifications_none);
         }
-        List<User> users = mucOptions.getUsers();
+        final List<User> users = mucOptions.getUsers();
         Collections.sort(users, (a, b) -> {
             if (b.getAffiliation().outranks(a.getAffiliation())) {
                 return 1;
@@ -570,6 +537,14 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
         });
         this.mUserPreviewAdapter.submitList(MucOptions.sub(users, GridManager.getCurrentColumnCount(binding.users)));
         this.binding.invite.setVisibility(mucOptions.canInvite() ? View.VISIBLE : View.GONE);
+        this.binding.showUsers.setVisibility(users.size() > 0 ? View.VISIBLE : View.GONE);
+        this.binding.usersWrapper.setVisibility(users.size() > 0 || mucOptions.canInvite() ? View.VISIBLE : View.GONE);
+        if (users.size() == 0) {
+            this.binding.noUsersHints.setText(mucOptions.isPrivateAndNonAnonymous() ? R.string.no_users_hint_group_chat : R.string.no_users_hint_channel);
+            this.binding.noUsersHints.setVisibility(View.VISIBLE);
+        } else {
+            this.binding.noUsersHints.setVisibility(View.GONE);
+        }
 
     }
 

src/main/java/eu/siacs/conversations/ui/util/MucConfiguration.java πŸ”—

@@ -0,0 +1,111 @@
+package eu.siacs.conversations.ui.util;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.support.annotation.StringRes;
+
+import eu.siacs.conversations.R;
+import eu.siacs.conversations.entities.MucOptions;
+
+public class MucConfiguration {
+
+    public final @StringRes
+    int title;
+    public final String[] names;
+    public final boolean[] values;
+    public final Option[] options;
+
+    private MucConfiguration(@StringRes int title, String[] names, boolean[] values, Option[] options) {
+        this.title = title;
+        this.names = names;
+        this.values = values;
+        this.options = options;
+    }
+
+    public static MucConfiguration get(Context context, MucOptions mucOptions) {
+        if (mucOptions.isPrivateAndNonAnonymous()) {
+            String[] names = new String[]{
+                    context.getString(R.string.allow_participants_to_edit_subject),
+                    context.getString(R.string.allow_participants_to_invite_others)
+            };
+            boolean[] values = new boolean[]{
+                    mucOptions.participantsCanChangeSubject(),
+                    mucOptions.allowInvites()
+            };
+            final Option[] options = new Option[]{
+                    new Option("muc#roomconfig_changesubject"),
+                    new Option("muc#roomconfig_allowinvites")
+            };
+            return new MucConfiguration(R.string.conference_options, names, values, options);
+        } else {
+            String[] names = new String[]{
+                    context.getString(R.string.non_anonymous),
+                    context.getString(R.string.allow_participants_to_edit_subject),
+            };
+            boolean[] values = new boolean[]{
+                    mucOptions.nonanonymous(),
+                    mucOptions.participantsCanChangeSubject()
+            };
+            final Option[] options = new Option[]{
+                    new Option("muc#roomconfig_whois","anyone","moderators"),
+                    new Option("muc#roomconfig_changesubject")
+            };
+            return new MucConfiguration(R.string.channel_options, names, values, options);
+        }
+    }
+
+    public static String describe(final Context context, final MucOptions mucOptions) {
+        final StringBuilder builder = new StringBuilder();
+        if (mucOptions.isPrivateAndNonAnonymous()) {
+            if (mucOptions.participantsCanChangeSubject()) {
+                builder.append(context.getString(R.string.anyone_can_edit_subject));
+            } else {
+                builder.append(context.getString(R.string.owners_can_edit_subject));
+            }
+            builder.append(' ');
+            if (mucOptions.allowInvites()) {
+                builder.append(context.getString(R.string.anyone_can_invite_others));
+            } else {
+                builder.append(context.getString(R.string.owners_can_invite_others));
+            }
+        } else {
+            if (mucOptions.nonanonymous()) {
+                builder.append(context.getString(R.string.jabber_ids_are_visible_to_anyone));
+            } else {
+                builder.append(context.getString(R.string.jabber_ids_are_visible_to_admins));
+            }
+            builder.append(' ');
+            if (mucOptions.participantsCanChangeSubject()) {
+                builder.append(context.getString(R.string.anyone_can_edit_subject));
+            } else {
+                builder.append(context.getString(R.string.admins_can_edit_subject));
+            }
+        }
+        return builder.toString();
+    }
+
+    public Bundle toBundle(boolean[] values) {
+        Bundle bundle = new Bundle();
+        for(int i = 0; i < values.length; ++i) {
+            final Option option = options[i];
+            bundle.putString(option.name,option.values[values[i] ? 0 : 1]);
+        }
+        return bundle;
+    }
+
+    private static class Option {
+        public final String name;
+        public final String[] values;
+
+        private Option(String name) {
+            this.name = name;
+            this.values = new String[]{"1","0"};
+        }
+
+        private Option(String name, String on, String off) {
+            this.name = name;
+            this.values = new String[]{on,off};
+        }
+    }
+
+}

src/main/res/layout/activity_muc_details.xml πŸ”—

@@ -232,6 +232,16 @@
                         android:layout_height="wrap_content"
                         android:orientation="vertical">
 
+                        <TextView
+                            android:id="@+id/no_users_hints"
+                            android:layout_width="wrap_content"
+                            android:layout_height="wrap_content"
+                            android:paddingTop="@dimen/card_padding_regular"
+                            android:paddingEnd="@dimen/card_padding_regular"
+                            android:paddingStart="@dimen/card_padding_regular"
+                            android:text="@string/no_users_hint_channel"
+                            android:textAppearance="@style/TextAppearance.Conversations.Body2"/>
+
                         <android.support.v7.widget.RecyclerView
                             android:id="@+id/users"
                             android:layout_width="match_parent"

src/main/res/values/strings.xml πŸ”—

@@ -376,9 +376,10 @@
     <string name="could_not_change_role">Could not change role of %s</string>
     <string name="public_conference">Publicly accessible group chat</string>
     <string name="private_conference">Private, members only group chat</string>
-    <string name="conference_options">Group chat options</string>
+    <string name="conference_options">Private group chat configuration</string>
+    <string name="channel_options">Public channel configuration</string>
     <string name="members_only">Private, members only</string>
-    <string name="non_anonymous">Non-anonymous</string>
+    <string name="non_anonymous">Make Jabber IDs visible to anyone</string>
     <string name="moderated">Moderated</string>
     <string name="you_are_not_participating">You are not participating</string>
     <string name="modified_conference_options">Modified group chat options!</string>
@@ -747,8 +748,8 @@
     <string name="pref_more_notification_settings_summary">Importance, Sound, Vibrate</string>
     <string name="video_compression_channel_name">Video compression</string>
     <string name="view_media">View media</string>
-    <string name="view_users">View members</string>
-    <string name="group_chat_members">Group chat members</string>
+    <string name="view_users">View participants</string>
+    <string name="group_chat_members">Participants</string>
     <string name="media_browser">Media browser</string>
     <string name="security_violation_not_attaching_file">File omitted due to security violation.</string>
     <string name="pref_video_compression">Video Quality</string>
@@ -807,7 +808,7 @@
     <string name="install_orbot">Install Orbot</string>
     <string name="start_orbot">Start Orbot</string>
     <string name="no_market_app_installed">No market app installed.</string>
-    <string name="group_chat_will_make_your_jabber_id_public">This group chat will make your Jabber ID public</string>
+    <string name="group_chat_will_make_your_jabber_id_public">This channel will make your Jabber ID public</string>
     <string name="ebook">e-book</string>
     <string name="video_original">Original (uncompressed)</string>
     <string name="open_with">Open with…</string>
@@ -834,4 +835,15 @@
     <string name="channel_already_exists">This channel already exits</string>
     <string name="joined_an_existing_channel">You’ve joined an existing channel</string>
     <string name="unable_to_set_channel_configuration">Unable to set channel configuration</string>
+    <string name="allow_participants_to_edit_subject">Allow anyone to edit the topic</string>
+    <string name="allow_participants_to_invite_others">Allow anyone to invite others</string>
+    <string name="anyone_can_edit_subject">Anyone can edit the topic.</string>
+    <string name="owners_can_edit_subject">Owners can edit the topic.</string>
+    <string name="admins_can_edit_subject">Admins can edit the topic.</string>
+    <string name="owners_can_invite_others">Owners can invite others.</string>
+    <string name="anyone_can_invite_others">Anyone can invite others.</string>
+    <string name="jabber_ids_are_visible_to_admins">Jabber IDs are visible to admins.</string>
+    <string name="jabber_ids_are_visible_to_anyone">Jabber IDs are visible to anyone.</string>
+    <string name="no_users_hint_channel">This public channel has no participants.</string>
+    <string name="no_users_hint_group_chat">This private group chat has no participants.</string>
 </resources>