From 84438b3d66efc1c322b37d78583ec209eba24f0e Mon Sep 17 00:00:00 2001
From: Janne Koschinski <janne@kuschku.de>
Date: Sun, 10 Jan 2016 01:50:30 +0100
Subject: [PATCH] Cleaned up some code, implemented sender colors

---
 .../java/de/kuschku/libquassel/Client.java    |  2 +-
 .../kuschku/quasseldroid_ng/MainActivity.java | 47 ++++++++++-
 .../quasseldroid_ng/NetworkDrawerItem.java    |  2 +-
 .../java/de/kuschku/util/IrcUserUtils.java    | 79 +++++++++++++++++++
 .../java/de/kuschku/util/ReflectionUtils.java | 10 +--
 .../de/kuschku/util/SortedListWrapper.java    |  2 +
 .../kuschku/util/{ => backports}/Absent.java  |  2 +-
 .../util/{ => backports}/BinaryFunction.java  |  2 +-
 .../util/{ => backports}/Consumer.java        |  2 +-
 .../util/{ => backports}/ICollector.java      |  2 +-
 .../util/{ => backports}/Optional.java        |  2 +-
 .../util/{ => backports}/Optionals.java       |  2 +-
 .../kuschku/util/{ => backports}/Present.java |  2 +-
 .../kuschku/util/{ => backports}/Stream.java  |  4 +-
 .../collectors/Collectors.java                |  4 +-
 .../collectors/ListCollector.java             |  6 +-
 .../collectors/MapCollector.java              |  6 +-
 17 files changed, 149 insertions(+), 27 deletions(-)
 create mode 100644 app/src/main/java/de/kuschku/util/IrcUserUtils.java
 rename app/src/main/java/de/kuschku/util/{ => backports}/Absent.java (96%)
 rename app/src/main/java/de/kuschku/util/{ => backports}/BinaryFunction.java (68%)
 rename app/src/main/java/de/kuschku/util/{ => backports}/Consumer.java (62%)
 rename app/src/main/java/de/kuschku/util/{ => backports}/ICollector.java (67%)
 rename app/src/main/java/de/kuschku/util/{ => backports}/Optional.java (94%)
 rename app/src/main/java/de/kuschku/util/{ => backports}/Optionals.java (92%)
 rename app/src/main/java/de/kuschku/util/{ => backports}/Present.java (97%)
 rename app/src/main/java/de/kuschku/util/{ => backports}/Stream.java (95%)
 rename app/src/main/java/de/kuschku/util/{ => backports}/collectors/Collectors.java (80%)
 rename app/src/main/java/de/kuschku/util/{ => backports}/collectors/ListCollector.java (59%)
 rename app/src/main/java/de/kuschku/util/{ => backports}/collectors/MapCollector.java (81%)

diff --git a/app/src/main/java/de/kuschku/libquassel/Client.java b/app/src/main/java/de/kuschku/libquassel/Client.java
index d556e4a45..199c761f0 100644
--- a/app/src/main/java/de/kuschku/libquassel/Client.java
+++ b/app/src/main/java/de/kuschku/libquassel/Client.java
@@ -23,7 +23,7 @@ import de.kuschku.libquassel.syncables.types.BufferSyncer;
 import de.kuschku.libquassel.syncables.types.BufferViewManager;
 import de.kuschku.libquassel.syncables.types.Network;
 import de.kuschku.libquassel.syncables.types.SyncableObject;
-import de.kuschku.util.Stream;
+import de.kuschku.util.backports.Stream;
 
 
 public class Client {
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/MainActivity.java b/app/src/main/java/de/kuschku/quasseldroid_ng/MainActivity.java
index 4b4960b60..b0d5681f5 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/MainActivity.java
+++ b/app/src/main/java/de/kuschku/quasseldroid_ng/MainActivity.java
@@ -7,12 +7,18 @@ import android.content.res.Configuration;
 import android.os.Bundle;
 import android.os.IBinder;
 import android.support.design.widget.Snackbar;
+import android.support.v4.text.TextUtilsCompat;
 import android.support.v7.app.AlertDialog;
 import android.support.v7.app.AppCompatActivity;
 import android.support.v7.widget.AppCompatImageButton;
 import android.support.v7.widget.LinearLayoutManager;
 import android.support.v7.widget.RecyclerView;
 import android.support.v7.widget.Toolbar;
+import android.text.SpannableString;
+import android.text.SpannableStringBuilder;
+import android.text.Spanned;
+import android.text.TextUtils;
+import android.text.style.ForegroundColorSpan;
 import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -33,6 +39,9 @@ import com.mikepenz.materialdrawer.model.interfaces.IDrawerItem;
 import com.mikepenz.materialdrawer.model.interfaces.IProfile;
 import com.mikepenz.materialdrawer.util.KeyboardUtil;
 
+import org.joda.time.format.DateTimeFormat;
+
+import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashSet;
@@ -52,8 +61,9 @@ import de.kuschku.libquassel.primitives.types.Message;
 import de.kuschku.libquassel.syncables.types.BufferViewConfig;
 import de.kuschku.libquassel.syncables.types.Network;
 import de.kuschku.quasseldroid_ng.utils.ServerAddress;
+import de.kuschku.util.IrcUserUtils;
 import de.kuschku.util.ObservableList;
-import de.kuschku.util.Stream;
+import de.kuschku.util.backports.Stream;
 
 public class MainActivity extends AppCompatActivity {
 
@@ -319,7 +329,40 @@ public class MainActivity extends AppCompatActivity {
 
         @Override
         public void onBindViewHolder(MessageViewHolder holder, int position) {
-            holder.text1.setText(messageList.list.get(position).toString());
+            int[] colors = {
+                    R.color.md_pink_500,
+                    R.color.md_purple_500,
+                    R.color.md_red_500,
+                    R.color.md_green_500,
+                    R.color.md_cyan_500,
+                    R.color.md_deep_purple_500,
+                    R.color.md_amber_500,
+                    R.color.md_blue_500,
+                    R.color.md_pink_700,
+                    R.color.md_purple_700,
+                    R.color.md_red_700,
+                    R.color.md_green_700,
+                    R.color.md_cyan_700,
+                    R.color.md_deep_purple_700,
+                    R.color.md_amber_700,
+                    R.color.md_blue_700
+            };
+
+            Message msg = messageList.list.get(position);
+            SpannableString timeSpan = new SpannableString(DateTimeFormat.forPattern("[hh:mm]").print(msg.time));
+            timeSpan.setSpan(new ForegroundColorSpan(getResources().getColor(R.color.md_light_secondary)), 0, timeSpan.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
+
+            String nick = IrcUserUtils.getNick(msg.sender);
+            SpannableString nickSpan = new SpannableString(nick);
+            nickSpan.setSpan(new ForegroundColorSpan(getResources().getColor(colors[IrcUserUtils.getSenderColor(nick)])), 0, nickSpan.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
+
+            holder.text1.setText(TextUtils.concat(
+                    timeSpan,
+                    " ",
+                    nickSpan,
+                    " ",
+                    msg.content
+            ));
         }
 
         @Override
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/NetworkDrawerItem.java b/app/src/main/java/de/kuschku/quasseldroid_ng/NetworkDrawerItem.java
index eb97d3f94..5def317fb 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/NetworkDrawerItem.java
+++ b/app/src/main/java/de/kuschku/quasseldroid_ng/NetworkDrawerItem.java
@@ -9,7 +9,7 @@ import java.util.Set;
 
 import de.kuschku.libquassel.localtypes.Buffer;
 import de.kuschku.libquassel.syncables.types.Network;
-import de.kuschku.util.Stream;
+import de.kuschku.util.backports.Stream;
 
 public class NetworkDrawerItem extends PrimaryDrawerItem {
     final Network network;
diff --git a/app/src/main/java/de/kuschku/util/IrcUserUtils.java b/app/src/main/java/de/kuschku/util/IrcUserUtils.java
new file mode 100644
index 000000000..03953b10a
--- /dev/null
+++ b/app/src/main/java/de/kuschku/util/IrcUserUtils.java
@@ -0,0 +1,79 @@
+package de.kuschku.util;
+
+import java.nio.charset.Charset;
+import java.util.Locale;
+
+public class IrcUserUtils {
+    private IrcUserUtils() {
+
+    }
+
+    public static int getSenderColor(String nick) {
+        nick = trimEnd(nick, '_').toLowerCase(Locale.US);
+        byte[] data = nick.getBytes(Charset.forName("ISO-8859-1"));
+        return (0xf & CRCUtils.qChecksum(data));
+    }
+
+    public static String trimEnd(String str, char character) {
+        char[] val = str.toCharArray();
+        int len = val.length;
+        while ((0 < len) && (val[len - 1] == character)) {
+            len--;
+        }
+        return ((len < val.length)) ? str.substring(0, len) : str;
+    }
+
+    public static class CRCUtils {
+        private CRCUtils() {
+
+        }
+
+        public static int qChecksum(byte[] data) {
+            int crc = 0xffff;
+            int crcHighBitMask = 0x8000;
+
+            for (byte b : data) {
+                int c = reflect(b, 8);
+                for (int j = 0x80; j > 0; j >>= 1) {
+                    int highBit = crc & crcHighBitMask;
+                    crc <<= 1;
+                    if ((c & j) > 0) {
+                        highBit ^= crcHighBitMask;
+                    }
+                    if (highBit > 0) {
+                        crc ^= 0x1021;
+                    }
+                }
+            }
+
+            crc = reflect(crc, 16);
+            crc ^= 0xffff;
+            crc &= 0xffff;
+
+            return crc;
+        }
+
+        private static int reflect(int crc, int n) {
+            int j = 1, crcout = 0;
+            for (int i = (1 << (n - 1)); i > 0; i >>= 1) {
+                if ((crc & i) > 0) {
+                    crcout |= j;
+                }
+                j <<= 1;
+            }
+            return crcout;
+        }
+    }
+
+    public static String getNick(String hostmask) {
+        return hostmask.split("!")[0];
+    }
+
+    public static String getUser(String hostmask) {
+        return hostmask.split("!")[1].split("@")[0];
+    }
+
+    public static String getHost(String hostmask) {
+        return hostmask.split("@")[1];
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/de/kuschku/util/ReflectionUtils.java b/app/src/main/java/de/kuschku/util/ReflectionUtils.java
index 979d097db..25f4b826f 100644
--- a/app/src/main/java/de/kuschku/util/ReflectionUtils.java
+++ b/app/src/main/java/de/kuschku/util/ReflectionUtils.java
@@ -23,16 +23,14 @@ public class ReflectionUtils {
             classes[i] = argv[i].getClass();
         }
         Method m = getMethodFromSignature(name, o.getClass(), classes);
-        try {
-
-            if (m != null) {
-                m.invoke(o, argv);
-            }
+        if (m == null)
+            throw new SyncInvocationException(String.format("Error invoking %s::%s with arguments %s", o.getClass().getSimpleName(), name, Arrays.toString(argv)));
 
+        try {
+            m.invoke(o, argv);
         } catch (Exception e) {
             throw new SyncInvocationException(e, String.format("Error invoking %s::%s with arguments %s", o.getClass().getSimpleName(), name, Arrays.toString(argv)));
         }
-        throw new SyncInvocationException(String.format("Error invoking %s::%s with arguments %s", o.getClass().getSimpleName(), name, Arrays.toString(argv)));
     }
 
     @NonNull
diff --git a/app/src/main/java/de/kuschku/util/SortedListWrapper.java b/app/src/main/java/de/kuschku/util/SortedListWrapper.java
index 3af1f8bfd..a50824ce1 100644
--- a/app/src/main/java/de/kuschku/util/SortedListWrapper.java
+++ b/app/src/main/java/de/kuschku/util/SortedListWrapper.java
@@ -8,6 +8,8 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.ListIterator;
 
+import de.kuschku.util.backports.Stream;
+
 public class SortedListWrapper<T> implements List<T> {
     final SortedList<T> list;
 
diff --git a/app/src/main/java/de/kuschku/util/Absent.java b/app/src/main/java/de/kuschku/util/backports/Absent.java
similarity index 96%
rename from app/src/main/java/de/kuschku/util/Absent.java
rename to app/src/main/java/de/kuschku/util/backports/Absent.java
index 515ed35ff..ac2e15cf8 100644
--- a/app/src/main/java/de/kuschku/util/Absent.java
+++ b/app/src/main/java/de/kuschku/util/backports/Absent.java
@@ -1,4 +1,4 @@
-package de.kuschku.util;
+package de.kuschku.util.backports;
 
 import com.google.common.base.Function;
 import com.google.common.base.Predicate;
diff --git a/app/src/main/java/de/kuschku/util/BinaryFunction.java b/app/src/main/java/de/kuschku/util/backports/BinaryFunction.java
similarity index 68%
rename from app/src/main/java/de/kuschku/util/BinaryFunction.java
rename to app/src/main/java/de/kuschku/util/backports/BinaryFunction.java
index 5ab2ebf27..3616eaa8e 100644
--- a/app/src/main/java/de/kuschku/util/BinaryFunction.java
+++ b/app/src/main/java/de/kuschku/util/backports/BinaryFunction.java
@@ -1,4 +1,4 @@
-package de.kuschku.util;
+package de.kuschku.util.backports;
 
 public interface BinaryFunction<A, B, C> {
     C apply(A arg0, B arg1);
diff --git a/app/src/main/java/de/kuschku/util/Consumer.java b/app/src/main/java/de/kuschku/util/backports/Consumer.java
similarity index 62%
rename from app/src/main/java/de/kuschku/util/Consumer.java
rename to app/src/main/java/de/kuschku/util/backports/Consumer.java
index b609ea123..65ab930cb 100644
--- a/app/src/main/java/de/kuschku/util/Consumer.java
+++ b/app/src/main/java/de/kuschku/util/backports/Consumer.java
@@ -1,4 +1,4 @@
-package de.kuschku.util;
+package de.kuschku.util.backports;
 
 public interface Consumer<T> {
     void apply(T elem);
diff --git a/app/src/main/java/de/kuschku/util/ICollector.java b/app/src/main/java/de/kuschku/util/backports/ICollector.java
similarity index 67%
rename from app/src/main/java/de/kuschku/util/ICollector.java
rename to app/src/main/java/de/kuschku/util/backports/ICollector.java
index 515173756..15c02a76c 100644
--- a/app/src/main/java/de/kuschku/util/ICollector.java
+++ b/app/src/main/java/de/kuschku/util/backports/ICollector.java
@@ -1,4 +1,4 @@
-package de.kuschku.util;
+package de.kuschku.util.backports;
 
 public interface ICollector<T, R> {
     R collect(Stream<T> stream);
diff --git a/app/src/main/java/de/kuschku/util/Optional.java b/app/src/main/java/de/kuschku/util/backports/Optional.java
similarity index 94%
rename from app/src/main/java/de/kuschku/util/Optional.java
rename to app/src/main/java/de/kuschku/util/backports/Optional.java
index 7f5d7f439..266bc9328 100644
--- a/app/src/main/java/de/kuschku/util/Optional.java
+++ b/app/src/main/java/de/kuschku/util/backports/Optional.java
@@ -1,4 +1,4 @@
-package de.kuschku.util;
+package de.kuschku.util.backports;
 
 import com.google.common.base.Function;
 import com.google.common.base.Predicate;
diff --git a/app/src/main/java/de/kuschku/util/Optionals.java b/app/src/main/java/de/kuschku/util/backports/Optionals.java
similarity index 92%
rename from app/src/main/java/de/kuschku/util/Optionals.java
rename to app/src/main/java/de/kuschku/util/backports/Optionals.java
index 68d886612..7a898eeb9 100644
--- a/app/src/main/java/de/kuschku/util/Optionals.java
+++ b/app/src/main/java/de/kuschku/util/backports/Optionals.java
@@ -1,4 +1,4 @@
-package de.kuschku.util;
+package de.kuschku.util.backports;
 
 public class Optionals {
     private Optionals() {
diff --git a/app/src/main/java/de/kuschku/util/Present.java b/app/src/main/java/de/kuschku/util/backports/Present.java
similarity index 97%
rename from app/src/main/java/de/kuschku/util/Present.java
rename to app/src/main/java/de/kuschku/util/backports/Present.java
index 87e9f3c4c..19a5168f6 100644
--- a/app/src/main/java/de/kuschku/util/Present.java
+++ b/app/src/main/java/de/kuschku/util/backports/Present.java
@@ -1,4 +1,4 @@
-package de.kuschku.util;
+package de.kuschku.util.backports;
 
 import com.google.common.base.Function;
 import com.google.common.base.Predicate;
diff --git a/app/src/main/java/de/kuschku/util/Stream.java b/app/src/main/java/de/kuschku/util/backports/Stream.java
similarity index 95%
rename from app/src/main/java/de/kuschku/util/Stream.java
rename to app/src/main/java/de/kuschku/util/backports/Stream.java
index c86550220..ddf14856b 100644
--- a/app/src/main/java/de/kuschku/util/Stream.java
+++ b/app/src/main/java/de/kuschku/util/backports/Stream.java
@@ -1,4 +1,4 @@
-package de.kuschku.util;
+package de.kuschku.util.backports;
 
 import com.google.common.base.Function;
 import com.google.common.base.Predicate;
@@ -10,7 +10,7 @@ import java.util.Collection;
 import java.util.Iterator;
 import java.util.List;
 
-import de.kuschku.util.collectors.Collectors;
+import de.kuschku.util.backports.collectors.Collectors;
 
 public class Stream<T> {
     List<T> list;
diff --git a/app/src/main/java/de/kuschku/util/collectors/Collectors.java b/app/src/main/java/de/kuschku/util/backports/collectors/Collectors.java
similarity index 80%
rename from app/src/main/java/de/kuschku/util/collectors/Collectors.java
rename to app/src/main/java/de/kuschku/util/backports/collectors/Collectors.java
index 957921a7b..c5ef5b374 100644
--- a/app/src/main/java/de/kuschku/util/collectors/Collectors.java
+++ b/app/src/main/java/de/kuschku/util/backports/collectors/Collectors.java
@@ -1,9 +1,9 @@
-package de.kuschku.util.collectors;
+package de.kuschku.util.backports.collectors;
 
 import java.util.List;
 import java.util.Map;
 
-import de.kuschku.util.Stream;
+import de.kuschku.util.backports.Stream;
 
 public class Collectors {
     private Collectors() {
diff --git a/app/src/main/java/de/kuschku/util/collectors/ListCollector.java b/app/src/main/java/de/kuschku/util/backports/collectors/ListCollector.java
similarity index 59%
rename from app/src/main/java/de/kuschku/util/collectors/ListCollector.java
rename to app/src/main/java/de/kuschku/util/backports/collectors/ListCollector.java
index a2f7749a7..95b94d522 100644
--- a/app/src/main/java/de/kuschku/util/collectors/ListCollector.java
+++ b/app/src/main/java/de/kuschku/util/backports/collectors/ListCollector.java
@@ -1,9 +1,9 @@
-package de.kuschku.util.collectors;
+package de.kuschku.util.backports.collectors;
 
 import java.util.List;
 
-import de.kuschku.util.ICollector;
-import de.kuschku.util.Stream;
+import de.kuschku.util.backports.ICollector;
+import de.kuschku.util.backports.Stream;
 
 public class ListCollector<T> implements ICollector<T, List<T>> {
     @Override
diff --git a/app/src/main/java/de/kuschku/util/collectors/MapCollector.java b/app/src/main/java/de/kuschku/util/backports/collectors/MapCollector.java
similarity index 81%
rename from app/src/main/java/de/kuschku/util/collectors/MapCollector.java
rename to app/src/main/java/de/kuschku/util/backports/collectors/MapCollector.java
index a23a21893..cc52c36dc 100644
--- a/app/src/main/java/de/kuschku/util/collectors/MapCollector.java
+++ b/app/src/main/java/de/kuschku/util/backports/collectors/MapCollector.java
@@ -1,11 +1,11 @@
-package de.kuschku.util.collectors;
+package de.kuschku.util.backports.collectors;
 
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
-import de.kuschku.util.ICollector;
-import de.kuschku.util.Stream;
+import de.kuschku.util.backports.ICollector;
+import de.kuschku.util.backports.Stream;
 
 public class MapCollector<T> implements ICollector<T, Map<T, T>> {
     @Override
-- 
GitLab