diff --git a/briar-android/res/values/color.xml b/briar-android/res/values/color.xml index 5df37c9f6bc34a59241ef77eca21380e4255f6e7..f034c112580077119b1735c711338dea7f430aad 100644 --- a/briar-android/res/values/color.xml +++ b/briar-android/res/values/color.xml @@ -7,5 +7,6 @@ <color name="private_message_date">#AAAAAA</color> <color name="unread_background">#FFFFFF</color> <color name="horizontal_border">#CCCCCC</color> + <color name="groups_available_background">#FCCF1C</color> <color name="no_posts">#AAAAAA</color> </resources> \ No newline at end of file diff --git a/briar-android/src/org/briarproject/android/AscendingHeaderComparator.java b/briar-android/src/org/briarproject/android/AscendingHeaderComparator.java deleted file mode 100644 index 11490c4ca8db8a2c97e2cb07a257de27f563d744..0000000000000000000000000000000000000000 --- a/briar-android/src/org/briarproject/android/AscendingHeaderComparator.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.briarproject.android; - -import java.util.Comparator; - -import org.briarproject.api.db.MessageHeader; - -public class AscendingHeaderComparator implements Comparator<MessageHeader> { - - public static final AscendingHeaderComparator INSTANCE = - new AscendingHeaderComparator(); - - public int compare(MessageHeader a, MessageHeader b) { - // The oldest message comes first - long aTime = a.getTimestamp(), bTime = b.getTimestamp(); - if(aTime < bTime) return -1; - if(aTime > bTime) return 1; - return 0; - } -} diff --git a/briar-android/src/org/briarproject/android/contact/ContactItem.java b/briar-android/src/org/briarproject/android/contact/ContactItem.java deleted file mode 100644 index 665a1c8acb5bfa2788de7c0bd989429c9236c66c..0000000000000000000000000000000000000000 --- a/briar-android/src/org/briarproject/android/contact/ContactItem.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.briarproject.android.contact; - -import org.briarproject.api.Contact; - -public class ContactItem { - - public static final ContactItem NEW = new ContactItem(null); - - private final Contact contact; - - public ContactItem(Contact contact) { - this.contact = contact; - } - - public Contact getContact() { - return contact; - } -} diff --git a/briar-android/src/org/briarproject/android/contact/ContactItemComparator.java b/briar-android/src/org/briarproject/android/contact/ContactItemComparator.java deleted file mode 100644 index 73538cc085c07074dd18db9ddf0dd1392d770d9e..0000000000000000000000000000000000000000 --- a/briar-android/src/org/briarproject/android/contact/ContactItemComparator.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.briarproject.android.contact; - -import java.util.Comparator; - -public class ContactItemComparator implements Comparator<ContactItem> { - - public static final ContactItemComparator INSTANCE = - new ContactItemComparator(); - - public int compare(ContactItem a, ContactItem b) { - if(a == b) return 0; - if(a == ContactItem.NEW) return 1; - if(b == ContactItem.NEW) return -1; - String aName = a.getContact().getAuthor().getName(); - String bName = b.getContact().getAuthor().getName(); - return String.CASE_INSENSITIVE_ORDER.compare(aName, bName); - } -} diff --git a/briar-android/src/org/briarproject/android/contact/ContactListActivity.java b/briar-android/src/org/briarproject/android/contact/ContactListActivity.java index 70519d531ea26cd6d800a2da3d9f26ab93ac16bb..ce574b5cc3630360ee83e81d741f98f22f83ad47 100644 --- a/briar-android/src/org/briarproject/android/contact/ContactListActivity.java +++ b/briar-android/src/org/briarproject/android/contact/ContactListActivity.java @@ -12,7 +12,6 @@ import static org.briarproject.android.util.CommonLayoutParams.MATCH_WRAP; import static org.briarproject.android.util.CommonLayoutParams.MATCH_WRAP_1; import java.util.Collection; -import java.util.Comparator; import java.util.Map; import java.util.concurrent.Executor; import java.util.logging.Logger; @@ -178,7 +177,7 @@ ConnectionListener { // Add a new item adapter.add(new ContactListItem(c, connected, lastConnected, inbox, headers)); - adapter.sort(ItemComparator.INSTANCE); + adapter.sort(ContactListItemComparator.INSTANCE); adapter.notifyDataSetChanged(); } }); @@ -318,15 +317,4 @@ ConnectionListener { } }); } - - private static class ItemComparator implements Comparator<ContactListItem> { - - private static final ItemComparator INSTANCE = new ItemComparator(); - - public int compare(ContactListItem a, ContactListItem b) { - String aName = a.getContact().getAuthor().getName(); - String bName = b.getContact().getAuthor().getName(); - return String.CASE_INSENSITIVE_ORDER.compare(aName, bName); - } - } } diff --git a/briar-android/src/org/briarproject/android/contact/ContactListItemComparator.java b/briar-android/src/org/briarproject/android/contact/ContactListItemComparator.java new file mode 100644 index 0000000000000000000000000000000000000000..db41a3ef52be317d5cc77df42369b448c023435b --- /dev/null +++ b/briar-android/src/org/briarproject/android/contact/ContactListItemComparator.java @@ -0,0 +1,15 @@ +package org.briarproject.android.contact; + +import java.util.Comparator; + +class ContactListItemComparator implements Comparator<ContactListItem> { + + static final ContactListItemComparator INSTANCE = + new ContactListItemComparator(); + + public int compare(ContactListItem a, ContactListItem b) { + String aName = a.getContact().getAuthor().getName(); + String bName = b.getContact().getAuthor().getName(); + return String.CASE_INSENSITIVE_ORDER.compare(aName, bName); + } +} diff --git a/briar-android/src/org/briarproject/android/groups/GroupListActivity.java b/briar-android/src/org/briarproject/android/groups/GroupListActivity.java index 09ff3fa76034c0c2a25b93f2e923719cef591624..1103a73df492fae59fb4b167f8a937684256301e 100644 --- a/briar-android/src/org/briarproject/android/groups/GroupListActivity.java +++ b/briar-android/src/org/briarproject/android/groups/GroupListActivity.java @@ -8,13 +8,11 @@ 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 org.briarproject.android.groups.GroupListItem.MANAGE; import static org.briarproject.android.util.CommonLayoutParams.MATCH_MATCH; import static org.briarproject.android.util.CommonLayoutParams.MATCH_WRAP; import static org.briarproject.android.util.CommonLayoutParams.MATCH_WRAP_1; import java.util.Collection; -import java.util.Comparator; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Executor; @@ -26,6 +24,7 @@ import org.briarproject.R; import org.briarproject.android.BriarActivity; import org.briarproject.android.util.ElasticHorizontalSpace; import org.briarproject.android.util.HorizontalBorder; +import org.briarproject.android.util.LayoutUtils; import org.briarproject.android.util.ListLoadingProgressBar; import org.briarproject.api.android.DatabaseUiExecutor; import org.briarproject.api.db.DatabaseComponent; @@ -54,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 GroupListActivity extends BriarActivity implements EventListener, OnClickListener, OnItemClickListener { @@ -67,6 +67,7 @@ implements EventListener, OnClickListener, OnItemClickListener { private GroupListAdapter adapter = null; private ListView list = null; private ListLoadingProgressBar loading = null; + private TextView available = null; private ImageButton newGroupButton = null, manageGroupsButton = null; // Fields that are accessed from background threads must be volatile @@ -82,26 +83,39 @@ implements EventListener, OnClickListener, OnItemClickListener { layout.setOrientation(VERTICAL); layout.setGravity(CENTER_HORIZONTAL); + int pad = LayoutUtils.getPadding(this); + 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); + 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); + available = new TextView(this); + available.setLayoutParams(MATCH_WRAP); + available.setGravity(CENTER); + available.setTextSize(18); + Resources res = getResources(); + int background = res.getColor(R.color.groups_available_background); + available.setBackgroundColor(background); + available.setPadding(pad, pad, pad, pad); + available.setOnClickListener(this); + available.setVisibility(GONE); + layout.addView(available); + layout.addView(new HorizontalBorder(this)); LinearLayout footer = new LinearLayout(this); footer.setLayoutParams(MATCH_WRAP); footer.setOrientation(HORIZONTAL); footer.setGravity(CENTER); - Resources res = getResources(); footer.setBackgroundColor(res.getColor(R.color.button_bar_background)); footer.addView(new ElasticHorizontalSpace(this)); @@ -136,7 +150,7 @@ implements EventListener, OnClickListener, OnItemClickListener { public void run() { try { lifecycleManager.waitForDatabase(); - int available = 0; + int availableCount = 0; long now = System.currentTimeMillis(); for(GroupStatus s : db.getAvailableGroups()) { Group g = s.getGroup(); @@ -149,13 +163,13 @@ implements EventListener, OnClickListener, OnItemClickListener { // Continue } } else { - available++; + availableCount++; } } long duration = System.currentTimeMillis() - now; if(LOG.isLoggable(INFO)) LOG.info("Full load took " + duration + " ms"); - displayAvailable(available); + displayAvailable(availableCount); } catch(DbException e) { if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e); @@ -173,6 +187,7 @@ implements EventListener, OnClickListener, OnItemClickListener { public void run() { groups.clear(); list.setVisibility(GONE); + available.setVisibility(GONE); loading.setVisibility(VISIBLE); adapter.clear(); adapter.notifyDataSetChanged(); @@ -193,20 +208,26 @@ implements EventListener, OnClickListener, OnItemClickListener { if(item != null) adapter.remove(item); // Add a new item adapter.add(new GroupListItem(g, headers)); - adapter.sort(ItemComparator.INSTANCE); + adapter.sort(GroupListItemComparator.INSTANCE); adapter.notifyDataSetChanged(); selectFirstUnread(); } }); } - private void displayAvailable(final int available) { + private void displayAvailable(final int availableCount) { runOnUiThread(new Runnable() { public void run() { list.setVisibility(VISIBLE); loading.setVisibility(GONE); - adapter.setAvailable(available); - adapter.notifyDataSetChanged(); + if(availableCount == 0) { + available.setVisibility(GONE); + } else { + available.setVisibility(VISIBLE); + String format = getResources().getQuantityString( + R.plurals.forums_available, availableCount); + available.setText(String.format(format, availableCount)); + } } }); } @@ -215,7 +236,6 @@ implements EventListener, OnClickListener, OnItemClickListener { int count = adapter.getCount(); for(int i = 0; i < count; i++) { GroupListItem item = adapter.getItem(i); - if(item == MANAGE) continue; if(item.getGroup().getId().equals(g)) return item; } return null; // Not found @@ -224,9 +244,7 @@ implements EventListener, OnClickListener, OnItemClickListener { private void selectFirstUnread() { int firstUnread = -1, count = adapter.getCount(); for(int i = 0; i < count; i++) { - GroupListItem item = adapter.getItem(i); - if(item == MANAGE) continue; - if(item.getUnreadCount() > 0) { + if(adapter.getItem(i).getUnreadCount() > 0) { firstUnread = i; break; } @@ -334,7 +352,9 @@ implements EventListener, OnClickListener, OnItemClickListener { } public void onClick(View view) { - if(view == newGroupButton) { + if(view == available) { + startActivity(new Intent(this, ManageGroupsActivity.class)); + } else if(view == newGroupButton) { startActivity(new Intent(this, CreateGroupActivity.class)); } else if(view == manageGroupsButton) { startActivity(new Intent(this, ManageGroupsActivity.class)); @@ -343,35 +363,10 @@ implements EventListener, OnClickListener, OnItemClickListener { public void onItemClick(AdapterView<?> parent, View view, int position, long id) { - GroupListItem item = adapter.getItem(position); - if(item == MANAGE) { - startActivity(new Intent(this, ManageGroupsActivity.class)); - } else { - Intent i = new Intent(this, GroupActivity.class); - Group g = item.getGroup(); - i.putExtra("briar.GROUP_ID", g.getId().getBytes()); - i.putExtra("briar.GROUP_NAME", g.getName()); - startActivity(i); - } - } - - private static class ItemComparator implements Comparator<GroupListItem> { - - private static final ItemComparator INSTANCE = new ItemComparator(); - - public int compare(GroupListItem a, GroupListItem b) { - if(a == b) return 0; - // The manage groups item comes last - if(a == MANAGE) return 1; - if(b == MANAGE) return -1; - // The item with the newest message comes first - long aTime = a.getTimestamp(), bTime = b.getTimestamp(); - if(aTime > bTime) return -1; - if(aTime < bTime) return 1; - // Break ties by group name - String aName = a.getGroup().getName(); - String bName = b.getGroup().getName(); - return String.CASE_INSENSITIVE_ORDER.compare(aName, bName); - } + Intent i = new Intent(this, GroupActivity.class); + Group g = adapter.getItem(position).getGroup(); + i.putExtra("briar.GROUP_ID", g.getId().getBytes()); + i.putExtra("briar.GROUP_NAME", g.getName()); + startActivity(i); } } \ No newline at end of file diff --git a/briar-android/src/org/briarproject/android/groups/GroupListAdapter.java b/briar-android/src/org/briarproject/android/groups/GroupListAdapter.java index a82c13606275ca2c26402cdb420c8609ee963fcb..0e8c34bb69b9dbdce58989d42dccb457c5929673 100644 --- a/briar-android/src/org/briarproject/android/groups/GroupListAdapter.java +++ b/briar-android/src/org/briarproject/android/groups/GroupListAdapter.java @@ -1,15 +1,10 @@ package org.briarproject.android.groups; import static android.text.TextUtils.TruncateAt.END; -import static android.view.Gravity.CENTER; import static android.widget.LinearLayout.HORIZONTAL; -import static org.briarproject.android.groups.GroupListItem.MANAGE; import static org.briarproject.android.util.CommonLayoutParams.WRAP_WRAP_1; 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,61 +14,25 @@ import android.content.res.Resources; import android.text.format.DateUtils; import android.view.View; import android.view.ViewGroup; -import android.widget.BaseAdapter; +import android.widget.ArrayAdapter; import android.widget.LinearLayout; import android.widget.TextView; -class GroupListAdapter extends BaseAdapter { +class GroupListAdapter extends ArrayAdapter<GroupListItem> { - private final Context ctx; private final int pad; - private final List<GroupListItem> list = new ArrayList<GroupListItem>(); - private int available = 0; GroupListAdapter(Context ctx) { - this.ctx = ctx; + super(ctx, android.R.layout.simple_expandable_list_item_1, + new ArrayList<GroupListItem>()); pad = LayoutUtils.getPadding(ctx); } - public void setAvailable(int available) { - this.available = available; - } - - public void add(GroupListItem item) { - list.add(item); - } - - public void clear() { - list.clear(); - } - - public int getCount() { - return available == 0 ? list.size() : list.size() + 1; - } - - public GroupListItem getItem(int position) { - return position == list.size() ? MANAGE : list.get(position); - } - - public long getItemId(int position) { - return android.R.layout.simple_expandable_list_item_1; - } - public View getView(int position, View convertView, ViewGroup parent) { GroupListItem item = getItem(position); + Context ctx = getContext(); Resources res = ctx.getResources(); - if(item == MANAGE) { - TextView manage = new TextView(ctx); - manage.setGravity(CENTER); - manage.setTextSize(18); - manage.setPadding(pad, pad, pad, pad); - String format = res.getQuantityString(R.plurals.forums_available, - available); - manage.setText(String.format(format, available)); - return manage; - } - LinearLayout layout = new LinearLayout(ctx); layout.setOrientation(HORIZONTAL); int unread = item.getUnreadCount(); @@ -110,17 +69,4 @@ class GroupListAdapter extends BaseAdapter { return layout; } - - @Override - public boolean isEmpty() { - return list.isEmpty() && available == 0; - } - - public void remove(GroupListItem item) { - list.remove(item); - } - - public void sort(Comparator<GroupListItem> comparator) { - Collections.sort(list, comparator); - } } diff --git a/briar-android/src/org/briarproject/android/groups/GroupListItem.java b/briar-android/src/org/briarproject/android/groups/GroupListItem.java index f7b525eb06f374fb58cad48374bcfa8b55071931..20f9c7a3ffb4dd1f3d869796df3721dad6e92ae6 100644 --- a/briar-android/src/org/briarproject/android/groups/GroupListItem.java +++ b/briar-android/src/org/briarproject/android/groups/GroupListItem.java @@ -1,7 +1,6 @@ package org.briarproject.android.groups; import java.util.Collection; -import java.util.Collections; import org.briarproject.api.Author; import org.briarproject.api.db.MessageHeader; @@ -9,9 +8,6 @@ import org.briarproject.api.messaging.Group; class GroupListItem { - static final GroupListItem MANAGE = new GroupListItem(null, - Collections.<MessageHeader>emptyList()); - private final Group group; private final boolean empty; private final String authorName, contentType; diff --git a/briar-android/src/org/briarproject/android/groups/GroupListItemComparator.java b/briar-android/src/org/briarproject/android/groups/GroupListItemComparator.java new file mode 100644 index 0000000000000000000000000000000000000000..7943ea1dffd5adad07d55d18f318c098f362db40 --- /dev/null +++ b/briar-android/src/org/briarproject/android/groups/GroupListItemComparator.java @@ -0,0 +1,21 @@ +package org.briarproject.android.groups; + +import java.util.Comparator; + +class GroupListItemComparator implements Comparator<GroupListItem> { + + static final GroupListItemComparator INSTANCE = + new GroupListItemComparator(); + + public int compare(GroupListItem a, GroupListItem b) { + if(a == b) return 0; + // The item with the newest message comes first + long aTime = a.getTimestamp(), bTime = b.getTimestamp(); + if(aTime > bTime) return -1; + if(aTime < bTime) return 1; + // Break ties by group name + String aName = a.getGroup().getName(); + String bName = b.getGroup().getName(); + return String.CASE_INSENSITIVE_ORDER.compare(aName, bName); + } +} diff --git a/briar-android/src/org/briarproject/android/groups/ManageGroupsActivity.java b/briar-android/src/org/briarproject/android/groups/ManageGroupsActivity.java index ce8d1171fb8549ad8537ff4240492f3c58c64ae2..22574a038988441fc16ca549b04c1296fa38bd4a 100644 --- a/briar-android/src/org/briarproject/android/groups/ManageGroupsActivity.java +++ b/briar-android/src/org/briarproject/android/groups/ManageGroupsActivity.java @@ -6,7 +6,6 @@ import static org.briarproject.android.groups.ManageGroupsItem.NONE; import static org.briarproject.android.util.CommonLayoutParams.MATCH_MATCH; import java.util.Collection; -import java.util.Comparator; import java.util.concurrent.Executor; import java.util.logging.Logger; @@ -100,7 +99,7 @@ implements EventListener, OnItemClickListener { adapter.clear(); for(GroupStatus s : available) adapter.add(new ManageGroupsItem(s)); - adapter.sort(ItemComparator.INSTANCE); + adapter.sort(ManageGroupsItemComparator.INSTANCE); adapter.notifyDataSetChanged(); } }); @@ -140,19 +139,4 @@ implements EventListener, OnItemClickListener { i.putExtra("briar.VISIBLE_TO_ALL", s.isVisibleToAll()); startActivity(i); } - - private static class ItemComparator - implements Comparator<ManageGroupsItem> { - - private static final ItemComparator INSTANCE = new ItemComparator(); - - 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/ManageGroupsItemComparator.java b/briar-android/src/org/briarproject/android/groups/ManageGroupsItemComparator.java new file mode 100644 index 0000000000000000000000000000000000000000..ceb264fbba51fecb670ef44b5b1d5c1e095b8e7b --- /dev/null +++ b/briar-android/src/org/briarproject/android/groups/ManageGroupsItemComparator.java @@ -0,0 +1,20 @@ +package org.briarproject.android.groups; + +import static org.briarproject.android.groups.ManageGroupsItem.NONE; + +import java.util.Comparator; + +class ManageGroupsItemComparator implements Comparator<ManageGroupsItem> { + + static final ManageGroupsItemComparator INSTANCE = + new ManageGroupsItemComparator(); + + 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); + } +}