From 084b83bb45832452b9ece896cf760ab08c44f0e2 Mon Sep 17 00:00:00 2001 From: akwizgran Date: Sat, 13 Apr 2013 16:22:12 +0100 Subject: [PATCH] Display conversations and groups even if they're empty. --- briar-android/res/values/color.xml | 5 +- briar-android/res/values/strings.xml | 2 + .../sf/briar/android/groups/GroupAdapter.java | 19 ++-- .../android/groups/GroupListActivity.java | 88 +++++++++++++------ .../android/groups/GroupListAdapter.java | 57 +++++++----- .../briar/android/groups/GroupListItem.java | 53 ++++++++--- .../groups/ReadGroupMessageActivity.java | 1 - .../android/messages/ConversationAdapter.java | 18 ++-- .../messages/ConversationListActivity.java | 27 ++---- .../messages/ConversationListAdapter.java | 36 +++++--- .../messages/ConversationListItem.java | 32 +++++-- 11 files changed, 209 insertions(+), 129 deletions(-) diff --git a/briar-android/res/values/color.xml b/briar-android/res/values/color.xml index 986454bcf..7dfd4ee1f 100644 --- a/briar-android/res/values/color.xml +++ b/briar-android/res/values/color.xml @@ -4,6 +4,7 @@ #FFFFFF #FFFFFF #CCCCCC - #AAAAAA - #000000 + #999999 + #999999 + #999999 \ No newline at end of file diff --git a/briar-android/res/values/strings.xml b/briar-android/res/values/strings.xml index dbbb46c06..d3580ced8 100644 --- a/briar-android/res/values/strings.xml +++ b/briar-android/res/values/strings.xml @@ -40,6 +40,7 @@ Contact added Done Messages + (No messages) From: %1$s To: %1$s New Message @@ -47,6 +48,7 @@ To: (Anonymous) Groups + (No posts) New Group Choose a name for your group: New Post diff --git a/briar-android/src/net/sf/briar/android/groups/GroupAdapter.java b/briar-android/src/net/sf/briar/android/groups/GroupAdapter.java index 048f62256..121fd5039 100644 --- a/briar-android/src/net/sf/briar/android/groups/GroupAdapter.java +++ b/briar-android/src/net/sf/briar/android/groups/GroupAdapter.java @@ -17,7 +17,6 @@ import net.sf.briar.android.widgets.HorizontalSpace; import net.sf.briar.api.Author; import net.sf.briar.api.db.GroupMessageHeader; import net.sf.briar.api.messaging.Rating; -import net.sf.briar.util.StringUtils; import android.content.Context; import android.content.res.Resources; import android.text.format.DateUtils; @@ -77,22 +76,20 @@ class GroupAdapter extends ArrayAdapter { name.setTextColor(res.getColor(R.color.anonymous_author)); name.setText(R.string.anonymous); } else { - name.setTextColor(res.getColor(R.color.pseudonymous_author)); name.setText(author.getName()); } authorLayout.addView(name); innerLayout.addView(authorLayout); if(item.getContentType().equals("text/plain")) { - if(!StringUtils.isNullOrEmpty(item.getSubject())) { - TextView subject = new TextView(ctx); - subject.setTextSize(14); - subject.setMaxLines(2); - subject.setPadding(10, 0, 10, 10); - if(!item.isRead()) subject.setTypeface(null, BOLD); - subject.setText(item.getSubject()); - innerLayout.addView(subject); - } + TextView subject = new TextView(ctx); + subject.setTextSize(14); + subject.setMaxLines(2); + subject.setPadding(10, 0, 10, 10); + if(!item.isRead()) subject.setTypeface(null, BOLD); + String s = item.getSubject(); + subject.setText(s == null ? "" : s); + innerLayout.addView(subject); } else { LinearLayout attachmentLayout = new LinearLayout(ctx); attachmentLayout.setOrientation(HORIZONTAL); diff --git a/briar-android/src/net/sf/briar/android/groups/GroupListActivity.java b/briar-android/src/net/sf/briar/android/groups/GroupListActivity.java index 5ca3267d5..ccbfa93dc 100644 --- a/briar-android/src/net/sf/briar/android/groups/GroupListActivity.java +++ b/briar-android/src/net/sf/briar/android/groups/GroupListActivity.java @@ -10,10 +10,10 @@ import static net.sf.briar.android.widgets.CommonLayoutParams.MATCH_MATCH; import static net.sf.briar.android.widgets.CommonLayoutParams.MATCH_WRAP; import static net.sf.briar.android.widgets.CommonLayoutParams.MATCH_WRAP_1; -import java.util.ArrayList; import java.util.Collection; import java.util.Comparator; -import java.util.List; +import java.util.HashSet; +import java.util.Set; import java.util.concurrent.Executor; import java.util.logging.Logger; @@ -62,7 +62,6 @@ implements OnClickListener, DatabaseListener, NoGroupsDialog.Listener { @Inject private volatile DatabaseComponent db; @Inject @DatabaseUiExecutor private volatile Executor dbUiExecutor; private volatile boolean restricted = false; - private volatile boolean noGroups = true; @Override public void onCreate(Bundle state) { @@ -126,23 +125,39 @@ implements OnClickListener, DatabaseListener, NoGroupsDialog.Listener { } private void loadHeaders() { + clearHeaders(); dbUiExecutor.execute(new Runnable() { public void run() { try { serviceConnection.waitForStartup(); long now = System.currentTimeMillis(); - if(restricted) noGroups = db.getLocalGroups().isEmpty(); - for(Group g : db.getSubscriptions()) { - // Filter out restricted/unrestricted groups - if(g.isRestricted() != restricted) continue; - if(!restricted) noGroups = false; - try { - Collection headers = - db.getMessageHeaders(g.getId()); - displayHeaders(g, headers); - } catch(NoSuchSubscriptionException e) { - if(LOG.isLoggable(INFO)) - LOG.info("Subscription removed"); + Collection subs = db.getSubscriptions(); + if(restricted) { + Set local = new HashSet(); + for(Group g : db.getLocalGroups()) local.add(g.getId()); + for(Group g : subs) { + if(!g.isRestricted()) continue; + boolean postable = local.contains(g.getId()); + try { + Collection headers = + db.getMessageHeaders(g.getId()); + displayHeaders(g, postable, headers); + } catch(NoSuchSubscriptionException e) { + if(LOG.isLoggable(INFO)) + LOG.info("Subscription removed"); + } + } + } else { + for(Group g : subs) { + if(g.isRestricted()) continue; + try { + Collection headers = + db.getMessageHeaders(g.getId()); + displayHeaders(g, true, headers); + } catch(NoSuchSubscriptionException e) { + if(LOG.isLoggable(INFO)) + LOG.info("Subscription removed"); + } } } long duration = System.currentTimeMillis() - now; @@ -160,20 +175,24 @@ implements OnClickListener, DatabaseListener, NoGroupsDialog.Listener { }); } - private void displayHeaders(final Group g, + private void clearHeaders() { + runOnUiThread(new Runnable() { + public void run() { + adapter.clear(); + } + }); + } + + private void displayHeaders(final Group g, final boolean postable, final Collection headers) { runOnUiThread(new Runnable() { public void run() { // Remove the old item, if any GroupListItem item = findGroup(g.getId()); if(item != null) adapter.remove(item); - // Add a new item if there are any headers to display - if(!headers.isEmpty()) { - List headerList = - new ArrayList(headers); - adapter.add(new GroupListItem(g, headerList)); - adapter.sort(GroupComparator.INSTANCE); - } + // Add a new item + adapter.add(new GroupListItem(g, postable, headers)); + adapter.sort(GroupComparator.INSTANCE); adapter.notifyDataSetChanged(); selectFirstUnread(); } @@ -219,7 +238,7 @@ implements OnClickListener, DatabaseListener, NoGroupsDialog.Listener { startActivity(new Intent(this, CreateBlogActivity.class)); else startActivity(new Intent(this, CreateGroupActivity.class)); } else if(view == composeButton) { - if(noGroups) { + if(countPostableGroups() == 0) { NoGroupsDialog dialog = new NoGroupsDialog(); dialog.setListener(this); dialog.setRestricted(restricted); @@ -232,6 +251,13 @@ implements OnClickListener, DatabaseListener, NoGroupsDialog.Listener { } } + private int countPostableGroups() { + int postable = 0, count = adapter.getCount(); + for(int i = 0; i < count; i++) + if(adapter.getItem(i).isPostable()) postable++; + return postable; + } + public void eventOccurred(DatabaseEvent e) { if(e instanceof GroupMessageAddedEvent) { Group g = ((GroupMessageAddedEvent) e).getGroup(); @@ -258,12 +284,15 @@ implements OnClickListener, DatabaseListener, NoGroupsDialog.Listener { try { serviceConnection.waitForStartup(); long now = System.currentTimeMillis(); + boolean postable; + if(restricted) postable = db.getLocalGroups().contains(g); + else postable = true; Collection headers = db.getMessageHeaders(g.getId()); long duration = System.currentTimeMillis() - now; if(LOG.isLoggable(INFO)) LOG.info("Partial load took " + duration + " ms"); - displayHeaders(g, headers); + displayHeaders(g, postable, headers); } catch(NoSuchSubscriptionException e) { if(LOG.isLoggable(INFO)) LOG.info("Subscription removed"); removeGroup(g.getId()); @@ -306,8 +335,13 @@ implements OnClickListener, DatabaseListener, NoGroupsDialog.Listener { private static final GroupComparator INSTANCE = new GroupComparator(); public int compare(GroupListItem a, GroupListItem b) { - return String.CASE_INSENSITIVE_ORDER.compare(a.getGroupName(), - b.getGroupName()); + // 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.getGroupName(), bName = b.getGroupName(); + return String.CASE_INSENSITIVE_ORDER.compare(aName, bName); } } } \ No newline at end of file diff --git a/briar-android/src/net/sf/briar/android/groups/GroupListAdapter.java b/briar-android/src/net/sf/briar/android/groups/GroupListAdapter.java index 87b36a1e6..0fd73a29a 100644 --- a/briar-android/src/net/sf/briar/android/groups/GroupListAdapter.java +++ b/briar-android/src/net/sf/briar/android/groups/GroupListAdapter.java @@ -10,7 +10,6 @@ import java.util.ArrayList; import net.sf.briar.R; import net.sf.briar.android.widgets.HorizontalSpace; -import net.sf.briar.util.StringUtils; import android.content.Context; import android.content.Intent; import android.content.res.Resources; @@ -36,12 +35,12 @@ implements OnItemClickListener { public View getView(int position, View convertView, ViewGroup parent) { GroupListItem item = getItem(position); Context ctx = getContext(); + Resources res = ctx.getResources(); + LinearLayout layout = new LinearLayout(ctx); layout.setOrientation(HORIZONTAL); - if(item.getUnreadCount() > 0) { - Resources res = ctx.getResources(); + if(item.getUnreadCount() > 0) layout.setBackgroundColor(res.getColor(R.color.unread_background)); - } LinearLayout innerLayout = new LinearLayout(ctx); // Give me all the unused width @@ -57,34 +56,43 @@ implements OnItemClickListener { else name.setText(item.getGroupName()); innerLayout.addView(name); - if(item.getContentType().equals("text/plain")) { - if(!StringUtils.isNullOrEmpty(item.getSubject())) { + if(item.isEmpty()) { + TextView noPosts = new TextView(ctx); + noPosts.setTextSize(14); + noPosts.setPadding(10, 0, 10, 10); + noPosts.setTextColor(res.getColor(R.color.no_posts)); + noPosts.setText(R.string.no_posts); + innerLayout.addView(noPosts); + layout.addView(innerLayout); + } else { + if(item.getContentType().equals("text/plain")) { TextView subject = new TextView(ctx); subject.setTextSize(14); subject.setMaxLines(2); subject.setPadding(10, 0, 10, 10); if(item.getUnreadCount() > 0) subject.setTypeface(null, BOLD); - subject.setText(item.getSubject()); + String s = item.getSubject(); + subject.setText(s == null ? "" : s); innerLayout.addView(subject); + } else { + LinearLayout attachmentLayout = new LinearLayout(ctx); + attachmentLayout.setOrientation(HORIZONTAL); + ImageView attachment = new ImageView(ctx); + attachment.setPadding(10, 0, 10, 10); + attachment.setImageResource(R.drawable.content_attachment); + attachmentLayout.addView(attachment); + attachmentLayout.addView(new HorizontalSpace(ctx)); + innerLayout.addView(attachmentLayout); } - } else { - LinearLayout attachmentLayout = new LinearLayout(ctx); - attachmentLayout.setOrientation(HORIZONTAL); - ImageView attachment = new ImageView(ctx); - attachment.setPadding(10, 0, 10, 10); - attachment.setImageResource(R.drawable.content_attachment); - attachmentLayout.addView(attachment); - attachmentLayout.addView(new HorizontalSpace(ctx)); - innerLayout.addView(attachmentLayout); - } - layout.addView(innerLayout); + layout.addView(innerLayout); - TextView date = new TextView(ctx); - date.setTextSize(14); - date.setPadding(0, 10, 10, 10); - long then = item.getTimestamp(), now = System.currentTimeMillis(); - date.setText(DateUtils.formatSameDayTime(then, now, SHORT, SHORT)); - layout.addView(date); + TextView date = new TextView(ctx); + date.setTextSize(14); + date.setPadding(0, 10, 10, 10); + long then = item.getTimestamp(), now = System.currentTimeMillis(); + date.setText(DateUtils.formatSameDayTime(then, now, SHORT, SHORT)); + layout.addView(date); + } return layout; } @@ -93,6 +101,7 @@ implements OnItemClickListener { long id) { GroupListItem item = getItem(position); Intent i = new Intent(getContext(), GroupActivity.class); + i.putExtra("net.sf.briar.RESTRICTED", item.isRestricted()); i.putExtra("net.sf.briar.GROUP_ID", item.getGroupId().getBytes()); i.putExtra("net.sf.briar.GROUP_NAME", item.getGroupName()); getContext().startActivity(i); diff --git a/briar-android/src/net/sf/briar/android/groups/GroupListItem.java b/briar-android/src/net/sf/briar/android/groups/GroupListItem.java index 6302b5153..abc61370d 100644 --- a/briar-android/src/net/sf/briar/android/groups/GroupListItem.java +++ b/briar-android/src/net/sf/briar/android/groups/GroupListItem.java @@ -1,5 +1,7 @@ package net.sf.briar.android.groups; +import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.List; @@ -12,24 +14,37 @@ import net.sf.briar.api.messaging.GroupId; class GroupListItem { private final Group group; + private final boolean postable, empty; private final String authorName, contentType, subject; private final long timestamp; private final int unread; - GroupListItem(Group group, List headers) { - if(headers.isEmpty()) throw new IllegalArgumentException(); + GroupListItem(Group group, boolean postable, + Collection headers) { this.group = group; - Collections.sort(headers, DescendingHeaderComparator.INSTANCE); - GroupMessageHeader newest = headers.get(0); - Author a = newest.getAuthor(); - if(a == null) authorName = null; - else authorName = a.getName(); - contentType = newest.getContentType(); - subject = newest.getSubject(); - timestamp = newest.getTimestamp(); - int unread = 0; - for(GroupMessageHeader h : headers) if(!h.isRead()) unread++; - this.unread = unread; + this.postable = postable; + empty = headers.isEmpty(); + if(empty) { + authorName = null; + contentType = null; + subject = null; + timestamp = 0; + unread = 0; + } else { + List list = + new ArrayList(headers); + Collections.sort(list, DescendingHeaderComparator.INSTANCE); + GroupMessageHeader newest = list.get(0); + Author a = newest.getAuthor(); + if(a == null) authorName = null; + else authorName = a.getName(); + contentType = newest.getContentType(); + subject = newest.getSubject(); + timestamp = newest.getTimestamp(); + int unread = 0; + for(GroupMessageHeader h : list) if(!h.isRead()) unread++; + this.unread = unread; + } } GroupId getGroupId() { @@ -40,6 +55,18 @@ class GroupListItem { return group.getName(); } + boolean isRestricted() { + return group.isRestricted(); + } + + boolean isPostable() { + return postable; + } + + boolean isEmpty() { + return empty; + } + String getAuthorName() { return authorName; } diff --git a/briar-android/src/net/sf/briar/android/groups/ReadGroupMessageActivity.java b/briar-android/src/net/sf/briar/android/groups/ReadGroupMessageActivity.java index 14b138061..cce96dde7 100644 --- a/briar-android/src/net/sf/briar/android/groups/ReadGroupMessageActivity.java +++ b/briar-android/src/net/sf/briar/android/groups/ReadGroupMessageActivity.java @@ -150,7 +150,6 @@ implements OnClickListener { author.setTextColor(res.getColor(R.color.anonymous_author)); author.setText(R.string.anonymous); } else { - author.setTextColor(res.getColor(R.color.pseudonymous_author)); author.setText(authorName); } header.addView(author); diff --git a/briar-android/src/net/sf/briar/android/messages/ConversationAdapter.java b/briar-android/src/net/sf/briar/android/messages/ConversationAdapter.java index 92e98c143..7094b77ed 100644 --- a/briar-android/src/net/sf/briar/android/messages/ConversationAdapter.java +++ b/briar-android/src/net/sf/briar/android/messages/ConversationAdapter.java @@ -11,7 +11,6 @@ import java.util.ArrayList; import net.sf.briar.R; import net.sf.briar.android.widgets.HorizontalSpace; import net.sf.briar.api.db.PrivateMessageHeader; -import net.sf.briar.util.StringUtils; import android.content.Context; import android.content.res.Resources; import android.text.format.DateUtils; @@ -65,15 +64,14 @@ class ConversationAdapter extends ArrayAdapter { innerLayout.addView(name); if(item.getContentType().equals("text/plain")) { - if(!StringUtils.isNullOrEmpty(item.getSubject())) { - TextView subject = new TextView(ctx); - subject.setTextSize(14); - subject.setMaxLines(2); - subject.setPadding(10, 0, 10, 10); - if(!item.isRead()) subject.setTypeface(null, BOLD); - subject.setText(item.getSubject()); - innerLayout.addView(subject); - } + TextView subject = new TextView(ctx); + subject.setTextSize(14); + subject.setMaxLines(2); + subject.setPadding(10, 0, 10, 10); + if(!item.isRead()) subject.setTypeface(null, BOLD); + String s = item.getSubject(); + subject.setText(s == null ? "" : s); + innerLayout.addView(subject); } else { LinearLayout attachmentLayout = new LinearLayout(ctx); attachmentLayout.setOrientation(HORIZONTAL); diff --git a/briar-android/src/net/sf/briar/android/messages/ConversationListActivity.java b/briar-android/src/net/sf/briar/android/messages/ConversationListActivity.java index 0e8f50293..746552eee 100644 --- a/briar-android/src/net/sf/briar/android/messages/ConversationListActivity.java +++ b/briar-android/src/net/sf/briar/android/messages/ConversationListActivity.java @@ -7,10 +7,8 @@ import static java.util.logging.Level.WARNING; import static net.sf.briar.android.widgets.CommonLayoutParams.MATCH_MATCH; import static net.sf.briar.android.widgets.CommonLayoutParams.MATCH_WRAP_1; -import java.util.ArrayList; import java.util.Collection; import java.util.Comparator; -import java.util.List; import java.util.concurrent.Executor; import java.util.logging.Logger; @@ -57,7 +55,6 @@ implements OnClickListener, DatabaseListener, NoContactsDialog.Listener { // Fields that are accessed from background threads must be volatile @Inject private volatile DatabaseComponent db; @Inject @DatabaseUiExecutor private volatile Executor dbUiExecutor; - private volatile boolean noContacts = true; @Override public void onCreate(Bundle state) { @@ -101,18 +98,12 @@ implements OnClickListener, DatabaseListener, NoContactsDialog.Listener { dbUiExecutor.execute(new Runnable() { public void run() { try { - // Wait for the service to be bound and started serviceConnection.waitForStartup(); - // Load the contact list from the database long now = System.currentTimeMillis(); - Collection contacts = db.getContacts(); - noContacts = contacts.isEmpty(); - for(Contact c : contacts) { + for(Contact c : db.getContacts()) { try { - // Load the headers from the database Collection headers = db.getPrivateMessageHeaders(c.getId()); - // Display the headers in the UI displayHeaders(c, headers); } catch(NoSuchContactException e) { if(LOG.isLoggable(INFO)) @@ -141,13 +132,9 @@ implements OnClickListener, DatabaseListener, NoContactsDialog.Listener { // Remove the old item, if any ConversationListItem item = findConversation(c.getId()); if(item != null) adapter.remove(item); - // Add a new item if there are any headers to display - if(!headers.isEmpty()) { - List headerList = - new ArrayList(headers); - adapter.add(new ConversationListItem(c, headerList)); - adapter.sort(ConversationComparator.INSTANCE); - } + // Add a new item + adapter.add(new ConversationListItem(c, headers)); + adapter.sort(ConversationComparator.INSTANCE); adapter.notifyDataSetChanged(); selectFirstUnread(); } @@ -188,7 +175,7 @@ implements OnClickListener, DatabaseListener, NoContactsDialog.Listener { } public void onClick(View view) { - if(noContacts) { + if(adapter.isEmpty()) { NoContactsDialog dialog = new NoContactsDialog(); dialog.setListener(this); dialog.show(getSupportFragmentManager(), "NoContactsDialog"); @@ -270,7 +257,9 @@ implements OnClickListener, DatabaseListener, NoContactsDialog.Listener { long aTime = a.getTimestamp(), bTime = b.getTimestamp(); if(aTime > bTime) return -1; if(aTime < bTime) return 1; - return 0; + // Break ties by contact name + String aName = a.getContactName(), bName = b.getContactName(); + return String.CASE_INSENSITIVE_ORDER.compare(aName, bName); } } } diff --git a/briar-android/src/net/sf/briar/android/messages/ConversationListAdapter.java b/briar-android/src/net/sf/briar/android/messages/ConversationListAdapter.java index 442c4a293..80431fa55 100644 --- a/briar-android/src/net/sf/briar/android/messages/ConversationListAdapter.java +++ b/briar-android/src/net/sf/briar/android/messages/ConversationListAdapter.java @@ -10,7 +10,6 @@ import static net.sf.briar.android.widgets.CommonLayoutParams.WRAP_WRAP_1; import java.util.ArrayList; import net.sf.briar.R; -import net.sf.briar.util.StringUtils; import android.content.Context; import android.content.Intent; import android.content.res.Resources; @@ -35,12 +34,12 @@ implements OnItemClickListener { public View getView(int position, View convertView, ViewGroup parent) { ConversationListItem item = getItem(position); Context ctx = getContext(); + Resources res = ctx.getResources(); + LinearLayout layout = new LinearLayout(ctx); layout.setOrientation(HORIZONTAL); - if(item.getUnreadCount() > 0) { - Resources res = ctx.getResources(); + if(item.getUnreadCount() > 0) layout.setBackgroundColor(res.getColor(R.color.unread_background)); - } LinearLayout innerLayout = new LinearLayout(ctx); // Give me all the unused width @@ -58,23 +57,32 @@ implements OnItemClickListener { else name.setText(contactName); innerLayout.addView(name); - if(!StringUtils.isNullOrEmpty(item.getSubject())) { + if(item.isEmpty()) { + TextView noMessages = new TextView(ctx); + noMessages.setTextSize(14); + noMessages.setPadding(10, 0, 10, 10); + noMessages.setTextColor(res.getColor(R.color.no_messages)); + noMessages.setText(R.string.no_messages); + innerLayout.addView(noMessages); + layout.addView(innerLayout); + } else { TextView subject = new TextView(ctx); subject.setTextSize(14); subject.setMaxLines(2); subject.setPadding(10, 0, 10, 10); if(unread > 0) subject.setTypeface(null, BOLD); - subject.setText(item.getSubject()); + String s = item.getSubject(); + subject.setText(s == null ? "" : s); innerLayout.addView(subject); - } - layout.addView(innerLayout); + layout.addView(innerLayout); - TextView date = new TextView(ctx); - date.setTextSize(14); - date.setPadding(0, 10, 10, 10); - long then = item.getTimestamp(), now = System.currentTimeMillis(); - date.setText(DateUtils.formatSameDayTime(then, now, SHORT, SHORT)); - layout.addView(date); + TextView date = new TextView(ctx); + date.setTextSize(14); + date.setPadding(0, 10, 10, 10); + long then = item.getTimestamp(), now = System.currentTimeMillis(); + date.setText(DateUtils.formatSameDayTime(then, now, SHORT, SHORT)); + layout.addView(date); + } return layout; } diff --git a/briar-android/src/net/sf/briar/android/messages/ConversationListItem.java b/briar-android/src/net/sf/briar/android/messages/ConversationListItem.java index f7ffc36f8..52a3dcb87 100644 --- a/briar-android/src/net/sf/briar/android/messages/ConversationListItem.java +++ b/briar-android/src/net/sf/briar/android/messages/ConversationListItem.java @@ -1,5 +1,7 @@ package net.sf.briar.android.messages; +import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.List; @@ -12,19 +14,29 @@ import net.sf.briar.api.db.PrivateMessageHeader; class ConversationListItem { private final Contact contact; + private final boolean empty; private final String subject; private final long timestamp; private final int unread; - ConversationListItem(Contact contact, List headers) { - if(headers.isEmpty()) throw new IllegalArgumentException(); + ConversationListItem(Contact contact, + Collection headers) { this.contact = contact; - Collections.sort(headers, DescendingHeaderComparator.INSTANCE); - subject = headers.get(0).getSubject(); - timestamp = headers.get(0).getTimestamp(); - int unread = 0; - for(PrivateMessageHeader h : headers) if(!h.isRead()) unread++; - this.unread = unread; + empty = headers.isEmpty(); + if(empty) { + subject = null; + timestamp = 0; + unread = 0; + } else { + List list = + new ArrayList(headers); + Collections.sort(list, DescendingHeaderComparator.INSTANCE); + subject = list.get(0).getSubject(); + timestamp = list.get(0).getTimestamp(); + int unread = 0; + for(PrivateMessageHeader h : list) if(!h.isRead()) unread++; + this.unread = unread; + } } ContactId getContactId() { @@ -39,6 +51,10 @@ class ConversationListItem { return contact.getLocalAuthorId(); } + boolean isEmpty() { + return empty; + } + String getSubject() { return subject; }