From 5754a3a177afb4b43c1211eb5edb1fd130dc829d Mon Sep 17 00:00:00 2001
From: Vavassor <copernicus-@hotmail.com>
Date: Thu, 13 Jul 2017 20:17:50 -0400
Subject: [PATCH] Fixes bug where the order of notifications could be jumbled
 when removing duplicates using a HashSet.

---
 .../com/keylesspalace/tusky/adapter/AccountAdapter.java  | 5 ++---
 .../tusky/adapter/NotificationsAdapter.java              | 7 +++----
 .../com/keylesspalace/tusky/adapter/TimelineAdapter.java | 7 +++----
 .../java/com/keylesspalace/tusky/util/ListUtils.java     | 9 +++++++++
 4 files changed, 17 insertions(+), 11 deletions(-)

diff --git a/app/src/main/java/com/keylesspalace/tusky/adapter/AccountAdapter.java b/app/src/main/java/com/keylesspalace/tusky/adapter/AccountAdapter.java
index b47b6777..699a33e3 100644
--- a/app/src/main/java/com/keylesspalace/tusky/adapter/AccountAdapter.java
+++ b/app/src/main/java/com/keylesspalace/tusky/adapter/AccountAdapter.java
@@ -20,9 +20,9 @@ import android.support.v7.widget.RecyclerView;
 
 import com.keylesspalace.tusky.entity.Account;
 import com.keylesspalace.tusky.interfaces.AccountActionListener;
+import com.keylesspalace.tusky.util.ListUtils;
 
 import java.util.ArrayList;
-import java.util.HashSet;
 import java.util.List;
 
 public abstract class AccountAdapter extends RecyclerView.Adapter {
@@ -57,8 +57,7 @@ public abstract class AccountAdapter extends RecyclerView.Adapter {
             topId = uptoId;
         }
         if (accountList.isEmpty()) {
-            // This construction removes duplicates.
-            accountList = new ArrayList<>(new HashSet<>(newAccounts));
+            accountList = ListUtils.removeDuplicates(newAccounts);
         } else {
             int index = accountList.indexOf(newAccounts.get(newAccounts.size() - 1));
             for (int i = 0; i < index; i++) {
diff --git a/app/src/main/java/com/keylesspalace/tusky/adapter/NotificationsAdapter.java b/app/src/main/java/com/keylesspalace/tusky/adapter/NotificationsAdapter.java
index fb0ed466..d03902b9 100644
--- a/app/src/main/java/com/keylesspalace/tusky/adapter/NotificationsAdapter.java
+++ b/app/src/main/java/com/keylesspalace/tusky/adapter/NotificationsAdapter.java
@@ -34,10 +34,10 @@ import com.keylesspalace.tusky.entity.Notification;
 import com.keylesspalace.tusky.entity.Status;
 import com.keylesspalace.tusky.interfaces.AdapterItemRemover;
 import com.keylesspalace.tusky.interfaces.StatusActionListener;
+import com.keylesspalace.tusky.util.ListUtils;
 import com.squareup.picasso.Picasso;
 
 import java.util.ArrayList;
-import java.util.HashSet;
 import java.util.List;
 
 public class NotificationsAdapter extends RecyclerView.Adapter implements AdapterItemRemover {
@@ -181,7 +181,7 @@ public class NotificationsAdapter extends RecyclerView.Adapter implements Adapte
 
     public void update(@Nullable List<Notification> newNotifications, @Nullable String fromId,
             @Nullable String uptoId) {
-        if (newNotifications == null || newNotifications.isEmpty()) {
+        if (ListUtils.isEmpty(newNotifications)) {
             return;
         }
         if (fromId != null) {
@@ -191,8 +191,7 @@ public class NotificationsAdapter extends RecyclerView.Adapter implements Adapte
             topId = uptoId;
         }
         if (notifications.isEmpty()) {
-            // This construction removes duplicates.
-            notifications = new ArrayList<>(new HashSet<>(newNotifications));
+            notifications = ListUtils.removeDuplicates(newNotifications);
         } else {
             int index = notifications.indexOf(newNotifications.get(newNotifications.size() - 1));
             for (int i = 0; i < index; i++) {
diff --git a/app/src/main/java/com/keylesspalace/tusky/adapter/TimelineAdapter.java b/app/src/main/java/com/keylesspalace/tusky/adapter/TimelineAdapter.java
index fa92e32f..158ca39c 100644
--- a/app/src/main/java/com/keylesspalace/tusky/adapter/TimelineAdapter.java
+++ b/app/src/main/java/com/keylesspalace/tusky/adapter/TimelineAdapter.java
@@ -25,9 +25,9 @@ import com.keylesspalace.tusky.R;
 import com.keylesspalace.tusky.interfaces.AdapterItemRemover;
 import com.keylesspalace.tusky.interfaces.StatusActionListener;
 import com.keylesspalace.tusky.entity.Status;
+import com.keylesspalace.tusky.util.ListUtils;
 
 import java.util.ArrayList;
-import java.util.HashSet;
 import java.util.List;
 
 public class TimelineAdapter extends RecyclerView.Adapter implements AdapterItemRemover {
@@ -113,7 +113,7 @@ public class TimelineAdapter extends RecyclerView.Adapter implements AdapterItem
 
     public void update(@Nullable List<Status> newStatuses, @Nullable String fromId,
             @Nullable String uptoId) {
-        if (newStatuses == null || newStatuses.isEmpty()) {
+        if (ListUtils.isEmpty(newStatuses)) {
             return;
         }
         if (fromId != null) {
@@ -123,8 +123,7 @@ public class TimelineAdapter extends RecyclerView.Adapter implements AdapterItem
             topId = uptoId;
         }
         if (statuses.isEmpty()) {
-            // This construction removes duplicates.
-            statuses = new ArrayList<>(new HashSet<>(newStatuses));
+            statuses = ListUtils.removeDuplicates(newStatuses);
         } else {
             int index = statuses.indexOf(newStatuses.get(newStatuses.size() - 1));
             for (int i = 0; i < index; i++) {
diff --git a/app/src/main/java/com/keylesspalace/tusky/util/ListUtils.java b/app/src/main/java/com/keylesspalace/tusky/util/ListUtils.java
index ae269683..76623f2e 100644
--- a/app/src/main/java/com/keylesspalace/tusky/util/ListUtils.java
+++ b/app/src/main/java/com/keylesspalace/tusky/util/ListUtils.java
@@ -17,6 +17,8 @@ package com.keylesspalace.tusky.util;
 
 import android.support.annotation.Nullable;
 
+import java.util.ArrayList;
+import java.util.LinkedHashSet;
 import java.util.List;
 
 public class ListUtils {
@@ -33,4 +35,11 @@ public class ListUtils {
             return list.size();
         }
     }
+
+    /** @return a new ArrayList containing the elements without duplicates in the same order */
+    public static <T> ArrayList<T> removeDuplicates(List<T> list) {
+        LinkedHashSet<T> set = new LinkedHashSet<>();
+        set.addAll(list);
+        return new ArrayList<>(set);
+    }
 }