diff --git a/briar-android/AndroidManifest.xml b/briar-android/AndroidManifest.xml index 8dcdb7163d7ee18e4a19a2b196d4175e7ebc96f4..ba01be5bfcd1ad5e5581f9f0089c6eb7aaed7674 100644 --- a/briar-android/AndroidManifest.xml +++ b/briar-android/AndroidManifest.xml @@ -40,6 +40,10 @@ android:name=".android.invitation.AddContactActivity" android:label="@string/add_contact_title" > </activity> + <activity + android:name=".android.messages.ConversationActivity" + android:label="@string/messages_title" > + </activity> <activity android:name=".android.messages.ConversationListActivity" android:label="@string/messages_title" > diff --git a/briar-android/res/values/strings.xml b/briar-android/res/values/strings.xml index 79236a39603272358460928e4e20ae5da0d13a27..df481efc4dd7d18c1cdef0b7fddb741de288109a 100644 --- a/briar-android/res/values/strings.xml +++ b/briar-android/res/values/strings.xml @@ -11,8 +11,9 @@ <string name="quit_button">Quit</string> <string name="contact_list_title">Contacts</string> <string name="contact_connected">Connected</string> - <string name="contact_last_connected">Last connected <br /> %s</string> + <string name="contact_last_connected">Last connected <br /> %1$s</string> <string name="add_contact_button">New Contact</string> + <string name="search_button">Search</string> <string name="add_contact_title">Add a Contact</string> <string name="same_network">Briar can add contacts via Wi-Fi or Bluetooth. For security reasons, you must be face-to-face to add someone as a contact. To use Wi-Fi you must both be connected to the same network.</string> <string name="wifi_not_available">Wi-Fi is not available on this device</string> @@ -39,7 +40,7 @@ <string name="interfering">This could mean that someone is trying to interfere with your connection.</string> <string name="contact_added">Contact added</string> <string name="enter_nickname">Please enter a nickname for this contact:</string> + <string name="done_button">Done</string> <string name="messages_title">Messages</string> <string name="compose_button">New Message</string> - <string name="done_button">Done</string> </resources> diff --git a/briar-android/src/net/sf/briar/android/contact/ContactComparator.java b/briar-android/src/net/sf/briar/android/contact/ContactComparator.java new file mode 100644 index 0000000000000000000000000000000000000000..6495bf631051e67b2e2f1d23f5e77da4844c8735 --- /dev/null +++ b/briar-android/src/net/sf/briar/android/contact/ContactComparator.java @@ -0,0 +1,13 @@ +package net.sf.briar.android.contact; + +import java.util.Comparator; + +class ContactComparator implements Comparator<ContactListItem> { + + static final ContactComparator INSTANCE = new ContactComparator(); + + public int compare(ContactListItem a, ContactListItem b) { + return String.CASE_INSENSITIVE_ORDER.compare(a.contact.getName(), + b.contact.getName()); + } +} \ No newline at end of file diff --git a/briar-android/src/net/sf/briar/android/contact/ContactListActivity.java b/briar-android/src/net/sf/briar/android/contact/ContactListActivity.java index c1c00ad104d34f4a92a6225a589e210d357681b2..a6e7e3f32133dbf091c4b20b71f13534e019b6e1 100644 --- a/briar-android/src/net/sf/briar/android/contact/ContactListActivity.java +++ b/briar-android/src/net/sf/briar/android/contact/ContactListActivity.java @@ -31,7 +31,6 @@ import android.content.Intent; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; -import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.LinearLayout; import android.widget.LinearLayout.LayoutParams; @@ -52,7 +51,7 @@ implements OnClickListener, DatabaseListener, ConnectionListener { @Inject @DatabaseExecutor private Executor dbExecutor; @Inject private ConnectionRegistry connectionRegistry; - private ArrayAdapter<ContactListItem> adapter = null; + private ContactListAdapter adapter = null; @Override public void onCreate(Bundle state) { @@ -67,6 +66,7 @@ implements OnClickListener, DatabaseListener, ConnectionListener { // Give me all the width and all the unused height list.setLayoutParams(new LayoutParams(MATCH_PARENT, WRAP_CONTENT, 1f)); list.setAdapter(adapter); + list.setOnItemClickListener(adapter); layout.addView(list); Button addContactButton = new Button(this); @@ -167,7 +167,7 @@ implements OnClickListener, DatabaseListener, ConnectionListener { boolean conn = connectionRegistry.isConnected(c.getId()); adapter.add(new ContactListItem(c, conn)); } - adapter.sort(ContactListItem.COMPARATOR); + adapter.sort(ContactComparator.INSTANCE); } }); } diff --git a/briar-android/src/net/sf/briar/android/contact/ContactListAdapter.java b/briar-android/src/net/sf/briar/android/contact/ContactListAdapter.java index 1849d60ede19774a6eab6c344d97a04a568bcd9f..1521492c9360d2e3ab9f9433c74a2eb36633f578 100644 --- a/briar-android/src/net/sf/briar/android/contact/ContactListAdapter.java +++ b/briar-android/src/net/sf/briar/android/contact/ContactListAdapter.java @@ -8,17 +8,21 @@ import java.util.ArrayList; import net.sf.briar.R; import android.content.Context; +import android.content.res.Resources; import android.text.Html; import android.text.format.DateUtils; import android.view.View; import android.view.ViewGroup; +import android.widget.AdapterView; +import android.widget.AdapterView.OnItemClickListener; import android.widget.ArrayAdapter; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.LinearLayout.LayoutParams; import android.widget.TextView; -class ContactListAdapter extends ArrayAdapter<ContactListItem> { +class ContactListAdapter extends ArrayAdapter<ContactListItem> +implements OnItemClickListener { ContactListAdapter(Context ctx) { super(ctx, android.R.layout.simple_expandable_list_item_1, @@ -47,13 +51,13 @@ class ContactListAdapter extends ArrayAdapter<ContactListItem> { layout.addView(name); TextView connected = new TextView(ctx); - connected.setTextSize(12); + connected.setTextSize(14); connected.setPadding(5, 0, 5, 0); if(item.isConnected()) { connected.setText(R.string.contact_connected); } else { - String format = ctx.getResources().getString( - R.string.contact_last_connected); + Resources res = ctx.getResources(); + String format = res.getString(R.string.contact_last_connected); long then = item.getLastConnected(); CharSequence ago = DateUtils.getRelativeTimeSpanString(then); connected.setText(Html.fromHtml(String.format(format, ago))); @@ -62,4 +66,9 @@ class ContactListAdapter extends ArrayAdapter<ContactListItem> { return layout; } + + public void onItemClick(AdapterView<?> parent, View view, int position, + long id) { + // FIXME: Hook this up to an activity + } } diff --git a/briar-android/src/net/sf/briar/android/contact/ContactListItem.java b/briar-android/src/net/sf/briar/android/contact/ContactListItem.java index 47747e3a1bc267c2e85d4aace6af8129294f2766..cba805e863df13b0d69393146c8559d9b6c836d2 100644 --- a/briar-android/src/net/sf/briar/android/contact/ContactListItem.java +++ b/briar-android/src/net/sf/briar/android/contact/ContactListItem.java @@ -1,16 +1,12 @@ package net.sf.briar.android.contact; -import java.util.Comparator; - import net.sf.briar.api.Contact; import net.sf.briar.api.ContactId; // This class is not thread-safe class ContactListItem { - static Comparator<ContactListItem> COMPARATOR = new ItemComparator(); - - private final Contact contact; + final Contact contact; private boolean connected; ContactListItem(Contact contact, boolean connected) { @@ -37,12 +33,4 @@ class ContactListItem { void setConnected(boolean connected) { this.connected = connected; } - - private static class ItemComparator implements Comparator<ContactListItem> { - - public int compare(ContactListItem a, ContactListItem b) { - return String.CASE_INSENSITIVE_ORDER.compare(a.contact.getName(), - b.contact.getName()); - } - } } \ No newline at end of file diff --git a/briar-android/src/net/sf/briar/android/messages/AscendingHeaderComparator.java b/briar-android/src/net/sf/briar/android/messages/AscendingHeaderComparator.java new file mode 100644 index 0000000000000000000000000000000000000000..651f719bea7206758654ad6febe2224df33e182d --- /dev/null +++ b/briar-android/src/net/sf/briar/android/messages/AscendingHeaderComparator.java @@ -0,0 +1,19 @@ +package net.sf.briar.android.messages; + +import java.util.Comparator; + +import net.sf.briar.api.db.PrivateMessageHeader; + +class AscendingHeaderComparator implements Comparator<PrivateMessageHeader> { + + static final AscendingHeaderComparator INSTANCE = + new AscendingHeaderComparator(); + + public int compare(PrivateMessageHeader a, PrivateMessageHeader 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/net/sf/briar/android/messages/ConversationActivity.java b/briar-android/src/net/sf/briar/android/messages/ConversationActivity.java new file mode 100644 index 0000000000000000000000000000000000000000..1782a6ceb140bbf2a43498805fe559e2681a06f3 --- /dev/null +++ b/briar-android/src/net/sf/briar/android/messages/ConversationActivity.java @@ -0,0 +1,156 @@ +package net.sf.briar.android.messages; + +import static android.view.Gravity.CENTER_HORIZONTAL; +import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; +import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT; +import static android.widget.LinearLayout.VERTICAL; +import static java.util.logging.Level.INFO; +import static java.util.logging.Level.WARNING; + +import java.util.Collection; +import java.util.concurrent.Executor; +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.BriarService.BriarServiceConnection; +import net.sf.briar.api.ContactId; +import net.sf.briar.api.db.DatabaseComponent; +import net.sf.briar.api.db.DatabaseExecutor; +import net.sf.briar.api.db.DbException; +import net.sf.briar.api.db.PrivateMessageHeader; +import net.sf.briar.api.db.event.DatabaseEvent; +import net.sf.briar.api.db.event.DatabaseListener; +import net.sf.briar.api.db.event.MessageAddedEvent; +import net.sf.briar.api.db.event.MessageExpiredEvent; +import android.content.Intent; +import android.os.Bundle; +import android.view.View; +import android.view.View.OnClickListener; +import android.widget.Button; +import android.widget.LinearLayout; +import android.widget.LinearLayout.LayoutParams; +import android.widget.ListView; + +import com.google.inject.Inject; + +public class ConversationActivity extends BriarActivity +implements OnClickListener, DatabaseListener { + + private static final Logger LOG = + Logger.getLogger(ConversationActivity.class.getName()); + + private final BriarServiceConnection serviceConnection = + new BriarServiceConnection(); + + @Inject private DatabaseComponent db; + @Inject @DatabaseExecutor private Executor dbExecutor; + + private ContactId contactId = null; + private ConversationAdapter adapter = null; + + @Override + public void onCreate(Bundle state) { + super.onCreate(null); + + Intent i = getIntent(); + int id = i.getIntExtra("net.sf.briar.CONTACT_ID", -1); + if(id == -1) throw new IllegalStateException(); + contactId = new ContactId(id); + String contactName = i.getStringExtra("net.sf.briar.CONTACT_NAME"); + if(contactName == null) throw new IllegalStateException(); + setTitle(contactName); + + LinearLayout layout = new LinearLayout(this); + layout.setLayoutParams(new LayoutParams(MATCH_PARENT, MATCH_PARENT)); + layout.setOrientation(VERTICAL); + layout.setGravity(CENTER_HORIZONTAL); + + adapter = new ConversationAdapter(this); + ListView list = new ListView(this); + // Give me all the width and all the unused height + list.setLayoutParams(new LayoutParams(MATCH_PARENT, WRAP_CONTENT, 1f)); + list.setAdapter(adapter); + list.setOnItemClickListener(adapter); + layout.addView(list); + + Button composeButton = new Button(this); + composeButton.setBackgroundResource(0); + composeButton.setLayoutParams(new LayoutParams(MATCH_PARENT, + WRAP_CONTENT)); + composeButton.setCompoundDrawablesWithIntrinsicBounds(0, + R.drawable.content_new_email, 0, 0); + composeButton.setText(R.string.compose_button); + composeButton.setOnClickListener(this); + layout.addView(composeButton); + + setContentView(layout); + + // Listen for messages being added or removed + db.addListener(this); + // Bind to the service so we can wait for the DB to be opened + bindService(new Intent(BriarService.class.getName()), + serviceConnection, 0); + // Load the message headers from the DB + reloadMessageHeaders(); + } + + @Override + public void onDestroy() { + super.onDestroy(); + db.removeListener(this); + unbindService(serviceConnection); + } + + public void onClick(View view) { + // FIXME: Hook this button up to an activity + } + + public void eventOccurred(DatabaseEvent e) { + if(e instanceof MessageAddedEvent) { + if(LOG.isLoggable(INFO)) LOG.info("Message added, reloading"); + reloadMessageHeaders(); + } else if(e instanceof MessageExpiredEvent) { + if(LOG.isLoggable(INFO)) LOG.info("Message removed, reloading"); + reloadMessageHeaders(); + } + } + + private void reloadMessageHeaders() { + dbExecutor.execute(new Runnable() { + public void run() { + try { + // Wait for the service to be bound and started + serviceConnection.waitForStartup(); + // Load the message headers from the database + Collection<PrivateMessageHeader> headers = + db.getPrivateMessageHeaders(); + if(LOG.isLoggable(INFO)) + LOG.info("Loaded " + headers.size() + " headers"); + // Update the conversation + updateConversation(headers); + } catch(DbException e) { + if(LOG.isLoggable(WARNING)) + LOG.log(WARNING, e.toString(), e); + } catch(InterruptedException e) { + if(LOG.isLoggable(INFO)) + LOG.info("Interrupted while waiting for service"); + Thread.currentThread().interrupt(); + } + } + }); + } + + private void updateConversation( + final Collection<PrivateMessageHeader> headers) { + runOnUiThread(new Runnable() { + public void run() { + adapter.clear(); + for(PrivateMessageHeader h : headers) + if(h.getContactId().equals(contactId)) adapter.add(h); + adapter.sort(AscendingHeaderComparator.INSTANCE); + } + }); + } +} diff --git a/briar-android/src/net/sf/briar/android/messages/ConversationAdapter.java b/briar-android/src/net/sf/briar/android/messages/ConversationAdapter.java new file mode 100644 index 0000000000000000000000000000000000000000..6720b08dd7c683b6f5c71c465ddee6283fe59877 --- /dev/null +++ b/briar-android/src/net/sf/briar/android/messages/ConversationAdapter.java @@ -0,0 +1,71 @@ +package net.sf.briar.android.messages; + +import static android.graphics.Typeface.BOLD; +import static android.view.Gravity.CENTER; +import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT; +import static android.widget.LinearLayout.HORIZONTAL; +import static java.text.DateFormat.SHORT; + +import java.util.ArrayList; + +import net.sf.briar.R; +import net.sf.briar.api.db.PrivateMessageHeader; +import android.content.Context; +import android.text.format.DateUtils; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AdapterView; +import android.widget.AdapterView.OnItemClickListener; +import android.widget.ArrayAdapter; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.LinearLayout.LayoutParams; +import android.widget.TextView; + +class ConversationAdapter extends ArrayAdapter<PrivateMessageHeader> +implements OnItemClickListener { + + ConversationAdapter(Context ctx) { + super(ctx, android.R.layout.simple_expandable_list_item_1, + new ArrayList<PrivateMessageHeader>()); + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + PrivateMessageHeader item = getItem(position); + Context ctx = getContext(); + LinearLayout layout = new LinearLayout(ctx); + layout.setOrientation(HORIZONTAL); + layout.setGravity(CENTER); + + ImageView star = new ImageView(ctx); + star.setPadding(5, 5, 5, 5); + if(item.getStarred()) + star.setImageResource(R.drawable.rating_important); + else star.setImageResource(R.drawable.rating_not_important); + layout.addView(star); + + TextView subject = new TextView(ctx); + // Give me all the unused width + subject.setLayoutParams(new LayoutParams(WRAP_CONTENT, WRAP_CONTENT, + 1)); + subject.setTextSize(14); + if(!item.getRead()) subject.setTypeface(null, BOLD); + subject.setText(item.getSubject()); + layout.addView(subject); + + TextView date = new TextView(ctx); + date.setTextSize(14); + date.setPadding(5, 0, 10, 0); + long then = item.getTimestamp(), now = System.currentTimeMillis(); + date.setText(DateUtils.formatSameDayTime(then, now, SHORT, SHORT)); + layout.addView(date); + + return layout; + } + + public void onItemClick(AdapterView<?> parent, View view, int position, + long id) { + // FIXME + } +} diff --git a/briar-android/src/net/sf/briar/android/messages/ConversationComparator.java b/briar-android/src/net/sf/briar/android/messages/ConversationComparator.java new file mode 100644 index 0000000000000000000000000000000000000000..fcf0b179991c325eb1ed87942245f9d9a0d57824 --- /dev/null +++ b/briar-android/src/net/sf/briar/android/messages/ConversationComparator.java @@ -0,0 +1,16 @@ +package net.sf.briar.android.messages; + +import java.util.Comparator; + +class ConversationComparator implements Comparator<ConversationListItem> { + + static final ConversationComparator INSTANCE = new ConversationComparator(); + + public int compare(ConversationListItem a, ConversationListItem b) { + // 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; + return 0; + } +} \ No newline at end of file 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 ebdd646567003bb92e480ae5547e49a7e1059dbf..9188d61770359bd36a30c8e69fbf261fdb639c2f 100644 --- a/briar-android/src/net/sf/briar/android/messages/ConversationListActivity.java +++ b/briar-android/src/net/sf/briar/android/messages/ConversationListActivity.java @@ -37,7 +37,6 @@ import android.content.Intent; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; -import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.LinearLayout; import android.widget.LinearLayout.LayoutParams; @@ -58,7 +57,7 @@ implements OnClickListener, DatabaseListener { @Inject @DatabaseExecutor private Executor dbExecutor; @Inject private MessageFactory messageFactory; - private ArrayAdapter<ConversationListItem> adapter = null; + private ConversationListAdapter adapter = null; @Override public void onCreate(Bundle state) { @@ -73,6 +72,7 @@ implements OnClickListener, DatabaseListener { // Give me all the width and all the unused height list.setLayoutParams(new LayoutParams(MATCH_PARENT, WRAP_CONTENT, 1f)); list.setAdapter(adapter); + list.setOnItemClickListener(adapter); layout.addView(list); Button composeButton = new Button(this); @@ -110,16 +110,23 @@ implements OnClickListener, DatabaseListener { LOG.info("Inserting fake contact and messages"); // Insert a fake contact ContactId contactId = db.addContact("Carol"); - // Insert some messages to the contact + // Insert some fake messages to and from the contact Message m = messageFactory.createPrivateMessage(null, - "First message's subject", + "First message's subject is quite long to test" + + " line wrapping and stuff like that", "First message's body".getBytes("UTF-8")); db.addLocalPrivateMessage(m, contactId); + db.setReadFlag(m.getId(), true); db.setStarredFlag(m.getId(), true); - Thread.sleep(2000); + Thread.sleep(1000); m = messageFactory.createPrivateMessage(m.getId(), - "Second message's subject", + "Second message's subject is short", "Second message's body".getBytes("UTF-8")); + db.receiveMessage(contactId, m); + Thread.sleep(1000); + m = messageFactory.createPrivateMessage(m.getId(), + "Third message's subject is also short", + "Third message's body".getBytes("UTF-8")); db.addLocalPrivateMessage(m, contactId); db.setReadFlag(m.getId(), true); } @@ -198,7 +205,7 @@ implements OnClickListener, DatabaseListener { adapter.clear(); for(ConversationListItem i : sortHeaders(contacts, headers)) adapter.add(i); - adapter.sort(ConversationListItem.COMPARATOR); + adapter.sort(ConversationComparator.INSTANCE); } }); } 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 f0ef7ec79ff4f41a1b4c1bf01caae5a464813c78..50a8a574a0084419cc82f1178bbee5a57084072e 100644 --- a/briar-android/src/net/sf/briar/android/messages/ConversationListAdapter.java +++ b/briar-android/src/net/sf/briar/android/messages/ConversationListAdapter.java @@ -12,16 +12,20 @@ import java.util.ArrayList; import net.sf.briar.R; import android.content.Context; +import android.content.Intent; import android.text.format.DateUtils; import android.view.View; import android.view.ViewGroup; +import android.widget.AdapterView; +import android.widget.AdapterView.OnItemClickListener; import android.widget.ArrayAdapter; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.LinearLayout.LayoutParams; import android.widget.TextView; -class ConversationListAdapter extends ArrayAdapter<ConversationListItem> { +class ConversationListAdapter extends ArrayAdapter<ConversationListItem> +implements OnItemClickListener { ConversationListAdapter(Context ctx) { super(ctx, android.R.layout.simple_expandable_list_item_1, @@ -72,4 +76,13 @@ class ConversationListAdapter extends ArrayAdapter<ConversationListItem> { return layout; } + + public void onItemClick(AdapterView<?> parent, View view, int position, + long id) { + ConversationListItem item = getItem(position); + Intent i = new Intent(getContext(), ConversationActivity.class); + i.putExtra("net.sf.briar.CONTACT_ID", item.getContactId().getInt()); + i.putExtra("net.sf.briar.CONTACT_NAME", item.getName()); + getContext().startActivity(i); + } } 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 711329ec3bfdb302121854bb4411f0c1899e0513..24b2e63a44c12544c84077da0a3d19a015820ba5 100644 --- a/briar-android/src/net/sf/briar/android/messages/ConversationListItem.java +++ b/briar-android/src/net/sf/briar/android/messages/ConversationListItem.java @@ -1,48 +1,51 @@ package net.sf.briar.android.messages; import java.util.Collections; -import java.util.Comparator; import java.util.List; import net.sf.briar.api.Contact; +import net.sf.briar.api.ContactId; import net.sf.briar.api.db.PrivateMessageHeader; class ConversationListItem { - static final Comparator<ConversationListItem> COMPARATOR = - new ItemComparator(); - - private static final Comparator<PrivateMessageHeader> HEADER_COMPARATOR = - new HeaderComparator(); - - private final Contact contact; - private final List<PrivateMessageHeader> headers; + private final ContactId contactId; + private final String name, subject; + private final long timestamp; + private final int length; private final boolean read, starred; ConversationListItem(Contact contact, List<PrivateMessageHeader> headers) { if(headers.isEmpty()) throw new IllegalArgumentException(); - Collections.sort(headers, HEADER_COMPARATOR); - boolean read = false, starred = false; + contactId = contact.getId(); + name = contact.getName(); + Collections.sort(headers, DescendingHeaderComparator.INSTANCE); + subject = headers.get(0).getSubject(); + timestamp = headers.get(0).getTimestamp(); + length = headers.size(); + boolean allRead = false, anyStarred = false; for(PrivateMessageHeader h : headers) { - read &= h.getRead(); - starred |= h.getStarred(); + allRead &= h.getRead(); + anyStarred |= h.getStarred(); } - this.contact = contact; - this.headers = headers; - this.read = read; - this.starred = starred; + read = allRead; + starred = anyStarred; + } + + ContactId getContactId() { + return contactId; } String getName() { - return contact.getName(); + return name; } String getSubject() { - return headers.get(0).getSubject(); + return subject; } long getTimestamp() { - return headers.get(0).getTimestamp(); + return timestamp; } boolean getRead() { @@ -54,28 +57,6 @@ class ConversationListItem { } int getLength() { - return headers.size(); - } - - private static class HeaderComparator - implements Comparator<PrivateMessageHeader> { - - public int compare(PrivateMessageHeader a, PrivateMessageHeader b) { - // The newest message comes first - long aTime = a.getTimestamp(), bTime = b.getTimestamp(); - if(aTime > bTime) return -1; - if(aTime < bTime) return 1; - return 0; - } - } - - private static class ItemComparator - implements Comparator<ConversationListItem> { - - public int compare(ConversationListItem a, ConversationListItem b) { - // The item with the newest message comes first - return HEADER_COMPARATOR.compare(a.headers.get(0), - b.headers.get(0)); - } + return length; } } diff --git a/briar-android/src/net/sf/briar/android/messages/DescendingHeaderComparator.java b/briar-android/src/net/sf/briar/android/messages/DescendingHeaderComparator.java new file mode 100644 index 0000000000000000000000000000000000000000..1a8032f0987bed60d75d76d15635734917175685 --- /dev/null +++ b/briar-android/src/net/sf/briar/android/messages/DescendingHeaderComparator.java @@ -0,0 +1,19 @@ +package net.sf.briar.android.messages; + +import java.util.Comparator; + +import net.sf.briar.api.db.PrivateMessageHeader; + +class DescendingHeaderComparator implements Comparator<PrivateMessageHeader> { + + static final DescendingHeaderComparator INSTANCE = + new DescendingHeaderComparator(); + + public int compare(PrivateMessageHeader a, PrivateMessageHeader b) { + // The newest message comes first + long aTime = a.getTimestamp(), bTime = b.getTimestamp(); + if(aTime > bTime) return -1; + if(aTime < bTime) return 1; + return 0; + } +} \ No newline at end of file