From a9159568b9aca24563a3b8c732b257d246e33a1a Mon Sep 17 00:00:00 2001
From: Daniel Gultsch <inputmice@siacs.eu>
Date: Thu, 8 Jan 2015 21:29:26 +0100
Subject: [PATCH] allow for very basic muc configuration

---
 .../conversations/entities/MucOptions.java    |   6 +-
 .../services/XmppConnectionService.java       |   3 +-
 .../ui/ConferenceDetailsActivity.java         |  80 +++++-
 src/main/res/layout/activity_muc_details.xml  | 237 ++++++++++--------
 src/main/res/values-de/strings.xml            |  10 +-
 src/main/res/values/strings.xml               |  11 +-
 6 files changed, 229 insertions(+), 118 deletions(-)

diff --git a/src/main/java/eu/siacs/conversations/entities/MucOptions.java b/src/main/java/eu/siacs/conversations/entities/MucOptions.java
index 96860a164..d4b997fca 100644
--- a/src/main/java/eu/siacs/conversations/entities/MucOptions.java
+++ b/src/main/java/eu/siacs/conversations/entities/MucOptions.java
@@ -13,7 +13,6 @@ import eu.siacs.conversations.xmpp.jid.Jid;
 import eu.siacs.conversations.xmpp.stanzas.PresencePacket;
 
 import android.annotation.SuppressLint;
-import android.util.Log;
 
 @SuppressLint("DefaultLocale")
 public class MucOptions {
@@ -224,6 +223,10 @@ public class MucOptions {
 		return hasFeature("muc_membersonly");
 	}
 
+	public boolean nonanonymous() {
+		return hasFeature("muc_nonanonymous");
+	}
+
 	public void deleteUser(String name) {
 		for (int i = 0; i < users.size(); ++i) {
 			if (users.get(i).getName().equals(name)) {
@@ -244,7 +247,6 @@ public class MucOptions {
 	}
 
 	public void processPacket(PresencePacket packet, PgpEngine pgp) {
-		Log.d(Config.LOGTAG, packet.toString());
 		final Jid from = packet.getFrom();
 		if (!from.isBareJid()) {
 			final String name = from.getResourcepart();
diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java
index ad951f3e2..e13a3e657 100644
--- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java
+++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java
@@ -1497,6 +1497,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
 						}
 					}
 					conversation.getMucOptions().updateFeatures(features);
+					updateConversationUi();
 				}
 			}
 		});
@@ -2229,7 +2230,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
 		public void onMucRosterUpdate();
 	}
 
-	private interface OnConferenceOptionsPushed {
+	public interface OnConferenceOptionsPushed {
 		public void onPushSucceeded();
 		public void onPushFailed();
 	}
diff --git a/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java b/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java
index a6df1085f..ce3672407 100644
--- a/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java
+++ b/src/main/java/eu/siacs/conversations/ui/ConferenceDetailsActivity.java
@@ -41,7 +41,7 @@ import eu.siacs.conversations.services.XmppConnectionService.OnConversationUpdat
 import eu.siacs.conversations.xmpp.jid.Jid;
 import eu.siacs.conversations.xmpp.stanzas.MessagePacket;
 
-public class ConferenceDetailsActivity extends XmppActivity implements OnConversationUpdate, OnMucRosterUpdate, XmppConnectionService.OnAffiliationChanged, XmppConnectionService.OnRoleChanged {
+public class ConferenceDetailsActivity extends XmppActivity implements OnConversationUpdate, OnMucRosterUpdate, XmppConnectionService.OnAffiliationChanged, XmppConnectionService.OnRoleChanged, XmppConnectionService.OnConferenceOptionsPushed {
 	public static final String ACTION_VIEW_MUC = "view_muc";
 	private Conversation mConversation;
 	private OnClickListener inviteListener = new OnClickListener() {
@@ -59,6 +59,8 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
 	private TextView mAccountJid;
 	private LinearLayout membersView;
 	private LinearLayout mMoreDetails;
+	private TextView mConferenceType;
+	private ImageButton mChangeConferenceSettingsButton;
 	private Button mInviteButton;
 	private String uuid = null;
 	private List<User> users = new ArrayList<>();
@@ -94,6 +96,36 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
 
 		}
 	};
+	private OnClickListener mChangeConferenceSettings = new OnClickListener() {
+		@Override
+		public void onClick(View v) {
+			final MucOptions mucOptions = mConversation.getMucOptions();
+			AlertDialog.Builder builder = new AlertDialog.Builder(ConferenceDetailsActivity.this);
+			builder.setTitle(R.string.conference_options);
+			String[] options = {getString(R.string.members_only),
+					getString(R.string.non_anonymous)};
+			final boolean[] values = new boolean[options.length];
+			values[0] = mucOptions.membersOnly();
+			values[1] = mucOptions.nonanonymous();
+			builder.setMultiChoiceItems(options,values,new DialogInterface.OnMultiChoiceClickListener() {
+				@Override
+				public void onClick(DialogInterface dialog, int which, boolean isChecked) {
+					values[which] = isChecked;
+				}
+			});
+			builder.setNegativeButton(R.string.cancel, null);
+			builder.setPositiveButton(R.string.confirm,new DialogInterface.OnClickListener() {
+				@Override
+				public void onClick(DialogInterface dialog, int which) {
+					Bundle options = new Bundle();
+					options.putString("muc#roomconfig_membersonly", values[0] ? "1" : "0");
+					options.putString("muc#roomconfig_whois", values[1] ? "anyone" : "moderators");
+					xmppConnectionService.pushConferenceConfiguration(mConversation,options,ConferenceDetailsActivity.this);
+				}
+			});
+			builder.create().show();
+		}
+	};
 
 	@Override
 	public void onConversationUpdate() {
@@ -129,8 +161,12 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
 		mAccountJid = (TextView) findViewById(R.id.details_account);
 		mMoreDetails = (LinearLayout) findViewById(R.id.muc_more_details);
 		mMoreDetails.setVisibility(View.GONE);
+		mChangeConferenceSettingsButton = (ImageButton) findViewById(R.id.change_conference_button);
+		mChangeConferenceSettingsButton.setOnClickListener(this.mChangeConferenceSettings);
+		mConferenceType = (TextView) findViewById(R.id.muc_conference_type);
 		mInviteButton = (Button) findViewById(R.id.invite);
 		mInviteButton.setOnClickListener(inviteListener);
+		mConferenceType = (TextView) findViewById(R.id.muc_conference_type);
 		if (getActionBar() != null) {
 			getActionBar().setHomeButtonEnabled(true);
 			getActionBar().setDisplayHomeAsUpEnabled(true);
@@ -361,16 +397,17 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
 	}
 
 	private void updateView() {
+		final MucOptions mucOptions = mConversation.getMucOptions();
+		final User self = mucOptions.getSelf();
 		mAccountJid.setText(getString(R.string.using_account, mConversation
 					.getAccount().getJid().toBareJid()));
 		mYourPhoto.setImageBitmap(avatarService().get(mConversation.getAccount(), getPixel(48)));
 		setTitle(mConversation.getName());
 		mFullJid.setText(mConversation.getJid().toBareJid().toString());
-		mYourNick.setText(mConversation.getMucOptions().getActualNick());
+		mYourNick.setText(mucOptions.getActualNick());
 		mRoleAffiliaton = (TextView) findViewById(R.id.muc_role);
-		if (mConversation.getMucOptions().online()) {
+		if (mucOptions.online()) {
 			mMoreDetails.setVisibility(View.VISIBLE);
-			User self = mConversation.getMucOptions().getSelf();
 			final String status = getStatus(self);
 			if (status != null) {
 				mRoleAffiliaton.setVisibility(View.VISIBLE);
@@ -378,9 +415,19 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
 			} else {
 				mRoleAffiliaton.setVisibility(View.GONE);
 			}
+			if (mucOptions.membersOnly()) {
+				mConferenceType.setText(R.string.private_conference);
+			} else {
+				mConferenceType.setText(R.string.public_conference);
+			}
+			if (self.getAffiliation().ranks(MucOptions.Affiliation.OWNER)) {
+				mChangeConferenceSettingsButton.setVisibility(View.VISIBLE);
+			} else {
+				mChangeConferenceSettingsButton.setVisibility(View.GONE);
+			}
 		}
 		this.users.clear();
-		this.users.addAll(mConversation.getMucOptions().getUsers());
+		this.users.addAll(mucOptions.getUsers());
 		LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
 		membersView.removeAllViews();
 		for (final User user : mConversation.getMucOptions().getUsers()) {
@@ -479,7 +526,7 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
 
 	@Override
 	public void onAffiliationChangeFailed(Jid jid, int resId) {
-
+		displayToast(getString(resId,jid.toBareJid().toString()));
 	}
 
 	@Override
@@ -488,7 +535,26 @@ public class ConferenceDetailsActivity extends XmppActivity implements OnConvers
 	}
 
 	@Override
-	public void onRoleChangeFailed(String nick, int resid) {
+	public void onRoleChangeFailed(String nick, int resId) {
+		displayToast(getString(resId,nick));
+	}
 
+	@Override
+	public void onPushSucceeded() {
+		displayToast(getString(R.string.modified_conference_options));
+	}
+
+	@Override
+	public void onPushFailed() {
+		displayToast(getString(R.string.could_not_modify_conference_options));
+	}
+
+	private void displayToast(final String msg) {
+		runOnUiThread(new Runnable() {
+			@Override
+			public void run() {
+				Toast.makeText(ConferenceDetailsActivity.this,msg,Toast.LENGTH_SHORT).show();
+			}
+		});
 	}
 }
diff --git a/src/main/res/layout/activity_muc_details.xml b/src/main/res/layout/activity_muc_details.xml
index f689f10d3..8299e8324 100644
--- a/src/main/res/layout/activity_muc_details.xml
+++ b/src/main/res/layout/activity_muc_details.xml
@@ -1,119 +1,146 @@
 <?xml version="1.0" encoding="utf-8"?>
 <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="fill_parent"
-    android:layout_height="fill_parent"
-    android:background="@color/secondarybackground" >
-
-    <LinearLayout
-        android:layout_width="fill_parent"
-        android:layout_height="wrap_content"
-        android:orientation="vertical" >
-
-    <LinearLayout
-        android:layout_width="fill_parent"
-        android:layout_height="wrap_content"
-        android:layout_margin="8dp"
-        android:background="@drawable/infocard_border"
-        android:orientation="vertical"
-        android:padding="16dp" >
-
-        <TextView
-            android:id="@+id/muc_jabberid"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:text="@string/account_settings_example_jabber_id"
-            android:textColor="@color/primarytext"
-            android:textSize="?attr/TextSizeHeadline"
-            android:textStyle="bold"
-            android:layout_marginBottom="16dp"/>
-        
-        <RelativeLayout
             android:layout_width="fill_parent"
-            android:layout_height="wrap_content">
+            android:layout_height="fill_parent"
+            android:background="@color/secondarybackground">
 
-            <ImageView
-                android:id="@+id/your_photo"
-                android:layout_width="48dp"
-                android:layout_height="48dp"
-                android:layout_alignParentLeft="true"
-                android:src="@drawable/ic_profile" >
-            </ImageView>
+	<LinearLayout
+		android:layout_width="fill_parent"
+		android:layout_height="wrap_content"
+		android:orientation="vertical">
 
-            <LinearLayout
-                android:layout_width="fill_parent"
-                android:layout_height="wrap_content"
-                android:layout_centerVertical="true"
-                android:layout_toRightOf="@+id/your_photo"
-                android:orientation="vertical"
-                android:paddingLeft="8dp" >
+		<LinearLayout
+			android:layout_width="fill_parent"
+			android:layout_height="wrap_content"
+			android:layout_margin="8dp"
+			android:background="@drawable/infocard_border"
+			android:orientation="vertical"
+			android:padding="16dp">
 
-                <TextView
-                    android:id="@+id/muc_your_nick"
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:singleLine="true"
-                    android:textColor="@color/primarytext"
-                    android:textSize="?attr/TextSizeHeadline" />
+			<TextView
+				android:id="@+id/muc_jabberid"
+				android:layout_width="wrap_content"
+				android:layout_height="wrap_content"
+				android:layout_marginBottom="16dp"
+				android:text="@string/account_settings_example_jabber_id"
+				android:textColor="@color/primarytext"
+				android:textSize="?attr/TextSizeHeadline"
+				android:textStyle="bold"/>
 
-                <TextView
-                    android:id="@+id/muc_role"
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:singleLine="true"
-                    android:textColor="@color/primarytext"
-                    android:textSize="?attr/TextSizeBody" />
-            </LinearLayout>
+			<RelativeLayout
+				android:layout_width="fill_parent"
+				android:layout_height="wrap_content"
+				android:layout_marginBottom="32dp">
 
-            <ImageButton
-                android:id="@+id/edit_nick_button"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_alignParentRight="true"
-                android:layout_centerVertical="true"
-                android:background="?android:selectableItemBackground"
-                android:padding="8dp"
-                android:src="@drawable/ic_action_edit_dark" />
-        </RelativeLayout>
-         <TextView
-                android:id="@+id/details_account"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_gravity="right"
-                android:layout_marginTop="32dp"
-                android:text="@string/using_account"
-                android:textColor="@color/secondarytext"
-                android:textSize="?attr/TextSizeInfo" />
-    </LinearLayout>
+				<ImageView
+					android:id="@+id/your_photo"
+					android:layout_width="48dp"
+					android:layout_height="48dp"
+					android:layout_alignParentLeft="true"
+					android:src="@drawable/ic_profile">
+				</ImageView>
 
-    <LinearLayout
-        android:id="@+id/muc_more_details"
-        android:layout_width="fill_parent"
-        android:layout_height="wrap_content"
-        android:layout_margin="8dp"
-        android:background="@drawable/infocard_border"
-        android:orientation="vertical"
-        android:padding="8dp" >
+				<LinearLayout
+					android:layout_width="fill_parent"
+					android:layout_height="wrap_content"
+					android:layout_centerVertical="true"
+					android:layout_toRightOf="@+id/your_photo"
+					android:orientation="vertical"
+					android:paddingLeft="8dp">
+
+					<TextView
+						android:id="@+id/muc_your_nick"
+						android:layout_width="wrap_content"
+						android:layout_height="wrap_content"
+						android:singleLine="true"
+						android:textColor="@color/primarytext"
+						android:textSize="?attr/TextSizeHeadline"/>
+
+					<TextView
+						android:id="@+id/muc_role"
+						android:layout_width="wrap_content"
+						android:layout_height="wrap_content"
+						android:singleLine="true"
+						android:textColor="@color/primarytext"
+						android:textSize="?attr/TextSizeBody"/>
+				</LinearLayout>
+
+				<ImageButton
+					android:id="@+id/edit_nick_button"
+					android:layout_width="wrap_content"
+					android:layout_height="wrap_content"
+					android:layout_alignParentRight="true"
+					android:layout_centerVertical="true"
+					android:background="?android:selectableItemBackground"
+					android:padding="8dp"
+					android:src="@drawable/ic_action_edit_dark"/>
+			</RelativeLayout>
+
+			<RelativeLayout
+				android:layout_width="fill_parent"
+				android:layout_height="wrap_content">
+				<TextView
+				android:id="@+id/muc_conference_type"
+				android:layout_width="wrap_content"
+				android:layout_height="wrap_content"
+			    android:text="@string/private_conference"
+				android:layout_centerVertical="true"
+				android:textColor="@color/primarytext"
+				android:textSize="?attr/TextSizeBody"
+				/>
+			<ImageButton
+				android:id="@+id/change_conference_button"
+				style="?android:attr/buttonStyleSmall"
+				android:layout_width="wrap_content"
+				android:layout_height="wrap_content"
+				android:layout_gravity="center_horizontal"
+				android:layout_alignParentRight="true"
+				android:layout_centerVertical="true"
+				android:background="?android:selectableItemBackground"
+				android:padding="8dp"
+				android:src="@drawable/ic_action_settings"/>
+				</RelativeLayout>
+
+			<TextView
+				android:id="@+id/details_account"
+				android:layout_width="wrap_content"
+				android:layout_height="wrap_content"
+				android:layout_gravity="right"
+				android:layout_marginTop="32dp"
+				android:text="@string/using_account"
+				android:textColor="@color/secondarytext"
+				android:textSize="?attr/TextSizeInfo"/>
+		</LinearLayout>
+
+		<LinearLayout
+			android:id="@+id/muc_more_details"
+			android:layout_width="fill_parent"
+			android:layout_height="wrap_content"
+			android:layout_margin="8dp"
+			android:background="@drawable/infocard_border"
+			android:orientation="vertical"
+			android:padding="8dp">
 
 
-            <LinearLayout
-                android:id="@+id/muc_members"
-                android:layout_width="fill_parent"
-                android:layout_height="0dp"
-                android:layout_weight="1"
-                android:divider="?android:dividerHorizontal"
-                android:orientation="vertical"
-                android:showDividers="middle" >
-            </LinearLayout>
+			<LinearLayout
+				android:id="@+id/muc_members"
+				android:layout_width="fill_parent"
+				android:layout_height="0dp"
+				android:layout_weight="1"
+				android:divider="?android:dividerHorizontal"
+				android:orientation="vertical"
+				android:showDividers="middle">
+			</LinearLayout>
 
-        <Button
-            android:id="@+id/invite"
-            style="?android:attr/buttonStyleSmall"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_gravity="center_horizontal"
-            android:layout_marginTop="24dp"
-            android:text="@string/invite_contact" />
-    </LinearLayout>
+			<Button
+				android:id="@+id/invite"
+				style="?android:attr/buttonStyleSmall"
+				android:layout_width="wrap_content"
+				android:layout_height="wrap_content"
+				android:layout_gravity="center_horizontal"
+				android:layout_marginTop="24dp"
+				android:text="@string/invite_contact"/>
+		</LinearLayout>
 
-</LinearLayout>
+	</LinearLayout>
 </ScrollView>
\ No newline at end of file
diff --git a/src/main/res/values-de/strings.xml b/src/main/res/values-de/strings.xml
index c9876d013..1240da79c 100644
--- a/src/main/res/values-de/strings.xml
+++ b/src/main/res/values-de/strings.xml
@@ -390,8 +390,16 @@
     <string name="grant_admin_privileges">Administratorrechte gewähren</string>
     <string name="remove_admin_privileges">Administratorrechte entziehen</string>
     <string name="remove_from_room">Aus Konferenz entfernen</string>
-    <string name="could_not_change_affiliation">Zugehörigkeit kann nicht geändert werden</string>
+    <string name="could_not_change_affiliation">Zugehörigkeit von %s konnte nicht verändernd werden</string>
     <string name="ban_from_conference">Von Konferenz ausschließen.</string>
     <string name="removing_from_public_conference">Du versuchst %s aus einer öffentlichen Konferenz zu entfernen. Die einzige Möglichkeit, dies dauerhaft zu tun, ist den Kontakt aus dieser Konferenz zu verbannen.</string>
     <string name="ban_now">Kontakt ausschließen</string>
+	<string name="could_not_change_role">Rolle von %s konnte nicht geändert werden</string>
+	<string name="public_conference">Das ist eine öffentlich zugängliche Konferenz</string>
+	<string name="private_conference">Das ist eine private Konferenz nur für Mitglieder</string>
+	<string name="conference_options">Konferenzoptionen</string>
+	<string name="members_only">Privat (Nur für Mitglieder)</string>
+	<string name="non_anonymous">De-anonymisiert</string>
+	<string name="modified_conference_options">Konferenzoptionen wurden modifiziert!</string>
+	<string name="could_not_modify_conference_options">Konferenzoptionen konnten nicht modifiziert werden</string>
 </resources>
diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml
index bbac0c7ca..fdc211e4d 100644
--- a/src/main/res/values/strings.xml
+++ b/src/main/res/values/strings.xml
@@ -416,9 +416,16 @@
 	<string name="grant_admin_privileges">Grant admin privileges</string>
 	<string name="remove_admin_privileges">Revoke admin privileges</string>
 	<string name="remove_from_room">Remove from conference</string>
-	<string name="could_not_change_affiliation">Could not change affiliation</string>
+	<string name="could_not_change_affiliation">Could not change affiliation of %s</string>
 	<string name="ban_from_conference">Ban from conference</string>
 	<string name="removing_from_public_conference">You are trying to remove %s from a public conference. The only way to do that is to ban that user for ever.</string>
 	<string name="ban_now">Ban now</string>
-	<string name="could_not_change_role">Could not change role</string>
+	<string name="could_not_change_role">Could not change role of %s</string>
+	<string name="public_conference">This is a publicly accessible conference</string>
+	<string name="private_conference">This is a private, members only conference</string>
+	<string name="conference_options">Conference options</string>
+	<string name="members_only">Private (Members only)</string>
+	<string name="non_anonymous">Non-anonymous</string>
+	<string name="modified_conference_options">Modified conference options!</string>
+	<string name="could_not_modify_conference_options">Could not modify conference options</string>
 </resources>