diff --git a/briar-android/res/values/strings.xml b/briar-android/res/values/strings.xml
index 003bfac94..b57845c6b 100644
--- a/briar-android/res/values/strings.xml
+++ b/briar-android/res/values/strings.xml
@@ -54,12 +54,14 @@
Share this group with all contacts
Share this group with chosen contacts
New Post
+ New group\u2026
Blogs
New Blog
Choose a name for your blog:
Share this blog with all contacts
Share this blog with chosen contacts
New Post
+ New blog\u2026
New nickname\u2026
Create an Identity
Choose your nickname:
diff --git a/briar-android/src/net/sf/briar/android/GroupNameComparator.java b/briar-android/src/net/sf/briar/android/GroupNameComparator.java
deleted file mode 100644
index 8e397be1b..000000000
--- a/briar-android/src/net/sf/briar/android/GroupNameComparator.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package net.sf.briar.android;
-
-import java.util.Comparator;
-
-import net.sf.briar.api.messaging.Group;
-
-public class GroupNameComparator implements Comparator {
-
- public static final GroupNameComparator INSTANCE =
- new GroupNameComparator();
-
- public int compare(Group a, Group b) {
- return String.CASE_INSENSITIVE_ORDER.compare(a.getName(), b.getName());
- }
-}
diff --git a/briar-android/src/net/sf/briar/android/blogs/LocalGroupItem.java b/briar-android/src/net/sf/briar/android/blogs/LocalGroupItem.java
new file mode 100644
index 000000000..cd7f89355
--- /dev/null
+++ b/briar-android/src/net/sf/briar/android/blogs/LocalGroupItem.java
@@ -0,0 +1,18 @@
+package net.sf.briar.android.blogs;
+
+import net.sf.briar.api.messaging.LocalGroup;
+
+class LocalGroupItem {
+
+ static final LocalGroupItem NEW = new LocalGroupItem(null);
+
+ private final LocalGroup localGroup;
+
+ LocalGroupItem(LocalGroup localGroup) {
+ this.localGroup = localGroup;
+ }
+
+ LocalGroup getLocalGroup() {
+ return localGroup;
+ }
+}
diff --git a/briar-android/src/net/sf/briar/android/blogs/LocalGroupItemComparator.java b/briar-android/src/net/sf/briar/android/blogs/LocalGroupItemComparator.java
new file mode 100644
index 000000000..b6943000c
--- /dev/null
+++ b/briar-android/src/net/sf/briar/android/blogs/LocalGroupItemComparator.java
@@ -0,0 +1,20 @@
+package net.sf.briar.android.blogs;
+
+import static net.sf.briar.android.blogs.LocalGroupItem.NEW;
+
+import java.util.Comparator;
+
+class LocalGroupItemComparator implements Comparator {
+
+ static final LocalGroupItemComparator INSTANCE =
+ new LocalGroupItemComparator();
+
+ public int compare(LocalGroupItem a, LocalGroupItem b) {
+ if(a == b) return 0;
+ if(a == NEW) return 1;
+ if(b == NEW) return -1;
+ String aName = a.getLocalGroup().getName();
+ String bName = b.getLocalGroup().getName();
+ return String.CASE_INSENSITIVE_ORDER.compare(aName, bName);
+ }
+}
diff --git a/briar-android/src/net/sf/briar/android/blogs/LocalGroupSpinnerAdapter.java b/briar-android/src/net/sf/briar/android/blogs/LocalGroupSpinnerAdapter.java
index 8dc22083a..c4cf025cb 100644
--- a/briar-android/src/net/sf/briar/android/blogs/LocalGroupSpinnerAdapter.java
+++ b/briar-android/src/net/sf/briar/android/blogs/LocalGroupSpinnerAdapter.java
@@ -1,35 +1,40 @@
package net.sf.briar.android.blogs;
+import static net.sf.briar.android.blogs.LocalGroupItem.NEW;
+
import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
import net.sf.briar.R;
-import net.sf.briar.api.messaging.LocalGroup;
import android.content.Context;
import android.content.res.Resources;
import android.view.View;
import android.view.ViewGroup;
-import android.widget.ArrayAdapter;
+import android.widget.BaseAdapter;
import android.widget.SpinnerAdapter;
import android.widget.TextView;
-class LocalGroupSpinnerAdapter extends ArrayAdapter
-implements SpinnerAdapter {
+class LocalGroupSpinnerAdapter extends BaseAdapter implements SpinnerAdapter {
- LocalGroupSpinnerAdapter(Context context) {
- super(context, android.R.layout.simple_spinner_item,
- new ArrayList());
+ private final Context ctx;
+ private final List list = new ArrayList();
+
+ LocalGroupSpinnerAdapter(Context ctx) {
+ this.ctx = ctx;
}
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- TextView name = new TextView(getContext());
- name.setTextSize(18);
- name.setMaxLines(1);
- Resources res = getContext().getResources();
- int pad = res.getInteger(R.integer.spinner_padding);
- name.setPadding(pad, pad, pad, pad);
- name.setText(getItem(position).getName());
- return name;
+ public void add(LocalGroupItem item) {
+ list.add(item);
+ }
+
+ public void clear() {
+ list.clear();
+ }
+
+ public int getCount() {
+ return list.size() + 1;
}
@Override
@@ -37,4 +42,35 @@ implements SpinnerAdapter {
ViewGroup parent) {
return getView(position, convertView, parent);
}
+
+ public LocalGroupItem getItem(int position) {
+ if(position == list.size()) return NEW;
+ return list.get(position);
+ }
+
+ public long getItemId(int position) {
+ return android.R.layout.simple_spinner_item;
+ }
+
+ public View getView(int position, View convertView, ViewGroup parent) {
+ TextView name = new TextView(ctx);
+ name.setTextSize(18);
+ name.setMaxLines(1);
+ Resources res = ctx.getResources();
+ int pad = res.getInteger(R.integer.spinner_padding);
+ name.setPadding(pad, pad, pad, pad);
+ LocalGroupItem item = getItem(position);
+ if(item == NEW) name.setText(R.string.new_blog_item);
+ else name.setText(item.getLocalGroup().getName());
+ return name;
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return getCount() == 0;
+ }
+
+ public void sort(Comparator comparator) {
+ Collections.sort(list, comparator);
+ }
}
diff --git a/briar-android/src/net/sf/briar/android/blogs/WriteBlogPostActivity.java b/briar-android/src/net/sf/briar/android/blogs/WriteBlogPostActivity.java
index 15a807ab4..57dfded06 100644
--- a/briar-android/src/net/sf/briar/android/blogs/WriteBlogPostActivity.java
+++ b/briar-android/src/net/sf/briar/android/blogs/WriteBlogPostActivity.java
@@ -7,8 +7,6 @@ import static android.widget.LinearLayout.HORIZONTAL;
import static android.widget.LinearLayout.VERTICAL;
import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING;
-import static net.sf.briar.android.identity.LocalAuthorItem.ANONYMOUS;
-import static net.sf.briar.android.identity.LocalAuthorItem.NEW;
import static net.sf.briar.android.widgets.CommonLayoutParams.MATCH_WRAP;
import java.io.IOException;
@@ -22,7 +20,6 @@ import net.sf.briar.R;
import net.sf.briar.android.BriarActivity;
import net.sf.briar.android.BriarService;
import net.sf.briar.android.BriarService.BriarServiceConnection;
-import net.sf.briar.android.GroupNameComparator;
import net.sf.briar.android.identity.CreateIdentityActivity;
import net.sf.briar.android.identity.LocalAuthorItem;
import net.sf.briar.android.identity.LocalAuthorItemComparator;
@@ -190,6 +187,7 @@ implements OnItemSelectedListener, OnClickListener {
final Collection localAuthors) {
runOnUiThread(new Runnable() {
public void run() {
+ if(localAuthors.isEmpty()) throw new IllegalStateException();
fromAdapter.clear();
for(LocalAuthor a : localAuthors)
fromAdapter.add(new LocalAuthorItem(a));
@@ -226,11 +224,14 @@ implements OnItemSelectedListener, OnClickListener {
public void run() {
if(groups.isEmpty()) finish();
toAdapter.clear();
- for(LocalGroup g : groups) toAdapter.add(g);
- toAdapter.sort(GroupNameComparator.INSTANCE);
+ for(LocalGroup g : groups) toAdapter.add(new LocalGroupItem(g));
+ toAdapter.sort(LocalGroupItemComparator.INSTANCE);
+ toAdapter.notifyDataSetChanged();
int count = toAdapter.getCount();
for(int i = 0; i < count; i++) {
- if(toAdapter.getItem(i).getId().equals(localGroupId)) {
+ LocalGroupItem item = toAdapter.getItem(i);
+ if(item == LocalGroupItem.NEW) continue;
+ if(item.getLocalGroup().getId().equals(localGroupId)) {
toSpinner.setSelection(i);
break;
}
@@ -256,18 +257,23 @@ implements OnItemSelectedListener, OnClickListener {
long id) {
if(parent == fromSpinner) {
LocalAuthorItem item = fromAdapter.getItem(position);
- if(item == ANONYMOUS) {
+ if(item == LocalAuthorItem.ANONYMOUS) {
localAuthor = null;
- } else if(item == NEW) {
+ } else if(item == LocalAuthorItem.NEW) {
localAuthor = null;
startActivity(new Intent(this, CreateIdentityActivity.class));
} else {
localAuthor = item.getLocalAuthor();
}
} else if(parent == toSpinner) {
- localGroup = toAdapter.getItem(position);
- localGroupId = localGroup.getId();
- sendButton.setEnabled(true);
+ LocalGroupItem item = toAdapter.getItem(position);
+ if(item == LocalGroupItem.NEW) {
+ startActivity(new Intent(this, CreateBlogActivity.class));
+ } else {
+ localGroup = item.getLocalGroup();
+ localGroupId = localGroup.getId();
+ sendButton.setEnabled(true);
+ }
}
}
diff --git a/briar-android/src/net/sf/briar/android/groups/GroupItem.java b/briar-android/src/net/sf/briar/android/groups/GroupItem.java
new file mode 100644
index 000000000..ff45e226b
--- /dev/null
+++ b/briar-android/src/net/sf/briar/android/groups/GroupItem.java
@@ -0,0 +1,18 @@
+package net.sf.briar.android.groups;
+
+import net.sf.briar.api.messaging.Group;
+
+class GroupItem {
+
+ static final GroupItem NEW = new GroupItem(null);
+
+ private final Group group;
+
+ GroupItem(Group group) {
+ this.group = group;
+ }
+
+ Group getGroup() {
+ return group;
+ }
+}
diff --git a/briar-android/src/net/sf/briar/android/groups/GroupItemComparator.java b/briar-android/src/net/sf/briar/android/groups/GroupItemComparator.java
new file mode 100644
index 000000000..f9f377ebd
--- /dev/null
+++ b/briar-android/src/net/sf/briar/android/groups/GroupItemComparator.java
@@ -0,0 +1,18 @@
+package net.sf.briar.android.groups;
+
+import static net.sf.briar.android.groups.GroupItem.NEW;
+
+import java.util.Comparator;
+
+class GroupItemComparator implements Comparator {
+
+ static final GroupItemComparator INSTANCE = new GroupItemComparator();
+
+ public int compare(GroupItem a, GroupItem b) {
+ if(a == b) return 0;
+ if(a == NEW) return 1;
+ if(b == NEW) return -1;
+ String aName = a.getGroup().getName(), bName = b.getGroup().getName();
+ return String.CASE_INSENSITIVE_ORDER.compare(aName, bName);
+ }
+}
diff --git a/briar-android/src/net/sf/briar/android/groups/GroupSpinnerAdapter.java b/briar-android/src/net/sf/briar/android/groups/GroupSpinnerAdapter.java
index 821c5ae16..c4180324b 100644
--- a/briar-android/src/net/sf/briar/android/groups/GroupSpinnerAdapter.java
+++ b/briar-android/src/net/sf/briar/android/groups/GroupSpinnerAdapter.java
@@ -1,35 +1,40 @@
package net.sf.briar.android.groups;
+import static net.sf.briar.android.groups.GroupItem.NEW;
+
import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
import net.sf.briar.R;
-import net.sf.briar.api.messaging.Group;
import android.content.Context;
import android.content.res.Resources;
import android.view.View;
import android.view.ViewGroup;
-import android.widget.ArrayAdapter;
+import android.widget.BaseAdapter;
import android.widget.SpinnerAdapter;
import android.widget.TextView;
-class GroupSpinnerAdapter extends ArrayAdapter
-implements SpinnerAdapter {
+class GroupSpinnerAdapter extends BaseAdapter implements SpinnerAdapter {
- GroupSpinnerAdapter(Context context) {
- super(context, android.R.layout.simple_spinner_item,
- new ArrayList());
+ private final Context ctx;
+ private final List list = new ArrayList();
+
+ GroupSpinnerAdapter(Context ctx) {
+ this.ctx = ctx;
}
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- TextView name = new TextView(getContext());
- name.setTextSize(18);
- name.setMaxLines(1);
- Resources res = getContext().getResources();
- int pad = res.getInteger(R.integer.spinner_padding);
- name.setPadding(pad, pad, pad, pad);
- name.setText(getItem(position).getName());
- return name;
+ public void add(GroupItem item) {
+ list.add(item);
+ }
+
+ public void clear() {
+ list.clear();
+ }
+
+ public int getCount() {
+ return list.size() + 1;
}
@Override
@@ -37,4 +42,35 @@ implements SpinnerAdapter {
ViewGroup parent) {
return getView(position, convertView, parent);
}
+
+ public GroupItem getItem(int position) {
+ if(position == list.size()) return NEW;
+ return list.get(position);
+ }
+
+ public long getItemId(int position) {
+ return android.R.layout.simple_spinner_item;
+ }
+
+ public View getView(int position, View convertView, ViewGroup parent) {
+ TextView name = new TextView(ctx);
+ name.setTextSize(18);
+ name.setMaxLines(1);
+ Resources res = ctx.getResources();
+ int pad = res.getInteger(R.integer.spinner_padding);
+ name.setPadding(pad, pad, pad, pad);
+ GroupItem item = getItem(position);
+ if(item == NEW) name.setText(R.string.new_group_item);
+ else name.setText(item.getGroup().getName());
+ return name;
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return getCount() == 0;
+ }
+
+ public void sort(Comparator comparator) {
+ Collections.sort(list, comparator);
+ }
}
diff --git a/briar-android/src/net/sf/briar/android/groups/WriteGroupPostActivity.java b/briar-android/src/net/sf/briar/android/groups/WriteGroupPostActivity.java
index 9b4621c7e..7fb542d74 100644
--- a/briar-android/src/net/sf/briar/android/groups/WriteGroupPostActivity.java
+++ b/briar-android/src/net/sf/briar/android/groups/WriteGroupPostActivity.java
@@ -7,8 +7,6 @@ import static android.widget.LinearLayout.HORIZONTAL;
import static android.widget.LinearLayout.VERTICAL;
import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING;
-import static net.sf.briar.android.identity.LocalAuthorItem.ANONYMOUS;
-import static net.sf.briar.android.identity.LocalAuthorItem.NEW;
import static net.sf.briar.android.widgets.CommonLayoutParams.MATCH_WRAP;
import java.io.IOException;
@@ -24,7 +22,6 @@ import java.util.logging.Logger;
import net.sf.briar.R;
import net.sf.briar.android.BriarActivity;
import net.sf.briar.android.BriarService;
-import net.sf.briar.android.GroupNameComparator;
import net.sf.briar.android.BriarService.BriarServiceConnection;
import net.sf.briar.android.identity.CreateIdentityActivity;
import net.sf.briar.android.identity.LocalAuthorItem;
@@ -193,6 +190,7 @@ implements OnItemSelectedListener, OnClickListener {
final Collection localAuthors) {
runOnUiThread(new Runnable() {
public void run() {
+ if(localAuthors.isEmpty()) throw new IllegalStateException();
fromAdapter.clear();
for(LocalAuthor a : localAuthors)
fromAdapter.add(new LocalAuthorItem(a));
@@ -231,11 +229,14 @@ implements OnItemSelectedListener, OnClickListener {
public void run() {
if(groups.isEmpty()) finish();
toAdapter.clear();
- for(Group g : groups) toAdapter.add(g);
- toAdapter.sort(GroupNameComparator.INSTANCE);
+ for(Group g : groups) toAdapter.add(new GroupItem(g));
+ toAdapter.sort(GroupItemComparator.INSTANCE);
+ toAdapter.notifyDataSetChanged();
int count = toAdapter.getCount();
for(int i = 0; i < count; i++) {
- if(toAdapter.getItem(i).getId().equals(groupId)) {
+ GroupItem g = toAdapter.getItem(i);
+ if(g == GroupItem.NEW) continue;
+ if(g.getGroup().getId().equals(groupId)) {
toSpinner.setSelection(i);
break;
}
@@ -261,18 +262,23 @@ implements OnItemSelectedListener, OnClickListener {
long id) {
if(parent == fromSpinner) {
LocalAuthorItem item = fromAdapter.getItem(position);
- if(item == ANONYMOUS) {
+ if(item == LocalAuthorItem.ANONYMOUS) {
localAuthor = null;
- } else if(item == NEW) {
+ } else if(item == LocalAuthorItem.NEW) {
localAuthor = null;
startActivity(new Intent(this, CreateIdentityActivity.class));
} else {
localAuthor = item.getLocalAuthor();
}
} else if(parent == toSpinner) {
- group = toAdapter.getItem(position);
- groupId = group.getId();
- sendButton.setEnabled(true);
+ GroupItem item = toAdapter.getItem(position);
+ if(item == GroupItem.NEW) {
+ startActivity(new Intent(this, CreateGroupActivity.class));
+ } else {
+ group = item.getGroup();
+ groupId = group.getId();
+ sendButton.setEnabled(true);
+ }
}
}