From 07b4d9b5d83fa2ea8fec980dcea2e26ea46307ba Mon Sep 17 00:00:00 2001
From: akwizgran <akwizgran@users.sourceforge.net>
Date: Thu, 27 Feb 2014 23:07:26 +0000
Subject: [PATCH] Show empty list text for contact list, group list, etc. Dev
 task #71.

---
 briar-android/AndroidManifest.xml             |  8 +--
 briar-android/res/values/strings.xml          | 17 ++---
 .../android/contact/ContactListActivity.java  | 21 +++++-
 .../android/contact/ContactListAdapter.java   |  1 -
 .../android/contact/ConversationActivity.java | 39 +++++++----
 .../contact/ReadPrivateMessageActivity.java   |  2 +-
 .../android/groups/GroupActivity.java         | 40 +++++++----
 .../android/groups/GroupListActivity.java     | 20 +++++-
 .../android/groups/GroupListAdapter.java      |  2 +-
 .../android/groups/ManageGroupsActivity.java  | 28 +++++---
 .../android/groups/ManageGroupsAdapter.java   | 70 ++++---------------
 .../android/groups/ManageGroupsItem.java      |  2 -
 .../groups/ManageGroupsItemComparator.java    |  4 --
 .../android/groups/NoContactsDialog.java      |  2 +-
 .../android/groups/ReadGroupPostActivity.java |  5 +-
 .../groups/WriteGroupPostActivity.java        |  3 +
 16 files changed, 141 insertions(+), 123 deletions(-)

diff --git a/briar-android/AndroidManifest.xml b/briar-android/AndroidManifest.xml
index 38fedeeccd..ab787cf379 100644
--- a/briar-android/AndroidManifest.xml
+++ b/briar-android/AndroidManifest.xml
@@ -78,7 +78,7 @@
 		<activity
 			android:name=".android.contact.ReadPrivateMessageActivity"
 			android:logo="@drawable/logo"
-			android:label="@string/read_message_title"
+			android:label="@string/app_name"
 		    android:parentActivityName=".android.contact.ContactListActivity" >
 			<meta-data
 				android:name="android.support.PARENT_ACTIVITY"
@@ -88,7 +88,7 @@
 		<activity
 			android:name=".android.contact.WritePrivateMessageActivity"
 			android:logo="@drawable/logo"
-			android:label="@string/write_message_title"
+			android:label="@string/app_name"
 		    android:parentActivityName=".android.contact.ContactListActivity" >
 			<meta-data
 				android:name="android.support.PARENT_ACTIVITY"
@@ -138,7 +138,7 @@
 		<activity
 		    android:name=".android.groups.ManageGroupsActivity"
 			android:logo="@drawable/logo"
-		    android:label="@string/manage_subscriptions_title"
+		    android:label="@string/manage_forums_title"
 		    android:parentActivityName=".android.groups.GroupListActivity" >
 			<meta-data
 				android:name="android.support.PARENT_ACTIVITY"
@@ -158,7 +158,7 @@
 		<activity
 			android:name=".android.groups.WriteGroupPostActivity"
 			android:logo="@drawable/logo"
-			android:label="@string/new_post_title"
+			android:label="@string/app_name"
 		    android:parentActivityName=".android.groups.GroupListActivity" >
 			<meta-data
 				android:name="android.support.PARENT_ACTIVITY"
diff --git a/briar-android/res/values/strings.xml b/briar-android/res/values/strings.xml
index b6e54ad64a..338a010865 100644
--- a/briar-android/res/values/strings.xml
+++ b/briar-android/res/values/strings.xml
@@ -8,10 +8,6 @@
     <string name="choose_password">Choose your password:</string>
     <string name="confirm_password">Confirm your password:</string>
     <string name="password_too_weak">Password is too weak</string>
-    <string name="password_weak">Password is weak</string>
-    <string name="password_quite_weak">Password is quite weak</string>
-    <string name="password_quite_strong">Password is quite strong</string>
-    <string name="password_strong">Password is strong</string>
     <string name="passwords_do_not_match">Passwords do not match</string>
     <string name="enter_password">Enter your password:</string>
     <string name="try_again">Wrong password, try again:</string>
@@ -23,6 +19,7 @@
     <string name="synchronize_button">Synchronize</string>
     <string name="sign_out_button">Sign Out</string>
     <string name="contact_list_title">Contacts</string>
+    <string name="no_contacts">No contacts</string>
     <string name="contact_connected">Connected</string>
     <string name="format_last_connected">Last connected &lt;br /&gt; %s</string>
     <string name="add_contact_title">Add a Contact</string>
@@ -44,13 +41,12 @@
     <string name="codes_do_not_match">Codes do not match</string>
     <string name="interfering">This could mean that someone is trying to interfere with your connection</string>
     <string name="contact_added_toast">Contact added</string>
+    <string name="no_private_messages">No messages</string>
     <string name="private_message_hint">Type message</string>
     <string name="message_sent_toast">Message sent</string>
-    <string name="read_message_title">Private Message</string>
-    <string name="write_message_title">New Private Message</string>
     <string name="format_from">From: %s</string>
-    <string name="new_contact_item">New contact\u2026</string>
     <string name="forums_title">Forums</string>
+    <string name="no_forums">No forums</string>
     <plurals name="forums_available">
         <item quantity="one">%d forum available from contacts</item>
         <item quantity="other">%d forums available from contacts</item>
@@ -62,19 +58,18 @@
     <string name="forum_visible_to_all">Share this forum with all contacts</string>
     <string name="forum_visible_to_some">Share this forum with chosen contacts</string>
     <string name="done_button">Done</string>
-    <string name="new_post_title">New Post</string>
     <string name="from">From:</string>
     <string name="anonymous">Anonymous</string>
     <string name="new_identity_item">New identity\u2026</string>
     <string name="group_post_hint">Type forum post</string>
-    <string name="manage_subscriptions_title">Available Forums</string>
-    <string name="no_forums_available">No forums available from contacts</string>
+    <string name="manage_forums_title">Available Forums</string>
+    <string name="no_forums_available">No forums available</string>
     <string name="subscribed_all">Subscribed, shared with all contacts</string>
     <string name="subscribed_some">Subscribed, shared with chosen contacts</string>
     <string name="not_subscribed">Not subscribed</string>
     <string name="new_identity_title">New Identity</string>
     <string name="create_button">Create</string>
-    <string name="no_contacts">You don\'t have any contacts. Add a contact now?</string>
+    <string name="no_contacts_prompt">You don\'t have any contacts. Add a contact now?</string>
     <string name="add_button">Add</string>
     <string name="cancel_button">Cancel</string>
     <string name="post_sent_toast">Post sent</string>
diff --git a/briar-android/src/org/briarproject/android/contact/ContactListActivity.java b/briar-android/src/org/briarproject/android/contact/ContactListActivity.java
index ce574b5cc3..14cb86f3a9 100644
--- a/briar-android/src/org/briarproject/android/contact/ContactListActivity.java
+++ b/briar-android/src/org/briarproject/android/contact/ContactListActivity.java
@@ -52,6 +52,7 @@ import android.widget.AdapterView.OnItemClickListener;
 import android.widget.ImageButton;
 import android.widget.LinearLayout;
 import android.widget.ListView;
+import android.widget.TextView;
 
 public class ContactListActivity extends BriarActivity
 implements OnClickListener, OnItemClickListener, EventListener,
@@ -61,6 +62,7 @@ ConnectionListener {
 			Logger.getLogger(ContactListActivity.class.getName());
 
 	@Inject private ConnectionRegistry connectionRegistry;
+	private TextView empty = null;
 	private ContactListAdapter adapter = null;
 	private ListView list = null;
 	private ListLoadingProgressBar loading = null;
@@ -79,16 +81,23 @@ ConnectionListener {
 		layout.setOrientation(VERTICAL);
 		layout.setGravity(CENTER_HORIZONTAL);
 
+		empty = new TextView(this);
+		empty.setLayoutParams(MATCH_WRAP_1);
+		empty.setGravity(CENTER);
+		empty.setTextSize(18);
+		empty.setText(R.string.no_contacts);
+		empty.setVisibility(GONE);
+		layout.addView(empty);
+
 		adapter = new ContactListAdapter(this);
 		list = new ListView(this);
-		// Give me all the width and all the unused height
 		list.setLayoutParams(MATCH_WRAP_1);
 		list.setAdapter(adapter);
 		list.setOnItemClickListener(this);
+		list.setVisibility(GONE);
 		layout.addView(list);
 
 		// Show a progress bar while the list is loading
-		list.setVisibility(GONE);
 		loading = new ListLoadingProgressBar(this);
 		layout.addView(loading);
 
@@ -156,6 +165,7 @@ ConnectionListener {
 	private void clearContacts() {
 		runOnUiThread(new Runnable() {
 			public void run() {
+				empty.setVisibility(GONE);
 				list.setVisibility(GONE);
 				loading.setVisibility(VISIBLE);
 				adapter.clear();
@@ -186,7 +196,8 @@ ConnectionListener {
 	private void hideProgressBar() {
 		runOnUiThread(new Runnable() {
 			public void run() {
-				list.setVisibility(VISIBLE);
+				if(adapter.isEmpty()) empty.setVisibility(VISIBLE);
+				else list.setVisibility(VISIBLE);
 				loading.setVisibility(GONE);
 			}
 		});
@@ -291,6 +302,10 @@ ConnectionListener {
 				if(item != null) {
 					adapter.remove(item);
 					adapter.notifyDataSetChanged();
+					if(adapter.isEmpty()) {
+						empty.setVisibility(VISIBLE);
+						list.setVisibility(GONE);
+					}
 				}
 			}
 		});
diff --git a/briar-android/src/org/briarproject/android/contact/ContactListAdapter.java b/briar-android/src/org/briarproject/android/contact/ContactListAdapter.java
index 501cff3f38..c43e0b0e5c 100644
--- a/briar-android/src/org/briarproject/android/contact/ContactListAdapter.java
+++ b/briar-android/src/org/briarproject/android/contact/ContactListAdapter.java
@@ -52,7 +52,6 @@ class ContactListAdapter extends ArrayAdapter<ContactListItem> {
 		layout.addView(bulb);
 
 		TextView name = new TextView(ctx);
-		// Give me all the unused width
 		name.setLayoutParams(WRAP_WRAP_1);
 		name.setTextSize(18);
 		name.setSingleLine();
diff --git a/briar-android/src/org/briarproject/android/contact/ConversationActivity.java b/briar-android/src/org/briarproject/android/contact/ConversationActivity.java
index 1eee142849..dd7ce04bca 100644
--- a/briar-android/src/org/briarproject/android/contact/ConversationActivity.java
+++ b/briar-android/src/org/briarproject/android/contact/ConversationActivity.java
@@ -2,6 +2,7 @@ package org.briarproject.android.contact;
 
 import static android.text.InputType.TYPE_CLASS_TEXT;
 import static android.text.InputType.TYPE_TEXT_FLAG_CAP_SENTENCES;
+import static android.view.Gravity.CENTER;
 import static android.view.Gravity.CENTER_VERTICAL;
 import static android.view.View.GONE;
 import static android.view.View.VISIBLE;
@@ -72,6 +73,7 @@ import android.widget.EditText;
 import android.widget.ImageButton;
 import android.widget.LinearLayout;
 import android.widget.ListView;
+import android.widget.TextView;
 import android.widget.Toast;
 
 public class ConversationActivity extends BriarActivity
@@ -84,6 +86,7 @@ implements EventListener, OnClickListener, OnItemClickListener {
 	@Inject @CryptoExecutor private Executor cryptoExecutor;
 	private Map<MessageId, byte[]> bodyCache = new HashMap<MessageId, byte[]>();
 	private String contactName = null;
+	private TextView empty = null;
 	private ConversationAdapter adapter = null;
 	private ListView list = null;
 	private ListLoadingProgressBar loading = null;
@@ -126,6 +129,14 @@ implements EventListener, OnClickListener, OnItemClickListener {
 		layout.setLayoutParams(MATCH_MATCH);
 		layout.setOrientation(VERTICAL);
 
+		empty = new TextView(this);
+		empty.setLayoutParams(MATCH_WRAP_1);
+		empty.setGravity(CENTER);
+		empty.setTextSize(18);
+		empty.setText(R.string.no_private_messages);
+		empty.setVisibility(GONE);
+		layout.addView(empty);
+
 		adapter = new ConversationAdapter(this);
 		list = new ListView(this) {
 			@Override
@@ -135,7 +146,6 @@ implements EventListener, OnClickListener, OnItemClickListener {
 				setSelection(getCount() - 1);
 			}
 		};
-		// Give me all the width and all the unused height
 		list.setLayoutParams(MATCH_WRAP_1);
 		int pad = LayoutUtils.getPadding(this);
 		list.setPadding(0, pad, 0, pad);
@@ -143,7 +153,6 @@ implements EventListener, OnClickListener, OnItemClickListener {
 		// Make the dividers the same colour as the background
 		Resources res = getResources();
 		int background = res.getColor(R.color.window_background);
-		list.setBackgroundColor(background);
 		list.setDivider(new ColorDrawable(background));
 		list.setDividerHeight(pad);
 		list.setAdapter(adapter);
@@ -224,21 +233,27 @@ implements EventListener, OnClickListener, OnItemClickListener {
 	private void displayHeaders(final Collection<MessageHeader> headers) {
 		runOnUiThread(new Runnable() {
 			public void run() {
-				list.setVisibility(VISIBLE);
 				loading.setVisibility(GONE);
 				sendButton.setEnabled(true);
 				adapter.clear();
-				for(MessageHeader h : headers) {
-					ConversationItem item = new ConversationItem(h);
-					byte[] body = bodyCache.get(h.getId());
-					if(body == null) loadMessageBody(h);
-					else item.setBody(body);
-					adapter.add(item);
+				if(headers.isEmpty()) {
+					empty.setVisibility(VISIBLE);
+					list.setVisibility(GONE);
+				} else {
+					empty.setVisibility(GONE);
+					list.setVisibility(VISIBLE);
+					for(MessageHeader h : headers) {
+						ConversationItem item = new ConversationItem(h);
+						byte[] body = bodyCache.get(h.getId());
+						if(body == null) loadMessageBody(h);
+						else item.setBody(body);
+						adapter.add(item);
+					}
+					adapter.sort(ConversationItemComparator.INSTANCE);
+					// Scroll to the bottom
+					list.setSelection(adapter.getCount() - 1);
 				}
-				adapter.sort(ConversationItemComparator.INSTANCE);
 				adapter.notifyDataSetChanged();
-				// Scroll to the bottom
-				list.setSelection(adapter.getCount() - 1);
 			}
 		});
 	}
diff --git a/briar-android/src/org/briarproject/android/contact/ReadPrivateMessageActivity.java b/briar-android/src/org/briarproject/android/contact/ReadPrivateMessageActivity.java
index 1b4e5be886..43db69ad26 100644
--- a/briar-android/src/org/briarproject/android/contact/ReadPrivateMessageActivity.java
+++ b/briar-android/src/org/briarproject/android/contact/ReadPrivateMessageActivity.java
@@ -75,6 +75,7 @@ implements OnClickListener {
 		Intent i = getIntent();
 		contactName = i.getStringExtra("briar.CONTACT_NAME");
 		if(contactName == null) throw new IllegalStateException();
+		setTitle(contactName);
 		byte[] b = i.getByteArrayExtra("briar.LOCAL_AUTHOR_ID");
 		if(b == null) throw new IllegalStateException();
 		localAuthorId = new AuthorId(b);
@@ -105,7 +106,6 @@ implements OnClickListener {
 		layout.setOrientation(VERTICAL);
 
 		ScrollView scrollView = new ScrollView(this);
-		// Give me all the width and all the unused height
 		scrollView.setLayoutParams(MATCH_WRAP_1);
 
 		LinearLayout message = new LinearLayout(this);
diff --git a/briar-android/src/org/briarproject/android/groups/GroupActivity.java b/briar-android/src/org/briarproject/android/groups/GroupActivity.java
index 5f21731f6c..06f475a2bc 100644
--- a/briar-android/src/org/briarproject/android/groups/GroupActivity.java
+++ b/briar-android/src/org/briarproject/android/groups/GroupActivity.java
@@ -53,6 +53,7 @@ import android.widget.AdapterView.OnItemClickListener;
 import android.widget.ImageButton;
 import android.widget.LinearLayout;
 import android.widget.ListView;
+import android.widget.TextView;
 
 public class GroupActivity extends BriarActivity implements EventListener,
 OnClickListener, OnItemClickListener {
@@ -63,6 +64,7 @@ OnClickListener, OnItemClickListener {
 
 	private Map<MessageId, byte[]> bodyCache = new HashMap<MessageId, byte[]>();
 	private String groupName = null;
+	private TextView empty = null;
 	private GroupAdapter adapter = null;
 	private ListView list = null;
 	private ListLoadingProgressBar loading = null;
@@ -90,16 +92,23 @@ OnClickListener, OnItemClickListener {
 		layout.setOrientation(VERTICAL);
 		layout.setGravity(CENTER_HORIZONTAL);
 
+		empty = new TextView(this);
+		empty.setLayoutParams(MATCH_WRAP_1);
+		empty.setGravity(CENTER);
+		empty.setTextSize(18);
+		empty.setText(R.string.no_posts);
+		empty.setVisibility(GONE);
+		layout.addView(empty);
+
 		adapter = new GroupAdapter(this);
 		list = new ListView(this);
-		// Give me all the width and all the unused height
 		list.setLayoutParams(MATCH_WRAP_1);
 		list.setAdapter(adapter);
 		list.setOnItemClickListener(this);
+		list.setVisibility(GONE);
 		layout.addView(list);
 
 		// Show a progress bar while the list is loading
-		list.setVisibility(GONE);
 		loading = new ListLoadingProgressBar(this);
 		layout.addView(loading);
 
@@ -156,20 +165,26 @@ OnClickListener, OnItemClickListener {
 	private void displayHeaders(final Collection<MessageHeader> headers) {
 		runOnUiThread(new Runnable() {
 			public void run() {
-				list.setVisibility(VISIBLE);
 				loading.setVisibility(GONE);
 				adapter.clear();
-				for(MessageHeader h : headers) {
-					GroupItem item = new GroupItem(h);
-					byte[] body = bodyCache.get(h.getId());
-					if(body == null) loadMessageBody(h);
-					else item.setBody(body);
-					adapter.add(item);
+				if(headers.isEmpty()) {
+					empty.setVisibility(VISIBLE);
+					list.setVisibility(GONE);
+				} else {
+					empty.setVisibility(GONE);
+					list.setVisibility(VISIBLE);
+					for(MessageHeader h : headers) {
+						GroupItem item = new GroupItem(h);
+						byte[] body = bodyCache.get(h.getId());
+						if(body == null) loadMessageBody(h);
+						else item.setBody(body);
+						adapter.add(item);
+					}
+					adapter.sort(GroupItemComparator.INSTANCE);
+					// Scroll to the bottom
+					list.setSelection(adapter.getCount() - 1);
 				}
-				adapter.sort(GroupItemComparator.INSTANCE);
 				adapter.notifyDataSetChanged();
-				// Scroll to the bottom
-				list.setSelection(adapter.getCount() - 1);
 			}
 		});
 	}
@@ -291,6 +306,7 @@ OnClickListener, OnItemClickListener {
 	public void onClick(View view) {
 		Intent i = new Intent(this, WriteGroupPostActivity.class);
 		i.putExtra("briar.GROUP_ID", groupId.getBytes());
+		i.putExtra("briar.GROUP_NAME", groupName);
 		startActivity(i);
 	}
 
diff --git a/briar-android/src/org/briarproject/android/groups/GroupListActivity.java b/briar-android/src/org/briarproject/android/groups/GroupListActivity.java
index 1103a73df4..5691b3bc34 100644
--- a/briar-android/src/org/briarproject/android/groups/GroupListActivity.java
+++ b/briar-android/src/org/briarproject/android/groups/GroupListActivity.java
@@ -64,6 +64,7 @@ implements EventListener, OnClickListener, OnItemClickListener {
 	private final Map<GroupId,GroupId> groups =
 			new ConcurrentHashMap<GroupId,GroupId>();
 
+	private TextView empty = null;
 	private GroupListAdapter adapter = null;
 	private ListView list = null;
 	private ListLoadingProgressBar loading = null;
@@ -85,9 +86,16 @@ implements EventListener, OnClickListener, OnItemClickListener {
 
 		int pad = LayoutUtils.getPadding(this);
 
+		empty = new TextView(this);
+		empty.setLayoutParams(MATCH_WRAP_1);
+		empty.setGravity(CENTER);
+		empty.setTextSize(18);
+		empty.setText(R.string.no_forums);
+		empty.setVisibility(GONE);
+		layout.addView(empty);
+
 		adapter = new GroupListAdapter(this);
 		list = new ListView(this);
-		// Give me all the width and all the unused height
 		list.setLayoutParams(MATCH_WRAP_1);
 		list.setAdapter(adapter);
 		list.setOnItemClickListener(this);
@@ -186,6 +194,7 @@ implements EventListener, OnClickListener, OnItemClickListener {
 		runOnUiThread(new Runnable() {
 			public void run() {
 				groups.clear();
+				empty.setVisibility(GONE);
 				list.setVisibility(GONE);
 				available.setVisibility(GONE);
 				loading.setVisibility(VISIBLE);
@@ -218,7 +227,7 @@ implements EventListener, OnClickListener, OnItemClickListener {
 	private void displayAvailable(final int availableCount) {
 		runOnUiThread(new Runnable() {
 			public void run() {
-				list.setVisibility(VISIBLE);
+				if(adapter.isEmpty()) empty.setVisibility(VISIBLE);
 				loading.setVisibility(GONE);
 				if(availableCount == 0) {
 					available.setVisibility(GONE);
@@ -320,7 +329,12 @@ implements EventListener, OnClickListener, OnItemClickListener {
 					groups.remove(g);
 					adapter.remove(item);
 					adapter.notifyDataSetChanged();
-					selectFirstUnread();
+					if(adapter.isEmpty()) {
+						empty.setVisibility(VISIBLE);
+						list.setVisibility(GONE);
+					} else {
+						selectFirstUnread();
+					}
 				}
 			}
 		});
diff --git a/briar-android/src/org/briarproject/android/groups/GroupListAdapter.java b/briar-android/src/org/briarproject/android/groups/GroupListAdapter.java
index 0e8c34bb69..b63d3d2647 100644
--- a/briar-android/src/org/briarproject/android/groups/GroupListAdapter.java
+++ b/briar-android/src/org/briarproject/android/groups/GroupListAdapter.java
@@ -28,6 +28,7 @@ class GroupListAdapter extends ArrayAdapter<GroupListItem> {
 		pad = LayoutUtils.getPadding(ctx);
 	}
 
+	@Override
 	public View getView(int position, View convertView, ViewGroup parent) {
 		GroupListItem item = getItem(position);
 		Context ctx = getContext();
@@ -40,7 +41,6 @@ class GroupListAdapter extends ArrayAdapter<GroupListItem> {
 			layout.setBackgroundColor(res.getColor(R.color.unread_background));
 
 		TextView name = new TextView(ctx);
-		// Give me all the unused width
 		name.setLayoutParams(WRAP_WRAP_1);
 		name.setTextSize(18);
 		name.setSingleLine();
diff --git a/briar-android/src/org/briarproject/android/groups/ManageGroupsActivity.java b/briar-android/src/org/briarproject/android/groups/ManageGroupsActivity.java
index 22574a0389..b698a8c591 100644
--- a/briar-android/src/org/briarproject/android/groups/ManageGroupsActivity.java
+++ b/briar-android/src/org/briarproject/android/groups/ManageGroupsActivity.java
@@ -1,8 +1,8 @@
 package org.briarproject.android.groups;
 
+import static android.view.Gravity.CENTER;
 import static java.util.logging.Level.INFO;
 import static java.util.logging.Level.WARNING;
-import static org.briarproject.android.groups.ManageGroupsItem.NONE;
 import static org.briarproject.android.util.CommonLayoutParams.MATCH_MATCH;
 
 import java.util.Collection;
@@ -11,6 +11,7 @@ import java.util.logging.Logger;
 
 import javax.inject.Inject;
 
+import org.briarproject.R;
 import org.briarproject.android.BriarActivity;
 import org.briarproject.android.util.ListLoadingProgressBar;
 import org.briarproject.api.android.DatabaseUiExecutor;
@@ -31,6 +32,7 @@ import android.view.View;
 import android.widget.AdapterView;
 import android.widget.AdapterView.OnItemClickListener;
 import android.widget.ListView;
+import android.widget.TextView;
 
 public class ManageGroupsActivity extends BriarActivity
 implements EventListener, OnItemClickListener {
@@ -38,6 +40,7 @@ implements EventListener, OnItemClickListener {
 	private static final Logger LOG =
 			Logger.getLogger(ManageGroupsActivity.class.getName());
 
+	private TextView empty = null;
 	private ManageGroupsAdapter adapter = null;
 	private ListView list = null;
 	private ListLoadingProgressBar loading = null;
@@ -51,6 +54,12 @@ implements EventListener, OnItemClickListener {
 	public void onCreate(Bundle state) {
 		super.onCreate(state);
 
+		empty = new TextView(this);
+		empty.setLayoutParams(MATCH_MATCH);
+		empty.setGravity(CENTER);
+		empty.setTextSize(18);
+		empty.setText(R.string.no_forums_available);
+
 		adapter = new ManageGroupsAdapter(this);
 		list = new ListView(this);
 		list.setLayoutParams(MATCH_MATCH);
@@ -95,12 +104,16 @@ implements EventListener, OnItemClickListener {
 	private void displayGroups(final Collection<GroupStatus> available) {
 		runOnUiThread(new Runnable() {
 			public void run() {
-				setContentView(list);
-				adapter.clear();
-				for(GroupStatus s : available)
-					adapter.add(new ManageGroupsItem(s));
-				adapter.sort(ManageGroupsItemComparator.INSTANCE);
-				adapter.notifyDataSetChanged();
+				if(available.isEmpty()) {
+					setContentView(empty);
+				} else {
+					setContentView(list);
+					adapter.clear();
+					for(GroupStatus s : available)
+						adapter.add(new ManageGroupsItem(s));
+					adapter.sort(ManageGroupsItemComparator.INSTANCE);
+					adapter.notifyDataSetChanged();
+				}
 			}
 		});
 	}
@@ -128,7 +141,6 @@ implements EventListener, OnItemClickListener {
 	public void onItemClick(AdapterView<?> parent, View view, int position,
 			long id) {
 		ManageGroupsItem item = adapter.getItem(position);
-		if(item == NONE) return;
 		GroupStatus s = item.getGroupStatus();
 		Group g = s.getGroup();
 		Intent i = new Intent(this, ConfigureGroupActivity.class);
diff --git a/briar-android/src/org/briarproject/android/groups/ManageGroupsAdapter.java b/briar-android/src/org/briarproject/android/groups/ManageGroupsAdapter.java
index 7b3f5656f2..e6fcd2c31e 100644
--- a/briar-android/src/org/briarproject/android/groups/ManageGroupsAdapter.java
+++ b/briar-android/src/org/briarproject/android/groups/ManageGroupsAdapter.java
@@ -1,16 +1,11 @@
 package org.briarproject.android.groups;
 
 import static android.text.TextUtils.TruncateAt.END;
-import static android.view.Gravity.CENTER;
 import static android.view.View.INVISIBLE;
 import static android.widget.LinearLayout.HORIZONTAL;
 import static android.widget.LinearLayout.VERTICAL;
-import static org.briarproject.android.groups.ManageGroupsItem.NONE;
 
 import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
 
 import org.briarproject.R;
 import org.briarproject.android.util.LayoutUtils;
@@ -19,63 +14,34 @@ import org.briarproject.api.messaging.GroupStatus;
 import android.content.Context;
 import android.view.View;
 import android.view.ViewGroup;
-import android.widget.BaseAdapter;
+import android.widget.ArrayAdapter;
 import android.widget.ImageView;
 import android.widget.LinearLayout;
 import android.widget.TextView;
 
-class ManageGroupsAdapter extends BaseAdapter {
+class ManageGroupsAdapter extends ArrayAdapter<ManageGroupsItem> {
 
-	private final Context ctx;
 	private final int pad;
-	private final List<ManageGroupsItem> list =
-			new ArrayList<ManageGroupsItem>();
 
 	ManageGroupsAdapter(Context ctx) {
-		this.ctx = ctx;
+		super(ctx, android.R.layout.simple_expandable_list_item_1,
+				new ArrayList<ManageGroupsItem>());
 		pad = LayoutUtils.getPadding(ctx);
 	}
 
-	public void add(ManageGroupsItem item) {
-		list.add(item);
-	}
-
-	public void clear() {
-		list.clear();
-	}
-
-	public int getCount() {
-		return list.isEmpty() ? 1 : list.size();
-	}
-
-	public ManageGroupsItem getItem(int position) {
-		return list.isEmpty() ? NONE : list.get(position);
-	}
-
-	public long getItemId(int position) {
-		return android.R.layout.simple_expandable_list_item_1;
-	}
-
+	@Override
 	public View getView(int position, View convertView, ViewGroup parent) {
 		ManageGroupsItem item = getItem(position);
+		GroupStatus groupStatus = item.getGroupStatus();
+		Context ctx = getContext();
 
-		if(item == NONE) {
-			TextView none = new TextView(ctx);
-			none.setGravity(CENTER);
-			none.setTextSize(18);
-			none.setPadding(pad, pad, pad, pad);
-			none.setText(R.string.no_forums_available);
-			return none;
-		}
-
-		GroupStatus s = item.getGroupStatus();
 		LinearLayout layout = new LinearLayout(ctx);
 		layout.setOrientation(HORIZONTAL);
 
 		ImageView subscribed = new ImageView(ctx);
 		subscribed.setPadding(pad, pad, pad, pad);
 		subscribed.setImageResource(R.drawable.navigation_accept);
-		if(!s.isSubscribed()) subscribed.setVisibility(INVISIBLE);
+		if(!groupStatus.isSubscribed()) subscribed.setVisibility(INVISIBLE);
 		layout.addView(subscribed);
 
 		LinearLayout innerLayout = new LinearLayout(ctx);
@@ -86,14 +52,15 @@ class ManageGroupsAdapter extends BaseAdapter {
 		name.setSingleLine();
 		name.setEllipsize(END);
 		name.setPadding(0, pad, pad, pad);
-		name.setText(s.getGroup().getName());
+		name.setText(groupStatus.getGroup().getName());
 		innerLayout.addView(name);
 
 		TextView status = new TextView(ctx);
 		status.setTextSize(14);
 		status.setPadding(0, 0, pad, pad);
-		if(s.isSubscribed()) {
-			if(s.isVisibleToAll()) status.setText(R.string.subscribed_all);
+		if(groupStatus.isSubscribed()) {
+			if(groupStatus.isVisibleToAll())
+				status.setText(R.string.subscribed_all);
 			else status.setText(R.string.subscribed_some);
 		} else {
 			status.setText(R.string.not_subscribed);
@@ -103,17 +70,4 @@ class ManageGroupsAdapter extends BaseAdapter {
 
 		return layout;
 	}
-
-	@Override
-	public boolean isEmpty() {
-		return false;
-	}
-
-	public void remove(ManageGroupsItem item) {
-		list.remove(item);
-	}
-
-	public void sort(Comparator<ManageGroupsItem> comparator) {
-		Collections.sort(list, comparator);
-	}
 }
diff --git a/briar-android/src/org/briarproject/android/groups/ManageGroupsItem.java b/briar-android/src/org/briarproject/android/groups/ManageGroupsItem.java
index 157153ecb5..16f67beaae 100644
--- a/briar-android/src/org/briarproject/android/groups/ManageGroupsItem.java
+++ b/briar-android/src/org/briarproject/android/groups/ManageGroupsItem.java
@@ -4,8 +4,6 @@ import org.briarproject.api.messaging.GroupStatus;
 
 class ManageGroupsItem {
 
-	static final ManageGroupsItem NONE = new ManageGroupsItem(null);
-
 	private final GroupStatus status;
 
 	ManageGroupsItem(GroupStatus status) {
diff --git a/briar-android/src/org/briarproject/android/groups/ManageGroupsItemComparator.java b/briar-android/src/org/briarproject/android/groups/ManageGroupsItemComparator.java
index ceb264fbba..def3fa7a7c 100644
--- a/briar-android/src/org/briarproject/android/groups/ManageGroupsItemComparator.java
+++ b/briar-android/src/org/briarproject/android/groups/ManageGroupsItemComparator.java
@@ -1,7 +1,5 @@
 package org.briarproject.android.groups;
 
-import static org.briarproject.android.groups.ManageGroupsItem.NONE;
-
 import java.util.Comparator;
 
 class ManageGroupsItemComparator implements Comparator<ManageGroupsItem> {
@@ -11,8 +9,6 @@ class ManageGroupsItemComparator implements Comparator<ManageGroupsItem> {
 
 	public int compare(ManageGroupsItem a, ManageGroupsItem b) {
 		if(a == b) return 0;
-		if(a == NONE) return 1;
-		if(b == NONE) return -1;
 		String aName = a.getGroupStatus().getGroup().getName();
 		String bName = b.getGroupStatus().getGroup().getName();
 		return String.CASE_INSENSITIVE_ORDER.compare(aName, bName);
diff --git a/briar-android/src/org/briarproject/android/groups/NoContactsDialog.java b/briar-android/src/org/briarproject/android/groups/NoContactsDialog.java
index a5be07741f..e21ba9d062 100644
--- a/briar-android/src/org/briarproject/android/groups/NoContactsDialog.java
+++ b/briar-android/src/org/briarproject/android/groups/NoContactsDialog.java
@@ -19,7 +19,7 @@ public class NoContactsDialog extends DialogFragment {
 	@Override
 	public Dialog onCreateDialog(Bundle state) {
 		AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
-		builder.setMessage(R.string.no_contacts);
+		builder.setMessage(R.string.no_contacts_prompt);
 		builder.setPositiveButton(R.string.add_button,
 				new DialogInterface.OnClickListener() {
 			public void onClick(DialogInterface dialog, int id) {
diff --git a/briar-android/src/org/briarproject/android/groups/ReadGroupPostActivity.java b/briar-android/src/org/briarproject/android/groups/ReadGroupPostActivity.java
index ba91e6e8be..c038bdbdfd 100644
--- a/briar-android/src/org/briarproject/android/groups/ReadGroupPostActivity.java
+++ b/briar-android/src/org/briarproject/android/groups/ReadGroupPostActivity.java
@@ -52,6 +52,7 @@ implements OnClickListener {
 			Logger.getLogger(ReadGroupPostActivity.class.getName());
 
 	private GroupId groupId = null;
+	private String groupName = null;
 	private boolean read;
 	private ImageButton readButton = null, prevButton = null, nextButton = null;
 	private ImageButton replyButton = null;
@@ -73,7 +74,7 @@ implements OnClickListener {
 		byte[] b = i.getByteArrayExtra("briar.GROUP_ID");
 		if(b == null) throw new IllegalStateException();
 		groupId = new GroupId(b);
-		String groupName = i.getStringExtra("briar.GROUP_NAME");
+		groupName = i.getStringExtra("briar.GROUP_NAME");
 		if(groupName == null) throw new IllegalStateException();
 		setTitle(groupName);
 		b = i.getByteArrayExtra("briar.MESSAGE_ID");
@@ -102,7 +103,6 @@ implements OnClickListener {
 		layout.setOrientation(VERTICAL);
 
 		ScrollView scrollView = new ScrollView(this);
-		// Give me all the width and all the unused height
 		scrollView.setLayoutParams(MATCH_WRAP_1);
 
 		LinearLayout message = new LinearLayout(this);
@@ -263,6 +263,7 @@ implements OnClickListener {
 		} else if(view == replyButton) {
 			Intent i = new Intent(this, WriteGroupPostActivity.class);
 			i.putExtra("briar.GROUP_ID", groupId.getBytes());
+			i.putExtra("briar.GROUP_NAME", groupName);
 			i.putExtra("briar.PARENT_ID", messageId.getBytes());
 			i.putExtra("briar.TIMESTAMP", timestamp);
 			startActivity(i);
diff --git a/briar-android/src/org/briarproject/android/groups/WriteGroupPostActivity.java b/briar-android/src/org/briarproject/android/groups/WriteGroupPostActivity.java
index db9cca5bfa..2222c9479b 100644
--- a/briar-android/src/org/briarproject/android/groups/WriteGroupPostActivity.java
+++ b/briar-android/src/org/briarproject/android/groups/WriteGroupPostActivity.java
@@ -95,6 +95,9 @@ implements OnItemSelectedListener, OnClickListener {
 		byte[] b = i.getByteArrayExtra("briar.GROUP_ID");
 		if(b == null) throw new IllegalStateException();
 		groupId = new GroupId(b);
+		String groupName = i.getStringExtra("briar.GROUP_NAME");
+		if(groupName == null) throw new IllegalStateException();
+		setTitle(groupName);
 		b = i.getByteArrayExtra("briar.PARENT_ID");
 		if(b != null) parentId = new MessageId(b);
 		timestamp = i.getLongExtra("briar.TIMESTAMP", -1);
-- 
GitLab