From a3876209e081f07766e47d54b1c0b6bc247c0153 Mon Sep 17 00:00:00 2001
From: Janne Koschinski <janne@kuschku.de>
Date: Tue, 13 Sep 2016 18:13:41 +0200
Subject: [PATCH] Fixed some bugs, improved handling of users that are away.

---
 .../libquassel/client/BufferManager.java      |  1 +
 .../syncables/types/impl/BufferSyncer.java    |  2 +
 .../syncables/types/impl/IrcUser.java         | 22 +++--
 .../quasseldroid_ng/ui/chat/MainActivity.java | 24 +++++-
 .../ui/chat/drawer/NetworkItem.java           | 35 ++++++--
 .../ui/chat/nicklist/NickListAdapter.java     | 19 ++++-
 app/src/main/res/layout/widget_nick.xml       | 19 +++--
 app/src/main/res/layout/widget_nick_away.xml  | 85 +++++++++++++++++++
 8 files changed, 181 insertions(+), 26 deletions(-)
 create mode 100644 app/src/main/res/layout/widget_nick_away.xml

diff --git a/app/src/main/java/de/kuschku/libquassel/client/BufferManager.java b/app/src/main/java/de/kuschku/libquassel/client/BufferManager.java
index f58fc882c..cb76664d8 100644
--- a/app/src/main/java/de/kuschku/libquassel/client/BufferManager.java
+++ b/app/src/main/java/de/kuschku/libquassel/client/BufferManager.java
@@ -121,6 +121,7 @@ public class BufferManager {
         Buffer buffer = buffer(bufferId);
         if (buffer != null) {
             buffer.renameBuffer(newName);
+            bufferIds().notifyItemChanged(bufferId);
         }
     }
 
diff --git a/app/src/main/java/de/kuschku/libquassel/syncables/types/impl/BufferSyncer.java b/app/src/main/java/de/kuschku/libquassel/syncables/types/impl/BufferSyncer.java
index e8a372134..cba73fa3d 100644
--- a/app/src/main/java/de/kuschku/libquassel/syncables/types/impl/BufferSyncer.java
+++ b/app/src/main/java/de/kuschku/libquassel/syncables/types/impl/BufferSyncer.java
@@ -95,6 +95,7 @@ public class BufferSyncer extends ABufferSyncer {
         for (Message m : filtered) {
             addActivity(m);
         }
+        client.bufferManager().bufferIds().notifyItemChanged(buffer);
         _update();
     }
 
@@ -108,6 +109,7 @@ public class BufferSyncer extends ABufferSyncer {
             markerLines.put(buffer, msgId);
             client.backlogStorage().setMarkerLine(buffer, msgId);
         }
+        client.bufferManager().bufferIds().notifyItemChanged(buffer);
         _update();
     }
 
diff --git a/app/src/main/java/de/kuschku/libquassel/syncables/types/impl/IrcUser.java b/app/src/main/java/de/kuschku/libquassel/syncables/types/impl/IrcUser.java
index bb22de2bf..2999b8483 100644
--- a/app/src/main/java/de/kuschku/libquassel/syncables/types/impl/IrcUser.java
+++ b/app/src/main/java/de/kuschku/libquassel/syncables/types/impl/IrcUser.java
@@ -37,6 +37,7 @@ import java.util.Set;
 
 import de.kuschku.libquassel.BusProvider;
 import de.kuschku.libquassel.client.Client;
+import de.kuschku.libquassel.localtypes.buffers.QueryBuffer;
 import de.kuschku.libquassel.primitives.types.QVariant;
 import de.kuschku.libquassel.syncables.types.abstracts.AIrcUser;
 import de.kuschku.libquassel.syncables.types.interfaces.QIrcChannel;
@@ -288,15 +289,6 @@ public class IrcUser extends AIrcUser {
     public void _setRealName(String realName) {
         this.realName = realName;
         _update();
-        for (String channel : this.channels) {
-            QNetwork network = this.network();
-            if (network != null) {
-                QIrcChannel channel1 = network.ircChannel(channel);
-                if (channel1 != null) {
-                    channel1.users().notifyItemChanged(nick);
-                }
-            }
-        }
     }
 
     @Override
@@ -493,6 +485,18 @@ public class IrcUser extends AIrcUser {
     @Override
     public void _update() {
         super._update();
+        for (String channel : this.channels) {
+            QNetwork network = this.network();
+            if (network != null) {
+                QIrcChannel channel1 = network.ircChannel(channel);
+                if (channel1 != null) {
+                    channel1.users().notifyItemChanged(nick);
+                }
+            }
+        }
+        QueryBuffer user = client.bufferManager().user(this);
+        if (user != null)
+            client.bufferManager().bufferIds().notifyItemChanged(user.getInfo().id);
     }
 
     @NonNull
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/MainActivity.java b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/MainActivity.java
index 0dae6699b..0f3512529 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/MainActivity.java
+++ b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/MainActivity.java
@@ -104,6 +104,7 @@ import de.kuschku.util.accounts.AccountManager;
 import de.kuschku.util.annotationbind.AutoBinder;
 import de.kuschku.util.certificates.CertificateUtils;
 import de.kuschku.util.certificates.SQLiteCertificateManager;
+import de.kuschku.util.observables.callbacks.ElementCallback;
 import de.kuschku.util.servicebound.BoundActivity;
 import de.kuschku.util.ui.DividerItemDecoration;
 import de.kuschku.util.ui.MenuTint;
@@ -383,6 +384,10 @@ public class MainActivity extends BoundActivity {
 
     private void updateBuffer(int id) {
         nickListAdapter.setChannel(null);
+        updateTitleAndSubtitle(id);
+    }
+
+    private void updateTitleAndSubtitle(int id) {
         Client client = context.client();
         if (client != null) {
             Buffer buffer = client.bufferManager().buffer(id);
@@ -393,7 +398,7 @@ public class MainActivity extends BoundActivity {
                     if (user == null) {
                         toolbarWrapper.setSubtitle(null);
                     } else {
-                        toolbarWrapper.setSubtitle(user.hostmask() + " | " + user.realName());
+                        toolbarWrapper.setSubtitle(user.realName());
                     }
                 } else if (buffer instanceof ChannelBuffer) {
                     QIrcChannel channel = ((ChannelBuffer) buffer).getChannel();
@@ -460,6 +465,23 @@ public class MainActivity extends BoundActivity {
         if (drawerLayout != null)
             drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
 
+        context.client().bufferManager().bufferIds().addCallback(new ElementCallback<Integer>() {
+            @Override
+            public void notifyItemInserted(Integer element) {
+
+            }
+
+            @Override
+            public void notifyItemRemoved(Integer element) {
+
+            }
+
+            @Override
+            public void notifyItemChanged(Integer element) {
+                if (element == context.client().backlogManager().open())
+                    updateTitleAndSubtitle(element);
+            }
+        });
         context.client().backlogManager().open(status.bufferId);
         if (context.client().bufferViewManager() != null) {
             chatListSpinner.setAdapter(new BufferViewConfigSpinnerAdapter(context.client().bufferViewManager()));
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/drawer/NetworkItem.java b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/drawer/NetworkItem.java
index 6eed74b4f..399870d15 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/drawer/NetworkItem.java
+++ b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/drawer/NetworkItem.java
@@ -23,6 +23,7 @@ package de.kuschku.quasseldroid_ng.ui.chat.drawer;
 
 import com.bignerdranch.expandablerecyclerview.Model.ParentListItem;
 
+import java.util.ArrayList;
 import java.util.List;
 
 import de.kuschku.libquassel.localtypes.buffers.Buffer;
@@ -39,6 +40,7 @@ public class NetworkItem implements ParentListItem {
     private final AppContext context;
     private final QBufferViewConfig config;
     private final QNetwork network;
+    private final List<Buffer> bufferList = new ArrayList<>();
     private final ObservableSortedList<Buffer> buffers = new ObservableSortedList<>(Buffer.class, new ObservableSortedList.ItemComparator<Buffer>() {
         @Override
         public int compare(Buffer o1, Buffer o2) {
@@ -78,6 +80,7 @@ public class NetworkItem implements ParentListItem {
             Buffer buffer = context.client().bufferManager().buffer(element);
             if (buffer != null && buffer.getInfo().networkId == network.networkId()) {
                 buffers.add(buffer);
+                bufferList.add(buffers.indexOf(buffer), buffer);
             }
         }
 
@@ -85,16 +88,13 @@ public class NetworkItem implements ParentListItem {
         public void notifyItemRemoved(Integer element) {
             Buffer buffer = context.client().bufferManager().buffer(element);
             if (buffer != null && buffer.getInfo().networkId == network.networkId()) {
-                buffers.remove(buffer);
+                buffers.remove(bufferList.indexOf(buffer));
+                bufferList.remove(buffer);
             }
         }
 
         @Override
         public void notifyItemChanged(Integer element) {
-            Buffer buffer = context.client().bufferManager().buffer(element);
-            if (buffer != null && buffer.getInfo().networkId == network.networkId() && buffers.contains(buffer)) {
-                buffers.notifyItemChanged(buffers.indexOf(buffer));
-            }
         }
     };
     private ObservableSet<Integer> backingSet;
@@ -148,18 +148,41 @@ public class NetworkItem implements ParentListItem {
                 }
             }
         });
+        context.client().bufferManager().bufferIds().addCallback(new ElementCallback<Integer>() {
+            @Override
+            public void notifyItemInserted(Integer element) {
+            }
+
+            @Override
+            public void notifyItemRemoved(Integer element) {
+            }
+
+            @Override
+            public void notifyItemChanged(Integer element) {
+                Buffer buffer = NetworkItem.this.context.client().bufferManager().buffer(element);
+                if (buffer != null && buffer.getInfo().networkId == NetworkItem.this.network.networkId() && bufferList.contains(buffer)) {
+                    buffers.remove(bufferList.indexOf(buffer));
+                    bufferList.remove(buffer);
+                    buffers.add(buffer);
+                    bufferList.add(buffers.indexOf(buffer), buffer);
+                }
+            }
+        });
     }
 
     public void populateList(ObservableSet<Integer> backingSet) {
         if (this.backingSet != null)
             this.backingSet.removeCallback(callback);
         buffers.clear();
+        bufferList.clear();
 
         backingSet.addCallback(callback);
         for (int id : backingSet) {
             Buffer buffer = context.client().bufferManager().buffer(id);
-            if (buffer != null && buffer.getInfo().networkId == network.networkId())
+            if (buffer != null && buffer.getInfo().networkId == network.networkId()) {
                 buffers.add(buffer);
+                bufferList.add(buffers.indexOf(buffer), buffer);
+            }
         }
         this.backingSet = backingSet;
     }
diff --git a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/nicklist/NickListAdapter.java b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/nicklist/NickListAdapter.java
index f4f4f606f..09c34fcc8 100644
--- a/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/nicklist/NickListAdapter.java
+++ b/app/src/main/java/de/kuschku/quasseldroid_ng/ui/chat/nicklist/NickListAdapter.java
@@ -44,6 +44,8 @@ import de.kuschku.util.observables.callbacks.wrappers.AdapterUICallbackWrapper;
 import de.kuschku.util.observables.lists.ObservableSortedList;
 
 public class NickListAdapter extends RecyclerView.Adapter<NickListAdapter.NickViewHolder> {
+    public static final int TYPE_NORMAL = 0;
+    public static final int TYPE_AWAY = 1;
     private final AppContext context;
     QIrcChannel channel;
 
@@ -125,10 +127,20 @@ public class NickListAdapter extends RecyclerView.Adapter<NickListAdapter.NickVi
     @Override
     public NickViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
         LayoutInflater inflater = LayoutInflater.from(parent.getContext());
-        View view = inflater.inflate(R.layout.widget_nick, parent, false);
+        View view = inflater.inflate(getLayoutResource(viewType), parent, false);
         return new NickViewHolder(view);
     }
 
+    public int getLayoutResource(int viewType) {
+        switch (viewType) {
+            default:
+            case TYPE_NORMAL:
+                return R.layout.widget_nick;
+            case TYPE_AWAY:
+                return R.layout.widget_nick_away;
+        }
+    }
+
     @Override
     public void onBindViewHolder(NickViewHolder holder, int position) {
         holder.bind(users.get(position));
@@ -148,6 +160,11 @@ public class NickListAdapter extends RecyclerView.Adapter<NickListAdapter.NickVi
         return builder.toString();
     }
 
+    @Override
+    public int getItemViewType(int position) {
+        return users.get(position).isAway() ? TYPE_AWAY : TYPE_NORMAL;
+    }
+
     class NickViewHolder extends RecyclerView.ViewHolder {
         @Bind(R.id.mode)
         TextView mode;
diff --git a/app/src/main/res/layout/widget_nick.xml b/app/src/main/res/layout/widget_nick.xml
index 5fe59b912..9e9ee3ff8 100644
--- a/app/src/main/res/layout/widget_nick.xml
+++ b/app/src/main/res/layout/widget_nick.xml
@@ -20,15 +20,16 @@
   ~ with this program.  If not, see <http://www.gnu.org/licenses/>.
   -->
 
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-              xmlns:tools="http://schemas.android.com/tools"
-              android:layout_width="match_parent"
-              android:layout_height="56dp"
-              android:background="?selectableItemBackground"
-              android:clickable="true"
-              android:orientation="horizontal"
-              android:paddingLeft="?listPreferredItemPaddingLeft"
-              android:paddingRight="?listPreferredItemPaddingRight">
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="56dp"
+    android:background="?selectableItemBackground"
+    android:clickable="true"
+    android:orientation="horizontal"
+    android:paddingLeft="?listPreferredItemPaddingLeft"
+    android:paddingRight="?listPreferredItemPaddingRight">
 
     <TextView
         android:id="@+id/mode"
diff --git a/app/src/main/res/layout/widget_nick_away.xml b/app/src/main/res/layout/widget_nick_away.xml
new file mode 100644
index 000000000..5b0fb2f3f
--- /dev/null
+++ b/app/src/main/res/layout/widget_nick_away.xml
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ QuasselDroid - Quassel client for Android
+  ~ Copyright (C) 2016 Janne Koschinski
+  ~ Copyright (C) 2016 Ken Børge Viktil
+  ~ Copyright (C) 2016 Magnus Fjell
+  ~ Copyright (C) 2016 Martin Sandsmark <martin.sandsmark@kde.org>
+  ~
+  ~ This program is free software: you can redistribute it and/or modify it
+  ~ under the terms of the GNU General Public License as published by the Free
+  ~ Software Foundation, either version 3 of the License, or (at your option)
+  ~ any later version.
+  ~
+  ~ This program is distributed in the hope that it will be useful,
+  ~ but WITHOUT ANY WARRANTY; without even the implied warranty of
+  ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  ~ GNU General Public License for more details.
+  ~
+  ~ You should have received a copy of the GNU General Public License along
+  ~ with this program.  If not, see <http://www.gnu.org/licenses/>.
+  -->
+
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="56dp"
+    android:background="?selectableItemBackground"
+    android:clickable="true"
+    android:orientation="horizontal"
+    android:paddingLeft="?listPreferredItemPaddingLeft"
+    android:paddingRight="?listPreferredItemPaddingRight">
+
+    <TextView
+        android:id="@+id/mode"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center_vertical"
+        android:layout_marginBottom="8dp"
+        android:layout_marginTop="8dp"
+        android:background="@drawable/badge"
+        android:fontFamily="monospace"
+        android:gravity="center"
+        android:minWidth="40dp"
+        android:textColor="?colorBackground"
+        android:textStyle="bold"
+        tools:text="\@"
+        />
+
+    <LinearLayout
+        android:layout_width="0dp"
+        android:layout_height="match_parent"
+        android:layout_marginLeft="16dp"
+        android:layout_marginStart="16dp"
+        android:layout_weight="1"
+        android:gravity="center_vertical|start"
+        android:orientation="vertical">
+
+        <TextView
+            android:id="@+id/nick"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:fontFamily="sans-serif-medium"
+            android:gravity="center_vertical|start"
+            android:lines="1"
+            android:singleLine="true"
+            android:textColor="?colorForegroundSecondary"
+            android:textSize="@dimen/material_drawer_item_primary_text"
+            android:textStyle="italic"
+            tools:text="justJanne"/>
+
+        <TextView
+            android:id="@+id/realname"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:fontFamily="sans-serif"
+            android:gravity="center_vertical|start"
+            android:lines="1"
+            android:singleLine="true"
+            android:textColor="?colorForegroundSecondary"
+            android:textSize="@dimen/material_drawer_item_primary_description"
+            android:textStyle="italic"
+            tools:text="Janne Koschinski: https://kuschku.de/"/>
+    </LinearLayout>
+</LinearLayout>
\ No newline at end of file
-- 
GitLab