From 027b3cd33ab6994e18fdee06befd920c64bd0620 Mon Sep 17 00:00:00 2001
From: Torsten Grote <t@grobox.de>
Date: Thu, 31 Dec 2015 11:38:37 -0200
Subject: [PATCH] Fix contacts duplicating itself when pressing back button in
 conversation view

This is done by update existing items rather than just adding them,
because different timestamps in added items change the sorting criteria
and cause duplicates in the SortedList.

Closes #200
---
 .../android/contact/ContactListActivity.java  | 17 ++++++++++++-
 .../android/contact/ContactListAdapter.java   | 25 ++++++++++++++++---
 2 files changed, 37 insertions(+), 5 deletions(-)

diff --git a/briar-android/src/org/briarproject/android/contact/ContactListActivity.java b/briar-android/src/org/briarproject/android/contact/ContactListActivity.java
index 7918832545..6817730efa 100644
--- a/briar-android/src/org/briarproject/android/contact/ContactListActivity.java
+++ b/briar-android/src/org/briarproject/android/contact/ContactListActivity.java
@@ -3,6 +3,7 @@ package org.briarproject.android.contact;
 import android.content.Intent;
 import android.os.Bundle;
 import android.support.design.widget.FloatingActionButton;
+import android.support.v7.util.SortedList;
 import android.support.v7.widget.LinearLayoutManager;
 import android.view.View;
 
@@ -134,7 +135,21 @@ public class ContactListActivity extends BriarActivity
 		runOnUiThread(new Runnable() {
 			public void run() {
 				if (contacts.size() > 0) {
-					adapter.addAll(contacts);
+					if (adapter.getItemCount() > 0) {
+						// update existing items rather than just adding them,
+						// because different timestamps in added items change
+						// sorting criteria and cause duplicates
+						for (ContactListItem contact : contacts) {
+							int position = adapter.findItemPosition(contact);
+							if (position == SortedList.INVALID_POSITION) {
+								adapter.add(contact);
+							} else {
+								adapter.updateItem(position, contact);
+							}
+						}
+					} else {
+						adapter.addAll(contacts);
+					}
 				} else {
 					// no contacts to display, make sure progress bar is hidden
 					list.showData();
diff --git a/briar-android/src/org/briarproject/android/contact/ContactListAdapter.java b/briar-android/src/org/briarproject/android/contact/ContactListAdapter.java
index 2abe5e6ffc..970461d708 100644
--- a/briar-android/src/org/briarproject/android/contact/ContactListAdapter.java
+++ b/briar-android/src/org/briarproject/android/contact/ContactListAdapter.java
@@ -60,13 +60,25 @@ public class ContactListAdapter
 						@Override
 						public boolean areItemsTheSame(ContactListItem c1,
 								ContactListItem c2) {
-							return c1.getContact().getId().equals(c2.getContact().getId());
+							return c1.getContact().getId()
+									.equals(c2.getContact().getId());
 						}
 
 						@Override
 						public boolean areContentsTheSame(ContactListItem c1,
 								ContactListItem c2) {
-							return c1.equals(c2);
+							// check for all properties that influence visual
+							// representation of contact
+							if (c1.isConnected() != c2.isConnected()) {
+								return false;
+							}
+							if (c1.getUnreadCount() != c2.getUnreadCount()) {
+								return false;
+							}
+							if (c1.getTimestamp() != c2.getTimestamp()) {
+								return false;
+							}
+							return true;
 						}
 					});
 	private Context ctx;
@@ -144,7 +156,8 @@ public class ContactListAdapter
 	}
 
 	public ContactListItem getItem(int position) {
-		if (position == -1 || contacts.size() <= position) {
+		if (position == SortedList.INVALID_POSITION ||
+				contacts.size() <= position) {
 			return null; // Not found
 		}
 		return contacts.get(position);
@@ -163,13 +176,17 @@ public class ContactListAdapter
 		return null; // Not found
 	}
 
+	public int findItemPosition(ContactListItem item) {
+		return contacts.indexOf(item);
+	}
+
 	public int findItemPosition(ContactId c) {
 		int count = getItemCount();
 		for (int i = 0; i < count; i++) {
 			ContactListItem item = getItem(i);
 			if (item.getContact().getId().equals(c)) return i;
 		}
-		return -1; // Not found
+		return SortedList.INVALID_POSITION; // Not found
 	}
 
 	public void addAll(final List<ContactListItem> contacts) {
-- 
GitLab