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); + } } }